Compare commits

...

191 Commits
1.56 ... master

Author SHA1 Message Date
Denis Molony 2bc330e377 tidying 2024-05-07 08:34:02 +10:00
Denis Molony 6c81bcc93b allow dos 4.5 2024-05-07 08:28:33 +10:00
Denis Molony 171fd66ba1 tidying 2024-05-02 12:38:45 +10:00
Denis Molony aa77ec1cd4 fixed catalog date display problem 2024-04-29 18:26:31 +10:00
Denis Molony 8f95988596 link to DiskBrowserApp 2024-04-06 16:33:53 +10:00
Denis Molony 8cb682f068 added C1/4100 2024-03-12 17:37:13 +10:00
Denis Molony dfc7a68580 renamed jarFolder 2023-09-30 23:55:41 +10:00
Denis Molony 4b476457d3 added ant build.xml 2023-09-28 15:27:27 +10:00
Denis Molony 3bf972a761 tidying 2023-09-16 06:51:31 +10:00
Denis Molony fd5bee6e5c tidying 2023-04-07 19:50:02 +10:00
Denis Molony 0af6714119 tidying 2023-03-16 09:00:31 +10:00
Denis Molony 22dfaf65c6 spacing 2023-03-11 16:35:48 +10:00
Denis Molony f4a6465b04 shorten absolute path 2023-02-24 12:33:21 +10:00
Denis Molony 64d5ce9ee2 allow 2img length = 0 2023-02-20 13:02:53 +10:00
Denis Molony 4e48437adc tidying 2023-02-15 20:30:34 +10:00
Denis Molony e2abdcabc9 added comment 2023-01-16 13:08:46 +10:00
Denis Molony bc0993e9d3 better pascal TEXT handling 2022-12-15 20:35:26 +10:00
Denis Molony 9fba3893ba tidying 2022-12-11 01:59:44 +10:00
Denis Molony 09c4542118 Merge branch 'master' of https://github.com/dmolony/DiskBrowser.git 2022-12-11 01:56:35 +10:00
Denis Molony af3ead0441 tidying 2022-12-11 01:54:00 +10:00
Denis Molony c12392200b
Merge pull request #24 from frankmilliron/master
Add some new equates
2022-11-27 04:53:01 +10:00
frankmilliron 794fef8610
Add some new equates 2022-11-26 10:31:06 -08:00
frankmilliron 2ec0e10c5e
Add some new equates 2022-11-26 10:27:06 -08:00
Denis Molony 668ed719fa tidying 2022-09-16 06:26:52 +10:00
Denis Molony 23b95675cf tidying 2022-08-22 16:55:32 +10:00
Denis Molony b98ecbed8d allow truncated bin2 files 2022-08-10 21:01:21 +10:00
Denis Molony 82381a6a47 fixed DateTime bug 2022-08-10 18:06:43 +10:00
Denis Molony 3f2f1bfbca stupid eclipse 2022-08-10 15:10:16 +10:00
Denis Molony a7119528a6 reorder block allocations 2022-08-10 15:08:10 +10:00
Denis Molony 6f943ae8c2 tidying 2022-07-31 10:08:15 +10:00
Denis Molony 5add6c0729 tidying 2022-07-31 09:58:00 +10:00
Denis Molony 921c946ab5 Added Squeeze format (BQY) 2022-07-31 09:21:52 +10:00
Denis Molony 898587b23b Added a formatted checkbox to the save dialog 2022-07-31 07:13:59 +10:00
Denis Molony 37c489f252 Fixed Pascal bug with invalid dates 2022-07-29 23:00:30 +10:00
Denis Molony 036e47b9b1 tidying 2022-07-09 08:13:05 +10:00
Denis Molony 250c1a9bd9 more spell code 2022-06-21 13:59:42 +10:00
Denis Molony b19e89d7cf fixed bug in known spells 2022-06-21 12:51:43 +10:00
Denis Molony d71cabb754 tidying 2022-06-17 18:24:43 +10:00
Denis Molony 848b2469ae refactoring Character 2022-06-11 15:52:58 +10:00
Denis Molony 989b1d5ab9 fixed link to WizardryApp 2022-06-10 15:59:47 +10:00
Denis Molony e0a2c50d5b fixed attributes bug 2022-06-10 15:56:48 +10:00
Denis Molony 8765299cf4 tidying 2022-06-09 16:14:52 +10:00
Denis Molony 97fe58d94d refactoring getWizLong and getSignedShort 2022-06-06 10:15:14 +10:00
Denis Molony 7d4d8c75e6 adjusted huffman decode routine 2022-06-04 13:06:20 +10:00
Denis Molony f5664a9ce9 Updated Item 2022-05-31 17:44:41 +10:00
Denis Molony 9d8cdcd67b explained wiz4 naming convention 2022-05-29 19:58:12 +10:00
Denis Molony 12b74f9d21 Wizardry IV screen 2022-05-29 19:51:19 +10:00
Denis Molony 1b405c6f38 tidying 2022-05-29 18:53:08 +10:00
Denis Molony 66d6910f91 started combining CharacterV1 and CharacterV4 2022-05-29 16:21:20 +10:00
Denis Molony 572ee8c3a1 added possessions to characters 2022-05-29 15:16:11 +10:00
Denis Molony 2a14b7baad display attributes and spells 2022-05-29 12:52:42 +10:00
Denis Molony a633e28ed3 added character parties 2022-05-29 10:43:10 +10:00
Denis Molony ca11e8ee68 improved group routine 2022-05-28 19:15:32 +10:00
Denis Molony ce52253f5d found how to group characters 2022-05-28 18:54:06 +10:00
Denis Molony e408aa3d62 tidying 2022-05-28 16:19:37 +10:00
Denis Molony c4b4d17f52 Items and Monsters for Wizardry IV 2022-05-28 12:59:25 +10:00
Denis Molony 0b72f1a37d Added characters to Wiz4 2022-05-27 18:30:30 +10:00
Denis Molony 1b86b31233 removed GregorianCalendar 2022-05-11 10:09:27 +10:00
Denis Molony 1b9e9d47ac checking Wiz4 disks 2022-05-03 15:36:37 +10:00
Denis Molony decc781572 tidying 2022-04-13 09:51:17 +10:00
Denis Molony 16ccc2632a allow woz disks to be saved as converted disk images 2022-04-09 18:25:02 +10:00
Denis Molony 40c2afbd48 tidying 2022-04-06 18:05:37 +10:00
Denis Molony f9038810d2 wrong picture 2022-03-31 12:06:39 +10:00
Denis Molony 3435e825df use stored experience points 2022-03-31 12:04:23 +10:00
Denis Molony ff7c6fd126 found bug in Wizardry exp points calculation 2022-03-29 18:00:32 +10:00
Denis Molony 91846d8563 later screen 2022-03-28 18:36:17 +10:00
Denis Molony 19b6339ac5 calculate experience points correctly 2022-03-28 17:02:01 +10:00
Denis Molony db4953618c allow woz format pascal disks 2022-03-28 13:55:49 +10:00
Denis Molony c1deee56a0 tidying 2022-03-26 21:37:41 +10:00
Denis Molony b1ed1a74ba tidying 2022-03-26 18:07:17 +10:00
Denis Molony cf0cfd278b added Message 2022-03-18 19:22:07 +10:00
Denis Molony 48aca6e1eb tidying 2022-03-14 08:46:56 +10:00
Denis Molony d83ac3afda changed Maze hex output to debug screen 2022-03-10 21:06:52 +10:00
Denis Molony 2270b1f6db tidying 2022-03-10 19:04:52 +10:00
Denis Molony da67dbe0d7 more details on maze levels 2022-03-10 16:21:18 +10:00
Denis Molony 133352ba31 various 2022-02-07 15:28:22 +10:00
Denis Molony 761c43dc3d changed award function 2022-02-07 15:26:42 +10:00
Denis Molony d03de97247 fixed stack overflow bug 2022-02-07 15:26:17 +10:00
Denis Molony e67bbeaf8b made some functions visible for Wizardry Disk Browser 2022-01-27 13:14:07 +10:00
Denis Molony 6dfc72b2d2 adding new instanceof pattern 2021-09-28 19:17:10 +10:00
Denis Molony fb748df4ae tidying 2021-09-19 17:09:34 +10:00
Denis Molony 4a03c411fc renamed DataPanel to OutputPanel 2021-09-18 23:44:48 +10:00
Denis Molony 54db7d95d6 replaced pascal screen 2021-09-18 23:28:48 +10:00
Denis Molony 59b22be2bd tidying 2021-09-16 18:24:13 +10:00
Denis Molony 47a07f5cfe added second pascal screen 2021-09-15 14:30:28 +10:00
Denis Molony bca12f0738 tidying 2021-09-15 10:51:45 +10:00
Denis Molony 27100ad38e DreamGraphix 3200 2021-08-30 16:56:43 +10:00
Denis Molony 2a6fd74013 tidying 2021-08-20 20:04:53 +10:00
Denis Molony 4767c317d0 fixed bad prodos date 2021-07-30 19:33:03 +10:00
Denis Molony 068f382c87 tidying 2021-07-30 06:03:40 +10:00
Denis Molony e7d8c4ebc2 tidying 2021-07-29 13:18:13 +10:00
Denis Molony 9ef0f82dea tidying 2021-07-29 13:17:36 +10:00
Denis Molony fba8c07142 tidying 2021-07-29 09:35:07 +10:00
Denis Molony 4aefc8b695 abandoned load address indexing 2021-07-29 09:33:41 +10:00
Denis Molony a8574d24f8 moved code to Utility 2021-07-29 06:32:22 +10:00
Denis Molony 449e6c0e9a tidying 2021-07-28 17:19:32 +10:00
Denis Molony 09b6f66855 MS floating point 2021-07-28 14:42:28 +10:00
Denis Molony f30fe1a78a debugged bug in debug 2021-07-27 17:58:39 +10:00
Denis Molony 0e40e25710 debug for CP/M basic 2021-07-27 17:55:19 +10:00
Denis Molony f02c932d91 tidying 2021-07-27 15:57:46 +10:00
Denis Molony c18cfe9ed7 more CP/M basic tokens 2021-07-27 11:58:43 +10:00
Denis Molony dcb3e32845 more CP/M basic 2021-07-26 21:39:05 +10:00
Denis Molony 08d6d1b136 better CP/M basic 2021-07-26 15:42:40 +10:00
Denis Molony 954b0c0bd8 more CP/M basic 2021-07-26 12:02:52 +10:00
Denis Molony f22b4dcd46 tidying 2021-07-25 21:11:50 +10:00
Denis Molony c42481637e oops 2021-07-25 18:31:02 +10:00
Denis Molony 7ca8160d13 initial CP/M basic 2021-07-25 18:30:22 +10:00
Denis Molony 26316a82a9 better CP/M format checker 2021-07-24 20:59:00 +10:00
Denis Molony 5f29cfcd09 removed protected from AbstractFile.name 2021-07-24 18:08:40 +10:00
Denis Molony 7f2e963689 tidying 2021-07-22 19:40:52 +10:00
Denis Molony 8ea18c8cc1 resource fork in DefaultAppleFile 2021-07-21 21:17:43 +10:00
Denis Molony f92fe5b57e edit 2021-07-02 20:36:59 +10:00
Denis Molony bb4dcbdd7c edit 2021-07-02 20:33:10 +10:00
Denis Molony 8aec65449e edit 2021-07-02 20:31:31 +10:00
Denis Molony ff273e7df9 edit 2021-07-02 20:26:59 +10:00
Denis Molony 1a1f9df93f edit 2021-07-02 16:33:12 +10:00
Denis Molony 80a07c0496 edit 2021-07-02 16:11:53 +10:00
Denis Molony 8369e4a788 edit 2021-07-02 16:09:37 +10:00
Denis Molony bfeab1477c edit 2021-07-02 16:04:42 +10:00
Denis Molony ad8464c6c2 edit 2021-07-02 16:03:31 +10:00
Denis Molony b1ff2f7740 edit 2021-07-02 16:01:45 +10:00
Denis Molony 4040238bbf edit 2021-07-02 15:59:50 +10:00
Denis Molony 70f21070d5 edit 2021-07-02 15:58:19 +10:00
Denis Molony 91693bbc37 edit 2021-07-02 15:56:54 +10:00
Denis Molony 8a9b824302 edit 2021-07-02 15:53:09 +10:00
Denis Molony 06f4713baa edit 2021-07-02 15:49:55 +10:00
Denis Molony e7ded68b03 extra screen 2021-07-02 15:48:30 +10:00
Denis Molony 58cec66535 edited 2021-07-02 15:45:07 +10:00
Denis Molony c105d07e60 doco for applesoft formatting 2021-07-02 15:43:17 +10:00
Denis Molony 3e32b3caf0 fixed bolloxed pascal date format 2021-06-25 19:04:20 +10:00
Denis Molony 7aa80b8b5e date format fix 2021-06-19 19:46:59 +10:00
Denis Molony 5e053872a9 CPM fixes 2021-06-18 10:48:38 +10:00
Denis Molony 7d162a4baf more listeners, recognise deleted CPM files 2021-06-14 15:55:35 +10:00
Denis Molony 83d5be3f9f more PropertyChangeListeners 2021-06-06 16:27:30 +10:00
Denis Molony ea0a827331 fixed the hide panel actions 2021-06-04 16:53:04 +10:00
Denis Molony dc551285bb tidying 2021-06-03 18:11:44 +10:00
Denis Molony 95538f5282 Extracted AnimationWorker from DataPanel 2021-06-03 14:59:13 +10:00
Denis Molony 9d706d62ef extracted ImagePanel from DataPanel 2021-06-03 14:52:10 +10:00
Denis Molony 63fc59accc using PropertyChangeListeners 2021-06-02 11:48:57 +10:00
Denis Molony beb0830c25 created more listeners 2021-06-01 20:29:34 +10:00
Denis Molony ae1188ae27 tidying 2021-06-01 20:21:21 +10:00
Denis Molony 1b27ea02e7 tidying 2021-05-22 20:15:20 +10:00
Denis Molony c2f2277717 use both 2021-05-22 11:10:59 +10:00
Denis Molony 79ccd6793c https://jdk.java.net/16/ 2021-05-22 11:02:49 +10:00
Denis Molony 5be0236845 changed to https://jdk.java.net 2021-05-22 10:55:19 +10:00
Denis Molony 59bf768d14 more descriptions 2021-05-22 10:41:04 +10:00
Denis Molony 566479450a added duplicates screenshot 2021-05-22 10:31:33 +10:00
Denis Molony b45e7d7e54 new disk list image 2021-05-22 09:59:06 +10:00
Denis Molony 9dddd2be3e combined file and buffer saves 2021-05-21 14:36:44 +10:00
Denis Molony d3f21e0d49 better save error dialogs 2021-05-21 13:34:33 +10:00
Denis Molony af706e03c7 tidying 2021-05-21 12:59:54 +10:00
Denis Molony b6496e9c87 created nufx package 2021-05-21 12:57:03 +10:00
Denis Molony a33aedd750 tidying 2021-05-21 12:50:23 +10:00
Denis Molony 13647213c6 refactoring 2021-05-20 20:13:06 +10:00
Denis Molony 5ea96a260d Save disk/file/sectors 2021-05-20 12:44:40 +10:00
Denis Molony 438dd9dd4c tidying save actions 2021-05-19 19:28:04 +10:00
Denis Molony 45a97d2959 tidying 2021-05-19 19:07:45 +10:00
Denis Molony a8de9099b1 tidying 2021-05-19 18:19:55 +10:00
Denis Molony adf77ba603 tidying 2021-05-19 18:19:25 +10:00
Denis Molony 62c09af14f consolidated some of the getWord() type routines in Utility, also allow
user to save the current file buffer to the local file system.
2021-05-19 18:13:17 +10:00
Denis Molony ddadfd3198 display resource forks 2021-05-17 21:07:09 +10:00
Denis Molony 4f95871d83 tidying 2021-05-14 12:38:45 +10:00
Denis Molony fe2df5247c removed getWordBigEndian 2021-05-14 12:23:01 +10:00
Denis Molony 3bd836a828 removing calls to intValue() 2021-05-14 12:19:32 +10:00
Denis Molony a72bdff81d Allow partial unpacking of corrupt NuFX disks 2021-05-13 14:56:56 +10:00
Denis Molony 90f8657722 binary2 summary 2021-05-12 19:15:32 +10:00
Denis Molony b7106787d1 keep suffixes private 2021-05-12 18:14:49 +10:00
Denis Molony 3c2816baf0 Delay the toString call on AppleDisk 2021-05-12 17:08:24 +10:00
Denis Molony c6443ff89e display nufx disks correctly 2021-05-08 19:56:57 +10:00
Denis Molony 269a1bbd83 show NuFX contents on disk file display 2021-05-06 21:30:23 +10:00
Denis Molony 768111571e no summary 2021-05-06 18:21:57 +10:00
Denis Molony d6d0b1672e wrap print lines at 80 columns 2021-05-06 18:14:40 +10:00
Denis Molony 76b2d4a291 moved toString() back to SubLine 2021-05-06 08:26:47 +10:00
Denis Molony c3ee00673d applesoft alignment bug 2021-05-06 08:12:46 +10:00
Denis Molony 7ec277e0a3 tidying 2021-05-05 14:32:38 +10:00
Denis Molony 33b58e8d79 indicate resource forks 2021-05-05 13:10:33 +10:00
Denis Molony 73e964fe76 tidying 2021-05-04 16:31:11 +10:00
Denis Molony 7d79f8f365 use eof 2021-05-04 10:02:20 +10:00
Denis Molony 2dff5a966c write resource fork 2021-05-04 08:50:30 +10:00
Denis Molony ccbfc47a66 removed buffer parameter 2021-05-04 07:24:08 +10:00
Denis Molony 032da321c3 Created FileWriter 2021-05-04 06:12:44 +10:00
Denis Molony 39269d3b27 tidying 2021-05-02 14:46:52 +10:00
Denis Molony a006053297 NuFX summary 2021-05-02 14:45:26 +10:00
Denis Molony 4353d0e0ca tidying 2021-05-02 09:38:24 +10:00
Denis Molony f7b455a7f1 re-enabled bxy 2021-04-28 14:34:41 +10:00
Denis Molony bb1a7af6c8 debug output for prodos catalogs 2021-04-27 21:26:09 +10:00
Denis Molony 0032b0c2bb testing 2021-04-26 10:03:43 +10:00
Denis Molony 113917e278 tidying 2021-04-25 18:14:14 +10:00
Denis Molony 8db6489649 tidying 2021-04-25 12:08:09 +10:00
Denis Molony e135b65948 bug when adding a catalog block to the top level 2021-04-24 15:37:57 +10:00
Denis Molony d0bfde2e80 parentPointer bug 2021-04-24 13:01:58 +10:00
197 changed files with 7652 additions and 3698 deletions

4
.gitignore vendored
View File

@ -1,4 +0,0 @@
/bin/
.project
.classpath
build.xml

View File

@ -1,5 +1,6 @@
# Apple II Disk Browser
### Alternative
There is a new release of [DiskBrowser2](https://github.com/dmolony/diskbrowser2) available.
### Features
- Cross-platform (Windows, MacOS, Linux)
- Disk formats
@ -30,7 +31,7 @@
* [Usage](resources/usage.md)
### Installation
* Install the **latest** version of the [JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html).
* Install the **latest** version of the [JDK](https://www.oracle.com/java/technologies/downloads/).
* Download DiskBrowser.jar from the [releases](https://github.com/dmolony/diskbrowser/releases) page.
* Double-click the jar file, or enter 'java -jar DiskBrowser.jar' in the terminal.
* Set your root folder (the top-level folder where you keep your disk images).
@ -52,14 +53,24 @@ Java runs on Windows, MacOS and Linux.
#### Graphics
![Graphics](resources/graphics.png?raw=true "Graphics")
#### Applesoft Formatting and Analysis
Applesoft programs are displayed in a modern, easily-readable format. A comprehensive cross-listing of variables, strings, calls and jumps is available. Easily find duplicate variable names.
For the truly retro look, programs can be displayed in the [original 40-column line wrap](resources/basic.md) mode.
![Applesoft](resources/basic.png?raw=true "Applesoft")
#### Pascal code
![Pascal](resources/pascal.png?raw=true "Pascal")
![Pascal](resources/pascal1.png?raw=true "Pascal text")
![Pascal](resources/pascal2.png?raw=true "Pascal internals")
#### Infocom
![Infocom](resources/zork.png?raw=true "Infocom")
#### Wizardry
Wizardry scenarios 1 to 3 are reasonably complete, Wizardry IV and V are partially done. For a dedicated Wizardry application see [WizardryApp](https://github.com/dmolony/WizardryApp).
![Wizardry](resources/wizardry.png?raw=true "Wizardry")
Scenarios 4 and 5 come on multiple disks, and they need to be named so that the only difference between disk names is the identifier before the '.dsk' suffix.
![Wizardry](resources/wizardry4.png?raw=true "Wizardry IV")
#### Visicalc
DiskBrowser has an inbuilt Visicalc processor which will evaluate the sheet and display the results.
![Visicalc](resources/visicalc.png?raw=true "Visicalc")
#### Complete Disk List
Generates a list of all the disks in your collection. The list can be sorted by any of the table headings. Checksums can be generated as needed, or for the whole collection.
![Disk List](resources/disklist.png?raw=true "Disk List")
Select a disk and click the duplicates button to see all of the disks that share the same checksum.
![Duplicates](resources/duplicates.png?raw=true "Duplicates")

40
build.xml Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="DiskBrowser" default="jar" basedir=".">
<property name="srcDir" location="src" />
<property name="binDir" location="bin" />
<property name="jarDir" location="${user.home}/Dropbox/Java" />
<property name="jarFile" location="${jarDir}/DiskBrowser.jar" />
<target name="version">
<echo>DiskBrowser.jar</echo>
<echo>${ant.version}</echo>
<echo>Java/JVM version: ${ant.java.version}</echo>
<echo>Java/JVM detail version: ${java.version}</echo>
</target>
<target name="init" depends="version">
<delete file="${binDir}/*.class" />
<delete file="${jarFile}" />
</target>
<target name="compile" depends="init">
<javac debug="on" srcdir="${srcDir}" destdir="${binDir}" includeantruntime="false">
<classpath>
<pathelement location="." />
</classpath>
</javac>
</target>
<target name="jar" depends="compile">
<jar destfile="${jarFile}">
<fileset dir="${binDir}" />
<zipfileset src="${jarDir}/InputPanel.jar" />
<manifest>
<attribute name="Main-Class" value="com.bytezone.diskbrowser.gui.DiskBrowser" />
</manifest>
</jar>
</target>
</project>

13
resources/basic.md Normal file
View File

@ -0,0 +1,13 @@
### Applesoft program listing
#### State of the art circa 1980
<img src="basic0.png" alt="terrible" width="700"/>
#### Original (using Print Char 21)
<img src="basic5.png" alt="truly awful" width="400"/>
#### No formatting
<img src="basic2.png" alt="better" width="850"/>
#### Formatted
<img src="basic3.png" alt="best" width="550"/>

BIN
resources/basic0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

BIN
resources/basic1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
resources/basic2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
resources/basic3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
resources/basic4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
resources/basic5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
resources/duplicates.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 KiB

BIN
resources/pascal1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
resources/pascal2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 642 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
resources/wizardry4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -6,6 +6,7 @@ import javax.swing.JComponent;
import javax.swing.JPanel;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.prodos.ResourceFork;
import com.bytezone.diskbrowser.utilities.HexFormatter;
// -----------------------------------------------------------------------------------//
@ -16,9 +17,10 @@ public abstract class AbstractFile implements DataSource
protected String name;
public byte[] buffer;
protected AssemblerProgram assembler;
AssemblerProgram assembler;
protected BufferedImage image;
protected int loadAddress;
int loadAddress;
ResourceFork resourceFork;
// ---------------------------------------------------------------------------------//
public AbstractFile (String name, byte[] buffer)
@ -28,12 +30,37 @@ public abstract class AbstractFile implements DataSource
this.buffer = buffer;
}
// ---------------------------------------------------------------------------------//
public void setName (String name)
// ---------------------------------------------------------------------------------//
{
this.name = name; // Infocom ZObject uses this - but it sucks
}
// ---------------------------------------------------------------------------------//
@Override
public String getText () // Override this to get a tailored text representation
// ---------------------------------------------------------------------------------//
{
return "Name : " + name + "\n\nNo text description";
StringBuilder text = new StringBuilder ();
text.append ("Name : " + name + "\n\nNo text description");
if (resourceFork != null)
{
text.append ("\n\nResource Fork:\n\n");
text.append (resourceFork);
}
return text.toString ();
}
// ---------------------------------------------------------------------------------//
@Override
public byte[] getBuffer ()
// ---------------------------------------------------------------------------------//
{
return buffer;
}
// ---------------------------------------------------------------------------------//
@ -43,6 +70,13 @@ public abstract class AbstractFile implements DataSource
showDebugText = value;
}
// ---------------------------------------------------------------------------------//
public void setResourceFork (ResourceFork resourceFork)
// ---------------------------------------------------------------------------------//
{
this.resourceFork = resourceFork;
}
// ---------------------------------------------------------------------------------//
public static void setDebug (boolean value)
// ---------------------------------------------------------------------------------//
@ -106,7 +140,6 @@ public abstract class AbstractFile implements DataSource
public JComponent getComponent ()
// ---------------------------------------------------------------------------------//
{
JPanel panel = new JPanel ();
return panel;
return new JPanel ();
}
}

View File

@ -1,7 +1,5 @@
package com.bytezone.diskbrowser.applefile;
import static com.bytezone.diskbrowser.utilities.Utility.isControlCharacter;
// ---------------------------------------------------------------------------------//
class Alignment implements ApplesoftConstants
// ---------------------------------------------------------------------------------//
@ -34,8 +32,6 @@ class Alignment implements ApplesoftConstants
void check (SubLine subline)
// ---------------------------------------------------------------------------------//
{
// System.out.printf ("%-20s %d %d%n", subline, subline.equalsPosition,
// subline.endPosition - subline.equalsPosition);
if (equalsPosition < subline.equalsPosition)
equalsPosition = subline.equalsPosition;
@ -50,7 +46,7 @@ class Alignment implements ApplesoftConstants
public String getAlignedText (SubLine subline)
// ---------------------------------------------------------------------------------//
{
StringBuilder line = toStringBuilder (subline); // get line
StringBuilder line = subline.toStringBuilder (); // get line
if (equalsPosition == 0 || subline.is (TOKEN_REM))
return line.toString ();
@ -59,48 +55,28 @@ class Alignment implements ApplesoftConstants
int targetLength = subline.endPosition - equalsPosition;
// insert spaces before '=' until it lines up with the other assignment lines
while (alignEqualsPos-- > equalsPosition)
line.insert (equalsPosition, ' ');
while (alignEqualsPos-- > subline.equalsPosition)
line.insert (subline.equalsPosition, ' ');
if (line.charAt (line.length () - 1) == ':')
while (targetLength++ <= targetLength)
while (targetLength++ <= this.targetLength)
line.append (" ");
return line.toString ();
}
// ---------------------------------------------------------------------------------//
private StringBuilder toStringBuilder (SubLine subline)
@Override
public String toString ()
// ---------------------------------------------------------------------------------//
{
StringBuilder line = new StringBuilder ();
StringBuilder text = new StringBuilder ();
// All sublines end with 0 or : except IF lines that are split into two
int max = subline.startPtr + subline.length - 1;
if (subline.buffer[max] == 0)
--max;
text.append (String.format ("Equals position ..... %d%n", equalsPosition));
text.append (String.format ("Target length ....... %d%n", targetLength));
text.append (String.format ("First subline ....... %s%n", firstSubLine));
text.append (String.format ("Last subline ........ %s", lastSubLine));
if (subline.isImpliedGoto () && !ApplesoftBasicProgram.basicPreferences.showThen)
line.append ("GOTO ");
for (int p = subline.startPtr; p <= max; p++)
{
byte b = subline.buffer[p];
if (subline.isToken (b))
{
if (line.length () > 0 && line.charAt (line.length () - 1) != ' ')
line.append (' ');
int val = b & 0x7F;
if (b != TOKEN_THEN || ApplesoftBasicProgram.basicPreferences.showThen)
line.append (ApplesoftConstants.tokens[val] + " ");
}
// else if (Utility.isControlCharacter (b))
// line.append (ApplesoftBasicProgram.basicPreferences.showCaret
// ? "^" + (char) (b + 64) : "?");
else if (!isControlCharacter (b))
line.append ((char) b);
}
return line;
return text.toString ();
}
}

View File

@ -4,8 +4,8 @@ import static com.bytezone.diskbrowser.utilities.Utility.ASCII_BACKSPACE;
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_CR;
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_LF;
import static com.bytezone.diskbrowser.utilities.Utility.getIndent;
import static com.bytezone.diskbrowser.utilities.Utility.getShort;
import static com.bytezone.diskbrowser.utilities.Utility.isHighBitSet;
import static com.bytezone.diskbrowser.utilities.Utility.unsignedShort;
import com.bytezone.diskbrowser.gui.BasicPreferences;
@ -37,9 +37,9 @@ public class AppleBasicFormatter extends BasicFormatter
LineFormatter formatter =
basicPreferences.appleLineWrap ? wrapFormatter : flatFormatter;
while ((linkField = unsignedShort (buffer, ptr)) != 0)
while ((linkField = getShort (buffer, ptr)) != 0)
{
int lineNumber = unsignedShort (buffer, ptr + 2);
int lineNumber = getShort (buffer, ptr + 2);
currentLine.append (String.format (" %d ", lineNumber));
ptr += 4;

View File

@ -10,7 +10,7 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons
// -----------------------------------------------------------------------------------//
{
private final List<SourceLine> sourceLines = new ArrayList<> ();
private int ptr; // end-of-program marker
private int ptr = 0; // end-of-program marker
private final UserBasicFormatter userBasicFormatter;
private final AppleBasicFormatter appleBasicFormatter;
@ -78,13 +78,6 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons
return sourceLines;
}
// ---------------------------------------------------------------------------------//
byte[] getBuffer ()
// ---------------------------------------------------------------------------------//
{
return buffer;
}
// ---------------------------------------------------------------------------------//
int getEndPtr ()
// ---------------------------------------------------------------------------------//

View File

@ -1,6 +1,6 @@
package com.bytezone.diskbrowser.applefile;
import static com.bytezone.diskbrowser.utilities.Utility.unsignedShort;
import static com.bytezone.diskbrowser.utilities.Utility.getShort;
import java.util.List;
@ -35,14 +35,14 @@ public abstract class BasicFormatter implements ApplesoftConstants
int getLoadAddress ()
// ---------------------------------------------------------------------------------//
{
return (buffer.length > 3) ? unsignedShort (buffer, 0) - getFirstLineLength () : 0;
return (buffer.length > 3) ? getShort (buffer, 0) - getFirstLineLength () : 0;
}
// ---------------------------------------------------------------------------------//
private int getFirstLineLength ()
// ---------------------------------------------------------------------------------//
{
int linkField = unsignedShort (buffer, 0);
int linkField = getShort (buffer, 0);
if (linkField == 0)
return 2;

View File

@ -136,7 +136,7 @@ public class BasicProgramGS extends BasicProgram
ptr += labelLength;
int lineLength = buffer[ptr] & 0xFF;
lineNumber = Utility.intValue (buffer[ptr + 1], buffer[ptr + 2]);
lineNumber = Utility.getShort (buffer, ptr + 1);
length = labelLength + lineLength;
if (lineNumber == 0)

View File

@ -8,8 +8,8 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class BasicTextFile extends TextFile
// -----------------------------------------------------------------------------------//
{
private static String underline = "------------------------------------------"
+ "------------------------------------\n";
private static String underline =
"------------------------------------------" + "------------------------------------\n";
private static String fullUnderline = "---------- ------- " + underline;
private int recordLength; // prodos aux
private List<TextBuffer> buffers; // only used if it is a Prodos text file
@ -30,6 +30,7 @@ public class BasicTextFile extends TextFile
super (name, buffer);
this.eof = eof;
recordLength = auxType;
prodosFile = true;
}
@ -42,6 +43,7 @@ public class BasicTextFile extends TextFile
this.buffers = buffers;
this.eof = eof;
recordLength = auxType;
prodosFile = true;
}
@ -167,8 +169,7 @@ public class BasicTextFile extends TextFile
if (textPreferences.showTextOffsets)
{
line = line.replaceAll ("\\n", "\n ");
text.append (
String.format ("%,10d %,8d %s%n", recNo * recordLength, recNo, line));
text.append (String.format ("%,10d %,8d %s%n", recNo * recordLength, recNo, line));
}
else
text.append (String.format ("%s%n", line));

View File

@ -0,0 +1,229 @@
package com.bytezone.diskbrowser.applefile;
import static com.bytezone.diskbrowser.utilities.Utility.getShort;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class CPMBasicFile extends BasicProgram
// -----------------------------------------------------------------------------------//
{
String[] tokens = { //
"", "END", "FOR", "NEXT", "DATA", "INPUT", "DIM", "READ", // 0x80
"LET", "GOTO", "RUN", "IF", "RESTORE", "GOSUB", "RETURN", "REM", // 0x88
"STOP", "PRINT", "CLEAR", "LIST", "NEW", "ON", "DEF", "POKE", // 0x90
"", "", "", "LPRINT", "LLIST", "WIDTH", "ELSE", "", // 0x98
"", "SWAP", "ERASE", "", "ERROR", "RESUME", "DELETE", "", // 0xA0
"RENUM", "DEFSTR", "DEFINT", "", "DEFDBL", "LINE", "", "WHILE", // 0xA8
"WEND", "CALL", "WRITE", "COMMON", "CHAIN", // 0xB0
"OPTION", "RANDOMIZE", "SYSTEM", // 0xB5
"OPEN", "FIELD", "GET", "PUT", "CLOSE", "LOAD", "MERGE", "", // 0xB8
"NAME", "KILL", "LSET", "RSET", "SAVE", "RESET", "TEXT", "HOME", // 0xC0
"VTAB", "HTAB", "INVERSE", "NORMAL", "", "", "", "", // 0xC8
"", "", "", "", "", "WAIT", "", "", // 0xD0
"", "", "", "", "", "TO", "THEN", "TAB(", // 0xD8
"STEP", "USR", "FN", "SPC(", "", "ERL", "ERR", "STRING$", // 0xE0
"USING", "INSTR", "'", "VARPTR", "", "", "INKEY$", ">", // 0xE8
"=", "<", "+", "-", "*", "/", "", "AND", // 0xF0
"OR", "", "", "", "MOD", "/", "", "", // 0xF8
};
String[] functions = { //
"", "LEFT$", "RIGHT$", "MID$", "SGN", "INT", "ABS", "SQR", // 0x80
"RND", "SIN", "LOG", "EXP", "COS", "TAN", "ATN", "FRE", // 0x88
"POS", "LEN", "STR$", "VAL", "ASC", "CHR$", "PEEK", "SPACE$", // 0x90
"OCT$", "HEX$", "LPOS", "CINT", "CSNG", "CDBL", "FIX", "", // 0x98
"", "", "", "", "", "", "", "", // 0xA0
"", "", "CVI", "CVS", "CVD", "", "EOF", "LOC", // 0xA8
"", "MKI$", "MKS$", "MKD$", // 0xB0
};
// ---------------------------------------------------------------------------------//
public CPMBasicFile (String name, byte[] buffer)
// ---------------------------------------------------------------------------------//
{
super (name, buffer);
}
// ---------------------------------------------------------------------------------//
@Override
public String getText ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
if (basicPreferences.showHeader)
text.append ("Name : " + name + "\n\n");
int ptr = 5;
while (buffer[ptr] != 0)
ptr++;
if (showDebugText)
return debugText ();
ptr = 1;
while (ptr < buffer.length)
{
int nextAddress = getShort (buffer, ptr);
if (nextAddress == 0)
break;
int lineNumber = getShort (buffer, ptr + 2);
text.append (String.format (" %d ", lineNumber));
ptr += 4;
while (true)
{
int val = buffer[ptr++] & 0xFF;
if (val == 0)
break;
if ((val & 0x80) != 0)
{
if (val == 0xFF)
{
val = buffer[ptr++] & 0xFF;
String token = functions[val & 0x7F];
if (token.length () == 0)
token = String.format ("<FF %02X>", val);
text.append (token);
}
else
{
String token = tokens[val & 0x7F];
if (token.length () == 0)
token = String.format ("<%02X>", val);
text.append (token);
}
continue;
}
if (val >= 0x20 && val <= 0x7E) // printable
{
// check for stupid apostrophe comment
if (val == 0x3A && ptr + 1 < buffer.length && buffer[ptr] == (byte) 0x8F
&& buffer[ptr + 1] == (byte) 0xEA)
{
text.append ("'");
ptr += 2;
}
else if (val == 0x3A && ptr < buffer.length && buffer[ptr] == (byte) 0x9E)
{
// ignore colon before ELSE
}
else
text.append (String.format ("%s", (char) val));
continue;
}
if (val >= 0x11 && val <= 0x1A) // inline numbers
{
text.append (val - 0x11);
continue;
}
switch (val)
{
case 0x07:
text.append ("<BELL>");
break;
case 0x09:
text.append (" ");
break;
case 0x0A:
text.append ("\n ");
break;
case 0x0C:
text.append ("&H" + String.format ("%X", Utility.getShort (buffer, ptr)));
ptr += 2;
break;
case 0x0E: // same as 0x1C ??
text.append (Utility.getShort (buffer, ptr));
ptr += 2;
break;
case 0x0F:
text.append (buffer[ptr++] & 0xFF);
break;
case 0x1C: // same as 0x0E ??
text.append (Utility.getShort (buffer, ptr));
ptr += 2;
break;
case 0x1D:
String d4 = Utility.floatValueMS4 (buffer, ptr) + "";
if (d4.endsWith (".0"))
d4 = d4.substring (0, d4.length () - 2);
text.append (d4 + "!");
ptr += 4;
break;
case 0x1F:
String d8 = Utility.floatValueMS8 (buffer, ptr) + "";
if (d8.endsWith (".0"))
d8 = d8.substring (0, d8.length () - 2);
text.append (d8 + "#");
ptr += 8;
break;
default:
text.append (String.format ("<%02X>", val));
}
}
text.append ("\n");
}
return Utility.rtrim (text);
}
// ---------------------------------------------------------------------------------//
private String debugText ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
int ptr = 1;
int lastPtr;
while (ptr < buffer.length)
{
int nextAddress = getShort (buffer, ptr);
if (nextAddress == 0)
break;
int lineNumber = getShort (buffer, ptr + 2);
lastPtr = ptr;
ptr += 4;
int val;
while ((val = buffer[ptr++]) != 0)
{
ptr += switch (val)
{
case 0x0C, 0x0E, 0x1C -> 2; // 2 byte numeric
case 0x1D -> 4; // 4 byte single precision
case 0x1F -> 8; // 8 byte double precision
case 0x0F, 0xFF -> 1; // 1 byte numeric, function table entry
default -> 0;
};
}
text.append (String.format (" %d %s%n", lineNumber,
HexFormatter.getHexString (buffer, lastPtr + 4, ptr - lastPtr - 4)));
}
return Utility.rtrim (text);
}
}

View File

@ -26,7 +26,10 @@ public class CPMTextFile extends TextFile
{
String line = getLine (ptr);
text.append (line + "\n");
ptr += line.length () + 2;
ptr += line.length () + 1;
if (ptr < buffer.length && buffer[ptr - 1] == 0x0D && buffer[ptr] == 0x0A)
++ptr;
while (ptr < buffer.length && buffer[ptr] == 0)
++ptr;
}
@ -43,8 +46,8 @@ public class CPMTextFile extends TextFile
{
StringBuilder line = new StringBuilder ();
int max = buffer.length - 1;
while (ptr < max && buffer[ptr] != 0x0D && buffer[ptr + 1] != 0x0A)
// int max = buffer.length - 1;
while (ptr < buffer.length && buffer[ptr] != 0x0D && buffer[ptr] != 0x0A)
line.append ((char) (buffer[ptr++] & 0x7F));
return line.toString ();

View File

@ -18,6 +18,7 @@ public class DefaultAppleFile extends AbstractFile
// ---------------------------------------------------------------------------------//
{
super (name, buffer);
this.text = "Name : " + name + "\n\n" + text;
}
@ -35,8 +36,10 @@ public class DefaultAppleFile extends AbstractFile
{
if (text != null)
return text;
if (buffer == null)
return "Invalid file : " + name;
return super.getText ();
}
}

View File

@ -44,22 +44,22 @@ public class DosMasterFile extends AbstractFile
System.out.print ("\nFirst Block : ");
for (int i = 0; i < 16; i += 2)
{
System.out.printf ("%04X ", Utility.unsignedShort (buffer, 0x40 + i));
System.out.printf ("%04X ", Utility.getShort (buffer, 0x40 + i));
if (i % 4 == 2)
System.out.print (": ");
}
System.out.print ("\nLast Block : ");
for (int i = 0; i < 8; i += 2)
System.out.printf ("%04X : ", Utility.unsignedShort (buffer, 0x50 + i));
System.out.printf ("%04X : ", Utility.getShort (buffer, 0x50 + i));
System.out.print ("\nImage Size : ");
for (int i = 0; i < 8; i += 2)
System.out.printf ("%04X : ", Utility.unsignedShort (buffer, 0x58 + i));
System.out.printf ("%04X : ", Utility.getShort (buffer, 0x58 + i));
System.out.print ("\nAddress : ");
for (int i = 0; i < 8; i += 2)
System.out.printf ("%04X : ", Utility.unsignedShort (buffer, 0x60 + i));
System.out.printf ("%04X : ", Utility.getShort (buffer, 0x60 + i));
System.out.println ();
System.out.println ();
@ -75,12 +75,12 @@ public class DosMasterFile extends AbstractFile
int slot = (slotDrive & 0x70) >>> 4;
int drive = ((slotDrive & 0x80) >>> 7) + 1;
int firstBlock = Utility.unsignedShort (buffer, 0x40 + i * 2); // of first volume
int firstBlock = Utility.getShort (buffer, 0x40 + i * 2); // of first volume
int skip = i / 2 * 2; // 0, 0, 2, 2, 4, 4, 6, 6 - same for both drives
int lastBlock = Utility.unsignedShort (buffer, 0x50 + skip); // of last volume
int volSize = Utility.unsignedShort (buffer, 0x58 + skip);
int lastBlock = Utility.getShort (buffer, 0x50 + skip); // of last volume
int volSize = Utility.getShort (buffer, 0x58 + skip);
int originalFirstBlock = firstBlock;
if (firstBlock > lastBlock) // WTF?
@ -176,9 +176,9 @@ public class DosMasterFile extends AbstractFile
text.append (String.format ("Slot %d, Drive %d has", s / 16, dr + 1));
int ptr = v0 + 2 * d0 + 2 * dr;
int st = Utility.unsignedShort (buffer, ptr); // start block of first volume
int v = Utility.unsignedShort (buffer, size + d0); // end block of last volume
int sz = Utility.unsignedShort (buffer, vsiz + d0); // blocks per volume
int st = Utility.getShort (buffer, ptr); // start block of first volume
int v = Utility.getShort (buffer, size + d0); // end block of last volume
int sz = Utility.getShort (buffer, vsiz + d0); // blocks per volume
if (st > v)
st -= 16 * 4096;

View File

@ -84,7 +84,7 @@ public class ExoBuffer
return false;
}
int address = Utility.unsignedShort (buffer, buffer.length - 2);
int address = Utility.getShort (buffer, buffer.length - 2);
if (address != 0x6000 && address != 0x8000 && address != 0xA000)
{

View File

@ -28,11 +28,11 @@ public class FileTypeDescriptorTable extends AbstractFile
versionMajor = buffer[0] & 0xFF;
versionMinor = buffer[1] & 0xFF;
flags = Utility.unsignedShort (buffer, 2);
numEntries = Utility.unsignedShort (buffer, 4);
spareWord = Utility.unsignedShort (buffer, 6);
indexRecordSize = Utility.unsignedShort (buffer, 8);
offsetToIdx = Utility.unsignedShort (buffer, 10);
flags = Utility.getShort (buffer, 2);
numEntries = Utility.getShort (buffer, 4);
spareWord = Utility.getShort (buffer, 6);
indexRecordSize = Utility.getShort (buffer, 8);
offsetToIdx = Utility.getShort (buffer, 10);
int ptr = offsetToIdx;
for (int i = 0; i < numEntries; i++)
@ -80,10 +80,10 @@ public class FileTypeDescriptorTable extends AbstractFile
public IndexRecord (byte[] buffer, int offset)
{
fileType = Utility.unsignedShort (buffer, offset);
auxType = Utility.unsignedLong (buffer, offset + 2);
flags = Utility.unsignedShort (buffer, offset + 6);
this.offset = Utility.unsignedShort (buffer, offset + 8);
fileType = Utility.getShort (buffer, offset);
auxType = Utility.getLong (buffer, offset + 2);
flags = Utility.getShort (buffer, offset + 6);
this.offset = Utility.getShort (buffer, offset + 8);
string = HexFormatter.getPascalString (buffer, this.offset);
}

View File

@ -18,98 +18,101 @@ public abstract class HiResImage extends AbstractFile
{
static final String[] auxTypes =
{ "Paintworks Packed SHR Image", "Packed Super Hi-Res Image",
"Super Hi-Res Image (Apple Preferred Format)", "Packed QuickDraw II PICT File",
"Packed Super Hi-Res 3200 color image" };
"Super Hi-Res Image (Apple Preferred Format)", "Packed QuickDraw II PICT File",
"Packed Super Hi-Res 3200 color image", "DreamGraphix" };
static final int COLOR_TABLE_SIZE = 32;
static final int COLOR_TABLE_OFFSET_AUX_0 = 32_256;
static final int COLOR_TABLE_OFFSET_AUX_2 = 32_000;
public static final int FADDEN_AUX = 0x8066;
private byte[] fourBuf = new byte[4];
private ColorTable defaultColorTable320 = new ColorTable (0, 0x00);
private ColorTable defaultColorTable640 = new ColorTable (0, 0x80);
// ---- ---- ------ -------------------------------------- ------------------------
// File Type Aux Name Description
// ---- ---- ------ -------------------------------------- ------------------------
// $06 BIN isGif() OriginalHiResImage
// $06 BIN isPng() OriginalHiResImage
// $06 BIN .BMP isBmp() OriginalHiResImage
// $06 BIN .AUX DoubleHiResImage
// $06 BIN .PAC DoubleHiResImage
// $06 BIN .A2FC DoubleHiResImage
// $06 BIN $2000 eof $4000 DoubleHiResImage
// $06 BIN $1FFF eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
// $06 BIN $2000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
// $06 BIN $4000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage (?)
// $06 BIN $4000 eof $4000 DoubleHiResImage (?)
// $06 BIN .3200 SHRPictureFile2
// $06 BIN .3201 SHRPictureFile2 packed
// ---- ---- ------ -------------------------------------- ------------------------
// $08 FOT <$4000 Apple II Graphics File OriginalHiResImage
// $08 FOT $4000 Packed Hi-Res file ???
// $08 FOT $4001 Packed Double Hi-Res file ???
// $08 FOT $8066 Fadden Hi-res FaddenHiResImage
// ---- ---- ------ -------------------------------------- ------------------------
// * $C0 PNT $0000 Paintworks Packed Super Hi-Res SHRPictureFile2
// * $C0 PNT $0001 Packed IIGS Super Hi-Res Image SHRPictureFile2
// * $C0 PNT $0002 IIGS Super Hi-Res Picture File (APF) SHRPictureFile1
// $C0 PNT $0003 Packed IIGS QuickDraw II PICT File SHRPictureFile2 *
// * $C0 PNT $0004 Packed Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3201
// $C0 PNT $1000
// $C0 PNT $8000 Drawplus? Paintworks Gold?
// $C0 PNT $8001 GTv background picture
// $C0 PNT $8005 DreamGraphix document
// $C0 PNT $8006 GIF
// ---- ---- ------ -------------------------------------- ------------------------
// * $C1 PIC $0000 IIGS Super Hi-Res Image SHRPictureFile2
// $C1 PIC $0001 IIGS QuickDraw II PICT File SHRPictureFile2 *
// * $C1 PIC $0002 Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3200
// $C1 PIC $2000 = $C1/0000
// $C1 PIC $4100 = $C1/0000
// $C1 PIC $4950 = $C1/0000
// $C1 PIC $8001 Allison raw image
// $C1 PIC $8002 Thunderscan
// $C1 PIC $8003 DreamGraphix
// ---- ---- ------ -------------------------------------- ------------------------
// $C2 ANI Paintworks animation
// $C3 PAL Paintworks palette
// ---- ---- ------ -------------------------------------- ------------------------
// ---- ---- ------ -------------------------------------- ------------------------
// File Type Aux Name Description
// ---- ---- ------ -------------------------------------- ------------------------
// $06 BIN isGif() OriginalHiResImage
// $06 BIN isPng() OriginalHiResImage
// $06 BIN .BMP isBmp() OriginalHiResImage
// $06 BIN .AUX DoubleHiResImage
// $06 BIN .PAC DoubleHiResImage
// $06 BIN .A2FC DoubleHiResImage
// $06 BIN $2000 eof $4000 DoubleHiResImage
// $06 BIN $1FFF eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
// $06 BIN $2000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage
// $06 BIN $4000 eof $1FF8/$1FFF/$2000/$4000 OriginalHiResImage (?)
// $06 BIN $4000 eof $4000 DoubleHiResImage (?)
// $06 BIN .3200 SHRPictureFile2
// $06 BIN .3201 SHRPictureFile2 packed
// ---- ---- ------ -------------------------------------- ------------------------
// $08 FOT <$4000 Apple II Graphics File OriginalHiResImage
// $08 FOT $4000 Packed Hi-Res file ???
// $08 FOT $4001 Packed Double Hi-Res file ???
// $08 FOT $8066 Fadden Hi-res FaddenHiResImage
// ---- ---- ------ -------------------------------------- ------------------------
// * $C0 PNT $0000 Paintworks Packed Super Hi-Res SHRPictureFile2
// * $C0 PNT $0001 Packed IIGS Super Hi-Res Image SHRPictureFile2
// * $C0 PNT $0002 IIGS Super Hi-Res Picture File (APF) SHRPictureFile1
// $C0 PNT $0003 Packed IIGS QuickDraw II PICT File SHRPictureFile2 *
// * $C0 PNT $0004 Packed Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3201
// $C0 PNT $1000
// $C0 PNT $8000 Drawplus? Paintworks Gold?
// $C0 PNT $8001 GTv background picture
// $C0 PNT $8005 DreamGraphix document SHRPictureFile2
// $C0 PNT $8006 GIF
// ---- ---- ------ -------------------------------------- ------------------------
// * $C1 PIC $0000 IIGS Super Hi-Res Image SHRPictureFile2
// $C1 PIC $0001 IIGS QuickDraw II PICT File SHRPictureFile2 *
// * $C1 PIC $0002 Super Hi-Res 3200 (Brooks) SHRPictureFile2 .3200
// $C1 PIC $2000 = $C1/0000
// $C1 PIC $4100 = $C1/0000
// $C1 PIC $4950 = $C1/0000
// $C1 PIC $8001 Allison raw image
// $C1 PIC $8002 Thunderscan
// $C1 PIC $8003 DreamGraphix
// ---- ---- ------ -------------------------------------- ------------------------
// $C2 ANI Paintworks animation
// $C3 PAL Paintworks palette
// ---- ---- ------ -------------------------------------- ------------------------
// packed unpacked
// $06.3200 1
// $06.3201 .
// $08 0000 .
// $08 4000 .
// $08 4001 .
// $08 8066 3
// $C0 0000 1
// $C0 0001 $C1 0000 2 1
// $C0 0002 1,5
// $C0 0003 $C1 0001 . .
// $C0 0004 $C1 0002 . 1
// $C0 1000 .
// $C0 8000 .
// $C0 8001 .
// $C0 8005 .
// $C0 8006 .
// $C1 0042 4
// $C1 0043 4
// $C1 2000 .
// $C1 4100 1
// $C1 4950 .
// $C1 8001 .
// $C1 8002 .
// $C1 8003 .
// packed unpacked
// $06.3200 1
// $06.3201 .
// $08 0000 .
// $08 4000 .
// $08 4001 .
// $08 8066 3
// $C0 0000 1
// $C0 0001 $C1 0000 2 1
// $C0 0002 1,5
// $C0 0003 $C1 0001 . .
// $C0 0004 $C1 0002 . 1
// $C0 1000 .
// $C0 8000 .
// $C0 8001 .
// $C0 8005 6
// $C0 8006 .
// $C1 0042 4
// $C1 0043 4
// $C1 2000 .
// $C1 4100 1
// $C1 4950 .
// $C1 8001 .
// $C1 8002 .
// $C1 8003 .
// 1 Graphics & Animation.2mg
// 2 0603 Katie's Farm - Disk 2.po
// 3 CompressedSlides.do
// 4 System Addons.hdv
// 5 gfx.po
//
// 6 Dream Grafix v1.02.po
// see also - https://docs.google.com/spreadsheets/d
// /1rKR6A_bVniSCtIP_rrv8QLWJdj4h6jEU1jJj0AebWwg/edit#gid=0
// . /1rKR6A_bVniSCtIP_rrv8QLWJdj4h6jEU1jJj0AebWwg/edit#gid=0
// also - http://lukazi.blogspot.com/2017/03/double-high-resolution-graphics-dhgr.html
static PaletteFactory paletteFactory = new PaletteFactory ();
@ -297,7 +300,10 @@ public abstract class HiResImage extends AbstractFile
break;
case ProdosConstants.FILE_TYPE_PNT: // 0xC0
auxText = auxType > 4 ? "Unknown aux: " + auxType : auxTypes[auxType];
if (auxType == 0x8005)
auxText = auxTypes[5];
else
auxText = auxType > 4 ? "Unknown aux: " + auxType : auxTypes[auxType];
break;
case ProdosConstants.FILE_TYPE_PIC: // 0xC1
@ -495,7 +501,7 @@ public abstract class HiResImage extends AbstractFile
int calculateBufferSize (byte[] buffer, int ptr)
// ---------------------------------------------------------------------------------//
{
// int ptr = 0;
// int ptr = 0;
int size = 0;
while (ptr < buffer.length)
{
@ -620,15 +626,15 @@ public abstract class HiResImage extends AbstractFile
return false;
String text = new String (buffer, 0, 2);
int size = Utility.unsignedLong (buffer, 2);
int size = Utility.getLong (buffer, 2);
if (false)
{
int empty = Utility.unsignedLong (buffer, 6);
int offset = Utility.unsignedLong (buffer, 10);
int header = Utility.unsignedLong (buffer, 14);
int width = Utility.unsignedLong (buffer, 18);
int height = Utility.unsignedLong (buffer, 22);
int empty = Utility.getLong (buffer, 6);
int offset = Utility.getLong (buffer, 10);
int header = Utility.getLong (buffer, 14);
int width = Utility.getLong (buffer, 18);
int height = Utility.getLong (buffer, 22);
System.out.println (buffer.length);
System.out.println (size);
@ -800,7 +806,7 @@ public abstract class HiResImage extends AbstractFile
public ColorEntry (byte[] data, int offset)
// -------------------------------------------------------------------------------//
{
value = Utility.unsignedShort (data, offset);
value = Utility.getShort (data, offset);
int red = ((value >> 8) & 0x0f) * 17;
int green = ((value >> 4) & 0x0f) * 17;
@ -829,8 +835,8 @@ public abstract class HiResImage extends AbstractFile
public DirEntry (byte[] data, int offset)
// -------------------------------------------------------------------------------//
{
numBytes = Utility.unsignedShort (data, offset);
mode = Utility.unsignedShort (data, offset + 2);
numBytes = Utility.getShort (data, offset);
mode = Utility.getShort (data, offset + 2);
}
// -------------------------------------------------------------------------------//

View File

@ -29,16 +29,16 @@ public class IconFile extends AbstractFile implements ProdosConstants
{
super (name, buffer);
iBlkNext = Utility.unsignedLong (buffer, 0);
iBlkID = Utility.unsignedShort (buffer, 4);
iBlkPath = Utility.unsignedLong (buffer, 6);
iBlkNext = Utility.getLong (buffer, 0);
iBlkID = Utility.getShort (buffer, 4);
iBlkPath = Utility.getLong (buffer, 6);
iBlkName = HexFormatter.getHexString (buffer, 10, 16);
int ptr = 26;
while (true)
{
int dataLen = Utility.unsignedShort (buffer, ptr);
int dataLen = Utility.getShort (buffer, ptr);
if (dataLen == 0 || (dataLen + ptr) > buffer.length)
break;
@ -131,7 +131,7 @@ public class IconFile extends AbstractFile implements ProdosConstants
public Icon (byte[] fullBuffer, int ptr)
// -------------------------------------------------------------------------------//
{
iDataLen = Utility.unsignedShort (fullBuffer, ptr);
iDataLen = Utility.getShort (fullBuffer, ptr);
buffer = new byte[iDataLen];
System.arraycopy (fullBuffer, ptr, buffer, 0, buffer.length);
@ -142,8 +142,8 @@ public class IconFile extends AbstractFile implements ProdosConstants
len = buffer[66] & 0xFF;
dataName = new String (buffer, 67, len);
iDataType = Utility.unsignedShort (buffer, 82);
iDataAux = Utility.unsignedShort (buffer, 84);
iDataType = Utility.getShort (buffer, 82);
iDataAux = Utility.getShort (buffer, 84);
if (debug)
{
@ -200,10 +200,10 @@ public class IconFile extends AbstractFile implements ProdosConstants
public Image (byte[] buffer, int ptr) throws InvalidImageException
// -------------------------------------------------------------------------------//
{
iconType = Utility.unsignedShort (buffer, ptr);
iconSize = Utility.unsignedShort (buffer, ptr + 2);
iconHeight = Utility.unsignedShort (buffer, ptr + 4);
iconWidth = Utility.unsignedShort (buffer, ptr + 6);
iconType = Utility.getShort (buffer, ptr);
iconSize = Utility.getShort (buffer, ptr + 2);
iconHeight = Utility.getShort (buffer, ptr + 4);
iconWidth = Utility.getShort (buffer, ptr + 6);
if (debug)
{

View File

@ -70,6 +70,8 @@ public class OriginalHiResImage extends HiResImage
for (int ptr = base; ptr < max; ptr++)
{
int value = buffer[ptr] & 0x7F;
if ((buffer[ptr] & 0x80) != 0)
System.out.printf ("bit shift pixel found in %s%n", name);
for (int px = 0; px < 7; px++)
{
int val = (value >> px) & 0x01;

View File

@ -22,13 +22,13 @@ public class PascalArea extends AbstractFile
{
super (name, buffer);
size = Utility.unsignedShort (buffer, 0);
volumes = Utility.unsignedShort (buffer, 2);
size = Utility.getShort (buffer, 0);
volumes = Utility.getShort (buffer, 2);
ppmName = HexFormatter.getPascalString (buffer, 4);
start = Utility.unsignedShort (buffer, 8);
length = Utility.unsignedShort (buffer, 11);
start = Utility.getShort (buffer, 8);
length = Utility.getShort (buffer, 11);
defaultUnit = buffer[13] & 0xFF;
oldDriver = Utility.unsignedShort (buffer, 14);
oldDriver = Utility.getShort (buffer, 14);
// writeProtected = buffer[12] != 0;
}

View File

@ -47,7 +47,7 @@ public class PascalCode extends AbstractFile
for (int i = 0; i < 16; i++)
{
String codeName = HexFormatter.getString (buffer, 0x40 + i * 8, 8).trim ();
int size = Utility.intValue (buffer[i * 4 + 2], buffer[i * 4 + 3]);
int size = Utility.getShort (buffer, i * 4 + 2);
if (codeName.length () == 0 && size > 0)
codeName = "<NULL" + ++nonameCounter + ">";
if (size > 0)

View File

@ -79,10 +79,8 @@ public class PascalCodeStatement implements PascalConstants
int min = ptr + padding + 7;
int max = min + (p2 - p1) * 2;
for (int i = min; i <= max; i += 2)
{
jumps.add (
new Jump (i, i - Utility.intValue (buffer[i], buffer[i + 1]), v++));
}
jumps.add (new Jump (i, i - Utility.getShort (buffer, i), v++));
break;
// UB, <block> - word aligned

View File

@ -36,7 +36,7 @@ public class PascalProcedure
this.buffer = buffer;
this.slot = slot;
int p = buffer.length - 2 - slot * 2;
offset = Utility.intValue (buffer[p], buffer[p + 1]);
offset = Utility.getShort (buffer, p);
procOffset = p - offset;
valid = procOffset > 0;
@ -44,10 +44,10 @@ public class PascalProcedure
{
procedureNo = buffer[procOffset] & 0xFF;
procLevel = buffer[procOffset + 1] & 0xFF;
codeStart = Utility.intValue (buffer[procOffset - 2], buffer[procOffset - 1]);
codeEnd = Utility.intValue (buffer[procOffset - 4], buffer[procOffset - 3]);
parmSize = Utility.intValue (buffer[procOffset - 6], buffer[procOffset - 5]);
dataSize = Utility.intValue (buffer[procOffset - 8], buffer[procOffset - 7]);
codeStart = Utility.getShort (buffer, procOffset - 2);
codeEnd = Utility.getShort (buffer, procOffset - 4);
parmSize = Utility.getShort (buffer, procOffset - 6);
dataSize = Utility.getShort (buffer, procOffset - 8);
}
}

View File

@ -43,14 +43,12 @@ public class PascalSegment extends AbstractFile implements PascalConstants
// this.blockOffset = blockOffset;
// this.relocator = relocator;
this.blockNo = Utility.intValue (fullBuffer[seq * 4], fullBuffer[seq * 4 + 1]);
this.size = Utility.intValue (fullBuffer[seq * 4 + 2], fullBuffer[seq * 4 + 3]);
this.blockNo = Utility.getShort (fullBuffer, seq * 4);
this.size = Utility.getShort (fullBuffer, seq * 4 + 2);
segKind =
Utility.intValue (fullBuffer[0xC0 + seq * 2], fullBuffer[0xC0 + seq * 2 + 1]);
segKind = Utility.getShort (fullBuffer, 0xC0 + seq * 2);
textAddress =
Utility.intValue (fullBuffer[0xE0 + seq * 2], fullBuffer[0xE0 + seq * 2 + 1]);
textAddress = Utility.getShort (fullBuffer, 0xE0 + seq * 2);
// segment 1 is the main segment, 2-6 are used by the system, and 7
// onwards is for the program
@ -65,10 +63,8 @@ public class PascalSegment extends AbstractFile implements PascalConstants
version = (flags & 0xD0) >> 5;
intrinsSegs1 =
Utility.intValue (fullBuffer[0x120 + seq * 4], fullBuffer[0x120 + seq * 4 + 1]);
intrinsSegs2 = Utility.intValue (fullBuffer[0x120 + seq * 4 + 2],
fullBuffer[0x120 + seq * 4 + 3]);
intrinsSegs1 = Utility.getShort (fullBuffer, 0x120 + seq * 4);
intrinsSegs2 = Utility.getShort (fullBuffer, 0x120 + seq * 4 + 2);
int offset = blockNo * 512;

View File

@ -4,6 +4,8 @@ package com.bytezone.diskbrowser.applefile;
public class PascalText extends TextFile
// -----------------------------------------------------------------------------------//
{
private final static int PAGE_SIZE = 1024;
// ---------------------------------------------------------------------------------//
public PascalText (String name, byte[] buffer)
// ---------------------------------------------------------------------------------//
@ -16,26 +18,34 @@ public class PascalText extends TextFile
public String getText ()
// ---------------------------------------------------------------------------------//
{
// Text files are broken up into 1024-byte pages.
// [DLE] [indent] [text] [CR] ... [nulls]
StringBuilder text = new StringBuilder (getHeader ());
int ptr = 0x400;
int ptr = PAGE_SIZE; // skip text editor header
while (ptr < buffer.length)
{
if (buffer[ptr] == 0x00)
if (buffer[ptr] == 0x00) // padding to page boundary
{
++ptr;
ptr = (ptr / PAGE_SIZE + 1) * PAGE_SIZE; // skip to next page
continue;
}
if (buffer[ptr] == 0x10)
if (buffer[ptr] == 0x10) // Data Link Escape code
{
int tab = buffer[ptr + 1] - 0x20;
int tab = (buffer[ptr + 1] & 0xFF) - 32; // indent amaount
while (tab-- > 0)
text.append (" ");
ptr += 2;
}
String line = getLine (ptr);
text.append (line + "\n");
ptr += line.length () + 1;
while (buffer[ptr] != 0x0D)
text.append ((char) buffer[ptr++]);
text.append ("\n");
ptr++;
}
if (text.length () > 0)
@ -43,14 +53,4 @@ public class PascalText extends TextFile
return text.toString ();
}
// ---------------------------------------------------------------------------------//
private String getLine (int ptr)
// ---------------------------------------------------------------------------------//
{
StringBuilder line = new StringBuilder ();
while (buffer[ptr] != 0x0D)
line.append ((char) buffer[ptr++]);
return line.toString ();
}
}

View File

@ -1,19 +1,28 @@
package com.bytezone.diskbrowser.prodos;
package com.bytezone.diskbrowser.applefile;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;
import com.bytezone.diskbrowser.applefile.AbstractFile;
import com.bytezone.diskbrowser.disk.FormattedDisk;
import com.bytezone.diskbrowser.prodos.DirectoryHeader;
import com.bytezone.diskbrowser.prodos.ProdosConstants;
import com.bytezone.diskbrowser.prodos.ProdosDisk;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
class ProdosDirectory extends AbstractFile implements ProdosConstants
public class ProdosDirectory extends AbstractFile implements ProdosConstants
// -----------------------------------------------------------------------------------//
{
private static Locale US = Locale.US; // to force 3 character months
static final DateTimeFormatter df = DateTimeFormatter.ofPattern ("d-LLL-yy", US);
static final DateTimeFormatter tf = DateTimeFormatter.ofPattern ("H:mm");
static final String UNDERLINE =
"----------------------------------------------------\n";
private static final String NO_DATE = "<NO DATE>";
private static final String newLine = String.format ("%n");
private static final String newLine2 = newLine + newLine;
private final ProdosDisk parentFD;
private final int totalBlocks;
@ -21,8 +30,8 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
private final int usedBlocks;
// ---------------------------------------------------------------------------------//
ProdosDirectory (FormattedDisk parent, String name, byte[] buffer, int totalBlocks,
int freeBlocks, int usedBlocks)
public ProdosDirectory (FormattedDisk parent, String name, byte[] buffer,
int totalBlocks, int freeBlocks, int usedBlocks)
// ---------------------------------------------------------------------------------//
{
super (name, buffer);
@ -38,8 +47,38 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
public String getText ()
// ---------------------------------------------------------------------------------//
{
StringBuffer text = new StringBuffer ();
text.append ("File : " + parentFD.getDisplayPath () + newLine2);
if (showDebugText)
return getDebugText ();
else
return getDirectoryText ();
}
// ---------------------------------------------------------------------------------//
private String getDebugText ()
// ---------------------------------------------------------------------------------//
{
List<DirectoryHeader> directoryHeaders = parentFD.getDirectoryHeaders ();
StringBuilder text = new StringBuilder ();
for (DirectoryHeader directoryHeader : directoryHeaders)
{
text.append (UNDERLINE);
text.append (directoryHeader.getText ());
text.append ("\n");
text.append (UNDERLINE);
directoryHeader.listFileEntries (text);
}
return text.toString ();
}
// ---------------------------------------------------------------------------------//
private String getDirectoryText ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
text.append ("File : " + parentFD.getDisplayPath () + "\n\n");
for (int i = 0; i < buffer.length; i += ENTRY_SIZE)
{
int storageType = (buffer[i] & 0xF0) >> 4;
@ -49,16 +88,15 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
int nameLength = buffer[i] & 0x0F;
String filename = HexFormatter.getString (buffer, i + 1, nameLength);
String subType = "";
String locked;
switch (storageType)
{
case VOLUME_HEADER:
case SUBDIRECTORY_HEADER:
String root = storageType == VOLUME_HEADER ? "/" : "";
text.append (root + filename + newLine2);
text.append (root + filename + "\n\n");
text.append (" NAME TYPE BLOCKS "
+ "MODIFIED CREATED ENDFILE SUBTYPE" + newLine2);
+ "MODIFIED CREATED ENDFILE SUBTYPE" + "\n\n");
break;
case FREE:
@ -69,27 +107,27 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
case GSOS_EXTENDED_FILE:
case SUBDIRECTORY:
int type = buffer[i + 16] & 0xFF;
int blocks = Utility.intValue (buffer[i + 19], buffer[i + 20]);
int blocks = Utility.getShort (buffer, i + 19);
LocalDateTime createdDate = Utility.getAppleDate (buffer, i + 24);
LocalDateTime modifiedDate = Utility.getAppleDate (buffer, i + 33);
String dateC = createdDate == null ? NO_DATE
: createdDate.format (ProdosDisk.df).toUpperCase ();
String dateM = modifiedDate == null ? NO_DATE
: modifiedDate.format (ProdosDisk.df).toUpperCase ();
String dateC =
createdDate == null ? NO_DATE : createdDate.format (df).toUpperCase ();
String dateM =
modifiedDate == null ? NO_DATE : modifiedDate.format (df).toUpperCase ();
String timeC = createdDate == null ? "" : createdDate.format (ProdosDisk.tf);
String timeM = modifiedDate == null ? "" : modifiedDate.format (ProdosDisk.tf);
String timeC = createdDate == null ? "" : createdDate.format (tf);
String timeM = modifiedDate == null ? "" : modifiedDate.format (tf);
int eof = Utility.intValue (buffer[i + 21], buffer[i + 22], buffer[i + 23]);
int fileType = buffer[i + 16] & 0xFF;
locked = (buffer[i + 30] & 0xE0) == 0xE0 ? " " : "*";
String locked = (buffer[i + 30] & 0xE0) == 0xE0 ? " " : "*";
int aux = Utility.getShort (buffer, i + 31);
switch (fileType)
{
case FILE_TYPE_TEXT:
int aux = Utility.intValue (buffer[i + 31], buffer[i + 32]);
subType = String.format ("R=%5d", aux);
break;
@ -97,32 +135,35 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
case FILE_TYPE_PNT:
case FILE_TYPE_PIC:
case FILE_TYPE_FOT:
aux = Utility.intValue (buffer[i + 31], buffer[i + 32]);
subType = String.format ("A=$%4X", aux);
break;
case FILE_TYPE_AWP:
aux = Utility.intValue (buffer[i + 32], buffer[i + 31]); // backwards!
if (aux != 0)
filename = convert (filename, aux);
int flags = Utility.intValue (buffer[i + 32], buffer[i + 31]); // aux backwards!
if (flags != 0)
filename = convert (filename, flags);
break;
default:
subType = "";
}
text.append (String.format ("%s%-15s %3s %5d %9s %5s %9s %5s %8d %7s%n",
locked, filename, ProdosConstants.fileTypes[type], blocks, dateM, timeM,
dateC, timeC, eof, subType));
String forkFlag = storageType == 5 ? "+" : " ";
text.append (
String.format ("%s%-15s %3s%s %5d %9s %5s %9s %5s %8d %7s %04X%n",
locked, filename, ProdosConstants.fileTypes[type], forkFlag, blocks,
dateM, timeM, dateC, timeC, eof, subType, aux));
break;
default:
text.append (" <Unknown strage type : " + storageType + newLine);
text.append (" <Unknown strage type : " + storageType + "\n");
}
}
text.append (
String.format ("%nBLOCKS FREE:%5d BLOCKS USED:%5d TOTAL BLOCKS:%5d%n",
freeBlocks, usedBlocks, totalBlocks));
return text.toString ();
}

View File

@ -72,37 +72,37 @@ public class QuickDrawFont extends CharacterList
int ptr = nameLength + 1; // start of header record
headerSize = Utility.unsignedShort (buffer, ptr);
headerSize = Utility.getShort (buffer, ptr);
fontDefinitionOffset = nameLength + 1 + headerSize * 2;
fontFamily = Utility.unsignedShort (buffer, ptr + 2);
fontStyle = Utility.unsignedShort (buffer, ptr + 4);
fontSize = Utility.unsignedShort (buffer, ptr + 6);
fontFamily = Utility.getShort (buffer, ptr + 2);
fontStyle = Utility.getShort (buffer, ptr + 4);
fontSize = Utility.getShort (buffer, ptr + 6);
versionMajor = buffer[ptr + 8] & 0xFF;
versionMinor = buffer[ptr + 9] & 0xFF;
extent = Utility.unsignedShort (buffer, ptr + 10);
extent = Utility.getShort (buffer, ptr + 10);
ptr = fontDefinitionOffset;
fontType = Utility.unsignedShort (buffer, ptr);
firstChar = Utility.unsignedShort (buffer, ptr + 2);
lastChar = Utility.unsignedShort (buffer, ptr + 4);
widMax = Utility.unsignedShort (buffer, ptr + 6);
kernMax = Utility.signedShort (buffer, ptr + 8);
nDescent = Utility.signedShort (buffer, ptr + 10);
fRectWidth = Utility.unsignedShort (buffer, ptr + 12);
fRectHeight = Utility.unsignedShort (buffer, ptr + 14);
fontType = Utility.getShort (buffer, ptr);
firstChar = Utility.getShort (buffer, ptr + 2);
lastChar = Utility.getShort (buffer, ptr + 4);
widMax = Utility.getShort (buffer, ptr + 6);
kernMax = Utility.getSignedShort (buffer, ptr + 8);
nDescent = Utility.getSignedShort (buffer, ptr + 10);
fRectWidth = Utility.getShort (buffer, ptr + 12);
fRectHeight = Utility.getShort (buffer, ptr + 14);
owTLoc = Utility.unsignedShort (buffer, ptr + 16);
owTLoc = Utility.getShort (buffer, ptr + 16);
offsetWidthTableOffset = (ptr + 16) + owTLoc * 2;
locationTableOffset = offsetWidthTableOffset - (lastChar - firstChar + 3) * 2;
bitImageOffset = ptr + 26;
ascent = Utility.unsignedShort (buffer, ptr + 18);
descent = Utility.unsignedShort (buffer, ptr + 20);
leading = Utility.unsignedShort (buffer, ptr + 22);
rowWords = Utility.unsignedShort (buffer, ptr + 24);
ascent = Utility.getShort (buffer, ptr + 18);
descent = Utility.getShort (buffer, ptr + 20);
leading = Utility.getShort (buffer, ptr + 22);
rowWords = Utility.getShort (buffer, ptr + 24);
totalCharacters = lastChar - firstChar + 2; // includes 'missing' character
@ -151,12 +151,12 @@ public class QuickDrawFont extends CharacterList
for (int i = 0, max = totalCharacters + 1; i < max; i++)
{
// index into the strike
int location = Utility.unsignedShort (buffer, locationTableOffset + i * 2);
int location = Utility.getShort (buffer, locationTableOffset + i * 2);
int j = i + 1; // next character
if (j < max)
{
int nextLocation = Utility.unsignedShort (buffer, locationTableOffset + j * 2);
int nextLocation = Utility.getShort (buffer, locationTableOffset + j * 2);
int pixelWidth = nextLocation - location;
if (pixelWidth > 0)
@ -259,9 +259,8 @@ public class QuickDrawFont extends CharacterList
if (offset == 255 && width == 255)
continue;
int location = Utility.unsignedShort (buffer, locationTableOffset + i * 2);
int nextLocation =
Utility.unsignedShort (buffer, locationTableOffset + (i + 1) * 2);
int location = Utility.getShort (buffer, locationTableOffset + i * 2);
int nextLocation = Utility.getShort (buffer, locationTableOffset + (i + 1) * 2);
int pixelWidth = nextLocation - location;
text.append (String.format (

View File

@ -27,7 +27,7 @@ public class SHRPictureFile1 extends HiResImage
int ptr = 0;
while (ptr < buffer.length)
{
int len = Utility.unsignedLong (buffer, ptr);
int len = Utility.getLong (buffer, ptr);
if (len == 0 || len > buffer.length)
{
System.out.printf ("Block length: %d%n", len);
@ -141,7 +141,7 @@ public class SHRPictureFile1 extends HiResImage
int lo = dirEntry.mode & 0x00FF; // mode bit if hi == 0
boolean fillMode = (dirEntry.mode & 0x20) != 0;
// assert fillMode == false;
// assert fillMode == false;
if (hi != 0)
System.out.println ("hi not zero");
@ -232,7 +232,7 @@ public class SHRPictureFile1 extends HiResImage
super (kind, data);
int ptr = 5 + kind.length ();
numColorTables = Utility.unsignedShort (data, ptr);
numColorTables = Utility.getShort (data, ptr);
ptr += 2;
colorTables = new ColorTable[numColorTables];
@ -242,7 +242,8 @@ public class SHRPictureFile1 extends HiResImage
if (ptr < data.length - 32)
colorTables[i] = new ColorTable (i, data, ptr);
else
colorTables[i] = new ColorTable (i, 0x00); // default empty table !! not finished
colorTables[i] = new ColorTable (i, 0x00); // default empty table !! not
// finished
ptr += 32;
}
}
@ -286,9 +287,9 @@ public class SHRPictureFile1 extends HiResImage
super (kind, data);
int ptr = 5 + kind.length ();
masterMode = Utility.unsignedShort (data, ptr);
pixelsPerScanLine = Utility.unsignedShort (data, ptr + 2);
numColorTables = Utility.unsignedShort (data, ptr + 4);
masterMode = Utility.getShort (data, ptr);
pixelsPerScanLine = Utility.getShort (data, ptr + 2);
numColorTables = Utility.getShort (data, ptr + 4);
mode640 = (masterMode & 0x80) != 0;
ptr += 6;
@ -299,7 +300,7 @@ public class SHRPictureFile1 extends HiResImage
ptr += 32;
}
numScanLines = Utility.unsignedShort (data, ptr);
numScanLines = Utility.getShort (data, ptr);
ptr += 2;
scanLineDirectory = new DirEntry[numScanLines];
@ -332,11 +333,11 @@ public class SHRPictureFile1 extends HiResImage
ptr = 0;
for (int line = 0; line < numScanLines; line++)
{
// if (isOddAndEmpty (packedScanLines[line]))
// {
// System.out.println ("Odd number of bytes in empty buffer in " + name);
// break;
// }
// if (isOddAndEmpty (packedScanLines[line]))
// {
// System.out.println ("Odd number of bytes in empty buffer in " + name);
// break;
// }
int bytesUnpacked = unpack (packedScanLines[line], 0,
packedScanLines[line].length, unpackedBuffer, ptr);
@ -352,16 +353,17 @@ public class SHRPictureFile1 extends HiResImage
}
// -------------------------------------------------------------------------------//
// private boolean isOddAndEmpty (byte[] buffer)
// // -------------------------------------------------------------------------------//
// {
// if (buffer.length % 2 == 0)
// return false;
// for (byte b : buffer)
// if (b != 0)
// return false;
// return true;
// }
// private boolean isOddAndEmpty (byte[] buffer)
// //
// -------------------------------------------------------------------------------//
// {
// if (buffer.length % 2 == 0)
// return false;
// for (byte b : buffer)
// if (b != 0)
// return false;
// return true;
// }
// -------------------------------------------------------------------------------//
@Override

View File

@ -5,6 +5,7 @@ import java.awt.image.DataBuffer;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.nufx.LZW3;
import com.bytezone.diskbrowser.prodos.ProdosConstants;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
@ -99,10 +100,10 @@ public class SHRPictureFile2 extends HiResImage
unpack (buffer, 0, buffer.length, newBuffer, 0);
buffer = newBuffer;
int mode = Utility.unsignedShort (this.buffer, 0);
int rect1 = Utility.unsignedLong (this.buffer, 2);
int rect2 = Utility.unsignedLong (this.buffer, 6);
int version = Utility.unsignedShort (this.buffer, 10); // $8211
int mode = Utility.getShort (this.buffer, 0);
int rect1 = Utility.getLong (this.buffer, 2);
int rect2 = Utility.getLong (this.buffer, 6);
int version = Utility.getShort (this.buffer, 10); // $8211
break;
@ -144,6 +145,36 @@ public class SHRPictureFile2 extends HiResImage
break;
case 0x8005:
int ptr = buffer.length - 17;
int imageType = Utility.getShort (buffer, ptr);
int imageHeight = Utility.getShort (buffer, ptr + 2);
int imageWidth = Utility.getShort (buffer, ptr + 4);
String id = HexFormatter.getPascalString (buffer, ptr + 6);
assert "DreamWorld".equals (id);
int expectedLen = 32000 + 512;
if (imageType == 0) // 256 colours
expectedLen += (256 + 512);
else // 3200 colours
expectedLen += 6400;
byte[] dstBuffer = new byte[expectedLen + 1024];
LZW3 lzw3 = new LZW3 ();
int bytes = lzw3.unpack (buffer, dstBuffer, expectedLen);
buffer = dstBuffer;
colorTables = new ColorTable[imageHeight];
for (int i = 0; i < colorTables.length; i++)
{
colorTables[i] = new ColorTable (i, this.buffer, 32000 + i * COLOR_TABLE_SIZE);
colorTables[i].reverse ();
}
break;
default:
System.out.printf ("%s: PNT unknown aux: %04X%n", name, auxType);
failureReason = "unknown PNT aux";
@ -154,13 +185,13 @@ public class SHRPictureFile2 extends HiResImage
private void doAnimation ()
// ---------------------------------------------------------------------------------//
{
// int len = HexFormatter.unsignedLong (buffer, 0x8000);
delay = Utility.unsignedLong (buffer, 0x8004);
// int len = HexFormatter.getLong (buffer, 0x8000);
delay = Utility.getLong (buffer, 0x8004);
if (delay > 60)
delay = 10;
delay = delay * 1000 / 60;
// int offset = HexFormatter.unsignedLong (buffer, 0x8008);
// int offset = HexFormatter.getLong (buffer, 0x8008);
// int blockLen = eof - 0x8008;
// System.out.printf ("Delay: %,d%n", delay);
@ -173,7 +204,7 @@ public class SHRPictureFile2 extends HiResImage
int start = ptr;
while (ptr < buffer.length)
{
int off = Utility.unsignedShort (buffer, ptr);
int off = Utility.getShort (buffer, ptr);
ptr += 4;
if (off == 0)
@ -299,7 +330,7 @@ public class SHRPictureFile2 extends HiResImage
while (true)
{
int offset = Utility.unsignedShort (buffer, ptr);
int offset = Utility.getShort (buffer, ptr);
if (offset == 0)
break;

View File

@ -1,16 +1,40 @@
package com.bytezone.diskbrowser.applefile;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class SegmentDictionary
// -----------------------------------------------------------------------------------//
{
private final boolean isValid;
private int[] codeAddress = new int[16];
private int[] codeLength = new int[16];
private String[] segName = new String[16];
// ---------------------------------------------------------------------------------//
public SegmentDictionary (String name, byte[] buffer)
// ---------------------------------------------------------------------------------//
{
isValid = !name.equals ("SYSTEM.INTERP"); // temporary
int ptr = 0;
for (int seg = 0; seg < 16; seg++)
{
codeAddress[seg] = Utility.getShort (buffer, ptr);
ptr += 2;
codeLength[seg] = Utility.getShort (buffer, ptr);
ptr += 2;
}
ptr = 64;
for (int seg = 0; seg < 16; seg++)
{
segName[seg] = new String (buffer, ptr, 8);
ptr += 8;
}
// for (int seg = 0; seg < 16; seg++)
// System.out.printf ("%04X %04X %s%n", codeAddress[seg], codeLength[seg], segName[seg]);
}
// ---------------------------------------------------------------------------------//

View File

@ -37,6 +37,8 @@ public class SegmentHeader
String loadname;
String segname;
boolean debug = false;
// ---------------------------------------------------------------------------------//
public SegmentHeader (byte[] buffer, int offset)
// ---------------------------------------------------------------------------------//
@ -52,20 +54,20 @@ public class SegmentHeader
version = buffer[offset + 15] & 0xFF;
banksize = Utility.getLong (buffer, offset + 16);
kind2 = Utility.getWord (buffer, offset + 20);
unused = Utility.getWord (buffer, offset + 22);
kind2 = Utility.getShort (buffer, offset + 20);
unused = Utility.getShort (buffer, offset + 22);
org = Utility.getLong (buffer, offset + 24);
align = Utility.getLong (buffer, offset + 28);
numsex = buffer[offset + 32] & 0xFF;
lcbank = buffer[offset + 33] & 0xFF;
segnum = Utility.getWord (buffer, offset + 34);
segnum = Utility.getShort (buffer, offset + 34);
entry = Utility.getLong (buffer, offset + 36);
dispname = Utility.getWord (buffer, offset + 40);
dispdata = Utility.getWord (buffer, offset + 42);
dispname = Utility.getShort (buffer, offset + 40);
dispdata = Utility.getShort (buffer, offset + 42);
decodeKind ();
@ -79,7 +81,8 @@ public class SegmentHeader
else
segname = "not finished";
System.out.println (this);
if (debug)
System.out.println (this);
int ptr = offset + dispdata;
while (true)
@ -89,25 +92,33 @@ public class SegmentHeader
if (recType > 0 && recType <= 0xDF)
{
System.out.printf ("Const: %02X%n", recType);
System.out.println (HexFormatter.format (buffer, ptr, recType + 1, ptr));
if (debug)
{
System.out.printf ("Const: %02X%n", recType);
System.out.println (HexFormatter.format (buffer, ptr, recType + 1, ptr));
}
ptr += recType + 1;
continue;
}
System.out.printf ("%02X ", recType);
if (debug)
System.out.printf ("%02X ", recType);
switch (recType)
{
case 0x00: // END
System.out.println ("END");
if (debug)
System.out.println ("END");
break;
case 0xE0: // ALIGN
System.out.printf ("ALIGN:%n");
if (debug)
System.out.printf ("ALIGN:%n");
break;
case 0xE1: // ORG
System.out.printf ("ORG:%n");
if (debug)
System.out.printf ("ORG:%n");
break;
case 0xE2: // RELOC
@ -115,8 +126,9 @@ public class SegmentHeader
int bitShift = buffer[ptr + 2] & 0xFF;
int segmentOffset = Utility.getLong (buffer, ptr + 3);
int value = Utility.getLong (buffer, ptr + 7);
System.out.printf ("RELOC: %02X %02X %08X %08X%n", bytesRelocated, bitShift,
segmentOffset, value);
if (debug)
System.out.printf ("RELOC: %02X %02X %08X %08X%n", bytesRelocated, bitShift,
segmentOffset, value);
ptr += 11;
continue;
@ -124,102 +136,121 @@ public class SegmentHeader
int count1 = buffer[ptr + 1] & 0xFF;
int count2 = buffer[ptr + 2] & 0xFF;
int operandOffset = Utility.getLong (buffer, ptr + 3);
int fileNo = Utility.getWord (buffer, ptr + 7);
int segNo = Utility.getWord (buffer, ptr + 9);
int fileNo = Utility.getShort (buffer, ptr + 7);
int segNo = Utility.getShort (buffer, ptr + 9);
int subroutineOffset = Utility.getLong (buffer, ptr + 11);
System.out.printf ("INTERSEG: %02X %02X %08X %04X %04X %08X%n", count1, count2,
operandOffset, fileNo, segNo, subroutineOffset);
if (debug)
System.out.printf ("INTERSEG: %02X %02X %08X %04X %04X %08X%n", count1,
count2, operandOffset, fileNo, segNo, subroutineOffset);
ptr += 15;
break;
case 0xE4: // USING
System.out.printf ("USING:%n");
if (debug)
System.out.printf ("USING:%n");
break;
case 0xE5: // STRONG
System.out.printf ("STRONG:%n");
if (debug)
System.out.printf ("STRONG:%n");
break;
case 0xE6: // GLOBAL
System.out.printf ("GLOBAL:%n");
if (debug)
System.out.printf ("GLOBAL:%n");
break;
case 0xE7: // GEQU
System.out.printf ("GEQU:%n");
if (debug)
System.out.printf ("GEQU:%n");
break;
case 0xE8: // MEM
System.out.printf ("MEM:%n");
if (debug)
System.out.printf ("MEM:%n");
break;
case 0xEB: // EXPR
System.out.printf ("EXPR:%n");
if (debug)
System.out.printf ("EXPR:%n");
break;
case 0xEC: // ZEXPR
System.out.printf ("ZEXPR:%n");
if (debug)
System.out.printf ("ZEXPR:%n");
break;
case 0xED: // BEXPR
System.out.printf ("BEXPR:%n");
if (debug)
System.out.printf ("BEXPR:%n");
break;
case 0xEE: // RELEXPR
System.out.printf ("RELEXPR:%n");
if (debug)
System.out.printf ("RELEXPR:%n");
break;
case 0xEF: // LOCAL
System.out.printf ("LOCAL:%n");
if (debug)
System.out.printf ("LOCAL:%n");
break;
case 0xF0: // EQU
String label = HexFormatter.getPascalString (buffer, ptr + 1);
System.out.printf ("EQU: %s%n", label);
if (debug)
System.out.printf ("EQU: %s%n", label);
break;
case 0xF1: // DS
System.out.printf ("DS:%n");
if (debug)
System.out.printf ("DS:%n");
break;
case 0xF2: // LCONST
int constLength = Utility.getLong (buffer, ptr + 1);
System.out.printf ("Const: %04X%n", constLength);
if (debug)
System.out.printf ("Const: %04X%n", constLength);
ptr += constLength + 5;
continue;
case 0xF3: // LEXPR
System.out.printf ("LEXPR:%n");
if (debug)
System.out.printf ("LEXPR:%n");
break;
case 0xF4: // ENTRY
System.out.printf ("ENTRY:%n");
if (debug)
System.out.printf ("ENTRY:%n");
break;
case 0xF5: // cRELOC
int cBytesRelocated = buffer[ptr + 1] & 0xFF;
int cBitShift = buffer[ptr + 2] & 0xFF;
int cSegmentOffset = Utility.getWord (buffer, ptr + 3);
int cValue = Utility.getWord (buffer, ptr + 5);
System.out.printf ("cRELOC: %02X %02X %08X %08X%n", cBytesRelocated, cBitShift,
cSegmentOffset, cValue);
int cSegmentOffset = Utility.getShort (buffer, ptr + 3);
int cValue = Utility.getShort (buffer, ptr + 5);
if (debug)
System.out.printf ("cRELOC: %02X %02X %08X %08X%n", cBytesRelocated,
cBitShift, cSegmentOffset, cValue);
ptr += 7;
continue;
case 0xF6: // cINTERSEG
int cCount1 = buffer[ptr + 1] & 0xFF;
int cCount2 = buffer[ptr + 2] & 0xFF;
int cOperandOffset = Utility.getWord (buffer, ptr + 3);
int cOperandOffset = Utility.getShort (buffer, ptr + 3);
int cSegNo = buffer[ptr + 5] & 0xFF;
int cSubroutineOffset = Utility.getWord (buffer, ptr + 6);
System.out.printf ("cINTERSEG: %02X %02X %04X %02X %04X%n", cCount1, cCount2,
cOperandOffset, cSegNo, cSubroutineOffset);
int cSubroutineOffset = Utility.getShort (buffer, ptr + 6);
if (debug)
System.out.printf ("cINTERSEG: %02X %02X %04X %02X %04X%n", cCount1, cCount2,
cOperandOffset, cSegNo, cSubroutineOffset);
ptr += 8;
continue;
case 0xF7: // SUPER
int superLength = Utility.getLong (buffer, ptr + 1);
int recordType = buffer[ptr + 5] & 0xFF;
System.out.printf ("Super type %02X%n", recordType);
if (debug)
System.out.printf ("Super type %02X%n", recordType);
ptr += superLength + 5;
continue;
@ -228,7 +259,8 @@ public class SegmentHeader
break;
}
System.out.println ();
if (debug)
System.out.println ();
break;
}
}
@ -258,33 +290,18 @@ public class SegmentHeader
kindPrivate = (segAttr & 0x40) != 0;
kindStatic = (segAttr & 0x80) == 0;
switch (segType)
kindWhereText = switch (segType)
{
case 0:
kindWhereText = "Code Segment";
break;
case 1:
kindWhereText = "Data Segment";
break;
case 2:
kindWhereText = "Jump Table Segment";
break;
case 4:
kindWhereText = "Pathname Segment";
break;
case 8:
kindWhereText = "Library Dictionary Segment";
break;
case 0x10:
kindWhereText = "Initialization Segment";
break;
case 0x11:
kindWhereText = "Absolute Bank Segment";
break;
case 0x12:
kindWhereText = "Direct Page / Stack Segment";
break;
}
case 0x00 -> "Code Segment";
case 0x01 -> "Data Segment";
case 0x02 -> "Jump Table Segment";
case 0x04 -> "Pathname Segment";
case 0x08 -> "Library Dictionary Segment";
case 0x10 -> "Initialization Segment";
case 0x11 -> "Absolute Bank Segment";
case 0x12 -> "Direct Page / Stack Segment";
default -> "Unknown";
};
}
// ---------------------------------------------------------------------------------//

View File

@ -39,7 +39,7 @@ class Shape
int row = startRow;
int col = startCol;
offset = Utility.unsignedShort (buffer, index * 2 + 2);
offset = Utility.getShort (buffer, index * 2 + 2);
int ptr = offset;
while (ptr < buffer.length)

View File

@ -128,7 +128,7 @@ public class ShapeTable extends AbstractFile
return false;
// check index points inside the file
int offset = Utility.unsignedShort (buffer, ptr);
int offset = Utility.getShort (buffer, ptr);
if (offset == 0 || offset >= buffer.length)
return false;

View File

@ -32,6 +32,13 @@ public class SimpleText extends AbstractFile
if (ptr < buffer.length && buffer[ptr] == 0x0A)
ptr++;
}
if (resourceFork != null)
{
text.append ("\n\nResource Fork\n=============\n");
text.append (resourceFork);
}
return text.toString ();
}

View File

@ -2,7 +2,7 @@ package com.bytezone.diskbrowser.applefile;
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_COLON;
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_QUOTE;
import static com.bytezone.diskbrowser.utilities.Utility.unsignedShort;
import static com.bytezone.diskbrowser.utilities.Utility.getShort;
import java.util.ArrayList;
import java.util.List;
@ -30,8 +30,8 @@ public class SourceLine implements ApplesoftConstants
this.buffer = buffer;
linePtr = ptr;
linkField = unsignedShort (buffer, ptr);
lineNumber = unsignedShort (buffer, ptr + 2);
linkField = getShort (buffer, ptr);
lineNumber = getShort (buffer, ptr + 2);
int startPtr = ptr += 4; // skip link field and lineNumber
boolean inString = false; // can toggle

View File

@ -26,10 +26,10 @@ public class StoredVariables extends AbstractFile
int strPtr = buffer.length;
text.append ("File length : " + HexFormatter.format4 (buffer.length));
int totalLength = Utility.intValue (buffer[0], buffer[1]);
int totalLength = Utility.getShort (buffer, 0);
text.append ("\nTotal length : " + HexFormatter.format4 (totalLength));
int varLength = Utility.intValue (buffer[2], buffer[3]);
int varLength = Utility.getShort (buffer, 2);
text.append ("\nVar length : " + HexFormatter.format4 (varLength));
text.append ("\n\n");
@ -51,8 +51,8 @@ public class StoredVariables extends AbstractFile
}
else if (suffix == '%')
{
intValue = Utility.intValue (buffer[ptr + 3], buffer[ptr + 2]);
if ((buffer[ptr + 2] & 0x80) > 0)
intValue = Utility.intValue (buffer[ptr + 3], buffer[ptr + 2]); // backwards!
if ((buffer[ptr + 2] & 0x80) != 0)
intValue -= 65536;
text.append (" = " + intValue);
}
@ -60,7 +60,7 @@ public class StoredVariables extends AbstractFile
{
if (hasValue (ptr + 2))
{
String value = HexFormatter.floatValue (buffer, ptr + 2) + "";
String value = Utility.floatValue (buffer, ptr + 2) + "";
if (value.endsWith (".0"))
text.append (" = " + value.substring (0, value.length () - 2));
else
@ -101,7 +101,7 @@ public class StoredVariables extends AbstractFile
suffix = ' ';
}
StringBuffer variableName = new StringBuffer ();
StringBuilder variableName = new StringBuilder ();
variableName.append (c1);
if (c2 > 32)
variableName.append (c2);
@ -116,12 +116,14 @@ public class StoredVariables extends AbstractFile
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ("(");
for (int i = 0; i < values.length; i++)
{
text.append (values[i]);
if (i < values.length - 1)
text.append (',');
}
return text.append (')').toString ();
}
@ -133,14 +135,14 @@ public class StoredVariables extends AbstractFile
{
String variableName = getVariableName (buffer[ptr], buffer[ptr + 1]);
text.append ("\n");
int offset = Utility.intValue (buffer[ptr + 2], buffer[ptr + 3]);
int offset = Utility.getShort (buffer, ptr + 2);
int dimensions = buffer[ptr + 4] & 0xFF;
int[] dimensionSizes = new int[dimensions];
int totalElements = 0;
for (int i = 0; i < dimensions; i++)
{
int p = i * 2 + 5 + ptr;
int elements = Utility.intValue (buffer[p + 1], buffer[p]);
int elements = Utility.intValue (buffer[p + 1], buffer[p]); // backwards!
dimensionSizes[dimensions - i - 1] = elements - 1;
if (totalElements == 0)
totalElements = elements;
@ -160,7 +162,7 @@ public class StoredVariables extends AbstractFile
text.append (variableName + " " + getDimensionText (values) + " = ");
if (elementSize == 2)
{
int intValue = Utility.intValue (buffer[p + 1], buffer[p]);
int intValue = Utility.intValue (buffer[p + 1], buffer[p]); // backwards
if ((buffer[p] & 0x80) > 0)
intValue -= 65536;
text.append (intValue + "\n");
@ -178,7 +180,7 @@ public class StoredVariables extends AbstractFile
else if (elementSize == 5)
{
if (hasValue (p))
text.append (HexFormatter.floatValue (buffer, p));
text.append (Utility.floatValue (buffer, p));
text.append ("\n");
}
p += elementSize;
@ -201,6 +203,7 @@ public class StoredVariables extends AbstractFile
for (int i = 0; i < 5; i++)
if (buffer[p + i] != 0)
return true;
return false;
}
@ -212,10 +215,10 @@ public class StoredVariables extends AbstractFile
StringBuffer text = new StringBuffer ();
text.append ("File length : " + HexFormatter.format4 (buffer.length));
int totalLength = Utility.intValue (buffer[0], buffer[1]);
int totalLength = Utility.getShort (buffer, 0);
text.append ("\nTotal length : " + HexFormatter.format4 (totalLength));
int varLength = Utility.intValue (buffer[2], buffer[3]);
int varLength = Utility.getShort (buffer, 2);
text.append ("\nVar length : " + HexFormatter.format4 (varLength));
int unknown = buffer[4] & 0xFF;
@ -232,14 +235,14 @@ public class StoredVariables extends AbstractFile
text.append ("\nArrays : \n\n");
while (ptr < totalLength + 5)
{
int offset = Utility.intValue (buffer[ptr + 2], buffer[ptr + 3]);
int offset = Utility.getShort (buffer, ptr + 2);
int dimensions = buffer[ptr + 4] & 0xFF;
int[] dimensionSizes = new int[dimensions];
int totalElements = 0;
for (int i = 0; i < dimensions; i++)
{
int p = i * 2 + 5 + ptr;
int elements = Utility.intValue (buffer[p + 1], buffer[p]);
int elements = Utility.intValue (buffer[p + 1], buffer[p]); // backwards!
dimensionSizes[dimensions - i - 1] = elements;
if (totalElements == 0)
totalElements = elements;

View File

@ -12,6 +12,7 @@ import static com.bytezone.diskbrowser.utilities.Utility.ASCII_PERCENT;
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_QUOTE;
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_RIGHT_BRACKET;
import static com.bytezone.diskbrowser.utilities.Utility.getIndent;
import static com.bytezone.diskbrowser.utilities.Utility.isControlCharacter;
import static com.bytezone.diskbrowser.utilities.Utility.isDigit;
import static com.bytezone.diskbrowser.utilities.Utility.isHighBitSet;
import static com.bytezone.diskbrowser.utilities.Utility.isLetter;
@ -201,7 +202,7 @@ public class SubLine implements ApplesoftConstants
private void checkFunction (String var, byte terminator)
// ---------------------------------------------------------------------------------//
{
assert terminator == ASCII_LEFT_BRACKET;
// assert terminator == ASCII_LEFT_BRACKET;
if (!functions.contains (var))
functions.add (var);
@ -612,29 +613,6 @@ public class SubLine implements ApplesoftConstants
return false;
}
// ---------------------------------------------------------------------------------//
// public String getAlignedText (ApplesoftFormatter alignment)
// // ---------------------------------------------------------------------------------//
// {
// StringBuilder line = toStringBuilder (); // get line
//
// if (alignment.equalsPosition == 0 || is (TOKEN_REM))
// return line.toString ();
//
// int alignEqualsPos = alignment.equalsPosition;
// int targetLength = endPosition - equalsPosition;
//
// // insert spaces before '=' until it lines up with the other assignment lines
// while (alignEqualsPos-- > equalsPosition)
// line.insert (equalsPosition, ' ');
//
// if (line.charAt (line.length () - 1) == ':')
// while (targetLength++ <= alignment.targetLength)
// line.append (" ");
//
// return line.toString ();
// }
// ---------------------------------------------------------------------------------//
public byte[] getBuffer ()
// ---------------------------------------------------------------------------------//
@ -712,45 +690,45 @@ public class SubLine implements ApplesoftConstants
}
// ---------------------------------------------------------------------------------//
// private StringBuilder toStringBuilder ()
// // ---------------------------------------------------------------------------------//
// {
// StringBuilder line = new StringBuilder ();
//
// // All sublines end with 0 or : except IF lines that are split into two
// int max = startPtr + length - 1;
// if (buffer[max] == 0)
// --max;
//
// if (isImpliedGoto () && !ApplesoftBasicProgram.basicPreferences.showThen)
// line.append ("GOTO ");
//
// for (int p = startPtr; p <= max; p++)
// {
// byte b = buffer[p];
// if (isToken (b))
// {
// if (line.length () > 0 && line.charAt (line.length () - 1) != ' ')
// line.append (' ');
// int val = b & 0x7F;
// if (b != TOKEN_THEN || ApplesoftBasicProgram.basicPreferences.showThen)
// line.append (ApplesoftConstants.tokens[val] + " ");
// }
// // else if (Utility.isControlCharacter (b))
// // line.append (ApplesoftBasicProgram.basicPreferences.showCaret
// // ? "^" + (char) (b + 64) : "?");
// else if (!isControlCharacter (b))
// line.append ((char) b);
// }
//
// return line;
// }
StringBuilder toStringBuilder ()
// ---------------------------------------------------------------------------------//
{
StringBuilder line = new StringBuilder ();
// All sublines end with 0 or : except IF lines that are split into two
int max = startPtr + length - 1;
if (buffer[max] == 0)
--max;
if (isImpliedGoto () && !ApplesoftBasicProgram.basicPreferences.showThen)
line.append ("GOTO ");
for (int p = startPtr; p <= max; p++)
{
byte b = buffer[p];
if (isToken (b))
{
if (line.length () > 0 && line.charAt (line.length () - 1) != ' ')
line.append (' ');
int val = b & 0x7F;
if (b != TOKEN_THEN || ApplesoftBasicProgram.basicPreferences.showThen)
line.append (ApplesoftConstants.tokens[val] + " ");
}
// else if (Utility.isControlCharacter (b))
// line.append (ApplesoftBasicProgram.basicPreferences.showCaret
// ? "^" + (char) (b + 64) : "?");
else if (!isControlCharacter (b))
line.append ((char) b);
}
return line;
}
// ---------------------------------------------------------------------------------//
// @Override
// public String toString ()
// // ---------------------------------------------------------------------------------//
// {
// return toStringBuilder ().toString ();
// }
@Override
public String toString ()
// ---------------------------------------------------------------------------------//
{
return toStringBuilder ().toString ();
}
}

View File

@ -21,6 +21,8 @@ public class UserBasicFormatter extends BasicFormatter
private static final int INDENT_SIZE = 2;
private static final String EIGHT_SPACES = " ";
private static final String FOUR_SPACES = " ";
private static boolean FORCE = true;
private static boolean NO_FORCE = false;
// ---------------------------------------------------------------------------------//
public UserBasicFormatter (ApplesoftBasicProgram program,
@ -45,8 +47,8 @@ public class UserBasicFormatter extends BasicFormatter
{
StringBuilder text = new StringBuilder (String.format ("%5d", (line.lineNumber)));
int indentLevel = loopVariables.size (); // each full line starts at the loop indent
int ifIndent = 0; // IF statement(s) limit back indentation by NEXT
int indentLevel = loopVariables.size (); // each full line starts at the loop indent
int ifIndent = 0; // IF statement(s) limit back indentation by NEXT
for (SubLine subline : line.sublines)
{
@ -105,20 +107,29 @@ public class UserBasicFormatter extends BasicFormatter
String lineText = alignment.getAlignedText (subline);
if (subline.is (TOKEN_DATA) && basicPreferences.deleteExtraDataSpace)
lineText = lineText.replaceFirst ("DATA ", "DATA ");
lineText = lineText.replaceFirst ("DATA +", "DATA "); // regex
// Check for a wrappable REM/DATA/DIM statement
// (see SEA BATTLE on DISK283.DSK)
int inset = Math.max (text.length (), getIndent (fullText)) + 1;
if (subline.is (TOKEN_REM) && lineText.length () > basicPreferences.wrapRemAt)
{
List<String> lines = splitLine (lineText, basicPreferences.wrapRemAt, ' ');
List<String> lines =
splitLine (lineText, basicPreferences.wrapRemAt, ' ', FORCE);
addSplitLines (lines, text, inset);
}
else if (subline.is (TOKEN_DATA)
&& lineText.length () > basicPreferences.wrapDataAt)
{
List<String> lines = splitLine (lineText, basicPreferences.wrapDataAt, ',');
List<String> lines =
splitLine (lineText, basicPreferences.wrapDataAt, ',', FORCE);
addSplitLines (lines, text, inset);
}
else if (subline.is (TOKEN_PRINT)
&& lineText.length () > basicPreferences.wrapPrintAt)
{
List<String> lines =
splitLine (lineText, basicPreferences.wrapDataAt, ';', NO_FORCE);
addSplitLines (lines, text, inset);
}
else if (subline.is (TOKEN_DIM) && basicPreferences.splitDim)
@ -162,7 +173,8 @@ public class UserBasicFormatter extends BasicFormatter
}
// ---------------------------------------------------------------------------------//
private List<String> splitLine (String line, int wrapLength, char breakChar)
private List<String> splitLine (String line, int wrapLength, char breakChar,
boolean force)
// ---------------------------------------------------------------------------------//
{
int spaceAt = 0;
@ -182,14 +194,15 @@ public class UserBasicFormatter extends BasicFormatter
break;
lines.add (line.substring (0, breakAt + 1)); // keep breakChar at end
line = indent + line.substring (breakAt + 1);
line = indent + line.substring (breakAt + 1).trim ();
}
while (line.length () > wrapLength) // no breakChars found
{
lines.add (line.substring (0, wrapLength));
line = indent + line.substring (wrapLength);
}
if (force)
while (line.length () > wrapLength) // no breakChars found
{
lines.add (line.substring (0, wrapLength));
line = indent + line.substring (wrapLength);
}
lines.add (line);
return lines;
@ -258,6 +271,7 @@ public class UserBasicFormatter extends BasicFormatter
.size (); i++)
{
boolean precededByIf = false;
for (SubLine subline : sourceLines.get (i).sublines)
{
if (started)

View File

@ -22,10 +22,19 @@
0035 YSAV1
0036 CSWL
0037 CSHW
0044 A5L - volume number?
003D A1H
003C A1L
003F A2H
003E A2L
0041 A3H
0040 A3L
0043 A4H
0042 A4L
0045 A5H
0044 A5L
004E RND-LO
004F RND-HI
0050 LINNUM
0050 LINNUM line number, unsigned word
0067 Basic program address LO
0068 Basic program address HI
0069 Basic variables address LO
@ -52,8 +61,48 @@
0200 Input buffer
03D0 Applesoft warm start
03EA VECT
A56E catalog routine
03F2 RST: Control-reset vector
03F3 RST: Control-reset vector
03F4 RST: Control-reset checksum (EOR #$A5)
03FB NMI: Non-Maskable Interrupt vector
03FC NMI: Non-Maskable Interrupt vector
03F8 USR: user vector (Control-Y)
03F9 USR: user vector (Control-Y)
03FE IRQ: Interrupt Request/BRK vector
03FF IRQ: Interrupt Request/BRK vector
A54F DOS 3.3 INIT
A413 DOS 3.3 LOAD
A397 DOS 3.3 SAVE
A4D1 DOS 3.3 RUN
A4F0 DOS 3.3 CHAIN
A263 DOS 3.3 DELETE
A271 DOS 3.3 LOCK
A275 DOS 3.3 UNLOCK
A2EA DOS 3.3 CLOSE
A51B DOS 3.3 READ
A5C6 DOS 3.3 EXEC
A510 DOS 3.3 WRITE
A5DD DOS 3.3 POSITION
A2A3 DOS 3.3 OPEN
A298 DOS 3.3 APPEND
A281 DOS 3.3 RENAME
A56E DOS 3.3 CATALOG
A233 DOS 3.3 MON
A23D DOS 3.3 NOMON
A229 DOS 3.3 PR#
A22E DOS 3.3 IN#
A251 DOS 3.3 MAXFILES
A57A DOS 3.3 FP
A59E DOS 3.3 INT
A331 DOS 3.3 BSAVE
A35D DOS 3.3 BLOAD
A38E DOS 3.3 BRUN
A27D DOS 3.3 VERIFY
BF00 ProDOS MLI entry point
BF98 ProDOS Machine ID Byte
* C000 80STOREOFF Allow page2 to switch video page1 page2
C001 80STOREON Allow page2 to switch main & aux video memory
@ -68,8 +117,12 @@ C009 ALTZPON Enable aux memory from $0000-$01FF & avl BSR
C00A SLOTC3ROMOFF Enable main ROM from $C300-$C3FF
C00B SLOTC3ROMON Enable slot ROM from $C300-$C3FF
C000 KYBD - last key pressed
C010 STROBE - Clear KYBD
C000 KBD - Last key pressed
C010 KBDSTRB - Clear KYBD
C019 VBL - Vertical Blank
C020 TAPEOUT - Toggle cassette output
C030 SPKR - Toggle speaker
C040 STROBE - Output strobe pulse to game I/O connector
C050 TXTCLR - Display Graphics
C051 TXTSET - Display Text
C052 MIXCLR - Display Full Screen
@ -78,6 +131,15 @@ C054 TXTPAGE1 - Display Page 1
C055 TXTPAGE2 - If 80STORE Off: Display Page 2, If 80STORE On: Read/Write Aux Display Mem
C056 LORES - Display LoRes Graphics
C057 HIRES - Display HiRes Graphics
C060 TAPEIN - Read audio from cassette input
C061 PB0 - Read joystick button 0/Open-Apple key
C062 PB1 - Read joystick button 1/Closed-Apple key
C063 PB2 - Read joystick button 2
C064 PADDL0 - Read paddle/joystick 0
C065 PADDL1 - Read paddle/joystick 1
C066 PADDL2 - Read paddle/joystick 2
C067 PADDL3 - Read paddle/joystick 3
C070 PTRIG - Clear paddle/joystick timer
C080 Read RAM bank 2; no write
C081 ROMIN - Read ROM; write RAM bank 2
@ -96,6 +158,9 @@ C08D Read ROM; write RAM bank 1
C08E Read ROM; no write
C08F Read/write RAM bank 1
C600 BOOT0 - Disk II controller ROM
0801 BOOT1 - Disk II bootstrap RAM
D52C INLIN numeric input
DB3A STROUT - output a string
DB5C output a character
@ -106,6 +171,7 @@ DEC0 SYNCHR
DEC9 syntax error
DFE3 PTRGET
E000 Applesoft BASIC entry
E053 find a variable
E10C convert FP to INT
E2F2 GIVAYF - convert (A,Y) to FP
@ -177,15 +243,16 @@ F941 PRINTAX - print AX registers in hex
F948 PRBLNK - print 3 spaces
F94A PRBL2 - print X blank spaces
FAA6 reboot DOS
FAA6 PWRUP - reboot
FAFF 0 = Autostart ROM, 1 = Old Monitor
FB1E PREAD - read game paddle
FB2F initialise text screen
FB2F INIT - initialise text screen
FB39 text mode - SETTXT
FB40 SETGR
FB5B TABV - monitor tab routine
FB6F set powerup checksum
FB6F SETPWRC - set powerup checksum
FBB3 VERSION - monitor ROM ID byte
FBC1 BASCALC - calculate video address
FBDD BELL1 - beep speaker
FBF4 CURSRIT - move cursor right
@ -193,6 +260,7 @@ FBF4 CURSRIT - move cursor right
FC10 CURSLFT - move cursor left
FC1A CURSUP - move cursor up
FC22 VTAB
FC24 VTABZ
FC42 CLREOP - clear to end of page
FC58 HOME - clear screen
FC62 CR
@ -215,12 +283,13 @@ FDE3 PRHEX - print a hex digit
FDED COUT - print a character (in Acc)
FDF0 COUT1 - print character to screen
FE2C move a block of memory
FE1F IDROUTINE - detect //gs
FE2C MOVE - move a block of memory
FE80 SETINV - set inverse mode
FE84 SETNORM - set normal mode
FE89 disconnect DOS from I/O links
FE89 SETKBD - disconnect DOS from I/O links
FE8B INPORT
FE93 disconnect DOS from I/O links
FE93 SETVID - disconnect DOS from I/O links
FE95 OUTPORT
FECD WRITE
FEFD READ
@ -231,6 +300,14 @@ FF3A BELL
FF3F IOREST - restore all registers
FF4A IOSAVE - save all registers
FF58 RTS - jump to <address on stack> + 1
FF59 Monitor cold entry point
FF59 MON - Monitor cold entry point (w/BELL)
FF69 MONZ - Monitor entry point from BASIC (CALL -151)
FFA7 GETNUM - move num to A2L.A2H
FFC7 ZMODE - monitor get ASCII return
FFFA NMI_VECTOR
FFFB NMI_VECTOR
FFFC RESET_VECTOR
FFFD RESET_VECTOR
FFFE IRQ_VECTOR
FFFF IRQ_VECTOR

View File

@ -52,7 +52,7 @@ public class AppleworksADBFile extends AbstractFile
dbMinVersion = buffer[218] & 0xFF;
headerSize = Utility.unsignedShort (buffer, 0);
headerSize = Utility.getShort (buffer, 0);
cursorDirectionSRL = buffer[30];
cursorDirectionMRL = (char) buffer[31];
currentDisplay = (char) buffer[34];
@ -60,7 +60,7 @@ public class AppleworksADBFile extends AbstractFile
categoryNames = new String[categories];
totalReports = buffer[38] & 0xFF;
int recs = Utility.unsignedShort (buffer, 36);
int recs = Utility.getShort (buffer, 36);
totalRecords = dbMinVersion == 0 ? recs : recs & 0x7FFF;
for (int i = 0; i < 30; i++)
@ -79,9 +79,9 @@ public class AppleworksADBFile extends AbstractFile
for (int i = 0; i < 3; i++)
{
selectionRules[i] = Utility.unsignedShort (buffer, 223 + i * 2);
testTypes[i] = Utility.unsignedShort (buffer, 229 + i * 2);
continuation[i] = Utility.unsignedShort (buffer, 235 + i * 2);
selectionRules[i] = Utility.getShort (buffer, 223 + i * 2);
testTypes[i] = Utility.getShort (buffer, 229 + i * 2);
continuation[i] = Utility.getShort (buffer, 235 + i * 2);
comparison[i] = new String (buffer, 241 + i * 20, 20);
}
@ -106,7 +106,7 @@ public class AppleworksADBFile extends AbstractFile
ptr += 600;
}
int length = Utility.unsignedShort (buffer, ptr);
int length = Utility.getShort (buffer, ptr);
ptr += 2;
if (length == 0)
@ -118,7 +118,7 @@ public class AppleworksADBFile extends AbstractFile
for (int recordNo = 0; recordNo < totalRecords; recordNo++)
{
length = Utility.unsignedShort (buffer, ptr);
length = Utility.getShort (buffer, ptr);
ptr += 2;
if (length == 0)
break;

View File

@ -25,7 +25,7 @@ public class AppleworksSSFile extends AbstractFile
int ptr = header.ssMinVers == 0 ? 300 : 302;
while (ptr < buffer.length)
{
int length = Utility.unsignedShort (buffer, ptr);
int length = Utility.getShort (buffer, ptr);
if (length == 0xFFFF)
break;
@ -103,7 +103,7 @@ public class AppleworksSSFile extends AbstractFile
calcOrder = (char) buffer[131];
calcFrequency = (char) buffer[132];
lastRow = Utility.unsignedShort (buffer, 133);
lastRow = Utility.getShort (buffer, 133);
lastColumn = buffer[135] & 0xFF;
windowLayout = (char) buffer[136];
windowSynch = buffer[137] != 0;
@ -204,15 +204,15 @@ public class AppleworksSSFile extends AbstractFile
r1 = buffer[offset + 3] & 0xFF;
c1 = buffer[offset + 4] & 0xFF;
r2 = Utility.unsignedShort (buffer, offset + 5);
r2 = Utility.getShort (buffer, offset + 5);
c2 = buffer[offset + 7] & 0xFF;
r3 = Utility.unsignedShort (buffer, offset + 8);
r3 = Utility.getShort (buffer, offset + 8);
c3 = buffer[offset + 10] & 0xFF;
r4 = Utility.unsignedShort (buffer, offset + 11);
r4 = Utility.getShort (buffer, offset + 11);
c4 = buffer[offset + 13] & 0xFF;
r5 = buffer[offset + 14] & 0xFF;
c5 = buffer[offset + 15] & 0xFF;
r6 = Utility.unsignedShort (buffer, offset + 16);
r6 = Utility.getShort (buffer, offset + 16);
c6 = buffer[offset + 18] & 0xFF;
r7 = buffer[offset + 19] & 0xFF;
c7 = buffer[offset + 20] & 0xFF;
@ -265,7 +265,7 @@ public class AppleworksSSFile extends AbstractFile
public Row (int ptr)
{
rowNumber = Utility.unsignedShort (buffer, ptr);
rowNumber = Utility.getShort (buffer, ptr);
ptr += 2; // first control byte
int column = 0;

View File

@ -139,7 +139,7 @@ public class AppleworksWPFile extends AbstractFile
break;
default:
System.out.printf ("Unknown value in %s: %02X %02X%n", name, b1, b2);
System.out.printf ("Unknown value in %s: %02X %02X%n", getName (), b1, b2);
}
ptr += 2;
}

View File

@ -14,7 +14,7 @@ class CellAddress
// ---------------------------------------------------------------------------------//
{
colRef = buffer[offset];
rowRef = Utility.intValue (buffer[offset + 1], buffer[offset + 2]);
rowRef = Utility.getShort (buffer, offset + 1);
}
// ---------------------------------------------------------------------------------//

View File

@ -131,9 +131,9 @@ abstract class Report
if (buffer[offset + 480 + fudge] == 0) // test high byte
for (int i = 0; i < 3; i++)
{
selectionRules[i] = Utility.unsignedShort (buffer, offset + 479 + i * 2 + fudge);
testTypes[i] = Utility.unsignedShort (buffer, offset + 485 + i * 2 + fudge);
continuation[i] = Utility.unsignedShort (buffer, offset + 491 + i * 2 + fudge);
selectionRules[i] = Utility.getShort (buffer, offset + 479 + i * 2 + fudge);
testTypes[i] = Utility.getShort (buffer, offset + 485 + i * 2 + fudge);
continuation[i] = Utility.getShort (buffer, offset + 491 + i * 2 + fudge);
comparison[i] = pascalString (buffer, offset + 497 + i * 32 + fudge);
}
else

View File

@ -26,23 +26,28 @@ class CPMCatalogSector extends AbstractSector
for (int i = 0; i <= 255; i += CATALOG_ENTRY_SIZE)
{
if (buffer[i] == (byte) 0xE5)
if (buffer[i] == (byte) 0xE5 && buffer[i + 1] == (byte) 0xE5)
break;
int userNumber = buffer[i] & 0xFF;
if (userNumber > 31 && userNumber != (byte) 0xE5)
break;
boolean readOnly = (buffer[i + 9] & 0x80) != 0;
boolean systemFile = (buffer[i + 10] & 0x80) != 0;
boolean unknown = (buffer[i + 11] & 0x80) != 0;
String type;
String extra;
if (readOnly || systemFile)
if (readOnly || systemFile || unknown)
{
byte[] typeBuffer = new byte[3];
typeBuffer[0] = (byte) (buffer[i + 9] & 0x7F);
typeBuffer[1] = (byte) (buffer[i + 10] & 0x7F);
typeBuffer[2] = buffer[i + 11];
typeBuffer[2] = (byte) (buffer[i + 11] & 0x7F);
type = new String (typeBuffer).trim ();
extra = String.format (" (%s%s)", readOnly ? "read only" : "",
systemFile ? "system file" : "");
extra = String.format (" (%s%s%s)", readOnly ? "read only" : "",
systemFile ? "system file" : "", unknown ? "unknown" : "");
}
else
{
@ -50,8 +55,14 @@ class CPMCatalogSector extends AbstractSector
extra = "";
}
addText (text, buffer, i, 1, "User number");
addText (text, buffer, i + 1, 4, "File name : " + new String (buffer, i + 1, 8));
if (buffer[i] == (byte) 0xE5)
addText (text, buffer, i, 1, "Deleted file?");
else
addText (text, buffer, i, 1, "User number");
if (buffer[i + 1] == 0)
addText (text, buffer, i + 1, 4, "File name : ");
else
addText (text, buffer, i + 1, 4, "File name : " + new String (buffer, i + 1, 8));
addText (text, buffer, i + 5, 4, "");
addText (text, buffer, i + 9, 3, "File type : " + type + extra);
addText (text, buffer, i + 12, 1, "Extent counter LO");

View File

@ -1,6 +1,7 @@
package com.bytezone.diskbrowser.cpm;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import javax.swing.tree.DefaultMutableTreeNode;
@ -13,11 +14,15 @@ import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.SectorType;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.HexFormatter;
// https://www.retrotechnology.com/dri/howto_cpm.html
// -----------------------------------------------------------------------------------//
public class CPMDisk extends AbstractFormattedDisk
// -----------------------------------------------------------------------------------//
{
private static final int EMPTY_BYTE_VALUE = 0xE5;
private final Color green = new Color (0, 200, 0);
public final SectorType catalogSector = new SectorType ("Catalog", green);
@ -50,7 +55,7 @@ public class CPMDisk extends AbstractFormattedDisk
sectorTypesList.add (macSector);
sectorTypesList.add (otherSector);
setEmptyByte ((byte) 0xE5);
setEmptyByte ((byte) EMPTY_BYTE_VALUE);
// search for the version string
for (int i = 8; i >= 4; i -= 2)
@ -74,22 +79,28 @@ public class CPMDisk extends AbstractFormattedDisk
sectorTypes[da.getBlockNo ()] = catalogSector;
byte[] buffer = disk.readBlock (da);
int b1 = buffer[0] & 0xFF;
int b2 = buffer[1] & 0xFF;
if (b1 == 0xE5)
if (b1 == EMPTY_BYTE_VALUE && (b2 == EMPTY_BYTE_VALUE || b2 == 0))
continue;
if (b1 > 31)
if (b1 > 31 && b1 != EMPTY_BYTE_VALUE)
break;
if (b2 < 32 || (b2 > 126 && b2 != 0xE5))
if (b2 <= 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
break;
for (int i = 0; i < buffer.length; i += 32)
{
b1 = buffer[i] & 0xFF;
b2 = buffer[i + 1] & 0xFF;
if (b1 == 0xE5)
break;
if (b2 < 32 || (b2 > 126 && b2 != 0xE5))
if (b1 == EMPTY_BYTE_VALUE) // deleted file??
continue;
if (b2 <= 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
break;
DirectoryEntry entry = new DirectoryEntry (this, buffer, i);
@ -111,9 +122,6 @@ public class CPMDisk extends AbstractFormattedDisk
}
}
// root.setUserObject (getCatalog ()); // override the disk's default display
// makeNodeVisible (rootNode.getFirstLeaf ());
volumeNode.setUserObject (getCatalog ());
makeNodeVisible (volumeNode.getFirstLeaf ());
}
@ -147,6 +155,7 @@ public class CPMDisk extends AbstractFormattedDisk
{
if (fileEntries.size () > 0 && fileEntries.size () > fileNo)
return fileEntries.get (fileNo).getSectors ();
return null;
}
@ -180,19 +189,17 @@ public class CPMDisk extends AbstractFormattedDisk
public AppleFileSource getCatalog ()
// ---------------------------------------------------------------------------------//
{
String newLine = String.format ("%n");
String line =
"---- --------- --- - - -- -- -- -- ----------------------------"
+ "-------------------" + newLine;
String line = "---- --------- --- - - -- -- -- -- ----------------------------"
+ "-------------------\n";
StringBuilder text = new StringBuilder ();
text.append (String.format ("File : %s%n%n", getDisplayPath ()));
text.append ("User Name Typ R S Ex S2 S1 RC Blocks" + newLine);
text.append ("User Name Typ R S Ex S2 S1 RC Blocks\n");
text.append (line);
for (AppleFileSource entry : fileEntries)
{
text.append (((DirectoryEntry) entry).line ());
text.append (newLine);
text.append ("\n");
}
text.append (line);
if (version != 0)
@ -204,6 +211,64 @@ public class CPMDisk extends AbstractFormattedDisk
// ---------------------------------------------------------------------------------//
public static boolean isCorrectFormat (AppleDisk disk)
// ---------------------------------------------------------------------------------//
{
boolean debug = false;
disk.setInterleave (3);
// collect catalog sectors
List<DiskAddress> catalog = new ArrayList<> ();
for (int i = 0; i < 8; i++)
catalog.add (disk.getDiskAddress (3, i));
byte[] buffer = disk.readBlocks (catalog);
if (debug)
System.out.println (HexFormatter.format (buffer));
for (int i = 0; i < 2; i++)
{
int start = i * 1024;
int end = start + 1024;
for (int ptr = start; ptr < end; ptr += 32)
{
if (buffer[ptr] == (byte) EMPTY_BYTE_VALUE)
{
if (buffer[ptr + 1] == (byte) EMPTY_BYTE_VALUE //
|| buffer[ptr + 1] == 0) // finished this block
break;
continue; // deleted file?
}
int userNo = buffer[ptr] & 0xFF;
if (userNo > 31)
return false;
for (int j = 1; j < 12; j++)
{
int ch = buffer[ptr + j] & 0x7F; // remove flag
if (ch < 32 || ch > 126) // invalid ascii
return false;
}
if (debug)
{
String fileName = new String (buffer, ptr + 1, 8);
String fileType = new String (buffer, ptr + 9, 3);
System.out.printf ("%2d %s %s%n", userNo, fileName, fileType);
}
}
}
if (debug)
System.out.println ("CP/M disk");
return true;
}
// ---------------------------------------------------------------------------------//
private static boolean isCorrectFormat2 (AppleDisk disk)
// ---------------------------------------------------------------------------------//
{
disk.setInterleave (3);
@ -222,26 +287,60 @@ public class CPMDisk extends AbstractFormattedDisk
for (int sector = 0; sector < 8; sector++)
{
byte[] buffer = disk.readBlock (3, sector);
System.out.println (HexFormatter.format (buffer));
// check if entire sector is empty (everything == 0xE5)
if (bufferContainsAll (buffer, (byte) 0xE5))
if (bufferContainsAll (buffer, (byte) EMPTY_BYTE_VALUE))
break;
int b1 = buffer[0] & 0xFF;
int b2 = buffer[1] & 0xFF;
if (b1 == EMPTY_BYTE_VALUE && (b2 == EMPTY_BYTE_VALUE || b2 == 0))
continue;
if (b1 > 31 && b1 != EMPTY_BYTE_VALUE)
break;
if (b2 < 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
break;
for (int i = 0; i < buffer.length; i += 32)
{
int val = buffer[i] & 0xFF;
if (val == 0xE5)
break;
b1 = buffer[i] & 0xFF;
b2 = buffer[i + 1] & 0xFF;
if (val > 31)
if (b1 == EMPTY_BYTE_VALUE) // deleted file??
continue;
if (b2 < 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
return false;
for (int j = 1; j <= 8; j++)
{
val = buffer[i + j] & 0xFF;
if (val < 32 || (val > 126 && val != 0xE5))
return false;
}
// int val = buffer[i] & 0xFF;
// if (val == EMPTY_BYTE_VALUE)
// {
// if (debug)
// System.out.println ("empty value found - deleted file?");
// break;
// }
// if (val > 31)
// {
// if (debug)
// System.out.println ("val > 31");
// return false;
// }
// for (int j = 1; j <= 8; j++)
// {
// val = buffer[i + j] & 0xFF;
// if (val < 32 || (val > 126 && val != EMPTY_BYTE_VALUE))
// {
// if (debug)
// System.out.println ("val < 32 || val > 126");
// return false;
// }
// }
}
}

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.applefile.CPMBasicFile;
import com.bytezone.diskbrowser.applefile.CPMTextFile;
import com.bytezone.diskbrowser.applefile.DefaultAppleFile;
import com.bytezone.diskbrowser.disk.AppleDiskAddress;
@ -54,7 +55,11 @@ class DirectoryEntry implements AppleFileSource
type = new String (typeBuffer).trim ();
userNumber = buffer[offset] & 0xFF;
name = new String (buffer, offset + 1, 8).trim ();
if (userNumber == 0xE5 && buffer[offset + 1] == 0)
name = "";
else
name = new String (buffer, offset + 1, 8).trim ();
extent = buffer[offset + 12] & 0xFF;
s2 = buffer[offset + 13] & 0xFF;
s1 = buffer[offset + 14] & 0xFF;
@ -77,9 +82,6 @@ class DirectoryEntry implements AppleFileSource
for (int i = 0; i < 4; i++)
blocks.add (new AppleDiskAddress (disk, blockNumber + i));
}
// if (name.equals ("cp/m"))
// for (DiskAddress da : blocks)
// System.out.println (da);
}
// ---------------------------------------------------------------------------------//
@ -123,6 +125,7 @@ class DirectoryEntry implements AppleFileSource
for (DiskAddress sector : blocks)
if (sector.matches (da))
return true;
return false;
}
@ -136,9 +139,8 @@ class DirectoryEntry implements AppleFileSource
char ro = readOnly ? '*' : ' ';
char sf = systemFile ? '*' : ' ';
String text =
String.format ("%3d %-8s %-3s %s %s %02X %02X %02X %02X %s",
userNumber, name, type, ro, sf, extent, s2, s1, recordsUsed, bytes);
String text = String.format ("%3d %-8s %-3s %s %s %02X %02X %02X %02X %s",
userNumber, name, type, ro, sf, extent, s2, s1, recordsUsed, bytes);
for (DirectoryEntry entry : entries)
text = text + "\n" + entry.line ();
@ -210,23 +212,18 @@ class DirectoryEntry implements AppleFileSource
byte[] exactBuffer = new byte[len];
System.arraycopy (buffer, 0, exactBuffer, 0, len);
int max = Math.min (256, exactBuffer.length);
int count = 0;
for (int i = 1; i < max; i++)
{
if (exactBuffer[i - 1] == 0x0D && exactBuffer[i] == 0x0A)
++count;
}
if ("COM".equals (type))
appleFile = new DefaultAppleFile (name, exactBuffer, "COM File");
else if ("DVR".equals (type))
appleFile = new DefaultAppleFile (name, exactBuffer, "DVR File");
else if ("ASM".equals (type) || "DOC".equals (type) || "TXT".equals (type)
|| count > 2)
else if ("ASM".equals (type) || "DOC".equals (type) || "COB".equals (type)
|| "HLP".equals (type) || "TXT".equals (type) || "LET".equals (type) || "ALX".equals (type)
|| "SRC".equals (type) || "H".equals (type) || exactBuffer[len - 1] == 0x1A)
appleFile = new CPMTextFile (name, exactBuffer);
else if ("BAS".equals (type))
appleFile = new CPMBasicFile (name, exactBuffer);
else
appleFile = new DefaultAppleFile (name, exactBuffer, "CPM File : " + type);
appleFile = new DefaultAppleFile (name, exactBuffer, "CPM File : " + name + "." + type);
return appleFile;
}

View File

@ -85,7 +85,8 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
name = "tmp.dsk";
DefaultAppleFileSource afs =
new DefaultAppleFileSource (name, disk.toString (), this);
// new DefaultAppleFileSource (name, disk.toString (), this);
new DefaultAppleFileSource (name, new DefaultDataSource (disk), this);
DefaultMutableTreeNode root = new DefaultMutableTreeNode (afs);
DefaultTreeModel treeModel = new DefaultTreeModel (root);
catalogTree = new JTree (treeModel);
@ -205,8 +206,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
DefaultMutableTreeNode root = getCatalogTreeRoot ();
if (root.getUserObject () == null)
root.setUserObject (
new DefaultAppleFileSource (getName (), disk.toString (), this));
root.setUserObject (new DefaultAppleFileSource (getName (), disk.toString (), this));
}
// ---------------------------------------------------------------------------------//
@ -233,15 +233,15 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
public String getDisplayPath ()
// ---------------------------------------------------------------------------------//
{
// if (originalPath != null)
// return originalPath.toString ();
String home = System.getProperty ("user.home");
String path = originalPath != null ? originalPath.toString ()
: disk.getFile ().getAbsolutePath ();
if (path.startsWith (home))
return "~" + path.substring (home.length ());
String path =
originalPath != null ? originalPath.toString () : disk.getFile ().getAbsolutePath ();
int pos = path.indexOf (home);
if (pos == 0 || (path.startsWith ("/Volumes/") && pos > 0))
return "~" + path.substring (home.length () + pos);
return disk.getFile ().getAbsolutePath ();
}
@ -326,8 +326,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
if (children != null)
while (children.hasMoreElements ())
{
DefaultMutableTreeNode childNode =
(DefaultMutableTreeNode) children.nextElement ();
DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) children.nextElement ();
if (childNode.getUserObject ().toString ().indexOf (name) > 0)
return childNode;
}

View File

@ -8,14 +8,12 @@ import javax.swing.JPanel;
import com.bytezone.diskbrowser.applefile.AssemblerProgram;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public abstract class AbstractSector implements DataSource
// -----------------------------------------------------------------------------------//
{
private static String newLine = String.format ("%n");
private static String newLine2 = newLine + newLine;
final public byte[] buffer;
protected Disk disk;
protected DiskAddress diskAddress;
@ -56,6 +54,14 @@ public abstract class AbstractSector implements DataSource
return HexFormatter.format (buffer, 0, buffer.length);
}
// ---------------------------------------------------------------------------------//
@Override
public byte[] getBuffer ()
// ---------------------------------------------------------------------------------//
{
return buffer;
}
// ---------------------------------------------------------------------------------//
@Override
public BufferedImage getImage ()
@ -82,10 +88,11 @@ public abstract class AbstractSector implements DataSource
{
StringBuilder text = new StringBuilder ();
text.append (title + newLine2);
text.append ("Offset Value Description" + newLine);
text.append (title + "\n\n");
text.append ("Offset Value Description\n");
text.append ("======= =========== "
+ "===============================================================" + newLine);
+ "===============================================================\n");
return text;
}
@ -135,14 +142,13 @@ public abstract class AbstractSector implements DataSource
String desc)
// ---------------------------------------------------------------------------------//
{
if (size == 1)
desc += " (" + (b[offset] & 0xFF) + ")";
else if (size == 2)
desc +=
String.format (" (%,d)", ((b[offset + 1] & 0xFF) * 256 + (b[offset] & 0xFF)));
else if (size == 3)
desc += String.format (" (%,d)", ((b[offset + 2] & 0xFF) * 65536)
+ ((b[offset + 1] & 0xFF) * 256) + (b[offset] & 0xFF));
desc += switch (size)
{
case 1 -> " (" + (b[offset] & 0xFF) + ")";
case 2 -> String.format (" (%,d)", Utility.getShort (b, offset));
case 3 -> String.format (" (%,d)", Utility.readTriple (b, offset));
default -> "";
};
addText (text, b, offset, size, desc);
}

View File

@ -13,11 +13,13 @@ import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.nib.NibFile;
import com.bytezone.diskbrowser.nib.V2dFile;
import com.bytezone.diskbrowser.nib.WozFile;
import com.bytezone.diskbrowser.nufx.Binary2;
import com.bytezone.diskbrowser.nufx.NuFX;
import com.bytezone.diskbrowser.utilities.FileFormatException;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class AppleDisk implements Disk
@ -38,13 +40,19 @@ public class AppleDisk implements Disk
private final int trackSize; // 4096
public int sectorSize; // 256 or 512
private NuFX nuFX;
private Binary2 bin2;
private WozFile wozFile;
private PrefixDiskCopy prefixDiskCopy;
private Prefix2mg prefix2mg;
private int interleave = 0;
private static int[][] interleaveSector = //
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }, // None
{ 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15 }, // Prodos/Pascal
{ 0, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 15 }, // Infocom
{ 0, 6, 12, 3, 9, 15, 14, 5, 11, 2, 8, 7, 13, 4, 10, 1 } }; // CPM
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, //
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }, // None
{ 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 15 }, // Prodos/Pascal
{ 0, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 15 }, // Infocom
{ 0, 6, 12, 3, 9, 15, 14, 5, 11, 2, 8, 7, 13, 4, 10, 1 } }; // CPM
// Physical disk interleave:
// Info from http://www.applelogic.org/TheAppleIIEGettingStarted.html
@ -83,8 +91,6 @@ public class AppleDisk implements Disk
private ActionListener actionListenerList;
private List<DiskAddress> blockList;
private WozFile wozFile;
private final boolean debug = false;
// ---------------------------------------------------------------------------------//
@ -95,8 +101,7 @@ public class AppleDisk implements Disk
}
// ---------------------------------------------------------------------------------//
public AppleDisk (File file, int tracks, int sectors, int skip)
throws FileFormatException
public AppleDisk (File file, int tracks, int sectors, int skip) throws FileFormatException
// ---------------------------------------------------------------------------------//
{
assert (file.exists ()) : "No such path :" + file.getAbsolutePath ();
@ -114,15 +119,14 @@ public class AppleDisk implements Disk
if ("2mg".equalsIgnoreCase (suffix) || "2IMG".equals (prefix))
{
// System.out.println ("checking 2mg");
if ("2IMG".equals (prefix))
{
Prefix2mg prefix2mg = new Prefix2mg (buffer);
prefix2mg = new Prefix2mg (buffer);
if (debug)
System.out.println (prefix2mg);
if (prefix2mg.diskData > 0)
this.blocks = prefix2mg.diskData / 4096 * 8; // reduce blocks to a multiple of 8
if (prefix2mg.length > 0)
this.blocks = prefix2mg.length / 4096 * 8; // reduce blocks to a multiple of 8
this.sectorSize = 512;
this.trackSize = 8 * sectorSize;
@ -143,7 +147,7 @@ public class AppleDisk implements Disk
}
else if ("img".equals (suffix) || "dimg".equals (suffix))
{
PrefixDiskCopy prefixDiskCopy = new PrefixDiskCopy (buffer);
prefixDiskCopy = new PrefixDiskCopy (buffer);
blocks = prefixDiskCopy.getBlocks ();
this.sectorSize = 512;
@ -153,7 +157,7 @@ public class AppleDisk implements Disk
tracks = blocks / 8; // change parameter!
sectors = 8; // change parameter!
}
else if (suffix.equalsIgnoreCase ("HDV")
else if (suffix.equalsIgnoreCase ("HDV") //
|| (suffix.equalsIgnoreCase ("po") && tracks > 50)) // ULTIMATE APPLE1 CFFA 3.5.po
{
//this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8
@ -161,7 +165,7 @@ public class AppleDisk implements Disk
this.sectorSize = 512;
this.trackSize = sectors * sectorSize;
}
else if (file.length () == 143360 && tracks == 256 && sectors == 8) // wiz4
else if (file.length () == 143360 && tracks == 256 && sectors == 8) // wiz4 or wiz5
{
this.blocks = tracks * sectors;
this.sectorSize = 512;
@ -233,12 +237,27 @@ public class AppleDisk implements Disk
checkSectorsForData ();
}
// ---------------------------------------------------------------------------------//
void setNuFX (NuFX nufx)
// ---------------------------------------------------------------------------------//
{
this.nuFX = nufx;
}
// ---------------------------------------------------------------------------------//
void setBinary2 (Binary2 bin2)
// ---------------------------------------------------------------------------------//
{
this.bin2 = bin2;
}
// ---------------------------------------------------------------------------------//
public AppleDisk (V2dFile disk, int tracks, int sectors)
// ---------------------------------------------------------------------------------//
{
this.tracks = tracks;
this.sectors = sectors;
file = disk.file;
diskBuffer = disk.getDiskBuffer ();
@ -343,7 +362,6 @@ public class AppleDisk implements Disk
// ---------------------------------------------------------------------------------//
{
this.dosVersion = version;
// System.out.printf ("DOS version %02X%n", version);
}
/*
@ -449,6 +467,7 @@ public class AppleDisk implements Disk
readBuffer (da, buffer, ptr);
ptr += sectorSize;
}
return buffer;
}
@ -537,8 +556,7 @@ public class AppleDisk implements Disk
{
if (!isValidAddress (block))
{
System.out.printf ("getDiskAddress: Invalid block : %d of %d%n", block,
this.blocks);
System.out.printf ("getDiskAddress: Invalid block : %d of %d%n", block, this.blocks);
return null;
// return new AppleDiskAddress (this, 0); // this was looping 26/07/2016
}
@ -604,10 +622,9 @@ public class AppleDisk implements Disk
// ---------------------------------------------------------------------------------//
{
assert da.getDisk () == this : "Disk address not applicable to this disk";
assert sectorSize == SECTOR_SIZE
|| sectorSize == BLOCK_SIZE : "Invalid sector size : " + sectorSize;
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : "
+ interleave;
assert sectorSize == SECTOR_SIZE || sectorSize == BLOCK_SIZE : "Invalid sector size : "
+ sectorSize;
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : " + interleave;
if (sectorSize == SECTOR_SIZE)
{
@ -620,8 +637,7 @@ public class AppleDisk implements Disk
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, SECTOR_SIZE);
diskOffset = getBufferOffset (da, 1);
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + SECTOR_SIZE,
SECTOR_SIZE);
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + SECTOR_SIZE, SECTOR_SIZE);
}
}
@ -630,10 +646,9 @@ public class AppleDisk implements Disk
// ---------------------------------------------------------------------------------//
{
assert da.getDisk () == this : "Disk address not applicable to this disk";
assert sectorSize == SECTOR_SIZE
|| sectorSize == BLOCK_SIZE : "Invalid sector size : " + sectorSize;
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : "
+ interleave;
assert sectorSize == SECTOR_SIZE || sectorSize == BLOCK_SIZE : "Invalid sector size : "
+ sectorSize;
assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : " + interleave;
if (sectorSize == SECTOR_SIZE)
{
@ -650,6 +665,13 @@ public class AppleDisk implements Disk
}
}
// ---------------------------------------------------------------------------------//
public byte[] getBuffer ()
// ---------------------------------------------------------------------------------//
{
return diskBuffer;
}
// ---------------------------------------------------------------------------------//
private int getBufferOffset (DiskAddress da)
// ---------------------------------------------------------------------------------//
@ -698,11 +720,11 @@ public class AppleDisk implements Disk
}
// ---------------------------------------------------------------------------------//
public AppleFileSource getDetails ()
// ---------------------------------------------------------------------------------//
{
return new DefaultAppleFileSource (toString (), file.getName (), null);
}
// private AppleFileSource getDetails ()
// // ---------------------------------------------------------------------------------//
// {
// return new DefaultAppleFileSource (toString (), file.getName (), null);
// }
// ---------------------------------------------------------------------------------//
@Override
@ -711,28 +733,29 @@ public class AppleDisk implements Disk
{
StringBuilder text = new StringBuilder ();
String path = file.getAbsolutePath ();
String home = System.getProperty ("user.home");
if (path.startsWith (home))
path = "~" + path.substring (home.length ());
text.append (String.format ("Path................. %s%n", path));
text.append (String.format ("File name............ %s%n", file.getName ()));
text.append (String.format ("File size............ %,d%n", file.length ()));
text.append (String.format ("Tracks............... %d%n", tracks));
text.append (String.format ("Sectors.............. %d%n", sectors));
text.append (String.format ("Blocks............... %,d%n", blocks));
text.append (String.format ("Track size........... %,d%n", trackSize));
text.append (String.format ("Sector size.......... %d%n", sectorSize));
text.append (String.format ("Interleave........... %d", interleave));
text.append (
String.format ("Path ......... %s%n", Utility.getShortPath (file.getAbsolutePath ())));
text.append (String.format ("File name .... %s%n", file.getName ()));
text.append (String.format ("File size .... %,d%n", file.length ()));
text.append (String.format ("Tracks ....... %d%n", tracks));
text.append (String.format ("Sectors ...... %d%n", sectors));
text.append (String.format ("Blocks ....... %,d%n", blocks));
text.append (String.format ("Track size ... %,d%n", trackSize));
text.append (String.format ("Sector size .. %d%n", sectorSize));
text.append (String.format ("Interleave ... %d%n%n", interleave));
if (wozFile != null)
{
text.append ("\n\n");
text.append (wozFile);
}
else if (nuFX != null)
text.append (nuFX);
else if (bin2 != null)
text.append (bin2);
else if (prefixDiskCopy != null)
text.append (prefixDiskCopy);
else if (prefix2mg != null)
text.append (prefix2mg);
return text.toString ();
return Utility.rtrim (text).toString ();
}
// ---------------------------------------------------------------------------------//

View File

@ -49,8 +49,8 @@ public class DefaultAppleFileSource implements AppleFileSource
{
this (title, file, owner);
this.blocks = blocks;
if (file instanceof DefaultDataSource)
((DefaultDataSource) file).buffer = owner.getDisk ().readBlocks (blocks);
if (file instanceof DefaultDataSource dds)
dds.buffer = owner.getDisk ().readBlocks (blocks);
}
// ---------------------------------------------------------------------------------//
@ -58,8 +58,8 @@ public class DefaultAppleFileSource implements AppleFileSource
// ---------------------------------------------------------------------------------//
{
this.blocks = blocks;
if (file instanceof DefaultDataSource)
((DefaultDataSource) file).buffer = owner.getDisk ().readBlocks (blocks);
if (file instanceof DefaultDataSource dds)
dds.buffer = owner.getDisk ().readBlocks (blocks);
}
// ---------------------------------------------------------------------------------//

View File

@ -14,6 +14,7 @@ public class DefaultDataSource implements DataSource
{
public String text;
byte[] buffer;
Object textSource;
// ---------------------------------------------------------------------------------//
public DefaultDataSource (String text)
@ -22,6 +23,13 @@ public class DefaultDataSource implements DataSource
this.text = text;
}
// ---------------------------------------------------------------------------------//
public DefaultDataSource (Object textSource)
// ---------------------------------------------------------------------------------//
{
this.textSource = textSource;
}
// ---------------------------------------------------------------------------------//
@Override
public String getAssembler ()
@ -40,6 +48,14 @@ public class DefaultDataSource implements DataSource
return null;
}
// ---------------------------------------------------------------------------------//
@Override
public byte[] getBuffer ()
// ---------------------------------------------------------------------------------//
{
return buffer;
}
// ---------------------------------------------------------------------------------//
@Override
public BufferedImage getImage ()
@ -53,7 +69,7 @@ public class DefaultDataSource implements DataSource
public String getText ()
// ---------------------------------------------------------------------------------//
{
return text;
return textSource == null ? text : textSource.toString ();
}
// ---------------------------------------------------------------------------------//
@ -61,7 +77,6 @@ public class DefaultDataSource implements DataSource
public JComponent getComponent ()
// ---------------------------------------------------------------------------------//
{
System.out.println ("In DefaultDataSource.getComponent()");
JPanel panel = new JPanel ();
return panel;
}

View File

@ -1,5 +1,6 @@
package com.bytezone.diskbrowser.disk;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -18,10 +19,12 @@ import com.bytezone.diskbrowser.infocom.InfocomDisk;
import com.bytezone.diskbrowser.nib.NibFile;
import com.bytezone.diskbrowser.nib.V2dFile;
import com.bytezone.diskbrowser.nib.WozFile;
import com.bytezone.diskbrowser.nufx.Binary2;
import com.bytezone.diskbrowser.nufx.NuFX;
import com.bytezone.diskbrowser.pascal.PascalDisk;
import com.bytezone.diskbrowser.prodos.ProdosDisk;
import com.bytezone.diskbrowser.utilities.FileFormatException;
import com.bytezone.diskbrowser.utilities.NuFX;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
import com.bytezone.diskbrowser.wizardry.Wizardry4BootDisk;
import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk;
@ -32,6 +35,13 @@ public class DiskFactory
{
private static boolean debug = false;
private static final int DISK_800K = 819200;
private static final int DISK_143K = 143360;
private static final int DISK_116K = 116480;
private static NuFX nuFX;
private static Binary2 binary2;
// ---------------------------------------------------------------------------------//
private DiskFactory ()
// ---------------------------------------------------------------------------------//
@ -48,23 +58,13 @@ public class DiskFactory
// ---------------------------------------------------------------------------------//
public static FormattedDisk createDisk (String pathName)
// ---------------------------------------------------------------------------------//
{
FormattedDisk disk = create (pathName);
// if (disk.getDisk ().getInterleave () > 0)
// {
// System.out.println (disk);
// System.out.println ();
// }
return disk;
}
// ---------------------------------------------------------------------------------//
private static FormattedDisk create (String pathName)
// ---------------------------------------------------------------------------------//
{
if (debug)
System.out.println ("\nFactory : " + pathName);
nuFX = null;
binary2 = null;
File file = new File (pathName);
if (!file.exists ())
return null;
@ -98,7 +98,7 @@ public class DiskFactory
}
catch (IOException e) // can get EOFException: Unexpected end of ZLIB input stream
{
e.printStackTrace ();
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
return null;
}
}
@ -141,20 +141,26 @@ public class DiskFactory
}
catch (IOException e)
{
e.printStackTrace ();
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
return null;
}
}
if ("sdk".equals (suffix) || "shk".equals (suffix)) // shrinkit disk/file archive
if ("sdk".equals (suffix) // NuFX disk
|| "shk".equals (suffix) // NuFX files or disk
|| "bxy".equals (suffix)) // NuFX in Bin2
{
if (debug)
System.out.println (" ** sdk/shk **");
System.out.println (" ** sdk/shk/bxy **");
try
{
NuFX nuFX = new NuFX (file.toPath ());
nuFX = new NuFX (file.toPath ());
if (nuFX.getTotalDisks () == 0 && nuFX.getTotalFiles () == 0)
{
if (debug)
System.out.println ("Empty NuFX file");
return null;
}
byte[] diskBuffer = nuFX.getDiskBuffer ();
if (diskBuffer == null)
@ -169,16 +175,54 @@ public class DiskFactory
suffix = "dsk";
compressed = true;
}
catch (IOException e)
catch (Exception e)
{
e.printStackTrace ();
// e.printStackTrace ();
if (e.getMessage () == null)
System.out.println (e);
else
System.out.println (e.getMessage ());
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
// System.out.println (nuFX);
return null;
}
catch (FileFormatException e)
}
else if ("bny".equals (suffix) || "bqy".equals (suffix)) // Binary2 uncompressed files
{
if (debug)
System.out.println (" ** bny/bqy **");
try
{
binary2 = new Binary2 (file.toPath ());
byte[] diskBuffer = binary2.getDiskBuffer ();
File tmp = File.createTempFile (suffix, null);
FileOutputStream fos = new FileOutputStream (tmp);
fos.write (diskBuffer);
fos.close ();
tmp.deleteOnExit ();
file = tmp;
suffix = "dsk";
compressed = true;
}
catch (Exception e)
{
// e.printStackTrace ();
System.out.println (e.getMessage ());
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
// System.out.println (binary2);
return null;
}
}
else if ("bsq".equals (suffix))
{
if (debug)
System.out.println (" ** bsq **");
byte[] prefix = getPrefix (file);
System.out.println (HexFormatter.format (prefix));
String key = "FiLeStArTfIlEsTaRt";
}
FormattedDisk disk = null;
FormattedDisk disk2 = null;
@ -228,34 +272,34 @@ public class DiskFactory
// Toolkit.do = 143488
if (((suffix.equals ("po") || suffix.equals ("dsk") || suffix.equals ("do"))
&& file.length () > 143360))
&& file.length () > DISK_143K))
{
if (file.length () < 143500) // slightly bigger than a floppy
{
System.out.println ("File length is wrong: " + file.length ());
disk = checkDos (new AppleDisk (file, 35, 16));
if (disk != null)
return disk;
return check (disk);
}
if (debug)
System.out.printf (" Checking po or dsk hard drive: %,d%n", file.length ());
System.out.printf ("Checking po or dsk hard drive: %,d%n", file.length ());
disk = checkHardDisk (file);
if (disk != null)
{
if (compressed)
disk.setOriginalPath (originalPath);
return disk;
return check (disk);
}
if (file.length () == 819200) // 800K 3.5"
if (file.length () == DISK_800K) // 800K 3.5"
{
if (debug)
System.out.println ("UniDos ?");
// 2 x 400k disk images
AppleDisk appleDisk1 = new AppleDisk (file, 50, 32);
AppleDisk appleDisk2 = new AppleDisk (file, 50, 32, (int) (file.length () / 2));
AppleDisk appleDisk2 = new AppleDisk (file, 50, 32, 0x64000);
disk = checkUnidos (appleDisk1, 1);
disk2 = checkUnidos (appleDisk2, 2);
if (disk != null && disk2 != null)
@ -306,9 +350,10 @@ public class DiskFactory
{
if (debug)
System.out.println (" --> PRODOS hard disk");
return new ProdosDisk (disk800);
disk = new ProdosDisk (disk800);
}
disk = new DataDisk (disk800);
else
disk = new DataDisk (disk800);
}
else
{
@ -316,11 +361,15 @@ public class DiskFactory
disk = checkDos (appleDisk256);
if (disk == null)
disk = checkProdos (new AppleDisk (wozFile, 35, 8));
if (disk == null)
disk = checkPascalDisk (new AppleDisk (wozFile, 35, 8));
if (disk == null)
disk = new DataDisk (appleDisk256);
}
}
disk.setOriginalPath (originalPath); // allow Save converted disk...
return disk;
}
catch (Exception e)
@ -355,7 +404,7 @@ public class DiskFactory
long length = file.length ();
if (length == 116480) // 13 sector disk
if (length == DISK_116K) // 13 sector floppy disk
{
if (debug)
System.out.println (" ** 13 sector **");
@ -367,7 +416,7 @@ public class DiskFactory
return disk == null ? new DataDisk (appleDisk) : disk;
}
if (length != 143360)
if (length != DISK_143K) // 16 sector floppy disk
{
System.out.printf ("%s: invalid file length : %,d%n", file.getName (),
file.length ());
@ -379,7 +428,7 @@ public class DiskFactory
if (true)
{
// long checksum = appleDisk256.getBootChecksum ();
// long checksum = appleDisk256.getBootChecksum ();
long checksum = 0;
if (checksum == 227968344L) // empty boot sector
@ -404,7 +453,7 @@ public class DiskFactory
if (debug)
System.out.println (" known DOS checksum : " + checksum);
disk = checkDos (appleDisk256);
// disk2 = checkProdos (appleDisk512); // no need for this
// disk2 = checkProdos (appleDisk512); // no need for this
if (disk2 != null && disk != null) // should be impossible
{
if (debug)
@ -450,17 +499,17 @@ public class DiskFactory
else if (debug)
System.out.println (" unknown checksum : " + checksum);
// else if (checksum == 1212926910L || checksum == 1365043894L
// || checksum == 2128073918L)
// disk = checkCPMDisk (file);
// else if (checksum == 1212926910L || checksum == 1365043894L
// || checksum == 2128073918L)
// disk = checkCPMDisk (file);
// System.out.println (checksum);
// System.out.println (checksum);
if (disk != null)
{
if (compressed)
disk.setOriginalPath (originalPath);
return disk;
return check (disk);
}
// empty boot sector
@ -536,6 +585,21 @@ public class DiskFactory
if (disk != null && compressed)
disk.setOriginalPath (originalPath);
return check (disk);
}
// ---------------------------------------------------------------------------------//
private static FormattedDisk check (FormattedDisk disk)
// ---------------------------------------------------------------------------------//
{
if (disk.getDisk () instanceof AppleDisk appleDisk)
{
if (nuFX != null)
appleDisk.setNuFX (nuFX);
else if (binary2 != null)
appleDisk.setBinary2 (binary2);
}
return disk;
}
@ -553,7 +617,7 @@ public class DiskFactory
if (debug)
System.out.println (" --> DOS");
DosDisk dosDisk = new DosDisk (disk);
// disk.setDosVersion (dosDisk.getVersion ());
// disk.setDosVersion (dosDisk.getVersion ());
return dosDisk;
}
@ -622,7 +686,7 @@ public class DiskFactory
{
if (debug)
{
System.out.println ("\nChecking Prodos hard disk");
System.out.println ("\nChecking Prodos/Pascal hard disk");
System.out.printf ("Total blocks : %f%n", (float) file.length () / 512);
System.out.printf ("Total tracks : %f%n", (float) file.length () / 4096);
System.out.printf ("File length : %d%n", file.length ());
@ -645,13 +709,19 @@ public class DiskFactory
{
System.out.println ("*** extended ***"); // System Addons.hdv
}
AppleDisk disk = new AppleDisk (file, tracks, 8);
AppleDisk disk;
// if (nuFX == null)
disk = new AppleDisk (file, tracks, 8);
// else
// disk = new AppleDisk (file, tracks, 8, nuFX);
if (ProdosDisk.isCorrectFormat (disk))
{
if (debug)
System.out.println (" --> PRODOS hard disk");
return new ProdosDisk (disk);
}
if (PascalDisk.isCorrectFormat (disk, debug))
{
if (debug)
@ -662,11 +732,12 @@ public class DiskFactory
catch (Exception e)
{
System.out.println (e);
e.printStackTrace ();
System.out.println ("Prodos hard disk had error");
}
if (debug)
System.out.println (" not a Prodos hard disk\n");
System.out.println (" not a Prodos/Pascal hard disk\n");
return null;
}
@ -791,11 +862,16 @@ public class DiskFactory
if (Wizardry4BootDisk.isWizardryIVorV (disk, debug))
{
if (debug)
System.out.println ("checking Wizardry IV or V");
String fileName = file.getAbsolutePath ().toLowerCase ();
int pos = file.getAbsolutePath ().indexOf ('.');
char c = fileName.charAt (pos - 1);
// String suffix = fileName.substring (pos + 1);
int requiredDisks = c == '1' ? 6 : c == 'a' ? 10 : 0;
int pos = fileName.lastIndexOf ('.');
char c = fileName.charAt (pos - 1); // '1' (wiz4) or 'a' (wiz5)
int requiredDisks = c == '1' ? 7 : c == 'a' ? 10 : 0;
if (debug)
System.out.printf ("Required disks: %d%n", requiredDisks);
if (requiredDisks > 0)
{
@ -816,7 +892,7 @@ public class DiskFactory
}
}
if (debug)
System.out.println ("Not a Wizardry IV disk");
System.out.println ("Not a Wizardry IV or V disk");
PascalDisk pascalDisk = new PascalDisk (disk);
return pascalDisk;
@ -826,6 +902,9 @@ public class DiskFactory
private static boolean collectDataDisks (String fileName, int dotPos, AppleDisk[] disks)
// ---------------------------------------------------------------------------------//
{
if (debug)
System.out.println ("Collecting Wizardry disks");
char c = fileName.charAt (dotPos - 1);
String suffix = fileName.substring (dotPos + 1);
@ -833,14 +912,16 @@ public class DiskFactory
{
String old = new String (c + "." + suffix);
String rep = new String ((char) (c + i - 1) + "." + suffix);
File f = new File (fileName.replace (old, rep));
if (debug)
System.out.println (f);
if (!f.exists () || !f.isFile ())
return false;
AppleDisk dataDisk = new AppleDisk (f, 35, 8);
dataDisk.setInterleave (1);
disks[i] = dataDisk;
disks[i] = new AppleDisk (f, 35, 8);
disks[i].setInterleave (1);
}
return true;
@ -881,4 +962,22 @@ public class DiskFactory
return null;
}
// ---------------------------------------------------------------------------------//
private static byte[] getPrefix (File file)
// ---------------------------------------------------------------------------------//
{
byte[] buffer = new byte[1024];
try (BufferedInputStream bis = new BufferedInputStream (new FileInputStream (file)))
{
bis.read (buffer);
}
catch (IOException e)
{
e.printStackTrace ();
System.exit (1);
}
return buffer;
}
}

View File

@ -81,7 +81,4 @@ public interface FormattedDisk
public int falseNegativeBlocks ();
public String getName ();
}
// getFileTypeList ()
// getFiles (FileType type)
}

View File

@ -7,13 +7,25 @@ import com.bytezone.diskbrowser.utilities.Utility;
public class Prefix2mg
// -----------------------------------------------------------------------------------//
{
String[] creators = { "!nfc", "B2TR", "CTKG", "CdrP", "ShIm", "WOOF", "XGS!" };
String[] images = { "Dos3.3", "Prodos", "Nibbized" };
String prefix;
String creator;
int headerSize;
int version;
byte format;
int diskData;
int format;
int flags;
int length;
int blocks;
int offset;
int commentOffset;
int commentLength;
int creatorOffset;
int creatorLength;
boolean flagsLocked;
int flagsVolume;
// ---------------------------------------------------------------------------------//
public Prefix2mg (byte[] buffer)
@ -21,14 +33,29 @@ public class Prefix2mg
{
prefix = new String (buffer, 0, 4);
creator = new String (buffer, 4, 4);
headerSize = Utility.getWord (buffer, 8);
version = Utility.getWord (buffer, 10);
format = buffer[12];
headerSize = Utility.getShort (buffer, 0x08);
version = Utility.getShort (buffer, 0x0A);
format = Utility.getLong (buffer, 0x0C);
flags = Utility.getLong (buffer, 0x10);
blocks = Utility.getLong (buffer, 0x14); // 1600
offset = Utility.getLong (buffer, 0x18);
length = Utility.getLong (buffer, 0x1C);
commentOffset = Utility.getLong (buffer, 0x20);
commentLength = Utility.getLong (buffer, 0x24);
creatorOffset = Utility.getLong (buffer, 0x28);
creatorLength = Utility.getLong (buffer, 0x2C);
diskData = Utility.getLong (buffer, 28);
blocks = Utility.intValue (buffer[20], buffer[21]); // 1600
flagsLocked = (flags & 0x80000000) != 0;
if ((flags & 0x0100) != 0)
flagsVolume = flags & 0xFF;
if (format == 0 && flagsVolume == 0)
flagsVolume = 254;
if (length == 0)
length = 512 * blocks;
// see /Asimov disks/images/gs/os/prodos16/ProDOS 16v1_3.2mg
// System.out.println (this);
}
// ---------------------------------------------------------------------------------//
@ -38,14 +65,21 @@ public class Prefix2mg
{
StringBuilder text = new StringBuilder ();
text.append (String.format ("Prefix : %s%n", prefix));
text.append (String.format ("Creator : %s%n", creator));
text.append (String.format ("Header : %d%n", headerSize));
text.append (String.format ("Version : %d%n", version));
text.append (String.format ("Format : %02X%n", format));
text.append (String.format ("Data size : %08X (%<,d)%n", diskData));
text.append (String.format ("Blocks : %,d%n", blocks));
text.append (String.format ("Prefix : %s%n", prefix));
text.append (String.format ("Creator : %s%n", creator));
text.append (String.format ("Header : %d%n", headerSize));
text.append (String.format ("Version : %d%n", version));
text.append (String.format ("Format : %02X%n", format));
text.append (String.format ("Flags : %,d%n", flags));
text.append (String.format ("Locked : %s%n", flagsLocked));
text.append (String.format ("DOS Volume : %,d%n", flagsVolume));
text.append (String.format ("Blocks : %,d%n", blocks));
text.append (String.format ("Offset : %,d%n", offset));
text.append (String.format ("Length : %08X (%<,d)%n", length));
text.append (String.format ("Comment Offset : %,d%n", commentOffset));
text.append (String.format ("Comment Length : %08X (%<,d)%n", commentLength));
text.append (String.format ("Creator Offset : %,d%n", creatorOffset));
text.append (String.format ("Creator Length : %08X (%<,d)", creatorLength));
return text.toString ();
}

View File

@ -4,6 +4,7 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// https://www.discferret.com/wiki/Apple_DiskCopy_4.2
// Apple II File Type Notes $E0/0005 (macintosh)
// -----------------------------------------------------------------------------------//
public class PrefixDiskCopy
// -----------------------------------------------------------------------------------//
@ -11,9 +12,11 @@ public class PrefixDiskCopy
private String name;
private int dataSize;
private int tagSize;
private int encoding;
private int dataChecksum;
private int tagChecksum;
private int diskFormat;
private int format;
private int id;
private int id; // should be 0x0100
// ---------------------------------------------------------------------------------//
public PrefixDiskCopy (byte[] buffer)
@ -24,9 +27,11 @@ public class PrefixDiskCopy
name = HexFormatter.getPascalString (buffer, 0);
dataSize = Utility.getLongBigEndian (buffer, 0x40);
tagSize = Utility.getLongBigEndian (buffer, 0x44);
encoding = buffer[0x50] & 0xFF;
dataChecksum = Utility.getLongBigEndian (buffer, 0x48);
tagChecksum = Utility.getLongBigEndian (buffer, 0x4C);
diskFormat = buffer[0x50] & 0xFF;
format = buffer[0x51] & 0xFF;
id = Utility.getWordBigEndian (buffer, 0x52);
id = Utility.getShortBigEndian (buffer, 0x52);
}
// ---------------------------------------------------------------------------------//
@ -43,12 +48,14 @@ public class PrefixDiskCopy
{
StringBuilder text = new StringBuilder ();
text.append (String.format ("Name : %s%n", name));
text.append (String.format ("Data size : %08X (%<,d)%n", dataSize));
text.append (String.format ("Tag size : %08X (%<,d)%n", tagSize));
text.append (String.format ("Encoding : %02X%n", encoding));
text.append (String.format ("Format : %02X%n", format));
text.append (String.format ("ID : %04X%n", id));
text.append (String.format ("Name : %s%n", name));
text.append (String.format ("Data size : %08X (%<,d)%n", dataSize));
text.append (String.format ("Tag size : %08X (%<,d)%n", tagSize));
text.append (String.format ("Data checksum : %08X (%<,d)%n", dataChecksum));
text.append (String.format ("Tag checksum : %08X (%<,d)%n", tagChecksum));
text.append (String.format ("Disk format : %02X%n", diskFormat));
text.append (String.format ("Format byte : %02X%n", format));
text.append (String.format ("ID : %04X%n", id));
return text.toString ();
}

View File

@ -17,8 +17,7 @@ public class SectorListConverter
sectors = new ArrayList<> ();
sectorText = text;
String[] blocks = text.split (";");
for (String s : blocks)
for (String s : text.split (";"))
{
int pos = s.indexOf ('-');
if (pos > 0)

View File

@ -67,7 +67,7 @@ abstract class AbstractCatalogEntry implements AppleFileSource
this.catalogSectorDA = catalogSector;
name = getName ("", entryBuffer);
reportedSize = Utility.unsignedShort (entryBuffer, 33);
reportedSize = Utility.getShort (entryBuffer, 33);
int type = entryBuffer[2] & 0x7F;
locked = (entryBuffer[2] & 0x80) != 0;
@ -89,8 +89,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
lastModified = Utility.getDateTime (entryBuffer, 0x1B);
// CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6
String base = String.format ("%s%s %03d ", locked ? "*" : " ", getFileType (),
reportedSize & 0xFF);
String base =
String.format ("%s%s %03d ", locked ? "*" : " ", getFileType (), reportedSize & 0xFF);
catalogName = getName (base, entryBuffer);
displayName = getDisplayName (entryBuffer);
}
@ -234,30 +234,40 @@ abstract class AbstractCatalogEntry implements AppleFileSource
break;
case IntegerBasic:
reportedLength = Utility.unsignedShort (buffer, 0);
exactBuffer = new byte[reportedLength];
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
appleFile = new IntegerBasicProgram (name, exactBuffer);
reportedLength = Utility.getShort (buffer, 0);
if (reportedLength > 0)
{
exactBuffer = new byte[reportedLength];
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
appleFile = new IntegerBasicProgram (name, exactBuffer);
}
else
appleFile = new DefaultAppleFile (name, buffer);
break;
case ApplesoftBasic:
reportedLength = Utility.unsignedShort (buffer, 0);
exactBuffer = new byte[reportedLength];
if (reportedLength > buffer.length)
reportedLength = buffer.length - 2;
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
appleFile = new ApplesoftBasicProgram (name, exactBuffer);
reportedLength = Utility.getShort (buffer, 0);
if (reportedLength > 0)
{
exactBuffer = new byte[reportedLength];
if (reportedLength > buffer.length)
reportedLength = buffer.length - 2;
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
appleFile = new ApplesoftBasicProgram (name, exactBuffer);
}
else
appleFile = new DefaultAppleFile (name, buffer);
break;
case Binary: // binary file
case Relocatable: // relocatable binary file
case BB:
int loadAddress = Utility.unsignedShort (buffer, 0);
reportedLength = Utility.unsignedShort (buffer, 2);
int loadAddress = Utility.getShort (buffer, 0);
reportedLength = Utility.getShort (buffer, 2);
if (reportedLength == 0)
{
System.out.println (name.trim () + " reported length : 0 - reverting to "
+ (buffer.length - 4));
System.out.println (
name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
reportedLength = buffer.length - 4;
}
@ -268,9 +278,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
if ((name.endsWith (".FONT") || name.endsWith (" FONT")
|| name.endsWith (".SET") || name.startsWith ("ASCII."))
&& FontFile.isFont (exactBuffer))
if ((name.endsWith (".FONT") || name.endsWith (" FONT") || name.endsWith (".SET")
|| name.startsWith ("ASCII.")) && FontFile.isFont (exactBuffer))
appleFile = new FontFile (name, exactBuffer, loadAddress);
else if (name.endsWith (".MW"))
appleFile = new MagicWindowText (name, exactBuffer);
@ -305,8 +314,7 @@ abstract class AbstractCatalogEntry implements AppleFileSource
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
}
else if (reportedLength == 0x240 //
&& (loadAddress == 0x5800 || loadAddress == 0x6000
|| loadAddress == 0x7800))
&& (loadAddress == 0x5800 || loadAddress == 0x6000 || loadAddress == 0x7800))
appleFile = new PrintShopGraphic (name, exactBuffer);
else if (isRunCommand (exactBuffer))
{
@ -319,8 +327,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
{
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
if ((exactBuffer.length + 4) < buffer.length)
((AssemblerProgram) appleFile).setExtraBuffer (buffer,
exactBuffer.length + 4, buffer.length - (exactBuffer.length + 4));
((AssemblerProgram) appleFile).setExtraBuffer (buffer, exactBuffer.length + 4,
buffer.length - (exactBuffer.length + 4));
}
break;
@ -359,11 +367,11 @@ abstract class AbstractCatalogEntry implements AppleFileSource
{
byte[] exactBuffer;
int reportedLength = Utility.unsignedShort (buffer, 2);
int reportedLength = Utility.getShort (buffer, 2);
if (reportedLength == 0)
{
System.out.println (
name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
System.out
.println (name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
reportedLength = buffer.length - 4;
}

View File

@ -131,12 +131,12 @@ class CatalogEntry extends AbstractCatalogEntry
{
case IntegerBasic:
case ApplesoftBasic:
length = Utility.intValue (buffer[0], buffer[1]);
length = Utility.getShort (buffer, 0);
break;
default:
address = Utility.intValue (buffer[0], buffer[1]);
length = Utility.intValue (buffer[2], buffer[3]);
address = Utility.getShort (buffer, 0);
length = Utility.getShort (buffer, 2);
}
}
}

View File

@ -326,6 +326,8 @@ public class DosDisk extends AbstractFormattedDisk
return "4.2";
case 0x43:
return "4.3";
case 0x45:
return "4.5";
default:
return "??";
}
@ -376,7 +378,7 @@ public class DosDisk extends AbstractFormattedDisk
int version = buffer[3] & 0xFF;
if (debug)
System.out.printf ("Version: %02X%n", buffer[3]);
if (version == 0 || (version > 0x43 && version != 0xFF))
if (version == 0 || (version > 0x45 && version != 0xFF))
{
if (debug)
System.out.printf ("Bad version : %02X%n", version);

View File

@ -82,7 +82,7 @@ class DosTSListSector extends AbstractSector
addText (text, buffer, 7, 4, "Not used");
addText (text, buffer, 11, 1, "Not used");
int sectorBase = Utility.intValue (buffer[5], buffer[6]);
int sectorBase = Utility.getShort (buffer, 5);
for (int i = 12; i <= 255; i += 2)
{

View File

@ -35,7 +35,7 @@ class DosVTOCSector extends AbstractSector
direction = buffer[49];
maxTracks = buffer[52] & 0xFF;
maxSectors = buffer[53] & 0xFF;
sectorSize = Utility.intValue (buffer[54], buffer[55]);
sectorSize = Utility.getShort (buffer, 54);
flagSectors ();
}

View File

@ -120,7 +120,7 @@ public class DisksWindow extends JFrame
}
});
scrollPane.setPreferredSize (new Dimension (1200, 700));
scrollPane.setPreferredSize (new Dimension (1200, 693));
setDefaultCloseOperation (HIDE_ON_CLOSE);
deleteWindow = new DeleteWindow (rootFolderData);
@ -188,11 +188,11 @@ public class DisksWindow extends JFrame
}
});
for (int i = 0; i < Utility.suffixes.size (); i++)
for (int i = 0; i < Utility.getTotalSuffixes (); i++)
{
int total = rootFolderData.getTotalType (i);
JCheckBox btn =
new JCheckBox (String.format ("%s (%,d)", Utility.suffixes.get (i), total));
new JCheckBox (String.format ("%s (%,d)", Utility.getSuffix (i), total));
topPanel.add (btn);
boxes.add (btn);

View File

@ -8,6 +8,8 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
@ -20,11 +22,10 @@ import javax.swing.JFrame;
import javax.swing.JPanel;
import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener;
import com.bytezone.diskbrowser.gui.RootDirectoryChangeListener;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class RootFolderData implements RootDirectoryChangeListener
public class RootFolderData implements PropertyChangeListener
// -----------------------------------------------------------------------------------//
{
private static final String header =
@ -66,7 +67,7 @@ public class RootFolderData implements RootDirectoryChangeListener
btnOK = new JButton ("OK");
progressPanel = new ProgressPanel ();
progressPanel.setPreferredSize (new Dimension (560, 340));
progressPanel.setPreferredSize (new Dimension (560, 380));
dialogTotals = new JFrame ("Disk Totals");
dialogTotals.add (progressPanel, BorderLayout.CENTER);
@ -154,7 +155,7 @@ public class RootFolderData implements RootDirectoryChangeListener
private void clear ()
// ---------------------------------------------------------------------------------//
{
typeTotals = new int[4][Utility.suffixes.size ()];
typeTotals = new int[4][Utility.getTotalSuffixes ()];
totalDisks = 0;
totalFolders = 0;
@ -177,38 +178,35 @@ public class RootFolderData implements RootDirectoryChangeListener
}
// ---------------------------------------------------------------------------------//
public void incrementType (File file, String filename)
public void incrementType (File file, String fileName)
// ---------------------------------------------------------------------------------//
{
int pos = Utility.getSuffixNo (filename);
int pos = Utility.getSuffixNo (fileName);
if (pos >= 0)
{
int cmp = 0;
if (filename.endsWith (".gz"))
cmp = 1;
else if (filename.endsWith (".zip"))
cmp = 2;
int cmp = fileName.endsWith (".zip") ? 2 : fileName.endsWith (".gz") ? 1 : 0;
typeTotals[cmp][pos]++;
typeTotals[3][pos]++;
++totalDisks;
}
else
System.out.println ("no suffix: " + filename);
System.out.println ("no suffix: " + fileName);
checkDuplicates (file, filename);
checkDuplicates (file, fileName);
}
// ---------------------------------------------------------------------------------//
private void checkDuplicates (File file, String filename)
private void checkDuplicates (File file, String fileName)
// ---------------------------------------------------------------------------------//
{
String rootName = file.getAbsolutePath ().substring (rootFolderNameLength);
DiskDetails diskDetails = new DiskDetails (file, rootName, filename, doChecksums);
DiskDetails diskDetails = new DiskDetails (file, rootName, fileName, doChecksums);
if (fileNameMap.containsKey (filename))
fileNameMap.get (filename).addDuplicateName (diskDetails);
if (fileNameMap.containsKey (fileName))
fileNameMap.get (fileName).addDuplicateName (diskDetails);
else
fileNameMap.put (filename, diskDetails);
fileNameMap.put (fileName, diskDetails);
if (doChecksums)
{
@ -256,7 +254,7 @@ public class RootFolderData implements RootDirectoryChangeListener
System.out.println (line);
for (int i = 0; i < typeTotals[0].length; i++)
{
System.out.printf ("%14.14s ", Utility.suffixes.get (i) + " ...........");
System.out.printf ("%14.14s ", Utility.getSuffix (i) + " ...........");
for (int j = 0; j < typeTotals.length; j++)
{
System.out.printf ("%,7d ", typeTotals[j][i]);
@ -277,8 +275,7 @@ public class RootFolderData implements RootDirectoryChangeListener
}
// ---------------------------------------------------------------------------------//
@Override
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
private void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
// ---------------------------------------------------------------------------------//
{
rootFolder = newRootFolder;
@ -286,6 +283,15 @@ public class RootFolderData implements RootDirectoryChangeListener
disksWindow = null; // force a recount
}
// ---------------------------------------------------------------------------------//
@Override
public void propertyChange (PropertyChangeEvent evt)
// ---------------------------------------------------------------------------------//
{
if (evt.getPropertyName ().equals ("RootDirectory"))
rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ());
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()
@ -326,16 +332,16 @@ public class RootFolderData implements RootDirectoryChangeListener
int grandTotal[] = new int[4];
for (int i = 0; i < typeTotals[0].length; i++)
{
line = String.format ("%14.14s %,7d %,7d %,7d %,7d",
Utility.suffixes.get (i) + " ...........", typeTotals[0][i], typeTotals[1][i],
typeTotals[2][i], typeTotals[3][i]);
g.drawString (line, x, y);
for (int j = 0; j < typeTotals.length; j++)
grandTotal[j] += typeTotals[j][i];
y += lineHeight;
}
if (typeTotals[3][i] > 0)
{
line = String.format ("%14.14s %,7d %,7d %,7d %,7d",
Utility.getSuffix (i) + " ...........", typeTotals[0][i], typeTotals[1][i],
typeTotals[2][i], typeTotals[3][i]);
g.drawString (line, x, y);
for (int j = 0; j < typeTotals.length; j++)
grandTotal[j] += typeTotals[j][i];
y += lineHeight;
}
line = String.format ("Total %,7d %,7d %,7d %,7d%n%n", grandTotal[0],
grandTotal[1], grandTotal[2], grandTotal[3]);

View File

@ -0,0 +1,58 @@
package com.bytezone.diskbrowser.gui;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import com.bytezone.diskbrowser.utilities.DefaultAction;
// -----------------------------------------------------------------------------------//
public abstract class AbstractSaveAction extends DefaultAction
// -----------------------------------------------------------------------------------//
{
protected JFileChooser fileChooser = new JFileChooser ();
// ---------------------------------------------------------------------------------//
public AbstractSaveAction (String menuText, String tip, String dialogTitle)
// ---------------------------------------------------------------------------------//
{
super (menuText, tip);
fileChooser.setDialogTitle (dialogTitle);
}
// ---------------------------------------------------------------------------------//
void setSelectedFile (File file)
// ---------------------------------------------------------------------------------//
{
fileChooser.setSelectedFile (file);
}
// ---------------------------------------------------------------------------------//
void saveBuffer (byte[] buffer)
// ---------------------------------------------------------------------------------//
{
File file = fileChooser.getSelectedFile ();
try
{
Files.write (file.toPath (), buffer, StandardOpenOption.CREATE_NEW);
JOptionPane.showMessageDialog (null, String.format ("File %s saved", file.getName ()));
}
catch (FileAlreadyExistsException e)
{
JOptionPane.showMessageDialog (null, "File " + file.getName () + " already exists", "Failed",
JOptionPane.ERROR_MESSAGE);
}
catch (IOException e)
{
e.printStackTrace ();
JOptionPane.showMessageDialog (null, "File failed to save - " + e.getMessage (), "Failed",
JOptionPane.ERROR_MESSAGE);
}
}
}

View File

@ -0,0 +1,62 @@
package com.bytezone.diskbrowser.gui;
import java.util.List;
import javax.swing.SwingWorker;
import com.bytezone.diskbrowser.applefile.SHRPictureFile2;
// -----------------------------------------------------------------------------------//
public class AnimationWorker extends SwingWorker<Void, Integer>
// -----------------------------------------------------------------------------------//
{
volatile boolean running;
SHRPictureFile2 image;
OutputPanel owner;
// ---------------------------------------------------------------------------------//
public AnimationWorker (OutputPanel owner, SHRPictureFile2 image)
// ---------------------------------------------------------------------------------//
{
assert image.isAnimation ();
this.image = image;
this.owner = owner;
}
// ---------------------------------------------------------------------------------//
public void cancel ()
// ---------------------------------------------------------------------------------//
{
running = false;
}
// ---------------------------------------------------------------------------------//
@Override
protected Void doInBackground () throws Exception
// ---------------------------------------------------------------------------------//
{
running = true;
try
{
while (running)
{
Thread.sleep (image.getDelay ());
publish (0);
}
}
catch (InterruptedException e)
{
e.printStackTrace ();
}
return null;
}
// ---------------------------------------------------------------------------------//
@Override
protected void process (List<Integer> chunks)
// ---------------------------------------------------------------------------------//
{
image.nextFrame ();
owner.update ();
}
}

View File

@ -158,9 +158,9 @@ class AppleDiskTab extends AbstractTab
// check for multi-volume disk (only search the current branch)
FormattedDisk fd = ((AppleFileSource) rootNode.getUserObject ()).getFormattedDisk ();
if (fd instanceof HybridDisk)
if (fd instanceof HybridDisk hd)
{
int volume = ((HybridDisk) fd).getCurrentDiskNo ();
int volume = hd.getCurrentDiskNo ();
rootNode = (DefaultMutableTreeNode) rootNode.getChildAt (volume);
}
@ -169,8 +169,8 @@ class AppleDiskTab extends AbstractTab
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode) children.nextElement ();
Object userObject = node.getUserObject ();
if (userObject instanceof AppleFileSource
&& nodeName.equals (((AppleFileSource) userObject).getUniqueName ()))
if (userObject instanceof AppleFileSource afs
&& nodeName.equals (afs.getUniqueName ()))
return node;
}
return null;

View File

@ -26,7 +26,7 @@ public class BasicPreferences
public boolean showConstants = false;
public boolean showDuplicateSymbols = false;
public int wrapPrintAt = 0;
public int wrapPrintAt = 80;
public int wrapRemAt = 80;
public int wrapDataAt = 80;

View File

@ -10,6 +10,8 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.EventObject;
@ -36,9 +38,8 @@ import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode;
// -----------------------------------------------------------------------------------//
class CatalogPanel extends JTabbedPane
implements RedoListener, SectorSelectionListener, QuitListener, FontChangeListener,
RootDirectoryChangeListener, DiskTableSelectionListener
class CatalogPanel extends JTabbedPane implements RedoListener, SectorSelectionListener,
QuitListener, FontChangeListener, DiskTableSelectionListener, PropertyChangeListener
// -----------------------------------------------------------------------------------//
{
private static final String prefsLastDiskUsed = "Last disk used";
@ -66,8 +67,7 @@ class CatalogPanel extends JTabbedPane
}
// ---------------------------------------------------------------------------------//
@Override
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
private void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
// ---------------------------------------------------------------------------------//
{
rootFolder = newRootFolder;
@ -82,6 +82,18 @@ class CatalogPanel extends JTabbedPane
setSelectedIndex (0);
}
// -------------------------------------------------------------------------------//
@Override
public void propertyChange (PropertyChangeEvent evt)
// -------------------------------------------------------------------------------//
{
if (evt.getPropertyName ().equals ("RootDirectory"))
rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ());
// else
// closeCurrentTab ();
// System.out.println (evt.getPropertyName ());
}
// ---------------------------------------------------------------------------------//
private void insertFileSystemTab (DiskSelectedEvent diskEvent)
// ---------------------------------------------------------------------------------//
@ -146,11 +158,10 @@ class CatalogPanel extends JTabbedPane
tab.refresh ();
// Any newly created disk needs to appear in the FileSystemTab's tree
if (tab instanceof AppleDiskTab)
fileTab.replaceDisk (((AppleDiskTab) tab).disk);
if (tab instanceof AppleDiskTab appleDiskTab)
fileTab.replaceDisk (appleDiskTab.disk);
}
// called from CloseTabAction
// ---------------------------------------------------------------------------------//
public void closeCurrentTab ()
// ---------------------------------------------------------------------------------//
@ -174,10 +185,7 @@ class CatalogPanel extends JTabbedPane
// ---------------------------------------------------------------------------------//
{
Tab tab = (Tab) getSelectedComponent ();
if (diskTabs.size () > 1 && tab instanceof AppleDiskTab)
closeTabAction.setEnabled (true);
else
closeTabAction.setEnabled (false);
closeTabAction.setEnabled (diskTabs.size () > 1 && tab instanceof AppleDiskTab);
}
// ---------------------------------------------------------------------------------//
@ -213,8 +221,8 @@ class CatalogPanel extends JTabbedPane
FormattedDisk fd = ((AppleDiskTab) selectedTab).disk;
prefs.put (prefsLastDiskUsed, fd.getAbsolutePath ());
if (fd instanceof HybridDisk)
prefs.putInt (prefsLastDosUsed, ((HybridDisk) fd).getCurrentDiskNo ());
if (fd instanceof HybridDisk hybridDisk)
prefs.putInt (prefsLastDosUsed, hybridDisk.getCurrentDiskNo ());
else
prefs.putInt (prefsLastDosUsed, -1);
@ -223,16 +231,16 @@ class CatalogPanel extends JTabbedPane
{
EventObject event = redoEvent.value;
if (event instanceof FileSelectedEvent)
if (event instanceof FileSelectedEvent fileSelectedEvent)
{
AppleFileSource afs = ((FileSelectedEvent) event).appleFileSource;
AppleFileSource afs = fileSelectedEvent.appleFileSource;
prefs.put (prefsLastFileUsed, afs == null ? "" : afs.getUniqueName ());
prefs.put (prefsLastSectorsUsed, "");
}
else if (event instanceof SectorSelectedEvent)
else if (event instanceof SectorSelectedEvent sectorSelectedEvent)
{
prefs.put (prefsLastFileUsed, "");
prefs.put (prefsLastSectorsUsed, ((SectorSelectedEvent) event).toText ());
prefs.put (prefsLastSectorsUsed, sectorSelectedEvent.toText ());
}
}
}
@ -265,8 +273,8 @@ class CatalogPanel extends JTabbedPane
if (diskEvent != null)
{
fd1 = diskEvent.getFormattedDisk ();
if (lastDosUsed >= 0 && fd1 instanceof HybridDisk)
((HybridDisk) fd1).setCurrentDiskNo (lastDosUsed);
if (lastDosUsed >= 0 && fd1 instanceof HybridDisk hybridDisk)
hybridDisk.setCurrentDiskNo (lastDosUsed);
}
}
else
@ -321,6 +329,14 @@ class CatalogPanel extends JTabbedPane
selector.addDiskSelectionListener (listener);
}
// ---------------------------------------------------------------------------------//
public void addDiskSelectionListener (DiskSelectionListener... listeners)
// ---------------------------------------------------------------------------------//
{
for (DiskSelectionListener diskSelectionListener : listeners)
selector.addDiskSelectionListener (diskSelectionListener);
}
// Pass through to DiskSelector
// ---------------------------------------------------------------------------------//
public void addFileSelectionListener (FileSelectionListener listener)
@ -329,6 +345,14 @@ class CatalogPanel extends JTabbedPane
selector.addFileSelectionListener (listener);
}
// ---------------------------------------------------------------------------------//
public void addFileSelectionListener (FileSelectionListener... listeners)
// ---------------------------------------------------------------------------------//
{
for (FileSelectionListener fileSelectionListener : listeners)
selector.addFileSelectionListener (fileSelectionListener);
}
// Pass through to DiskSelector
// ---------------------------------------------------------------------------------//
public void addFileNodeSelectionListener (FileNodeSelectionListener listener)
@ -337,6 +361,14 @@ class CatalogPanel extends JTabbedPane
selector.addFileNodeSelectionListener (listener);
}
// ---------------------------------------------------------------------------------//
public void addFileNodeSelectionListener (FileNodeSelectionListener... listeners)
// ---------------------------------------------------------------------------------//
{
for (FileNodeSelectionListener fileNodeSelectionListener : listeners)
selector.addFileNodeSelectionListener (fileNodeSelectionListener);
}
// ---------------------------------------------------------------------------------//
private class TabChangeListener implements ChangeListener
// ---------------------------------------------------------------------------------//
@ -367,13 +399,13 @@ class CatalogPanel extends JTabbedPane
{
case "DiskEvent":
case "FileNodeEvent":
if (tab instanceof FileSystemTab)
((FileSystemTab) tab).redoEvent (event);
if (tab instanceof FileSystemTab fileSystemTab)
fileSystemTab.redoEvent (event);
break;
case "FileEvent":
if (tab instanceof AppleDiskTab)
((AppleDiskTab) tab).redoEvent (event);
if (tab instanceof AppleDiskTab appleDiskTab)
appleDiskTab.redoEvent (event);
break;
case "SectorEvent":
@ -394,8 +426,8 @@ class CatalogPanel extends JTabbedPane
{
// user has clicked in the DiskLayoutPanel, so turn off any current file selection
Tab tab = (Tab) getSelectedComponent ();
if (tab instanceof AppleDiskTab)
((AppleDiskTab) tab).tree.setSelectionPath (null);
if (tab instanceof AppleDiskTab appleDiskTab)
appleDiskTab.tree.setSelectionPath (null);
}
// ---------------------------------------------------------------------------------//
@ -430,7 +462,7 @@ class CatalogPanel extends JTabbedPane
FileNode node = (FileNode) selectedNode.getUserObject ();
if (node.file.isDirectory ())
{
// lister.catalogLister.setNode (selectedNode);
// lister.catalogLister.setNode (selectedNode);
}
else if (e.getClickCount () == 2)
addDiskPanel (node.getFormattedDisk (), true);

View File

@ -19,6 +19,7 @@ public class CloseTabAction extends AbstractAction
// ---------------------------------------------------------------------------------//
{
super ("Close Tab");
putValue (Action.SHORT_DESCRIPTION, "Close the current disk tab");
// putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("ctrl W"));
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();

View File

@ -12,17 +12,15 @@ import javax.swing.KeyStroke;
public class ColourQuirksAction extends AbstractAction
// -----------------------------------------------------------------------------------//
{
private final DataPanel owner;
// ---------------------------------------------------------------------------------//
public ColourQuirksAction (DataPanel owner)
public ColourQuirksAction ()
// ---------------------------------------------------------------------------------//
{
super ("Smear HGR");
putValue (Action.SHORT_DESCRIPTION, "Display pixels like a TV screen");
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt Q"));
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_Q);
this.owner = owner;
}
// ---------------------------------------------------------------------------------//
@ -30,6 +28,7 @@ public class ColourQuirksAction extends AbstractAction
public void actionPerformed (ActionEvent e)
// ---------------------------------------------------------------------------------//
{
owner.setColourQuirks (((JMenuItem) e.getSource ()).isSelected ());
firePropertyChange (e.getActionCommand (), null,
((JMenuItem) e.getSource ()).isSelected ());
}
}

View File

@ -17,4 +17,6 @@ public interface DataSource
public BufferedImage getImage ();
public JComponent getComponent ();
public byte[] getBuffer ();
}

View File

@ -11,16 +11,14 @@ import javax.swing.KeyStroke;
public class DebuggingAction extends AbstractAction
// -----------------------------------------------------------------------------------//
{
private final DataPanel owner;
// ---------------------------------------------------------------------------------//
public DebuggingAction (DataPanel owner)
public DebuggingAction ()
// ---------------------------------------------------------------------------------//
{
super ("Debugging");
putValue (Action.SHORT_DESCRIPTION, "Show debugging information");
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("meta D"));
this.owner = owner;
}
// ---------------------------------------------------------------------------------//
@ -28,6 +26,7 @@ public class DebuggingAction extends AbstractAction
public void actionPerformed (ActionEvent e)
// ---------------------------------------------------------------------------------//
{
owner.setDebug (((JMenuItem) e.getSource ()).isSelected ());
firePropertyChange (e.getActionCommand (), null,
((JMenuItem) e.getSource ()).isSelected ());
}
}

View File

@ -6,6 +6,8 @@ import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;
@ -22,7 +24,8 @@ import javax.swing.UIManager;
import com.bytezone.diskbrowser.duplicates.RootFolderData;
// -----------------------------------------------------------------------------------//
public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitListener
public class DiskBrowser extends JFrame
implements DiskSelectionListener, QuitListener, PropertyChangeListener
// -----------------------------------------------------------------------------------//
{
private static String[] args;
@ -35,13 +38,21 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
private final RootFolderData rootFolderData = new RootFolderData ();
private final List<QuitListener> quitListeners = new ArrayList<> ();
private final JPanel catalogBorderPanel;
private final JPanel layoutBorderPanel;
private final HideCatalogAction hideCatalogAction = new HideCatalogAction ();
private final HideLayoutAction hideLayoutAction = new HideLayoutAction ();
// ---------------------------------------------------------------------------------//
public DiskBrowser ()
// ---------------------------------------------------------------------------------//
{
super (windowTitle);
UIManager.put ("TabbedPane.foreground", Color.BLACK); // java bug fix
// UIManager.put ("TabbedPane.foreground", Color.BLACK); // java bug fix
if (args.length > 0 && "-reset".equals (args[0]))
new WindowState (prefs).clear ();
@ -59,64 +70,56 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
// create and add the left-hand catalog panel
CatalogPanel catalogPanel = new CatalogPanel (redoHandler);
JPanel catalogBorderPanel = addPanel (catalogPanel, "Catalog", BorderLayout.WEST);
catalogBorderPanel = addPanel (catalogPanel, "Catalog", BorderLayout.WEST);
// create and add the centre output panel
DataPanel dataPanel = new DataPanel (menuHandler);
OutputPanel dataPanel = new OutputPanel (menuHandler);
addPanel (dataPanel, "Output", BorderLayout.CENTER);
// create and add the right-hand disk layout panel
DiskLayoutPanel diskLayoutPanel = new DiskLayoutPanel ();
JPanel layoutBorderPanel =
addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
layoutBorderPanel = addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
// create actions
DuplicateAction duplicateAction = new DuplicateAction (rootFolderData);
RootDirectoryAction rootDirectoryAction = new RootDirectoryAction ();
RefreshTreeAction refreshTreeAction = new RefreshTreeAction (catalogPanel);
// PreferencesAction preferencesAction = new PreferencesAction (this, prefs);
// PreferencesAction preferencesAction = new PreferencesAction (this, prefs);
AbstractAction print = new PrintAction (dataPanel);
// AboutAction aboutAction = new AboutAction ();
HideCatalogAction hideCatalogAction =
new HideCatalogAction (this, catalogBorderPanel);
HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
ShowFreeSectorsAction showFreeAction =
new ShowFreeSectorsAction (menuHandler, diskLayoutPanel);
// AboutAction aboutAction = new AboutAction ();
// HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
ShowFreeSectorsAction showFreeAction = new ShowFreeSectorsAction ();
CloseTabAction closeTabAction = new CloseTabAction (catalogPanel);
// closeTabAction.addPropertyChangeListener (catalogPanel);
hideCatalogAction.addPropertyChangeListener (this);
hideLayoutAction.addPropertyChangeListener (this);
// add action buttons to toolbar
toolBar.add (rootDirectoryAction);
toolBar.add (refreshTreeAction);
// toolBar.add (preferencesAction);
// toolBar.add (preferencesAction);
toolBar.add (duplicateAction);
toolBar.add (print);
// toolBar.add (aboutAction);
// toolBar.add (aboutAction);
// set the listeners
rootDirectoryAction.addListener (rootFolderData);
rootDirectoryAction.addListener (catalogPanel);
rootDirectoryAction.addListener (duplicateAction);
rootDirectoryAction.addPropertyChangeListener (rootFolderData);
rootDirectoryAction.addPropertyChangeListener (catalogPanel);
rootDirectoryAction.addPropertyChangeListener (duplicateAction);
catalogPanel.addDiskSelectionListener (this);
catalogPanel.addDiskSelectionListener (dataPanel);
catalogPanel.addDiskSelectionListener (diskLayoutPanel);
catalogPanel.addDiskSelectionListener (redoHandler);
catalogPanel.addDiskSelectionListener (menuHandler);
catalogPanel.addDiskSelectionListener (this, dataPanel, diskLayoutPanel, redoHandler,
menuHandler, menuHandler.saveDiskAction);
catalogPanel.addFileSelectionListener (dataPanel);
catalogPanel.addFileSelectionListener (diskLayoutPanel);
catalogPanel.addFileSelectionListener (redoHandler);
catalogPanel.addFileSelectionListener (menuHandler);
catalogPanel.addFileSelectionListener (dataPanel, diskLayoutPanel, redoHandler, menuHandler,
menuHandler.saveFileAction);
catalogPanel.addFileNodeSelectionListener (dataPanel);
catalogPanel.addFileNodeSelectionListener (redoHandler);
catalogPanel.addFileNodeSelectionListener (dataPanel, redoHandler);
diskLayoutPanel.addSectorSelectionListener (dataPanel);
diskLayoutPanel.addSectorSelectionListener (redoHandler);
diskLayoutPanel.addSectorSelectionListener (catalogPanel);
diskLayoutPanel.addSectorSelectionListener (menuHandler);
diskLayoutPanel.addSectorSelectionListener (menuHandler.saveSectorsAction);
diskLayoutPanel.addSectorSelectionListener (dataPanel, redoHandler, catalogPanel,
menuHandler.saveSectorsAction);
duplicateAction.addTableSelectionListener (catalogPanel);
@ -129,12 +132,10 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
menuHandler.fontAction.addFontChangeListener (dataPanel);
menuHandler.fontAction.addFontChangeListener (catalogPanel);
// menuHandler.fontAction.addFontChangeListener (diskLayoutPanel);
// menuHandler.fontAction.addFontChangeListener (diskLayoutPanel);
// set the MenuItem Actions
menuHandler.printItem.setAction (print);
// menuHandler.addHelpMenuAction (preferencesAction, "prefs");
// menuHandler.addHelpMenuAction (aboutAction, "about");
menuHandler.refreshTreeItem.setAction (refreshTreeAction);
menuHandler.rootItem.setAction (rootDirectoryAction);
menuHandler.showCatalogItem.setAction (hideCatalogAction);
@ -143,10 +144,12 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
menuHandler.duplicateItem.setAction (duplicateAction);
menuHandler.closeTabItem.setAction (closeTabAction);
addQuitListener (rootDirectoryAction);
addQuitListener (menuHandler);
addQuitListener (catalogPanel);
addQuitListener (this);
showFreeAction.addPropertyChangeListener (diskLayoutPanel);
quitListeners.add (rootDirectoryAction);
quitListeners.add (menuHandler);
quitListeners.add (catalogPanel);
quitListeners.add (this);
if (Desktop.isDesktopSupported ())
{
@ -157,14 +160,14 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
"Author - Denis Molony\nGitHub - https://github.com/dmolony/DiskBrowser",
"About DiskBrowser", JOptionPane.INFORMATION_MESSAGE));
if (desktop.isSupported (Desktop.Action.APP_PREFERENCES) && false)
desktop.setPreferencesHandler (
e -> JOptionPane.showMessageDialog (null, "Preferences dialog"));
// if (desktop.isSupported (Desktop.Action.APP_PREFERENCES) && false)
// desktop.setPreferencesHandler (
// e -> JOptionPane.showMessageDialog (null, "Preferences dialog"));
if (desktop.isSupported (Desktop.Action.APP_QUIT_HANDLER))
desktop.setQuitHandler ( (e, r) -> fireQuitEvent ());
// else
setQuitHandler ();
desktop.setQuitHandler ( (e, r) -> fireQuitEvent ()); // needed for cmd-Q
// else
setQuitHandler (); // needed for the close button
}
else
{
@ -184,9 +187,9 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
// Remove the two optional panels if they were previously hidden
if (!menuHandler.showLayoutItem.isSelected ())
hideLayoutAction.set (false);
setLayoutPanel (false);
if (!menuHandler.showCatalogItem.isSelected ())
hideCatalogAction.set (false);
setCatalogPanel (false);
menuHandler.addBasicPreferencesListener (dataPanel);
menuHandler.addAssemblerPreferencesListener (dataPanel);
@ -208,7 +211,6 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
fireQuitEvent ();
}
});
}
// ---------------------------------------------------------------------------------//
@ -223,13 +225,47 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
return panel;
}
// ---------------------------------------------------------------------------------//
@Override
public void propertyChange (PropertyChangeEvent evt)
// ---------------------------------------------------------------------------------//
{
if (evt.getSource () == hideCatalogAction)
setCatalogPanel ((boolean) evt.getNewValue ());
else if (evt.getSource () == hideLayoutAction)
setLayoutPanel ((boolean) evt.getNewValue ());
}
// ---------------------------------------------------------------------------------//
private void setCatalogPanel (boolean show)
// ---------------------------------------------------------------------------------//
{
if (show)
add (catalogBorderPanel, BorderLayout.WEST);
else
remove (catalogBorderPanel);
validate ();
}
// ---------------------------------------------------------------------------------//
private void setLayoutPanel (boolean show)
// ---------------------------------------------------------------------------------//
{
if (show)
add (layoutBorderPanel, BorderLayout.EAST);
else
remove (layoutBorderPanel);
validate ();
}
// ---------------------------------------------------------------------------------//
@Override
public void diskSelected (DiskSelectedEvent e)
// ---------------------------------------------------------------------------------//
{
setTitle (windowTitle + e.getFormattedDisk () == null ? ""
: e.getFormattedDisk ().getName ());
setTitle (windowTitle + e.getFormattedDisk () == null ? "" : e.getFormattedDisk ().getName ());
}
// ---------------------------------------------------------------------------------//
@ -249,31 +285,15 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
windowSaver.restoreWindow ();
}
// ---------------------------------------------------------------------------------//
public static void main (String[] args)
// ---------------------------------------------------------------------------------//
{
DiskBrowser.args = args;
EventQueue.invokeLater (new Runnable ()
{
@Override
public void run ()
{
setLookAndFeel ();
new DiskBrowser ().setVisible (true);
}
});
}
// ---------------------------------------------------------------------------------//
private static void setLookAndFeel ()
// ---------------------------------------------------------------------------------//
{
// FlatLightLaf.install ();
// FlatLightLaf.install ();
try
{
UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
// UIManager.setLookAndFeel (new FlatLightLaf ());
// UIManager.setLookAndFeel (new FlatLightLaf ());
if (MAC)
System.setProperty ("apple.laf.useScreenMenuBar", "true");
}
@ -283,22 +303,6 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
}
}
List<QuitListener> quitListeners = new ArrayList<> ();
// ---------------------------------------------------------------------------------//
public void addQuitListener (QuitListener listener)
// ---------------------------------------------------------------------------------//
{
quitListeners.add (listener);
}
// ---------------------------------------------------------------------------------//
public void removeQuitListener (QuitListener listener)
// ---------------------------------------------------------------------------------//
{
quitListeners.remove (listener);
}
// ---------------------------------------------------------------------------------//
private void fireQuitEvent ()
// ---------------------------------------------------------------------------------//
@ -316,4 +320,20 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
for (QuitListener listener : quitListeners)
listener.restore (prefs);
}
// ---------------------------------------------------------------------------------//
public static void main (String[] args)
// ---------------------------------------------------------------------------------//
{
DiskBrowser.args = args;
EventQueue.invokeLater (new Runnable ()
{
@Override
public void run ()
{
setLookAndFeel ();
new DiskBrowser ().setVisible (true);
}
});
}
}

View File

@ -97,9 +97,10 @@ class DiskLayoutImage extends DiskPanel implements Scrollable, RedoListener
selectionHandler.setSelection (sectors);
if (sectors != null && sectors.size () > 0)
{
DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1);
if (da != null)
scrollRectToVisible (layoutDetails.getLocation (da));
// DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1);
// if (da != null)
// scrollRectToVisible (layoutDetails.getLocation (da));
scrollRectToVisible (layoutDetails.getLocation (sectors.get (0)));
}
repaint ();
}

View File

@ -12,6 +12,8 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JPanel;
@ -19,14 +21,14 @@ import javax.swing.JScrollPane;
import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.HybridDisk;
import com.bytezone.diskbrowser.disk.FormattedDisk;
import com.bytezone.diskbrowser.disk.HybridDisk;
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
// -----------------------------------------------------------------------------------//
class DiskLayoutPanel extends JPanel
implements DiskSelectionListener, FileSelectionListener, RedoListener
class DiskLayoutPanel extends JPanel implements DiskSelectionListener,
FileSelectionListener, RedoListener, PropertyChangeListener
// -----------------------------------------------------------------------------------//
{
private static final int SIZE = 15; // basic unit of a display block
@ -134,6 +136,14 @@ class DiskLayoutPanel extends JPanel
diskLayoutImage.setShowFreeSectors (free);
}
// ---------------------------------------------------------------------------------//
@Override
public void propertyChange (PropertyChangeEvent evt)
// ---------------------------------------------------------------------------------//
{
setFree ((Boolean) evt.getNewValue ());
}
// ---------------------------------------------------------------------------------//
public void addSectorSelectionListener (SectorSelectionListener listener)
// ---------------------------------------------------------------------------------//
@ -141,6 +151,14 @@ class DiskLayoutPanel extends JPanel
diskLayoutImage.addSectorSelectionListener (listener);
}
// ---------------------------------------------------------------------------------//
public void addSectorSelectionListener (SectorSelectionListener... listeners)
// ---------------------------------------------------------------------------------//
{
for (SectorSelectionListener sectorSelectionListener : listeners)
diskLayoutImage.addSectorSelectionListener (sectorSelectionListener);
}
// ---------------------------------------------------------------------------------//
public void removeSectorSelectionListener (SectorSelectionListener listener)
// ---------------------------------------------------------------------------------//
@ -244,8 +262,8 @@ class DiskLayoutPanel extends JPanel
private void checkCorrectDisk (FormattedDisk newDisk)
{
if (newDisk instanceof HybridDisk)
newDisk = ((HybridDisk) newDisk).getCurrentDisk (); // never set to a Dual-dos disk
if (newDisk instanceof HybridDisk hybridDisk)
newDisk = hybridDisk.getCurrentDisk (); // never set to a hybrid disk
if (newDisk != diskLayoutImage.getDisk ())
{
LayoutDetails layout = new LayoutDetails (newDisk);

View File

@ -157,6 +157,7 @@ class DiskLayoutSelection implements Iterable<DiskAddress>
for (DiskAddress selection : highlights)
if (selection != null && da.matches (selection))
return true;
return false;
}

View File

@ -85,14 +85,13 @@ class DiskLegendPanel extends DiskPanel
int val = formattedDisk.falseNegativeBlocks ();
if (val > 0)
{
g.drawString (
val + " unused sector" + (val == 1 ? "" : "s") + " marked as unavailable", 10,
y);
g.drawString (val + " unused sector" + (val == 1 ? "" : "s") //
+ " marked as unavailable", 10, y);
y += lineHeight;
}
val = formattedDisk.falsePositiveBlocks ();
if (val > 0)
g.drawString (val + " used sector" + (val == 1 ? "" : "s") + " marked as available",
10, y);
g.drawString (val + " used sector" + (val == 1 ? "" : "s") //
+ " marked as available", 10, y);
}
}

View File

@ -13,6 +13,7 @@ public class DiskPanel extends JPanel
{
FormattedDisk formattedDisk;
LayoutDetails layoutDetails;
int blockWidth = 30; // default
int blockHeight = 15; // default
int centerOffset;
@ -20,11 +21,11 @@ public class DiskPanel extends JPanel
Color backgroundColor = new Color (0xE0, 0xE0, 0xE0);
// ---------------------------------------------------------------------------------//
public void setDisk (FormattedDisk disk, LayoutDetails details)
public void setDisk (FormattedDisk formattedDisk, LayoutDetails layoutDetails)
// ---------------------------------------------------------------------------------//
{
formattedDisk = disk;
layoutDetails = details;
this.formattedDisk = formattedDisk;
this.layoutDetails = layoutDetails;
blockWidth = layoutDetails.block.width;
blockHeight = layoutDetails.block.height;

View File

@ -9,7 +9,7 @@ import com.bytezone.diskbrowser.disk.FormattedDisk;
class DiskSelectedEvent extends EventObject
// -----------------------------------------------------------------------------------//
{
private final FormattedDisk owner;
private final FormattedDisk formattedDisk;
boolean redo;
// ---------------------------------------------------------------------------------//
@ -17,14 +17,14 @@ class DiskSelectedEvent extends EventObject
// ---------------------------------------------------------------------------------//
{
super (source);
this.owner = disk;
this.formattedDisk = disk;
}
// ---------------------------------------------------------------------------------//
public FormattedDisk getFormattedDisk ()
// ---------------------------------------------------------------------------------//
{
return owner;
return formattedDisk;
}
// ---------------------------------------------------------------------------------//
@ -32,14 +32,14 @@ class DiskSelectedEvent extends EventObject
public String toString ()
// ---------------------------------------------------------------------------------//
{
return owner.getDisk ().getFile ().getAbsolutePath ();
return formattedDisk.getDisk ().getFile ().getAbsolutePath ();
}
// ---------------------------------------------------------------------------------//
public String toText ()
// ---------------------------------------------------------------------------------//
{
return owner.getAbsolutePath ();
return formattedDisk.getAbsolutePath ();
}
// ---------------------------------------------------------------------------------//

View File

@ -3,6 +3,8 @@ package com.bytezone.diskbrowser.gui;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.Action;
@ -14,7 +16,7 @@ import com.bytezone.diskbrowser.duplicates.RootFolderData;
import com.bytezone.diskbrowser.utilities.DefaultAction;
// -----------------------------------------------------------------------------------//
public class DuplicateAction extends DefaultAction implements RootDirectoryChangeListener
public class DuplicateAction extends DefaultAction implements PropertyChangeListener
// -----------------------------------------------------------------------------------//
{
RootFolderData rootFolderData;
@ -36,14 +38,22 @@ public class DuplicateAction extends DefaultAction implements RootDirectoryChang
}
// ---------------------------------------------------------------------------------//
@Override
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
private void rootDirectoryChanged (File oldRootFolder, File newRootFolder)
// ---------------------------------------------------------------------------------//
{
assert rootFolderData.getRootFolder () == newRootFolder;
setEnabled (rootFolderData.getRootFolder () != null);
}
// ---------------------------------------------------------------------------------//
@Override
public void propertyChange (PropertyChangeEvent evt)
// ---------------------------------------------------------------------------------//
{
if (evt.getPropertyName ().equals ("RootDirectory"))
rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ());
}
// ---------------------------------------------------------------------------------//
@Override
public void actionPerformed (ActionEvent arg0)

View File

@ -3,8 +3,8 @@ package com.bytezone.diskbrowser.gui;
import java.util.EventObject;
import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.disk.HybridDisk;
import com.bytezone.diskbrowser.disk.FormattedDisk;
import com.bytezone.diskbrowser.disk.HybridDisk;
// -----------------------------------------------------------------------------------//
class FileSelectedEvent extends EventObject
@ -21,8 +21,9 @@ class FileSelectedEvent extends EventObject
super (source);
this.appleFileSource = appleFileSource;
// If a file is selected from a disk which is contained in a Dual-dos disk, then the DDS
// must be told so that it can ensure its internal currentDisk is set correctly
// If a file is selected from a disk which is part of a hybrid disk, then the
// parent must be told so that it can ensure its internal currentDisk is set
// correctly
FormattedDisk fd = appleFileSource.getFormattedDisk ();
HybridDisk ddd = (HybridDisk) fd.getParent ();
if (ddd != null)

View File

@ -36,6 +36,7 @@ public class FontAction extends DefaultAction implements QuitListener
{
super ("Set Font...", "Set display to a different font or font size",
"/com/bytezone/loadlister/");
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_F, mask));
}
@ -146,8 +147,7 @@ public class FontAction extends DefaultAction implements QuitListener
// ---------------------------------------------------------------------------------//
{
FontChangeEvent fontChangeEvent = new FontChangeEvent (font);
FontChangeListener[] listeners =
(listenerList.getListeners (FontChangeListener.class));
FontChangeListener[] listeners = (listenerList.getListeners (FontChangeListener.class));
for (FontChangeListener listener : listeners)
listener.changeFont (fontChangeEvent);
}

View File

@ -47,6 +47,7 @@ public class FontFrame extends JFrame
// ---------------------------------------------------------------------------------//
{
super ("Font Selection");
this.fontAction = fontAction;
buildLayout ();
getFonts ();
@ -96,8 +97,7 @@ public class FontFrame extends JFrame
public String getSelectedValue ()
// ---------------------------------------------------------------------------------//
{
String fontName = fontList.getSelectedValue ();
return fontName;
return fontList.getSelectedValue ();
}
// ---------------------------------------------------------------------------------//
@ -112,8 +112,7 @@ public class FontFrame extends JFrame
public String getSelectedSize ()
// ---------------------------------------------------------------------------------//
{
String fontSize = fontSizePanel.getSelectedText ();
return fontSize;
return fontSizePanel.getSelectedText ();
}
// ---------------------------------------------------------------------------------//
@ -130,20 +129,22 @@ public class FontFrame extends JFrame
{
String fonts[] =
GraphicsEnvironment.getLocalGraphicsEnvironment ().getAvailableFontFamilyNames ();
// for (String font : fonts)
// System.out.println (font);
String pf[] =
{ "Andale Mono", "Anonymous Pro", "Anonymous Pro Minus", "Apple2Forever",
"Apple2Forever80", "Consolas", "Bitstream Vera Sans Mono", "Consolas",
"Courier", "Courier New", "DejaVu Sans Mono", "Envy Code R", "Inconsolata",
"Input Mono", "Input Mono Narrow", "Iosevka", "Lucida Sans Typewriter",
"Luculent", "Menlo", "Monaco", "monofur", "Monospaced", "Nimbus Mono L",
"PCMyungjo", "PR Number 3", "Pragmata", "Print Char 21", "ProFont", "ProFontX",
"Proggy", "PT Mono", "Source Code Pro", "Ubuntu Mono" };
{ "Andale Mono", "Anonymous Pro", "Anonymous Pro Minus", "Apple II Display Pro",
"Apple II Pro", "Apple2Forever", "Apple2Forever80", "Bitstream Vera Sans Mono",
"Consolas", "Courier", "Courier New", "DejaVu Sans Mono", "Envy Code R",
"Inconsolata", "Input Mono", "Input Mono Narrow", "Iosevka",
"Lucida Sans Typewriter", "Luculent", "Menlo", "Monaco", "monofur",
"Monospaced", "Nimbus Mono L", "PCMyungjo", "PR Number 3", "Pragmata",
"Print Char 21", "ProFont", "ProFontX", "Proggy", "PT Mono", "Source Code Pro",
"Ubuntu Mono" };
DefaultListModel<String> lm = (DefaultListModel<String>) fontList.getModel ();
int ptr = 0;
for (String fontName : fonts)
{
while (ptr < pf.length)
{
int result = fontName.compareToIgnoreCase (pf[ptr]);
@ -156,7 +157,6 @@ public class FontFrame extends JFrame
}
break;
}
}
fontList.setSelectedValue (initialFont, true);
}
@ -251,13 +251,14 @@ public class FontFrame extends JFrame
private Font getCurrentFont ()
// ---------------------------------------------------------------------------------//
{
String fontName = getSelectedValue ();
String fontSize = getSelectedSize ();
if (fontSize.isEmpty ())
return null;
int pos = fontSize.indexOf (' ');
int size = Integer.parseInt (fontSize.substring (0, pos));
return new Font (fontName, Font.PLAIN, size);
return new Font (getSelectedValue (), Font.PLAIN, size);
}
// ---------------------------------------------------------------------------------//
@ -266,8 +267,10 @@ public class FontFrame extends JFrame
{
initialFont = getSelectedValue ();
initialSize = getSelectedSize ();
int pos = initialSize.indexOf (' ');
int size = Integer.parseInt (initialSize.substring (0, pos));
Font font = new Font (initialFont, Font.PLAIN, size);
fontAction.fireFontChangeEvent (font);
}

View File

@ -1,33 +1,26 @@
package com.bytezone.diskbrowser.gui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
// -----------------------------------------------------------------------------------//
class HideCatalogAction extends AbstractAction
// -----------------------------------------------------------------------------------//
{
JFrame owner;
JPanel catalogPanel;
// ---------------------------------------------------------------------------------//
public HideCatalogAction (JFrame owner, JPanel catalogPanel)
public HideCatalogAction ()
// ---------------------------------------------------------------------------------//
{
super ("Show catalog panel");
putValue (Action.SHORT_DESCRIPTION, "Show/hide the catalog panel");
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt C"));
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_C);
this.owner = owner;
this.catalogPanel = catalogPanel;
}
// ---------------------------------------------------------------------------------//
@ -35,22 +28,7 @@ class HideCatalogAction extends AbstractAction
public void actionPerformed (ActionEvent e)
// ---------------------------------------------------------------------------------//
{
set (((JMenuItem) e.getSource ()).isSelected ());
}
// ---------------------------------------------------------------------------------//
public void set (boolean show)
// ---------------------------------------------------------------------------------//
{
if (show)
{
owner.add (catalogPanel, BorderLayout.WEST);
owner.validate ();
}
else
{
owner.remove (catalogPanel);
owner.validate ();
}
firePropertyChange (e.getActionCommand (), null,
((JMenuItem) e.getSource ()).isSelected ());
}
}

View File

@ -1,33 +1,26 @@
package com.bytezone.diskbrowser.gui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
// -----------------------------------------------------------------------------------//
class HideLayoutAction extends AbstractAction
// -----------------------------------------------------------------------------------//
{
JFrame owner;
JPanel layoutPanel;
// ---------------------------------------------------------------------------------//
public HideLayoutAction (JFrame owner, JPanel layoutPanel)
public HideLayoutAction ()
// ---------------------------------------------------------------------------------//
{
super ("Show disk layout panel");
putValue (Action.SHORT_DESCRIPTION, "Show/hide the disk layout panel");
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt D"));
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_D);
this.owner = owner;
this.layoutPanel = layoutPanel;
}
// ---------------------------------------------------------------------------------//
@ -35,22 +28,7 @@ class HideLayoutAction extends AbstractAction
public void actionPerformed (ActionEvent e)
// ---------------------------------------------------------------------------------//
{
set (((JMenuItem) e.getSource ()).isSelected ());
}
// ---------------------------------------------------------------------------------//
public void set (boolean show)
// ---------------------------------------------------------------------------------//
{
if (show)
{
owner.add (layoutPanel, BorderLayout.EAST);
owner.validate ();
}
else
{
owner.remove (layoutPanel);
owner.validate ();
}
firePropertyChange (e.getActionCommand (), null,
((JMenuItem) e.getSource ()).isSelected ());
}
}

Some files were not shown because too many files have changed in this diff Show More