diff --git a/com.wudsn.ide.asm.compilers.test/.classpath b/com.wudsn.ide.asm.compilers.test/.classpath
new file mode 100644
index 00000000..8a8f1668
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers.test/.project b/com.wudsn.ide.asm.compilers.test/.project
new file mode 100644
index 00000000..0ef5742c
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/.project
@@ -0,0 +1,28 @@
+
+
+ com.wudsn.ide.asm.compilers.test
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/com.wudsn.ide.asm.compilers.test/.settings/org.eclipse.jdt.core.prefs b/com.wudsn.ide.asm.compilers.test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..f287d53c
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/com.wudsn.ide.asm.compilers.test/META-INF/MANIFEST.MF b/com.wudsn.ide.asm.compilers.test/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..680be15e
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: WUDSN IDE Assembler Test Compilers Plug-in
+Bundle-SymbolicName: com.wudsn.ide.asm.compilers.test;singleton:=true
+Bundle-Version: 1.7.0.qualifier
+Bundle-Vendor: Peter Dell
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-Localization: plugin
+Require-Bundle: com.wudsn.ide.asm
+Bundle-ActivationPolicy: lazy
diff --git a/com.wudsn.ide.asm.compilers.test/bin/.gitignore b/com.wudsn.ide.asm.compilers.test/bin/.gitignore
new file mode 100644
index 00000000..43e58b99
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/bin/.gitignore
@@ -0,0 +1 @@
+/com
diff --git a/com.wudsn.ide.asm.compilers.test/build.properties b/com.wudsn.ide.asm.compilers.test/build.properties
new file mode 100644
index 00000000..74239926
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/build.properties
@@ -0,0 +1,16 @@
+source.. = src/
+output.. = bin/
+bin.includes = .,\
+ plugin.xml,\
+ icons/,\
+ META-INF/,\
+ plugin.properties,\
+ src/,\
+ build.properties,\
+ plugin_de_DE.properties,\
+ .classpath,\
+ .project
+jars.compile.order = .
+src.includes = bin/,\
+ icons/
+
diff --git a/com.wudsn.ide.asm.compilers.test/icons/editor-test-16x16.gif b/com.wudsn.ide.asm.compilers.test/icons/editor-test-16x16.gif
new file mode 100644
index 00000000..751df8b8
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/editor-test-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_acorn.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_acorn.gif
new file mode 100644
index 00000000..2eec3b57
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_acorn.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_alambik.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_alambik.gif
new file mode 100644
index 00000000..12a44a06
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_alambik.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga.gif
new file mode 100644
index 00000000..36791b85
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga_aga.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga_aga.gif
new file mode 100644
index 00000000..3b17c6fe
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga_aga.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga_ppc.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga_ppc.gif
new file mode 100644
index 00000000..9af7ceea
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_amiga_ppc.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_amplus.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_amplus.gif
new file mode 100644
index 00000000..754e255f
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_amplus.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_apple2.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_apple2.gif
new file mode 100644
index 00000000..9755078c
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_apple2.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_falcon.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_falcon.gif
new file mode 100644
index 00000000..9dd7a559
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_falcon.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_st.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_st.gif
new file mode 100644
index 00000000..2ed2102e
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_st.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_ste.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_ste.gif
new file mode 100644
index 00000000..1637f160
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_ste.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_vcs.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_vcs.gif
new file mode 100644
index 00000000..ab28795f
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_vcs.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_xl_xe.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_xl_xe.gif
new file mode 100644
index 00000000..c93689bf
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_atari_xl_xe.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_bbcmicro.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_bbcmicro.gif
new file mode 100644
index 00000000..05cb0459
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_bbcmicro.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_beos.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_beos.gif
new file mode 100644
index 00000000..12ef66b7
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_beos.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_bk.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_bk.gif
new file mode 100644
index 00000000..7876d9d5
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_bk.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_c16.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_c16.gif
new file mode 100644
index 00000000..81d60af1
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_c16.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_coco.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_coco.gif
new file mode 100644
index 00000000..25fce626
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_coco.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_commodore.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_commodore.gif
new file mode 100644
index 00000000..c58eaa56
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_commodore.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_cpc.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_cpc.gif
new file mode 100644
index 00000000..470d5f41
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_cpc.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_dreamcast.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_dreamcast.gif
new file mode 100644
index 00000000..b4ca761a
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_dreamcast.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ds.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ds.gif
new file mode 100644
index 00000000..ac3b894a
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ds.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_dtv.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_dtv.gif
new file mode 100644
index 00000000..337e4f78
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_dtv.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ent.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ent.gif
new file mode 100644
index 00000000..bdecb692
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ent.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_flash.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_flash.gif
new file mode 100644
index 00000000..d445a378
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_flash.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_freebsd.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_freebsd.gif
new file mode 100644
index 00000000..79fae70a
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_freebsd.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_gameboy.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_gameboy.gif
new file mode 100644
index 00000000..2bb23105
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_gameboy.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_gamepark32.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_gamepark32.gif
new file mode 100644
index 00000000..31a52215
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_gamepark32.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_gba.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_gba.gif
new file mode 100644
index 00000000..75adba30
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_gba.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_gbc.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_gbc.gif
new file mode 100644
index 00000000..7521d7f8
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_gbc.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_gg.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_gg.gif
new file mode 100644
index 00000000..ecfc9552
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_gg.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_gp2x.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_gp2x.gif
new file mode 100644
index 00000000..1594ebfe
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_gp2x.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_gus.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_gus.gif
new file mode 100644
index 00000000..33fa35aa
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_gus.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_iigs.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_iigs.gif
new file mode 100644
index 00000000..ec06b373
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_iigs.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_intellivision.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_intellivision.gif
new file mode 100644
index 00000000..8ef3bcc0
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_intellivision.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ipod.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ipod.gif
new file mode 100644
index 00000000..3a1bfbcd
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ipod.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_jag.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_jag.gif
new file mode 100644
index 00000000..46d72705
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_jag.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_java.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_java.gif
new file mode 100644
index 00000000..61be6df9
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_java.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_js.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_js.gif
new file mode 100644
index 00000000..9c7ed9d1
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_js.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_linux.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_linux.gif
new file mode 100644
index 00000000..563d9051
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_linux.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_lynx.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_lynx.gif
new file mode 100644
index 00000000..c8d5f8c2
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_lynx.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_mac.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_mac.gif
new file mode 100644
index 00000000..16a3c824
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_mac.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_macb.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_macb.gif
new file mode 100644
index 00000000..6a038657
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_macb.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_macosx.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_macosx.gif
new file mode 100644
index 00000000..94ed00cf
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_macosx.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_mastersystem.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_mastersystem.gif
new file mode 100644
index 00000000..37af7cf0
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_mastersystem.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_megadrive.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_megadrive.gif
new file mode 100644
index 00000000..a8e455e3
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_megadrive.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_mobiles.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_mobiles.gif
new file mode 100644
index 00000000..4d37e153
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_mobiles.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_msdos.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_msdos.gif
new file mode 100644
index 00000000..879bc890
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_msdos.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_msx.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_msx.gif
new file mode 100644
index 00000000..01ca621b
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_msx.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_msx2.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_msx2.gif
new file mode 100644
index 00000000..38a9d0d8
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_msx2.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_msx2p.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_msx2p.gif
new file mode 100644
index 00000000..eb5e0099
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_msx2p.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_msxt.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_msxt.gif
new file mode 100644
index 00000000..420e76f4
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_msxt.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_n64.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_n64.gif
new file mode 100644
index 00000000..761f3c17
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_n64.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_neogeopocket.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_neogeopocket.gif
new file mode 100644
index 00000000..49425f5c
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_neogeopocket.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_nes.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_nes.gif
new file mode 100644
index 00000000..3269e0a1
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_nes.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ngc.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ngc.gif
new file mode 100644
index 00000000..1449e442
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ngc.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_oric.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_oric.gif
new file mode 100644
index 00000000..14e7c040
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_oric.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_palmos.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_palmos.gif
new file mode 100644
index 00000000..028625a9
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_palmos.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_pce.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_pce.gif
new file mode 100644
index 00000000..c8b61d27
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_pce.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_php.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_php.gif
new file mode 100644
index 00000000..350cb279
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_php.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_pocketpc.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_pocketpc.gif
new file mode 100644
index 00000000..8983388a
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_pocketpc.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_pokemon.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_pokemon.gif
new file mode 100644
index 00000000..2c88b9b0
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_pokemon.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_processing.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_processing.gif
new file mode 100644
index 00000000..1e09d303
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_processing.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ps1.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ps1.gif
new file mode 100644
index 00000000..ff6d5a12
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ps1.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ps2.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ps2.gif
new file mode 100644
index 00000000..d7d017d8
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ps2.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ps3.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ps3.gif
new file mode 100644
index 00000000..234803b7
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ps3.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_psp.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_psp.gif
new file mode 100644
index 00000000..58b0ca2a
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_psp.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_samcoupe.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_samcoupe.gif
new file mode 100644
index 00000000..fc0420b1
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_samcoupe.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_sgi.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_sgi.gif
new file mode 100644
index 00000000..bcae6722
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_sgi.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_snes.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_snes.gif
new file mode 100644
index 00000000..e288e90f
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_snes.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_solaris.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_solaris.gif
new file mode 100644
index 00000000..b0cc1c6a
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_solaris.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_sv.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_sv.gif
new file mode 100644
index 00000000..fc6fb052
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_sv.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_thomson.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_thomson.gif
new file mode 100644
index 00000000..bd0d28b7
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_thomson.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_ti8x.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_ti8x.gif
new file mode 100644
index 00000000..119d40c1
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_ti8x.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_tt.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_tt.gif
new file mode 100644
index 00000000..d60db5ba
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_tt.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_vb.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_vb.gif
new file mode 100644
index 00000000..80a7b256
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_vb.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_vectrex.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_vectrex.gif
new file mode 100644
index 00000000..9d75b216
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_vectrex.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_vic20.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_vic20.gif
new file mode 100644
index 00000000..4b689928
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_vic20.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_wii.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_wii.gif
new file mode 100644
index 00000000..a0637b6c
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_wii.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_wild.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_wild.gif
new file mode 100644
index 00000000..9bbbcd60
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_wild.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_win.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_win.gif
new file mode 100644
index 00000000..bf216199
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_win.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_wonderswan.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_wonderswan.gif
new file mode 100644
index 00000000..d71dad8f
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_wonderswan.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_xbox.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_xbox.gif
new file mode 100644
index 00000000..99cf3abd
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_xbox.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_xbox360.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_xbox360.gif
new file mode 100644
index 00000000..9360895d
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_xbox360.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_zx.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_zx.gif
new file mode 100644
index 00000000..9d54103a
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_zx.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/icons/os/k_zx81.gif b/com.wudsn.ide.asm.compilers.test/icons/os/k_zx81.gif
new file mode 100644
index 00000000..b6a56118
Binary files /dev/null and b/com.wudsn.ide.asm.compilers.test/icons/os/k_zx81.gif differ
diff --git a/com.wudsn.ide.asm.compilers.test/plugin.properties b/com.wudsn.ide.asm.compilers.test/plugin.properties
new file mode 100644
index 00000000..51dfa568
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/plugin.properties
@@ -0,0 +1,10 @@
+com.wudsn.ide.asm.preferences.test.AssemblerPreferencesTestCompilersPage.name=Test Compilers
+
+com.wudsn.ide.asm.compiler.test.TestCompiler.name=TEST
+
+com.wudsn.ide.asm.editor.test.TestEditor.name=Test Editor
+
+com.wudsn.ide.asm.editor.test.TestSourceFile.name=Test Source File
+
+com.wudsn.ide.asm.runner.test.runner1.name=First Application
+com.wudsn.ide.asm.runner.test.runner2.name=Second Application
diff --git a/com.wudsn.ide.asm.compilers.test/plugin.xml b/com.wudsn.ide.asm.compilers.test/plugin.xml
new file mode 100644
index 00000000..d8947fd6
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/plugin.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers.test/plugin_de_DE.properties b/com.wudsn.ide.asm.compilers.test/plugin_de_DE.properties
new file mode 100644
index 00000000..eaf6a521
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/plugin_de_DE.properties
@@ -0,0 +1,10 @@
+com.wudsn.ide.asm.preferences.test.AssemblerPreferencesTestCompilersPage.name=Test Kompiler
+
+com.wudsn.ide.asm.compiler.test.TestCompiler.name=TEST
+
+com.wudsn.ide.asm.editor.test.TestEditor.name=Test Editor
+
+com.wudsn.ide.asm.editor.test.TestSourceFile.name=Test Quell-Datei
+
+com.wudsn.ide.asm.runner.test.runner1.name=Erste Anwendung
+com.wudsn.ide.asm.runner.test.runner2.name=Zweite Anwendung
diff --git a/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompiler.java b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompiler.java
new file mode 100644
index 00000000..dc70e2f3
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.test;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for TEST.
+ *
+ * @author Peter Dell
+ */
+public final class TestCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public TestCompiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new TestCompilerSourceParser();
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new TestCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompiler.xml b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompiler.xml
new file mode 100644
index 00000000..a86fd45e
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompiler.xml
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompilerProcessLogParser.java
new file mode 100644
index 00000000..3dc665f1
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompilerProcessLogParser.java
@@ -0,0 +1,174 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.test;
+
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link TestCompiler}.
+ *
+ *
+ * Sample error message:
+ *
+ * "Pass 1: In Abbuc99-NetBalls-Init.asm, line 24-- Warning: Resizing
+ * 'BALLSCOLORTAB1', forcing another pass"
+ *
+ * "Pass 2: In Abbuc99-NetBalls-Init.asm, line 25-- Warning: Resizing
+ * 'BALLSCOLORTAB2', forcing another pass"
+ *
+ * @author Peter Dell
+ */
+final class TestCompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private Pattern pattern;
+ private String sourceFilePattern;
+
+ @Override
+ protected void initialize() {
+ pattern = Pattern.compile("In .* line ");
+ sourceFilePattern = "In " + mainSourceFilePath + ", line ";
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ int index;
+ String line;
+ boolean include;
+ String includeFile;
+ Matcher matcher = pattern.matcher(errorLog);
+
+ if (matcher.find()) {
+ index = matcher.start();
+ line = errorLog.substring(index);
+ if (line.startsWith(sourceFilePattern)) {
+ include = false;
+ includeFile = "";
+ } else {
+ include = true;
+ includeFile = line.substring(3, matcher.end() - matcher.start() - 7);
+ }
+ index = matcher.end();
+ String lineNumberLine = errorLog.substring(index);
+ errorLog = lineNumberLine;
+ int numberEndIndex = lineNumberLine.indexOf("--");
+ if (numberEndIndex > 0) {
+ String lineNumberString;
+ lineNumberString = lineNumberLine.substring(0, numberEndIndex);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ int nextIndex = lineNumberLine.indexOf('\n');
+ if (index > 0) {
+ message = lineNumberLine.substring(nextIndex + 1);
+ int nextIndex2 = message.indexOf('\n');
+ if (nextIndex > 0) {
+ message = message.substring(0, nextIndex2 - 1);
+ }
+ message = message.trim();
+ }
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ }
+
+ if (message.startsWith("Error:")) {
+ severity = IMarker.SEVERITY_ERROR;
+ message = message.substring(6);
+ } else if (message.startsWith("Warning:")) {
+ severity = IMarker.SEVERITY_WARNING;
+ message = message.substring(8);
+ }
+
+ if (include) {
+ if (lineNumber >= 0) {
+ message = includeFile + " line " + lineNumber + ": " + message;
+ } else {
+ message = includeFile + ": " + message;
+ }
+ lineNumber = -1;
+ }
+ message = message.trim();
+
+ // Message mapping.
+ if (severity == IMarker.SEVERITY_WARNING && message.startsWith("Using bank")) {
+ severity = IMarker.SEVERITY_INFO;
+ }
+ markerAvailable = true;
+ }
+ }
+
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+ final String EQUATES = "Equates:";
+ final String SYMBOL = "Symbol";
+ final String TABLE = "table:";
+
+ String log;
+ int index;
+
+ log = outputLog;
+ index = log.indexOf(EQUATES);
+ if (index >= 0) {
+ log = log.substring(index + EQUATES.length());
+
+ StringTokenizer st = new StringTokenizer(log);
+ String token;
+ String name;
+ String hexValue;
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (token.equals(SYMBOL)) {
+ break;
+ }
+ name = token.substring(0, token.length() - 1);
+ hexValue = st.nextToken(); // Must be there
+ compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
+ }
+
+ if (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (token.equals(TABLE)) {
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (!token.endsWith(":")) {
+ break;
+ }
+ name = token.substring(0, token.length() - 1);
+ hexValue = st.nextToken(); // Must be there
+ compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
+ }
+ }
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompilerSourceParser.java b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompilerSourceParser.java
new file mode 100644
index 00000000..ee96654a
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/compiler/test/TestCompilerSourceParser.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.test;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link TestCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class TestCompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ // Check for origin statement
+ if (symbol.equals("*")) { //$NON-NLS-1$
+ beginImplementationSection(startOffset, startOffset + symbolOffset, operand, comment);
+
+ } else {
+ if (instruction.equals("=")) { //$NON-NLS-1$
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+
+ }
+ }
+
+ } // Symbol not empty
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/editor/test/TestEditor.java b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/editor/test/TestEditor.java
new file mode 100644
index 00000000..2c497f73
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/editor/test/TestEditor.java
@@ -0,0 +1,18 @@
+package com.wudsn.ide.asm.editor.test;
+
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class TestEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public TestEditor() {
+
+ }
+
+ @Override
+ public String getCompilerId() {
+ return "test";
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/preferences/test/AssemblerPreferencesTestCompilersPage.java b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/preferences/test/AssemblerPreferencesTestCompilersPage.java
new file mode 100644
index 00000000..57d83797
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers.test/src/com/wudsn/ide/asm/preferences/test/AssemblerPreferencesTestCompilersPage.java
@@ -0,0 +1,42 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.preferences.test;
+
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesCompilersPage;
+
+/**
+ * Visual editor page for the assembler preferences regarding arbitrary compilers.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerPreferencesTestCompilersPage extends
+ AssemblerPreferencesCompilersPage {
+
+ /**
+ * Create is public. Used by extension point
+ * "org.eclipse.ui.preferencePages".
+ */
+ public AssemblerPreferencesTestCompilersPage() {
+ super(Hardware.TEST);
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/.classpath b/com.wudsn.ide.asm.compilers/.classpath
new file mode 100644
index 00000000..8a8f1668
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers/.project b/com.wudsn.ide.asm.compilers/.project
new file mode 100644
index 00000000..1c2697d4
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/.project
@@ -0,0 +1,40 @@
+
+
+ com.wudsn.ide.asm.compilers
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
+
+ binaries/build-compilers-new.bat
+ 1
+ C:/jac/wudsn/Tools/WWW/build-compilers-new.bat
+
+
+ binaries/build.bat
+ 1
+ C:/jac/wudsn/Tools/WWW/build.bat
+
+
+
diff --git a/com.wudsn.ide.asm.compilers/.settings/org.eclipse.jdt.core.prefs b/com.wudsn.ide.asm.compilers/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..f287d53c
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/com.wudsn.ide.asm.compilers/META-INF/MANIFEST.MF b/com.wudsn.ide.asm.compilers/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..696a81fa
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: WUDSN IDE Assembler Compilers Plug-in
+Bundle-SymbolicName: com.wudsn.ide.asm.compilers;singleton:=true
+Bundle-Version: 1.7.0.qualifier
+Bundle-Vendor: Peter Dell
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-Localization: plugin
+Require-Bundle: com.wudsn.ide.asm,
+ org.eclipse.ui.ide
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: .
diff --git a/com.wudsn.ide.asm.compilers/bin/.gitignore b/com.wudsn.ide.asm.compilers/bin/.gitignore
new file mode 100644
index 00000000..43e58b99
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/bin/.gitignore
@@ -0,0 +1 @@
+/com
diff --git a/com.wudsn.ide.asm.compilers/binaries/.gitignore b/com.wudsn.ide.asm.compilers/binaries/.gitignore
new file mode 100644
index 00000000..d1d483cb
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/binaries/.gitignore
@@ -0,0 +1 @@
+/compilers
diff --git a/com.wudsn.ide.asm.compilers/build.properties b/com.wudsn.ide.asm.compilers/build.properties
new file mode 100644
index 00000000..236bd606
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/build.properties
@@ -0,0 +1,15 @@
+source.. = src/
+output.. = bin/
+bin.includes = .,\
+ plugin.xml,\
+ icons/,\
+ META-INF/,\
+ plugin.properties,\
+ src/,\
+ build.properties,\
+ .project,\
+ .classpath,\
+ plugin_de_DE.properties
+jars.compile.order = .
+
+
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-acme-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-acme-16x16.gif
new file mode 100644
index 00000000..d6d12fd1
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-acme-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-asm6-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-asm6-16x16.gif
new file mode 100644
index 00000000..3269e0a1
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-asm6-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-atasm-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-atasm-16x16.gif
new file mode 100644
index 00000000..e4633f21
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-atasm-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-dasm-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-dasm-16x16.gif
new file mode 100644
index 00000000..933dc281
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-dasm-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-kickass-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-kickass-16x16.gif
new file mode 100644
index 00000000..21a1fbd3
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-kickass-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-mads-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-mads-16x16.gif
new file mode 100644
index 00000000..23b9db7c
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-mads-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-merlin32-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-merlin32-16x16.gif
new file mode 100644
index 00000000..9755078c
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-merlin32-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-tass-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-tass-16x16.gif
new file mode 100644
index 00000000..21a1fbd3
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-tass-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/icons/editor-xasm-16x16.gif b/com.wudsn.ide.asm.compilers/icons/editor-xasm-16x16.gif
new file mode 100644
index 00000000..86b761f4
Binary files /dev/null and b/com.wudsn.ide.asm.compilers/icons/editor-xasm-16x16.gif differ
diff --git a/com.wudsn.ide.asm.compilers/plugin.properties b/com.wudsn.ide.asm.compilers/plugin.properties
new file mode 100644
index 00000000..c08f51bc
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/plugin.properties
@@ -0,0 +1,75 @@
+com.wudsn.ide.asm.compiler.acme.AcmeCompiler.name=ACME
+com.wudsn.ide.asm.compiler.asm6.Asm6Compiler.name=ASM6
+com.wudsn.ide.asm.compiler.atasm.AtasmCompiler.name=ATASM
+com.wudsn.ide.asm.compiler.dasm.DasmCompiler.name=DASM
+com.wudsn.ide.asm.compiler.kickass.KickAssCompiler.name=KICKASS
+com.wudsn.ide.asm.compiler.mads.MadsCompiler.name=MADS
+com.wudsn.ide.asm.compiler.merlin32.Merlin32Compiler.name=MERLIN32
+com.wudsn.ide.asm.compiler.tass.TassCompiler.name=TASS
+com.wudsn.ide.asm.compiler.xasm.XasmCompiler.name=XASM
+
+com.wudsn.ide.asm.compiler.acme.AcmeSourceFile.name=ACME Source File
+com.wudsn.ide.asm.compiler.asm6.Asm6SourceFile.name=ASM6 Source File
+com.wudsn.ide.asm.compiler.atasm.AtasmSourceFile.name=ATASM Source File
+com.wudsn.ide.asm.compiler.dasm.DasmSourceFile.name=DASM Source File
+com.wudsn.ide.asm.compiler.kickass.KickAssSourceFile.name=KICKASS Source File
+com.wudsn.ide.asm.compiler.mads.MadsSourceFile.name=MADS Source File
+com.wudsn.ide.asm.compiler.merlin32.Merlin32SourceFile.name=MERLIN32 Source File
+com.wudsn.ide.asm.compiler.tass.TassSourceFile.name=TASS Source File
+com.wudsn.ide.asm.compiler.xasm.XasmSourceFile.name=XASM Source File
+
+com.wudsn.ide.asm.editor.acme.AcmeEditor.name=ACME Editor
+com.wudsn.ide.asm.editor.asm6.Asm6Editor.name=ASM6 Editor
+com.wudsn.ide.asm.editor.atasm.AtasmEditor.name=ATASM Editor
+com.wudsn.ide.asm.editor.dasm.DasmEditor.name=DASM Editor
+com.wudsn.ide.asm.editor.kickass.KickAssEditor.name=KICKASS Editor
+com.wudsn.ide.asm.editor.mads.MadsEditor.name=MADS Editor
+com.wudsn.ide.asm.editor.merlin32.Merlin32Editor.name=MERLIN32 Editor
+com.wudsn.ide.asm.editor.tass.TassEditor.name=TASS Editor
+com.wudsn.ide.asm.editor.xasm.XasmEditor.name=XASM Editor
+
+#
+# Hardware: APPLE2
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesApple2CompilersPage.name=Apple II Compilers
+com.wudsn.ide.asm.runner.apple2.applewin.name=AppleWin
+com.wudsn.ide.asm.runner.apple2.jace.name=JACE
+com.wudsn.ide.asm.runner.apple2.virtu.name=Virtu
+com.wudsn.ide.asm.runner.apple2.virtualii.name=Virtual ][
+
+#
+# Hardware: ATARI2600
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesAtari2600CompilersPage.name=Atari 2600 Compilers
+com.wudsn.ide.asm.runner.atari2600.stella.name=Stella
+
+#
+# Hardware: ATARI7800
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesAtari7800CompilersPage.name=Atari 7800 Compilers
+com.wudsn.ide.asm.runner.atari7800.emu7800.name=EMU7800
+
+#
+# Hardware: ATARI8
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesAtari8CompilersPage.name=Atari 8-bit Compilers
+com.wudsn.ide.asm.runner.atari8.atari800.name=Atari800
+com.wudsn.ide.asm.runner.atari8.atari800_win.name=Atari800Win
+com.wudsn.ide.asm.runner.atari8.atari800_macx.name=Atari800MacX
+com.wudsn.ide.asm.runner.atari8.altirra.name=Altirra
+com.wudsn.ide.asm.runner.atari8.atari_plus_plus.name=Atari++
+
+#
+# Hardware: C64
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesC64CompilersPage.name=C64 Compilers
+com.wudsn.ide.asm.runner.c64.ccs64.name=CCS64
+com.wudsn.ide.asm.runner.c64.vice.name=VICE
+
+#
+# Hardware: NES
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesNESCompilersPage.name=NES Compilers
+com.wudsn.ide.asm.runner.nes.bsnes.name=BSNES
+com.wudsn.ide.asm.runner.nes.fceux.name=FCEUX
+com.wudsn.ide.asm.runner.nes.nintendulator.name=Nintendulator
diff --git a/com.wudsn.ide.asm.compilers/plugin.xml b/com.wudsn.ide.asm.compilers/plugin.xml
new file mode 100644
index 00000000..ead35b4b
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/plugin.xml
@@ -0,0 +1,529 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers/plugin_de_DE.properties b/com.wudsn.ide.asm.compilers/plugin_de_DE.properties
new file mode 100644
index 00000000..4ba0fae0
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/plugin_de_DE.properties
@@ -0,0 +1,75 @@
+com.wudsn.ide.asm.compiler.acme.AcmeCompiler.name=ACME
+com.wudsn.ide.asm.compiler.asm6.Asm6Compiler.name=ASM6
+com.wudsn.ide.asm.compiler.atasm.AtasmCompiler.name=ATASM
+com.wudsn.ide.asm.compiler.dasm.DasmCompiler.name=DASM
+com.wudsn.ide.asm.compiler.kickass.KickAssCompiler.name=KICKASS
+com.wudsn.ide.asm.compiler.mads.MadsCompiler.name=MADS
+com.wudsn.ide.asm.compiler.merlin32.Merlin32Compiler.name=MERLIN32
+com.wudsn.ide.asm.compiler.tass.TassCompiler.name=TASS
+com.wudsn.ide.asm.compiler.xasm.XasmCompiler.name=XASM
+
+com.wudsn.ide.asm.compiler.acme.AcmeSourceFile.name=ACME Quelll-Datei
+com.wudsn.ide.asm.compiler.asm6.Asm6SourceFile.name=ASM6 Quelll-Datei
+com.wudsn.ide.asm.compiler.atasm.AtasmSourceFile.name=ATASM Quelll-Datei
+com.wudsn.ide.asm.compiler.dasm.DasmSourceFile.name=DASM Quelll-Datei
+com.wudsn.ide.asm.compiler.kickass.KickAssSourceFile.name=KICKASS Quelll-Datei
+com.wudsn.ide.asm.compiler.mads.MadsSourceFile.name=MADS Quelll-Datei
+com.wudsn.ide.asm.compiler.merlin32.Merlin32SourceFile.name=MERLIN32 Quelll-Datei
+com.wudsn.ide.asm.compiler.tass.TassSourceFile.name=TASS Quelll-Datei
+com.wudsn.ide.asm.compiler.xasm.XasmSourceFile.name=XASM Quelll-Datei
+
+com.wudsn.ide.asm.editor.acme.AcmeEditor.name=ACME Editor
+com.wudsn.ide.asm.editor.asm6.Asm6Editor.name=ASM6 Editor
+com.wudsn.ide.asm.editor.atasm.AtasmEditor.name=ATASM Editor
+com.wudsn.ide.asm.editor.dasm.DasmEditor.name=DASM Editor
+com.wudsn.ide.asm.editor.kickass.KickAssEditor.name=KICKASS Editor
+com.wudsn.ide.asm.editor.mads.MadsEditor.name=MADS Editor
+com.wudsn.ide.asm.editor.merlin32.Merlin32Editor.name=MERLIN32 Editor
+com.wudsn.ide.asm.editor.tass.TassEditor.name=TASS Editor
+com.wudsn.ide.asm.editor.xasm.XasmEditor.name=XASM Editor
+
+#
+# Hardware: APPLE2
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesApple2CompilersPage.name=Apple II Kompiler
+com.wudsn.ide.asm.runner.apple2.applewin.name=AppleWin
+com.wudsn.ide.asm.runner.apple2.jace.name=JACE
+com.wudsn.ide.asm.runner.apple2.virtu.name=Virtu
+com.wudsn.ide.asm.runner.apple2.virtualii.name=Virtual ][
+
+#
+# Hardware: ATARI2600
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesAtari2600CompilersPage.name=Atari 2600 Kompiler
+com.wudsn.ide.asm.runner.atari2600.stella.name=Stella
+
+#
+# Hardware: ATARI7800
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesAtari7800CompilersPage.name=Atari 7800 Kompiler
+com.wudsn.ide.asm.runner.atari7800.emu7800.name=EMU7800
+
+#
+# Hardware: ATARI8
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesAtari8CompilersPage.name=Atari 8-bit Kompiler
+com.wudsn.ide.asm.runner.atari8.atari800.name=Atari800
+com.wudsn.ide.asm.runner.atari8.atari800_win.name=Atari800Win
+com.wudsn.ide.asm.runner.atari8.atari800_macx.name=Atari800MacX
+com.wudsn.ide.asm.runner.atari8.altirra.name=Altirra
+com.wudsn.ide.asm.runner.atari8.atari_plus_plus.name=Atari++
+
+#
+# Hardware: C64
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesC64CompilersPage.name=C64 Kompiler
+com.wudsn.ide.asm.runner.c64.ccs64.name=CCS64
+com.wudsn.ide.asm.runner.c64.vice.name=VICE
+
+#
+# Hardware: NES
+#
+com.wudsn.ide.asm.preferences.AssemblerPreferencesNESCompilersPage.name=NES Kompiler
+com.wudsn.ide.asm.runner.nes.bsnes.name=BSNES
+com.wudsn.ide.asm.runner.nes.fceux.name=FCEUX
+com.wudsn.ide.asm.runner.nes.nintendulator.name=Nintendulator
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/CompilerId.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/CompilerId.java
new file mode 100644
index 00000000..cbc5569b
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/CompilerId.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+/**
+ * Compiler IDs for static use.
+ *
+ * @author Peter Dell
+ * @since 1.6.1
+ */
+public class CompilerId {
+ public static final String ACME = "acme";
+ public static final String ASM6 = "asm6";
+ public static final String ATASM = "atasm";
+ public static final String DASM = "dasm";
+ public static final String KICKASS = "kickass";
+ public static final String MADS = "mads";
+ public static final String MERLIN32 = "merlin32";
+ public static final String TASS = "tass";
+ public static final String XASM = "xasm";
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompiler.java
new file mode 100644
index 00000000..c3fa7461
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompiler.java
@@ -0,0 +1,49 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.compiler.acme;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for ACME.
+ *
+ * @author Peter Dell
+ */
+public final class AcmeCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public AcmeCompiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new AcmeCompilerSourceParser();
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new AcmeCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompiler.xml
new file mode 100644
index 00000000..2b62c867
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompiler.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompilerProcessLogParser.java
new file mode 100644
index 00000000..c79f5762
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompilerProcessLogParser.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.acme;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link AcmeCompiler}.
+ *
+ * Sample error message:
+ *
+ *
+ * Error - File include/ACME-Reference-Source-Include.a, line 3 (Zone ): Value not yet defined.
+ * Error - File C:\Users\D025328\Documents\Eclipse\workspace.jac\com.wudsn.ide.ref\ASM\C64\ACME\ACME-Error-Reference.a, line 9 (Zone ): Value not yet defined.
+ *
+ *
+ * @author Peter Dell
+ */
+final class AcmeCompilerProcessLogParser extends CompilerProcessLogParser {
+ private BufferedReader bufferedReader;
+
+ @Override
+ protected void initialize() {
+ bufferedReader = new BufferedReader(new StringReader(errorLog));
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ String line;
+ line = "";
+
+ while (line != null && !markerAvailable) {
+ try {
+ line = bufferedReader.readLine();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read line", ex);
+ }
+ if (line != null) {
+ String pattern;
+ int index;
+ pattern = "Error - File ";
+ severity = IMarker.SEVERITY_ERROR;
+ index = line.indexOf(pattern);
+ if (index < 0) {
+ pattern = "Warning - File ";
+ severity = IMarker.SEVERITY_WARNING;
+ index = line.indexOf(pattern);
+ }
+ if (index >= 0) {
+
+ index = index + pattern.length();
+ pattern = ", line ";
+ int i = line.indexOf(pattern);
+ if (i == -1) {
+ continue;
+ }
+ filePath = line.substring(index, i);
+
+ i = i + pattern.length();
+ int j = i;
+ while (line.charAt(j) != ' ' && j < line.length()) {
+ j++;
+ }
+
+ String lineNumberString = line.substring(i, j);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+
+ pattern = "): ";
+ line = line.substring(j);
+ j = line.indexOf(pattern);
+ if (j > -1) {
+ j = j + pattern.length();
+ message = line.substring(j);
+ } else {
+ message = line;
+ }
+
+ markerAvailable = true;
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompilerSourceParser.java
new file mode 100644
index 00000000..2f265526
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/acme/AcmeCompilerSourceParser.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.acme;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link AcmeCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class AcmeCompilerSourceParser extends CompilerSourceParser {
+
+ /**
+ * Creation is package local.
+ */
+ AcmeCompilerSourceParser() {
+
+ }
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ // Check for origin statement
+ if (symbol.equals("*")) {
+ beginImplementationSection(startOffset, startOffset + symbolOffset, operand, comment);
+
+ } else {
+ if (instruction.equals("=")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+
+ }
+ }
+
+ } // Symbol not empty
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6Compiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6Compiler.java
new file mode 100644
index 00000000..e29d08d1
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6Compiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.asm6;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for ASM6.
+ *
+ * @author Peter Dell
+ */
+public final class Asm6Compiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public Asm6Compiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new Asm6CompilerSourceParser();
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new Asm6CompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6Compiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6Compiler.xml
new file mode 100644
index 00000000..a03129c1
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6Compiler.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6CompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6CompilerProcessLogParser.java
new file mode 100644
index 00000000..f08713da
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6CompilerProcessLogParser.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.asm6;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link Asm6Compiler}.
+ *
+ * Sample error message:
+ *
+ *
+ *
+ * @author Peter Dell
+ */
+final class Asm6CompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private BufferedReader bufferedReader;
+
+ @Override
+ protected void initialize() {
+ bufferedReader = new BufferedReader(new StringReader(errorLog));
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ String line;
+ line = "";
+
+ while (line != null && !markerAvailable) {
+ try {
+ line = bufferedReader.readLine();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read line", ex);
+ }
+ if (line != null) {
+ String pattern;
+ int index;
+ pattern = "): ";
+ severity = IMarker.SEVERITY_ERROR;
+ index = line.indexOf(pattern);
+ if (index < 2) {
+ pattern = "): ";
+ severity = IMarker.SEVERITY_WARNING;
+ index = line.indexOf(pattern);
+ }
+ if (index > 2) {
+
+ int i = index - 2;
+ while (line.charAt(i) != '(' && i >= 0) {
+ i--;
+ }
+
+ if (line.charAt(i) == '(') {
+ String lineNumberString = line.substring(i + 1, index);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ } else {
+ lineNumber = -1;
+ }
+ message = line.substring(index + pattern.length()).trim();
+
+ filePath = line.substring(0, i);
+ markerAvailable = true;
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6CompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6CompilerSourceParser.java
new file mode 100644
index 00000000..ee30c3a3
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/asm6/Asm6CompilerSourceParser.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.asm6;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link Asm6Compiler}.
+ *
+ * @author Peter Dell
+ */
+final class Asm6CompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ // Check for origin statement
+ if (symbol.equals("*")) {
+ beginImplementationSection(startOffset, startOffset + symbolOffset, operand, comment);
+
+ } else {
+ if (instruction.equals("=")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+
+ }
+ }
+
+ } // Symbol not empty
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompiler.java
new file mode 100644
index 00000000..cb361dec
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.atasm;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for ATASM.
+ *
+ * @author Peter Dell
+ */
+public final class AtasmCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public AtasmCompiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new AtasmCompilerSourceParser();
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new AtasmCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompiler.xml
new file mode 100644
index 00000000..160487f6
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompiler.xml
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompilerProcessLogParser.java
new file mode 100644
index 00000000..271eac64
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompilerProcessLogParser.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.atasm;
+
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link AtasmCompiler}.
+ *
+ * Sample error message:
+ *
+ *
+ * "Pass 1: In Abbuc99-NetBalls-Init.asm, line 24-- Warning: Resizing 'BALLSCOLORTAB1', forcing another pass"
+ * "Pass 2: In Abbuc99-NetBalls-Init.asm, line 25-- Warning: Resizing 'BALLSCOLORTAB2', forcing another pass"
+ *
+ *
+ * @author Peter Dell
+ */
+final class AtasmCompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private Pattern pattern;
+
+ @Override
+ protected void initialize() {
+ pattern = Pattern.compile("In .* line ");
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ int index;
+ String line;
+ Matcher matcher = pattern.matcher(errorLog);
+
+ if (matcher.find()) {
+ index = matcher.start();
+ line = errorLog.substring(index);
+ filePath = line.substring(3, matcher.end() - matcher.start() - 7);
+ index = matcher.end();
+ String lineNumberLine = errorLog.substring(index);
+ errorLog = lineNumberLine;
+ int numberEndIndex = lineNumberLine.indexOf("--");
+ if (numberEndIndex > 0) {
+ String lineNumberString;
+ lineNumberString = lineNumberLine.substring(0, numberEndIndex);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ int nextIndex = lineNumberLine.indexOf("\n");
+ if (nextIndex > 0) {
+ message = lineNumberLine.substring(nextIndex + 1);
+ int nextIndex2 = message.indexOf("\n");
+ if (nextIndex2 > 0) {
+ message = message.substring(0, nextIndex2 - 1);
+ }
+ message = message.trim();
+ }
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ }
+
+ if (message.startsWith("Error:")) {
+ severity = IMarker.SEVERITY_ERROR;
+ message = message.substring(6);
+ } else if (message.startsWith("Warning:")) {
+ severity = IMarker.SEVERITY_WARNING;
+ message = message.substring(8);
+ }
+
+ message = message.trim();
+
+ // Message mapping.
+ if (severity == IMarker.SEVERITY_WARNING && message.startsWith("Using bank")) {
+ severity = IMarker.SEVERITY_INFO;
+ }
+ markerAvailable = true;
+ }
+ }
+
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+ final String EQUATES = "Equates:";
+ final String SYMBOL = "Symbol";
+ final String TABLE = "table:";
+
+ String log;
+ int index;
+
+ log = outputLog;
+ index = log.indexOf(EQUATES);
+ if (index >= 0) {
+ log = log.substring(index + EQUATES.length());
+
+ StringTokenizer st = new StringTokenizer(log);
+ String token;
+ String name;
+ String hexValue;
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (token.equals(SYMBOL)) {
+ break;
+ }
+ name = token.substring(0, token.length() - 1);
+ hexValue = st.nextToken(); // Must be there
+ compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
+ }
+
+ if (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (token.equals(TABLE)) {
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (!token.endsWith(":")) {
+ break;
+ }
+ name = token.substring(0, token.length() - 1);
+ hexValue = st.nextToken(); // Must be there
+ compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
+ }
+ }
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompilerSourceParser.java
new file mode 100644
index 00000000..ad3f0f5d
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/atasm/AtasmCompilerSourceParser.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.atasm;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link AtasmCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class AtasmCompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ // Check for origin statement
+ if (symbol.equals("*")) {
+ beginImplementationSection(startOffset, startOffset, operand, comment);
+
+ } else {
+ if (instruction.equals("=")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+ }
+ }
+
+ } // Symbol not empty
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DASM.txt b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DASM.txt
new file mode 100644
index 00000000..f524c3f6
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DASM.txt
@@ -0,0 +1,750 @@
+
+
+DOCUMENTATION FOR DASM, a high level macro cross assembler for:
+
+ -6502 (and 6507)
+ -68705
+ -6803
+ -HD6303 (extension of 6803)
+ -68HC11
+
+DASM was created in 1988 by Matthew Dillon (dillon@apollo.backplane.com)
+and modified in 1995 by Olaf 'Rhialto' Seibert (rhialto@polderland.nl), and
+is now updated and maintained by Andrew Davie (atari2600@taswegian.com)
+
+DASM's homepage is http://www.atari2600.org/dasm
+
+DASM is freely re-distributable, and provided with full source-code to
+allow recompilation for other target-platforms.
+
+
+PREFACE FROM MATT:
+
+ Over the last year my work has included writing software to drive small
+ single-chip microcomputers for various things (remote telemetry units,
+ for instance). I have had need to program quite a few different
+ processors over that time.
+
+ At the beginning, I used an awful macro assembler running on an IBM-PC.
+ I *really* wanted to do it on my Amiga. Thus the writing of this
+ program.
+
+ Feel free to suggest other similar processors for me to add to the list!
+ The processor type is specified with a pseudo-op (see below). This
+ assembler produces only binary output in one of three formats described
+ below. In general, one has a master assembly file which INCLUDEs all
+ the modules.
+
+ Also provided is FTOHEX which converts an output file in one of the
+ three formats to an intel-hex format suitable for many intelligent
+ prom programmers (I have a GTEK).
+
+ YES it's packed with features!
+
+FEATURES:
+
+ -fast assembly
+ -supports several common 8 bit processor models (NOT 8086, thank god!)
+ -takes as many passes as needed
+ -automatic checksum generation, special symbol '...'
+ -several binary output formats available. Format 2 allows reverse
+ indexed origins.
+ -multiple segments, BSS segments (no generation), relocatable origin.
+ -expressions, as in C but [] is used instead of () for parenthesis.
+ (all expressions are computed with 32 bit integers)
+ -no real limitation on label size, label values are 32 bits.
+ -complex pseudo ops, repeat loops, macros, etc....
+
+
+PREFACE FROM ANDREW (APRIL/2003)
+
+The documentation is lagging a bit behind the modifications. Essentially the information contained herein is correct, but there have been minor changes to the formatting of output data.
+
+Please see the accompanying ‘README.TXT’ in the distributable root directory for a list of recent changes to the package.
+
+
+COMMAND LINE:
+
+ dasm srcfile [options]
+
+ options: -f# select output format 1-3 (default 1, see below)
+ -oname select output file name (else a.out)
+ -lname select list file name (else none generated)
+ -Lname list file, containing all passes
+ -sname select symbol dump file (else none generated)
+ -v# select verboseness 0-4 (default 0, see below)
+ -d debug mode
+ -DSYMBOL predefine a symbol, set to 0
+ -DSYMBOL=EXPRESSION predefine a symbol, set to exp
+ -MSYMBOL=EXPRESSION define label as in EQM (same as –D)
+
+ -Idir search directory for include and incbin
+ -p# max number of passes
+ -P# max number of passes, with less checks
+
+ -T# sort symbol table by (0 = alphabetic (default)
+ or (non-zero= address/value)
+
+ Example: dasm master.asm -f2 -oout -llist -v3 -DVER=4
+
+Note: A slash (/) or dash (-) must prefix options.
+
+
+Return Value:
+
+ The assembler will return 0 on successful compilation, 1 otherwise.
+
+
+FORMAT OPTIONS:
+
+ 1 (DEFAULT)
+
+ The output file contains a two byte origin in LSB,MSB order, then
+ data until the end of the file.
+
+ Restrictions: Any instructions which generate output (within an
+ initialized segment) must do so with an ascending PC. Initialized
+ segments must occur in ascending order.
+
+ 2 RAS (Random Access Segment)
+
+ The output file contains one or more hunks. Each hunk consists
+ of a 2 byte origin (LSB,MSB), 2 byte length (LSB,MSB), and that
+ number of data bytes. The hunks occur in the same order as
+ initialized segments in the assembly. There are no restrictions
+ to segment ordering (i.e. reverse indexed ORG statements are
+ allowed). The next hunk begins after the previous hunk's data,
+ until the end of the file.
+
+ 3 RAW (Raw)
+
+ The output file contains data only (format #1 without the 2 byte
+ header). Restrictions are the same as for format #1.
+
+ Format 3 RAW (Raw format)
+ Same as format 1, but NO header origin is generated. You get
+ nothing but data.
+
+VERBOSE OPTIONS:
+
+ 0 (default)
+
+ Only warnings and errors are generated
+
+ 1
+ -Segment list information generated after each pass
+ -Include file names are displayed
+ -statistics on why the assembler is going to make another pass
+ R1,R2 reason code: R3
+ where R1 is the number of times the assembler encountered
+ something requiring another pass to resolve. R2 is the
+ number of references to unknown symbols which occured in the
+ pass (but only R1 determines the need for another pass). R3
+ is a BITMASK of the reasons why another pass is required.
+ See the end of this document for bit designations.
+
+ 2
+ mismatches between program labels and equates are displayed
+ on every pass (usually none occur in the first pass unless you
+ have re-declared a symbol name).
+
+ displayed information for symbols:
+ ???? = unknown value
+ str = symbol is a string
+ eqm = symbol is an eqm macro
+ (r) = symbol has been referenced
+ (s) = symbol created with SET or EQM pseudo-op
+
+ 3
+ Unresolved and unreferenced symbols are displayed every pass
+ (unsorted, sorry)
+
+ 4
+ An entire symbol list is displayed every pass to STDOUT.
+ (unsorted, sorry)
+
+
+
+PROCESSOR MODEL:
+
+ The processor model is chosen with the PROCESSOR pseudo-op and should
+ be the first thing you do in your assembly file. Different processor
+ models use different integer formats (see below). The word order does
+ not effect the headers in the output files (-f1 and -f2), which are
+ always LSB,MSB. The word ordering effects all address, word, and
+ long generation.
+
+ Only one PROCESSOR pseudo-op may be declared in the entire assembly,
+ and should be the first thing encountered.
+
+ -6502 LSB,MSB
+ -68HC11 MSB,LSB
+ -68705 MSB,LSB
+ -6803 MSB,LSB
+ -HD6303 MSB,LSB
+ -F8 ?
+
+SEGMENTS:
+ The SEG pseudo-op creates/sets the current segment. Each segment has
+ it's own origin and is optionally an 'uninitialized' segment.
+ Unitialized segments produce no output and have no restrictions. This
+ is useful for determining the size of a certain assembly sequence
+ without generating code, and for assigning RAM to labels.
+
+ 'Initialized' segments produce output. The following should be
+ considered when generating roms:
+
+ (1) The default fill character when using ORG (and format 1 or 3) to
+ skip forward is 00. This is a GLOBAL default and effects all
+ segments. See ORG.
+
+ (2) The default fill character for DS is 00 and is independant of
+ the default fill character for ORG (see DS).
+
+GENERAL:
+ Most everything is recursive. You cannot have a macro DEFINITION
+ within a macro definition, but can nest macro calls, repeat loops,
+ and include files.
+
+ The other major feature in this assembler is the SUBROUTINE pseudo-op,
+ which logically separates local labels (starting with a dot). This
+ allows you to reuse label names (for example, .1 .fail) rather than
+ think up crazy combinations of the current subroutine to keep it all
+ unique.
+
+ Almost nothing need be resolved in pass 1. The assembler will make
+ multiple passes in an attempt to resolve the assembly (including just
+ one pass if everything is resolved immediately).
+
+
+PSEUDOPS:
+
+ INCLUDE "name"
+
+ Include another assembly file.
+
+#if OlafIncbin
+
+[label] INCBIN "name"
+
+ Include another file literally in the output.
+#endif
+#if OlafIncdir
+
+ INCDIR "directory name"
+
+ Add the given directory name to the list of places where
+ INCLUDE and INCBIN search their files. First, the names are
+ tried relative to the current directory, if that fails and
+ the name is not an absolute pathname, the list is tried.
+ You can optionally end the name with a /. AmigaDOS filename
+ conventions imply that two slashes at the
+ end of an INCDIR (dir//) indicates the parent directory, and
+ so does an INCLUDE /filename.
+
+ The command-line option -Idir is equivalent to an INCDIR
+ directive placed before the source file.
+
+ Currently the list is not cleared between passes, but each
+ exact directory name is added to the list only once.
+ This may change in subsequent releases.
+#endif
+[label] SEG[.U] name
+
+ This sets the current segment, creating it if neccessary. If
+ a .U extension is specified on segment creation, the segment
+ is an UNINITIALIZED segment. The .U is not needed when going
+ back to an already created uninitialized segment, though it
+ makes the code more readable.
+
+[label] DC[.BWL] exp,exp,exp ...
+
+ Declare data in the current segment. No output is generated if
+ within a .U segment. Note that the byte ordering for the
+ selected processor is used for each entry.
+
+ The default size extension is a byte.
+#if OlafByte
+ BYTE, WORD and LONG are synonyms for DC.B, DC.W and DC.L.
+#endif
+
+[label] DS[.BWL] exp[,filler]
+
+ declare space (default filler is 0). Data is not generated if
+ within an uninitialized segment. Note that the number of bytes
+ generated is exp * entrysize (1,2, or 4)
+
+ The default size extension is a byte.
+
+ Note that the default filler is always 0 (has nothing to do
+ with the ORG default filler).
+
+[label] DV[.BWL] eqmlabel exp,exp,exp....
+
+ This is equivalent to DC, but each exp in the list is passed
+ through the symbolic expression specified by the EQM label.
+ The expression is held in a special symbol dotdot '..' on each
+ call to the EQM label.
+
+ See EQM below
+
+[label] HEX hh hh hh..
+
+ This sets down raw HEX data. Spaces are optional between bytes.
+ NO EXPRESSIONS are allowed. Note that you do NOT place a $
+ in front of the digits. This is a short form for creating
+ tables compactly. Data is always layed down on a byte-by-byte
+ basis.
+
+ Example: HEX 1A45 45 13254F 3E12
+
+ ERR
+
+ Abort assembly.
+
+[label] ORG exp[,DefaultFillVal]
+
+ This pseudop sets the current origin. You can also set the
+ global default fill character (a byte value) with this
+ pseudoop. NOTE that no filler is generated until the first
+ data-generating opcode/psueoop is encountered after this one.
+ Sequences like:
+
+ org 0,255
+ org 100,0
+ org 200
+ dc 23
+
+ will result in 200 zero's and a 23. This allows you to specify
+ some ORG, then change your mind and specify some other (lower
+ address) ORG without causing an error (assuming nothing is
+ generated inbetween).
+
+ Normally, DS and ALIGN are used to generate specific filler
+ values.
+
+[label] RORG exp
+
+ This activates the relocatable origin. All generated
+ addresses, including '.', although physically placed at the
+ true origin, will use values from the relocatable origin.
+ While in effect both the physical origin and relocatable origin
+ are updated.
+
+ The relocatable origin can skip around (no limitations). The
+ relocatable origin is a function of the segment. That is, you
+ can still SEG to another segment that does not have a
+ relocatable origin activated, do other (independant) stuff
+ there, and then switch back to the current segment and continue
+ where you left off.
+
+ PROCESSOR model
+
+ do not quote. model is one of: 6502,6803,HD6303,68705,68HC11,F8
+ Can only be executed once, and should be the first thing
+ encountered by the assembler.
+
+ ECHO exp,exp,exp
+
+ The expressions (which may also be strings), are echoed on the
+ screen and into the list file.
+
+[label] REND
+
+ Deactivate the relocatable origin for the current segment.
+ Generation uses the real origin for reference.
+
+[label] ALIGN N[,fill]
+
+ Align the current PC to an N byte boundry. The default
+ fill character is always 0, and has nothing to do with
+ the default fill character specifiable in an ORG.
+
+[label] SUBROUTINE name
+
+ This isn't really a subroutine, but a boundry between sets of
+ temporary labels (which begin with a dot). Temporary label
+ names are unique within segments of code bounded by SUBROUTINE:
+
+ CHARLIE subroutine
+ ldx #10
+ .1 dex
+ bne .1
+ BEN subroutine
+ ldx #20
+ .qq dex
+ bne .qq
+
+ Automatic temporary label boundries occur for each macro level.
+ Usually temporary labels are used in macros and within actual
+ subroutines (so you don't have to think up a thousand different
+ names)
+
+
+symbol EQU exp
+#if OlafAsgn
+symbol = exp
+#endif
+
+ The expression is evaluated and the result assigned to the
+ symbol.
+
+#if OlafDotAssign
+ If this option is enabled, you can use the common idiom of
+
+ . EQU . + 3 (or . = .+3)
+
+ in other words, you can assign to "." (or "*" if OlafStar
+ is also enabled) instead of an ORG or RORG directive.
+ More formally, a directive of the form ". EQU expr" is
+ interpreted as if it were written " (R)ORG expr".
+ The RORG is used if a relocatable origin is already in effect,
+ otherwise ORG is used. Note that the first example is NOT
+ equivalent with "DS.B 3" when the rorg is in effect.
+#endif
+
+symbol EQM exp
+
+ The STRING representing the expression is assigned to the
+ symbol. Occurances of the label in later expressions causes
+ the string to be evaluated for each occurance. Also used in
+ conjuction with the DV psuedo-op.
+
+symbol SET exp
+
+ Same as EQU, but the symbol may be reassigned later.
+
+ MAC name
+
+ Declare a macro. lines between MAC and ENDM are the macro.
+ You cannot recursively declare a macro. You CAN recursively
+ use a macro (reference a macro in a macro). No label is
+ allowed to the left of MAC or ENDM.
+
+ Arguments passed to macros are referenced with: {#}. The first
+ argument passed to a macro would thus be {1}. You should
+ always use LOCAL labels (.name) inside macros which you use
+ more than once. {0} represents an EXACT substitution of the
+ ENTIRE argument line.
+
+ ENDM
+
+ end of macro def. NO LABEL ALLOWED ON THE LEFT!
+
+ MEXIT
+
+ Used in conjuction with conditionals. Exits the current macro
+ level.
+
+[label] IFCONST exp
+
+ Is TRUE if the expression result is defined, FALSE otherwise
+ and NO error is generated if the expression is undefined.
+
+[label] IFNCONST exp
+
+ Is TRUE if the expression result is undefined, FALSE otherwise
+ and NO error is generated if the expression is undefined.
+
+[label] IF exp
+
+ Is TRUE if the expression result is defined AND non-zero.
+ Is FALSE if the expression result is defined AND zero.
+ Neither IF or ELSE will be executed if the expression result
+ is undefined. If the expression is undefined, another assembly
+ pass is automatically taken.
+#if OlafPhase
+ If this happens, phase errors in the next pass only will not
+ be reported unless the verboseness is 1 or more.
+#endif
+
+[label] ELSE
+
+ ELSE the current IF.
+
+[label] ENDIF
+[label] EIF
+
+ Terminate an IF. ENDIF and EIF are equivalent.
+
+[label] REPEAT exp
+[label] REPEND
+
+ Repeat code between REPEAT/REPEND 'exp' times.
+
+#if DAD
+ if exp == 0,
+ the code repeats forever. exp is evaluated once.
+
+ If exp == 0, the repeat loop is ignored.
+ If exp < 0, a warning “REPEAT parameter < 0 (ignored)” is generated and the repeat loop is ignored.
+#endif
+
+ Y SET 0
+ REPEAT 10
+ X SET 0
+ REPEAT 10
+ DC X,Y
+ X SET X + 1
+ REPEND
+ Y SET Y + 1
+ REPEND
+
+ generates an output table: 0,0 1,0 2,0 ... 9,0 0,1 1,1 2,1
+ ... 9,1, etc...
+
+ Labels within a REPEAT/REPEND should be temporary labels with a
+ SUBROUTINE pseudo-op to keep them unique.
+
+ The Label to the left of REPEND is assigned AFTER the loop
+ FINISHES.
+
+
+[label] XXX[.force] operand
+
+ XXX is some mnemonic, not necessarily three characters long.
+ The .FORCE optional extension is used to force specific
+ addressing modes (see below).
+
+[label] LIST ON or OFF
+
+ Globally turns listing on or off, starting with the current
+ line.
+#if OlafList
+ When you give LOCALON or LOCALOFF the effect is local to the
+ current macro or included file. For a line to be listed both
+ the global and local list switches must be on.
+#endif
+
+#if OlafDotop
+ All pseudo-ops (and incidentally also the mnemonics) can be
+ prefixed with a . for compatibility with other assemblers.
+ So .IF is the same as IF. This works only because lone .FORCE
+ extensions are meaningless.
+#endif
+
+#if OlafFreeFormat
+ The format of each input line is free: first all leading
+ spaces are discarded, and the first word is examined. If it
+ does not look like a directive or opcode (as known at that point),
+ it is taken as a label. This is sort-of nasty if you like labels
+ with names like END.
+ The two xxxFormat options are mutually exclusive.
+#endif
+
+#if OlafHashFormat
+ With this option an initial # (after optional initial spaces)
+ turns the next word into a directive/opcode.
+ A ^ skips more spaces and makes the next word a label.
+#endif
+
+GENERAL:
+
+ The label will be set to the current ORG/RORG either before or after
+ a pseudo-op is executed. Most of the time, the label to the left of a
+ pseudo-op is the current ORG/RORG. The following pseudo-op's labels are
+ created AFTER execution of the pseudo-op:
+
+ SEG, ORG, RORG, REND, ALIGN
+
+EXTENSIONS:
+
+ FORCE extensions are used to force an addressing mode. In some cases,
+ you can optimize the assembly to take fewer passes by telling it the
+ addressing mode. Force extensions are also used with DS,DC, and DV
+ to determine the element size. NOT ALL EXTENSIONS APPLY TO ALL
+ PROCESSORS!
+
+ example: lda.z charlie
+
+ i -implied
+ ind -indirect word
+ 0 -implied
+ 0x -implied indexing (0,x)
+ 0y -implied indexing (0,y)
+ b -byte address
+ bx -byte address indexed x
+ by -byte address indexed y
+ w -word address
+ wx -word address indexed x
+ wy -word address indexed y
+ l -longword (4 bytes) (DS/DC/DV)
+ r -relative
+ u -uninitialized (SEG)
+
+ First character equivalent substitutions:
+
+ b z d (byte, zeropage, direct)
+ w e a (word, extended, absolute)
+
+
+ASSEMBLER PASSES:
+ The assembler may have to make several passes through the source
+ code to resolve all generation. The number of passes is not
+ limited to two. Since this may result in an unexpected, verbose
+ option 2, 3, and 4 have been provided to allow determination of the
+ cause. The assembler will give up if it thinks it can't do the
+ assembly in *any* number of passes.
+
+ Error reporting could be better....
+
+#if OlafPasses
+
+ The check if another pass might resolve the source is pretty good, but
+ not perfect. You can specify the maximum number of passes to do
+ (default -p10), and with the -P option you can override the normal check.
+ This allows the following contrived example to resolve in 12 passes:
+
+ org 1
+ repeat [[x < 11] ? [x-11]] + 11
+ dc.b x
+ repend
+ x:
+
+#endif
+
+EXPRESSIONS:
+ [] may be used to group expressions. The precedense of operators
+ is the same as for the C language in almost all respects. Use
+ brackets [] when you are unsure. The reason () cannot be used to
+ group expressions is due to a conflict with the 6502 and other
+ assembly languages.
+#if OlafBraKet
+ It is possible to use () instead of [] in expressions following
+ pseudo-ops, but not following mnemonics. So this works:
+ if target & (pet3001 | pet4001), but this doesn't:
+ lda #target & (pet3001 | pet4001).
+#endif
+
+ Some operators, such as ||, can return a resolved value even if
+ one of the expressions is not resolved. Operators are as follows:
+
+ NOTE WELL! Some operations will result in non-byte values when a
+ byte value was wanted. For example: ~1 is NOT $FF, but
+ $FFFFFFFF. Preceding it with a < (take LSB of) will solve the
+ problem. ALL ARITHMETIC IS CARRIED OUT IN 32 BITS. The final
+ Result will be automatically truncated to the maximum handleable
+ by the particular machine language (usually a word) when applied
+ to standard mnemonics.
+
+ prec UNARY
+
+ 20 ~exp one's complement.
+ 20 -exp negation
+ 20 !exp not expression (returns 0 if exp non-zero, 1 if exp zero)
+ 20 exp take MSB byte of an expression
+
+ BINARY
+
+ 19 * multiplication
+ 19 / division
+ 19 % mod
+ 18 + addition
+ 18 - subtraction
+ 17 >>,<< shift right, shift left
+ 16 >,>= greater, greater equal
+ 16 <,<= smaller, smaller equal
+ 15 == equal to. Try to use this instead of =
+ 15 = exactly the same as == (exists compatibility)
+ 15 != not equal to
+ 14 & logical and
+ 13 ^ logical xor
+ 12 | logical or
+ 11 && left expression is true AND right expression is true
+ 10 || left expression is true OR right expression is true
+ 9 ? if left expression is true, result is right expression,
+ else result is 0. [10 ? 20] returns 20
+ 8 [] group expressions
+ 7 , separate expressions in list (also used in
+ addressing mode resolution, BE CAREFUL!
+
+ Note: The effect of the C conditional operator a ? b : c can be
+ had with [a ? b - c] + c.
+
+ Constants:
+
+ nnn decimal
+ 0nnn octal
+ %nnn binary
+ $nnn hex
+ 'c character
+ "cc.." string (NOT zero terminated if in DC/DS/DV)
+ [exp]d the constant expressions is evaluated and it's decimal
+ result turned into an ascii string.
+
+ Symbols:
+
+ ... -holds CHECKSUM so far (of actual-generated stuff)
+ .. -holds evaluated value in DV pseudo op
+ .name -represents a temporary symbol name. Temporary symbols
+ may be reused inside MACROS and between SUBROUTINES, but
+ may not be referenced across macros or across SUBROUTINEs.
+ . -current program counter (as of the beginning of the
+ instruction).
+ name -beginning with an alpha character and containing letters,
+ numbers, or '_'. Represents some global symbol name.
+#if OlafStar
+ * -synonym for ., when not confused as an operator.
+#endif
+#if OlafDol
+ nnn$ -temporary label, much like .name, except that defining
+ a non-temporary label has the effect that SUBROUTINE
+ has on .name. They are unique within macros, like
+ .name. Note that 0$ and 00$ are distinct, as are 8$
+ and 010$.
+ (mainly for compatibility with other assemblers.)
+#endif
+
+
+WHY codes:
+ Each bit in the WHY word (verbose option 1) is a reason (why
+ the assembler needs to do another pass), as follows:
+
+ bit 0 expression in mnemonic not resolved
+ 1 -
+ 2 expression in a DC not resolved
+ 3 expression in a DV not resolved (probably in DV's EQM symbol)
+ 4 expression in a DV not resolved (could be in DV's EQM symbol)
+ 5 expression in a DS not resolved
+ 6 expression in an ALIGN not resolved
+ 7 ALIGN: Relocatable origin not known (if in RORG at the time)
+ 8 ALIGN: Normal origin not known (if in ORG at the time)
+ 9 EQU: expression not resolved
+ 10 EQU: value mismatch from previous pass (phase error)
+ 11 IF: expression not resolved
+ 12 REPEAT: expression not resolved
+
+ 13 a program label has been defined after it has been
+ referenced (forward reference) and thus we need another
+ pass
+ 14 a program label's value is different from that of the
+ previous pass (phase error)
+
+ Certain errors will cause the assembly to abort immediately, others
+ will wait until the current pass is other. The remaining allow another
+ pass to occur in the hopes the error will fix itself.
+
+
+VERSIONS:
+
+ V2.12
+ -Fixed macro naming bug (macros wouldn't work if the name after
+ the 'mac' was in upper case).
+
+ V2.11
+ -Fixed exp bug, exp MSB (it used to
+ be reversed).
+ -Fixed many bugs in macros and other things
+ -Added automatic checksumming ... no more doing checksums manually!
+ -Added several new processors, including 6502.
+ -Source is now 16/32 bit int compatible, and will compile on an
+ IBM-PC (the ultimate portability test)
+
+ V2.01
+
+ -can now have REPEAT/REPEND's within macros
+ -fill field for DS.W is a word (used to be a byte fill)
+ -fill field for DS.L is a long (used to be a byte fill)
+
+
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompiler.java
new file mode 100644
index 00000000..33bbfed2
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.dasm;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for DASM.
+ *
+ * @author Peter Dell
+ */
+public final class DasmCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public DasmCompiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new DasmCompilerSourceParser();
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new DasmCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompiler.xml
new file mode 100644
index 00000000..dccb2126
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompiler.xml
@@ -0,0 +1,417 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompilerProcessLogParser.java
new file mode 100644
index 00000000..cb7c1700
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompilerProcessLogParser.java
@@ -0,0 +1,270 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.dasm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+import com.wudsn.ide.base.common.FileUtility;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Process log parser for {@link DasmCompiler}.
+ *
+ * Sample error message:
+ *
+ *
+ *
+ * @author Peter Dell
+ */
+final class DasmCompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private Pattern pattern;
+
+ private String listLog;
+ private String listLogErrorMessage;
+ private boolean fatalErrorFound;
+ private boolean unresolvedSymbolsFound;
+
+ @Override
+ protected void initialize() {
+ pattern = Pattern.compile(".* (.*): error:");
+
+ File listFile = new File(files.outputFolder, files.mainSourceFile.fileNameWithoutExtension + ".lst");
+ if (listFile.exists()) {
+ try {
+ listLog = FileUtility.readString(listFile.getPath(), new FileInputStream(listFile),
+ FileUtility.MAX_SIZE_UNLIMITED);
+ listLogErrorMessage = null;
+ } catch (FileNotFoundException ex) {
+ listLog = "";
+ listLogErrorMessage = ex.getMessage();
+ } catch (CoreException ex) {
+ listLog = "";
+ listLogErrorMessage = ex.getStatus().getMessage();
+ }
+ } else {
+ listLog = "";
+ listLogErrorMessage = "Expected list file '"
+ + listFile.getPath()
+ + "' does not exist. Check the compiler preferences and make sure you have set the option '-l${outputFilePathWithoutExtension}.lst'.";
+ }
+ fatalErrorFound = false;
+ unresolvedSymbolsFound = false;
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ if (listLogErrorMessage != null) {
+ filePath = mainSourceFilePath;
+ lineNumber = 0;
+ severity = IMarker.SEVERITY_ERROR;
+ message = listLogErrorMessage;
+ markerAvailable = true;
+ listLogErrorMessage = null;
+ return;
+ }
+
+ int index;
+ String line;
+ Matcher matcher = pattern.matcher(listLog);
+
+ if (matcher.find()) {
+ index = matcher.start();
+ line = listLog.substring(index);
+ listLog = listLog.substring(matcher.end());
+ int numberIndex = line.indexOf(" (");
+
+ if (numberIndex > 0) {
+
+ filePath = line.substring(0, numberIndex);
+
+ String lineNumberString;
+ int numberEndIndex = line.indexOf(')');
+ if (numberEndIndex > 0) {
+ lineNumberString = line.substring(numberIndex + 2, numberEndIndex);
+ } else {
+ lineNumberString = "-1";
+ }
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+
+ int nextIndex = line.indexOf("\n");
+ if (nextIndex > 0) {
+ message = line.substring(numberEndIndex + 10, nextIndex - 1);
+ }
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ message = ex.getMessage();
+ }
+
+ severity = IMarker.SEVERITY_ERROR;
+ message = message.trim();
+ markerAvailable = true;
+ return;
+ }
+ } else {
+ index = outputLog.indexOf("Fatal assembly error: ");
+ if (index > 0 && !fatalErrorFound) {
+ int nextIndex = outputLog.indexOf("\n", index);
+ if (nextIndex > 0) {
+ message = outputLog.substring(index, nextIndex - 1);
+ } else {
+ message = outputLog.substring(index);
+ }
+ fatalErrorFound = true;
+
+ severity = IMarker.SEVERITY_ERROR;
+ message = message.trim();
+ markerAvailable = true;
+ return;
+ }
+
+ if (fatalErrorFound) {
+ final String UNRESOLVED = "--- Unresolved Symbol List";
+ index = outputLog.lastIndexOf(UNRESOLVED);
+ if (index > 0) {
+ unresolvedSymbolsFound = true;
+ outputLog = outputLog.substring(index + UNRESOLVED.length()).trim();
+ }
+ }
+ if (unresolvedSymbolsFound) {
+ index = outputLog.indexOf('\n');
+ if (index > 0) {
+ line = outputLog.substring(0, index - 1);
+ if (!line.startsWith("--")) {
+ outputLog = outputLog.substring(index + 1);
+ severity = IMarker.SEVERITY_ERROR;
+ index = line.indexOf(" ");
+ if (index > 0) {
+ line = line.substring(0, index);
+ }
+ message = "Unresolved symbol " + line + ".";
+ markerAvailable = true;
+ return;
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * Type tokens in labels file:
+ *
+ * ???? = unknown value
+ * str = symbol is a string
+ * eqm = symbol is an eqm macro
+ * (r) = symbol has been referenced
+ * (s) = symbol created with SET or EQM pseudo-op
+ */
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+ final String SYMBOLS = "--- Symbol List (sorted by symbol)";
+
+ String log;
+ int index;
+
+ log = outputLog;
+ index = log.indexOf(SYMBOLS);
+ if (index >= 0) {
+ log = log.substring(index + SYMBOLS.length()).trim();
+
+ index = log.indexOf('\n');
+ while (index > 0) {
+ String line = log.substring(0, index - 1);
+ if (line.startsWith("--- End of Symbol List.")) {
+ break;
+ }
+ StringTokenizer st = new StringTokenizer(line);
+ String name = st.nextToken();
+ String hexValue = "";
+ if (st.hasMoreTokens()) {
+ hexValue = st.nextToken();
+ }
+
+ String token = "";
+ int valueType = CompilerSymbol.NUMBER;
+ String stringValue = "";
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ // "str" indicates that the symbol is a string value
+ if (token.equals("str")) {
+ valueType = CompilerSymbol.STRING;
+ }
+
+ // String values are enclosed in double quotes.
+ if (valueType == CompilerSymbol.STRING && token.startsWith("\"") && token.length() >= 2
+ && token.endsWith("\"")) {
+ stringValue = token.substring(1, token.length() - 1);
+ }
+ }
+
+ switch (valueType) {
+ case CompilerSymbol.NUMBER:
+ // Ignore unnamed symbol with value "0000"
+ if (StringUtility.isSpecified(hexValue)) {
+ compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
+ }
+ break;
+ case CompilerSymbol.STRING:
+ compilerSymbols.add(CompilerSymbol.createStringSymbol(name, stringValue));
+ break;
+ default:
+ throw new IllegalStateException("Unsupported value type '" + valueType + "'.");
+ }
+
+ log = log.substring(index).trim();
+ index = log.indexOf('\n');
+
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompilerSourceParser.java
new file mode 100644
index 00000000..74098666
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/dasm/DasmCompilerSourceParser.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.dasm;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link DasmCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class DasmCompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ // Check for origin statement
+ if (symbol.equals("*")) {
+ beginImplementationSection(startOffset, startOffset + symbolOffset, operand, comment);
+
+ } else {
+ if (instruction.equals("=")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+
+ }
+ }
+
+ } // Symbol not empty
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAss-Libraries.txt b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAss-Libraries.txt
new file mode 100644
index 00000000..4e3345ae
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAss-Libraries.txt
@@ -0,0 +1,424 @@
+Questions based on your list:
+>- There is "ANC_IMM" for "anc" but not "anc2" for "ANC2_IMM"?
+Yes thats right, but don't they do the same?
+
+>- BRA_REL is missing?
+From the constants? No, its after RLA_ABSY
+
+
+>- What are the "AT_.." constants?
+These are argument type constants. Pseudocommands are a kind of advanced macros that takes instruction arguments. An argument consist of a type (immediate, absolute, etc) and a value and you can manipulate these as you want. Let's say you want to define you own 16bit amgia/pc style move command that can be used like this:
+
+:mov16 #$1234 ; target // Move immediate to absolute
+:mov16 $1000 ; $2000,x // Move from absolute to absolute,x
+:mov16 $10,x ; $2000,y // zeropage,x to absolute
+
+Then you can define it like this:
+
+.pseudocommand mov16 src;tar {
+ lda src
+ sta tar
+ lda _16bit_nextArgument(src)
+ sta _16bit_nextArgument(tar)
+}
+
+.function _16bit_nextArgument(arg) {
+ .if (arg.getType()==AT_IMMEDIATE) .return CmdArgument(arg.getType(),>arg.getValue())
+ .return CmdArgument(arg.getType(),arg.getValue()+1)
+}
+
+Btw. Don't worry if you missed a detail in the above. The point is that you use AT_IMMEDIATE constant to detect if the argument is immediate, since you have to treat these differently.
+
+
+>- Is there a list of descriptions & values for the constants? In the content assist, I'd like to display that information.
+They are described in the manual. Most of them are seen in tables (left column=constant, right one - description).
+
+
+Hi Peter
+
+> Why "else" and not ".else"?
+Because else is considered part of the .if directive. (In the parse tree the if directive is a node with a true-condition branch and an optional false-condition branch (else))
+
+>Is everything case-senstive?
+Thats correct
+
+
+Eg:
+- All directives start with '.'. For Example: '.byte' '.word' '.import' '.fill' '.for'
+- All labels end with ':'. For example: 'label1:'
+- All macro / pseudocommand executions start with ':'. For Example: ':MyMacro(27, "Hello")' or ':mov #5 ; $d020'
+- Comments are like java / C++ (/* Block comment */, // Line comment)
+
+The Directives:
+
+".align"
+".assert"
+".asserterror"
+".by"
+".byte"
+".const"
+".define"
+".dw"
+".dword"
+".easteregg"
+".enum"
+".error"
+".eval"
+".filenamespace"
+".fill"
+".for"
+".function"
+".if"
+".import"
+".importonce"
+".label"
+".macro"
+".namespace"
+".pc"
+".print"
+".printnow"
+".pseudocommand"
+".pseudopc"
+".return"
+".struct"
+".te"
+".text"
+".var"
+".wo"
+".word"
+"else"
+
+
+
+Asm Commands (Including the illegal ones);
+"tas"|"php"|"sax"|"rti"|"sta"|"tsx"|"cpy"|"cpx"|"pha"|"bvs"|"bpl"|"dcp"|"adc"|
+"tya"|"eor"|"iny"|"inx"|"lax"|"bcs"|"bvc"|"las"|"bit"|"slo"|"txs"|"inc"|"bcc"|
+"lsr"|"sre"|"plp"|"txa"|"rla"|"jmp"|"jsr"|"rra"|"pla"|"sei"|"ahx"|"sed"|"sec"|
+"ora"|"isc"|"bne"|"and"|"anc"|"cmp"|"bmi"|"asl"|"ldy"|"clv"|"ldx"|"ror"|"cli"|
+"alr"|"dey"|"rol"|"cld"|"dex"|"clc"|"arr"|"brk"|"lda"|"shy"|"axs"|"shx"|"sty"|
+"stx"|"beq"|"nop"|"dec"|"sbc2"|"sbc"|"tay"|"xaa"|"tax"|"rts"
+
+
+Illegal Ones:
+"tas"|"sax"|"dcp"|"lax"|"las"|"slo"|"sre"|"rla"|""rra"|"ahx"|"isc"|"anc"
+"alr"|"arr"|"shy"|"axs"|"shx"|"sbc2"|"xaa"|
+
+
+DTV Commands:
+"sac"|"sir"|"bra"
+
+Default macros:
+:BasicUpstart(address)
+:BasicUpstart2(address)
+
+
+Default Constants:
+PI
+E
+AT_ABSOLUTE
+AT_ZEROPAGE
+AT_ABSOLUTEX
+AT_ABSOLUTEY
+AT_IMMEDIATE
+AT_INDIRECT
+AT_IZEROPAGEX
+AT_IZEROPAGEY
+AT_NONE
+BLACK
+WHITE
+RED
+CYAN
+PURPLE
+GREEN
+BLUE
+YELLOW
+ORANGE
+BROWN
+LIGHT_RED
+DARK_GRAY
+DARK_GREY
+GRAY
+GREY
+LIGHT_GREEN
+LIGHT_BLUE
+LIGHT_GRAY
+LIGHT_GREY
+BF_C64FILE
+BF_KOALA
+BF_FLI
+BF_BITMAP_SINGLECOLOR
+PLA
+SAC_IMM
+SLO_ZP
+SLO_ZPX
+SLO_IZPX
+SLO_IZPY
+SLO_ABS
+SLO_ABSX
+SLO_ABSY
+PHA
+BVC_REL
+BRK
+CLC
+CLD
+PLP
+EOR_IMM
+EOR_ZP
+EOR_ZPX
+EOR_IZPX
+EOR_IZPY
+EOR_ABS
+EOR_ABSX
+EOR_ABSY
+INC_ZP
+INC_ZPX
+INC_ABS
+INC_ABSX
+PHP
+RLA_ZP
+RLA_ZPX
+RLA_IZPX
+RLA_IZPY
+RLA_ABS
+RLA_ABSX
+RLA_ABSY
+BRA_REL
+JMP_ABS
+JMP_IND
+BVS_REL
+ROR
+ROR_ZP
+ROR_ZPX
+ROR_ABS
+ROR_ABSX
+CLV
+STA_ZP
+STA_ZPX
+STA_IZPX
+STA_IZPY
+STA_ABS
+STA_ABSX
+STA_ABSY
+ARR_IMM
+SBC_IMM
+SBC_ZP
+SBC_ZPX
+SBC_IZPX
+SBC_IZPY
+SBC_ABS
+SBC_ABSX
+SBC_ABSY
+CLI
+BEQ_REL
+LSR
+LSR_ZP
+LSR_ZPX
+LSR_ABS
+LSR_ABSX
+CPX_IMM
+CPX_ZP
+CPX_ABS
+CPY_IMM
+CPY_ZP
+CPY_ABS
+NOP
+BNE_REL
+JSR_ABS
+ANC_IMM
+LDA_IMM
+LDA_ZP
+LDA_ZPX
+LDA_IZPX
+LDA_IZPY
+LDA_ABS
+LDA_ABSX
+LDA_ABSY
+AND_IMM
+AND_ZP
+AND_ZPX
+AND_IZPX
+AND_IZPY
+AND_ABS
+AND_ABSX
+AND_ABSY
+RTI
+BIT_ZP
+BIT_ZPX
+BIT_ABS
+BIT_ABSX
+STX_ZP
+STX_ZPY
+STX_ABS
+TAY
+TAX
+RTS
+TAS_ABSY
+SAX_ZP
+SAX_ZPY
+SAX_IZPX
+SAX_ABS
+ROL
+ROL_ZP
+ROL_ZPX
+ROL_ABS
+ROL_ABSX
+INX
+INY
+STY_ZP
+STY_ZPX
+STY_ABS
+ASL
+ASL_ZP
+ASL_ZPX
+ASL_ABS
+ASL_ABSX
+TYA
+BMI_REL
+AHX_IZPY
+AHX_ABSY
+DEX
+DEY
+CMP_IMM
+CMP_ZP
+CMP_ZPX
+CMP_IZPX
+CMP_IZPY
+CMP_ABS
+CMP_ABSX
+CMP_ABSY
+AXS_IMM
+ADC_IMM
+ADC_ZP
+ADC_ZPX
+ADC_IZPX
+ADC_IZPY
+ADC_ABS
+ADC_ABSX
+ADC_ABSY
+TXS
+DEC_ZP
+DEC_ZPX
+DEC_ABS
+DEC_ABSX
+ISC_ZP
+ISC_ZPX
+ISC_IZPX
+ISC_IZPY
+ISC_ABS
+ISC_ABSX
+ISC_ABSY
+ALR_IMM
+SRE_ZP
+SRE_ZPX
+SRE_IZPX
+SRE_IZPY
+SRE_ABS
+SRE_ABSX
+SRE_ABSY
+TSX
+LAS_ABSY
+LAX_IMM
+LAX_ZP
+LAX_ZPY
+LAX_IZPX
+LAX_IZPY
+LAX_ABS
+LAX_ABSY
+TXA
+BCC_REL
+SHY_ABSX
+SHX_ABSY
+RRA_ZP
+RRA_ZPX
+RRA_IZPX
+RRA_IZPY
+RRA_ABS
+RRA_ABSX
+RRA_ABSY
+BPL_REL
+SEI
+XAA_IMM
+SIR_IMM
+DCP_ZP
+DCP_ZPX
+DCP_IZPX
+DCP_IZPY
+DCP_ABS
+DCP_ABSX
+DCP_ABSY
+SED
+ORA_IMM
+ORA_ZP
+ORA_ZPX
+ORA_IZPX
+ORA_IZPY
+ORA_ABS
+ORA_ABSX
+ORA_ABSY
+SEC
+ANC2_IMM
+BCS_REL
+SBC2_IMM
+LDY_IMM
+LDY_ZP
+LDY_ZPX
+LDY_ABS
+LDY_ABSX
+LDX_IMM
+LDX_ZP
+LDX_ZPY
+LDX_ABS
+LDX_ABSY
+
+Default functions:
+abs
+acos
+asin
+atan
+atan2
+cbrt
+ceil
+cos
+cosh
+exp
+expm1
+floor
+hypot
+IEEEremainder
+log
+log10
+log1p
+max
+min
+pow
+random
+round
+signum
+sin
+sinh
+sqrt
+tan
+tanh
+toDegrees
+toRadians
+mod
+toIntString
+toHexString
+toOctalString
+toBinaryString
+Vector
+Vector
+Matrix
+RotationMatrix
+ScaleMatrix
+MoveMatrix
+PerspectiveMatrix
+createFile
+List
+List
+Hashtable
+CmdArgument
+LoadSid
+LoadPicture
+LoadBinary
+asmCommandSize
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.java
new file mode 100644
index 00000000..712a040a
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.kickass;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for KICKASS.
+ *
+ * @author Peter Dell
+ */
+public final class KickAssCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public KickAssCompiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new KickAssCompilerSourceParser();
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new KickAssCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.txt b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.txt
new file mode 100644
index 00000000..803a8b0c
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.txt
@@ -0,0 +1,52 @@
+ if (title.equals(name)) {
+ int index = name.indexOf("_");
+ String opcode;
+ String addressing;
+ if (index >= 0) {
+ opcode = name.substring(0, index);
+
+ addressing = name.substring(index + 1);
+ } else {
+ index=name.length();
+ opcode = name;
+ addressing = "";
+ }
+
+ StringBuilder result = new StringBuilder("Opcode ");
+ for (int i = 0; i < index; i++) {
+ result.append("_");
+ result.append(opcode.charAt(i));
+ }
+ if (addressing.equals("ABS")) {
+ result.append(" _a_b_solute");
+ } else if (addressing.equals("ABSX")) {
+ result.append(" _a_b_solute,_x");
+ } else if (addressing.equals("ABSY")) {
+ result.append(" _a_b_solute,_y");
+ } else if (addressing.equals("IMM")) {
+ result.append(" #_i_m_mediate");
+ } else if (addressing.equals("IZPX")) {
+ result.append(" (_indirect _zero_page,_x)");
+ } else if (addressing.equals("IZPY")) {
+ result.append(" (_indirect _zero_page),_y");
+ } else if (addressing.equals("ZP")) {
+ result.append(" _zero_page");
+ } else if (addressing.equals("ZPX")) {
+ result.append(" _zero_page,_x");
+ } else if (addressing.equals("ZPY")) {
+ result.append(" _zero_page,_y");
+ }else if (addressing.equals("REL")) {
+ result.append(" _r_e_lative");
+ } else if (addressing.equals("IND")) {
+ result.append(" (_i_n_direct)");
+ } else if (addressing.equals("")) {
+ } else {
+ throw new RuntimeException(
+ "Unknown addressing mode " + addressing);
+ }
+ title = result.toString();
+ }
+ System.out.println(" ");
+ }
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.xml
new file mode 100644
index 00000000..8e82a2fc
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompiler.xml
@@ -0,0 +1,400 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompilerProcessLogParser.java
new file mode 100644
index 00000000..4a2e8f6a
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompilerProcessLogParser.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.kickass;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link KickAssCompiler}.
+ *
+ * Sample error message:
+ *
+ *
+ * Error: Unknown symbol 'unknownLabel'
+ * at line 9, column 6 in C:\Users\D025328\Documents\Eclipse\workspace.jac\com.wudsn.ide.ref\ASM\C64\KICKASS\KICKASS-Error-Reference.asm
+ *
+ *
+ * @author Peter Dell
+ */
+final class KickAssCompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private BufferedReader bufferedReader;
+
+ @Override
+ protected void initialize() {
+ bufferedReader = new BufferedReader(new StringReader(outputLog));
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ String line;
+ line = "";
+
+ while (line != null && !markerAvailable) {
+ try {
+ line = bufferedReader.readLine();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read line", ex);
+ }
+ if (line != null) {
+ String pattern;
+ int index;
+ pattern = "Error: ";
+ severity = IMarker.SEVERITY_ERROR;
+ index = line.indexOf(pattern);
+ if (index < 0) {
+ pattern = "Warning: ";
+ severity = IMarker.SEVERITY_WARNING;
+ index = line.indexOf(pattern);
+ }
+ if (index == 0) {
+
+ message = line.substring(index + pattern.length()).trim();
+ try {
+ line = bufferedReader.readLine();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read line", ex);
+ }
+ if (line != null) {
+ index = line.indexOf(',');
+ if (index > 8) {
+
+ String lineNumberString = line.substring(8,
+ index);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ } else {
+ lineNumber = -1;
+ }
+ index = line.indexOf(" in ");
+ if (index > 0) {
+ filePath = line.substring(index + 4);
+ }
+ }
+ markerAvailable = true;
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompilerSourceParser.java
new file mode 100644
index 00000000..b4e8b83f
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/kickass/KickAssCompilerSourceParser.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.kickass;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link KickAssCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class KickAssCompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ int symbolLength = symbol.length();
+ if (symbolLength > 0) {
+
+ if (symbol.charAt(symbolLength - 1) == ':') {
+ symbol = symbol.substring(0, symbolLength - 1);
+ }
+ if (instruction.equals("=")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+
+ }
+
+ } // Symbol not empty
+
+ // TODO Make .VAR an own type of instruction. Same code as in
+ // MadsCompilerSourceParser!
+ if (instruction.equals(".var")) {
+ operand = operand.trim();
+ int index = operand.indexOf('=');
+ String variable;
+ String value;
+ if (index < 0) {
+ variable = operand;
+ value = "";
+ } else {
+ variable = operand.substring(0, index).trim();
+ value = operand.substring(index).trim();
+ if (value.startsWith("=")) {
+ value = value.substring(1).trim();
+ }
+ }
+ if (value.length() > 0) {
+ createEquateDefinitionChild(startOffset, startOffset + instructionOffset, variable, value, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + instructionOffset, variable, comment);
+ }
+ }
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompiler.java
new file mode 100644
index 00000000..e13a55f7
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.mads;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for MADS.
+ *
+ * @author Peter Dell
+ */
+public final class MadsCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public MadsCompiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new MadsCompilerSourceParser();
+ }
+
+ @Override
+ public final CompilerProcessLogParser createLogParser() {
+
+ return new MadsCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompiler.xml
new file mode 100644
index 00000000..ef47be91
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompiler.xml
@@ -0,0 +1,909 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompilerProcessLogParser.java
new file mode 100644
index 00000000..7f8ed397
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompilerProcessLogParser.java
@@ -0,0 +1,228 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.mads;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+import com.wudsn.ide.asm.compiler.CompilerSymbolType;
+import com.wudsn.ide.base.common.FileUtility;
+
+/**
+ * Process log parser for {@link MadsCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class MadsCompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private BufferedReader bufferedReader;
+
+ @Override
+ protected void initialize() {
+ bufferedReader = new BufferedReader(new StringReader(outputLog));
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ String line;
+ line = "";
+
+ while (line != null && !markerAvailable) {
+ try {
+ line = bufferedReader.readLine();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read line", ex);
+ }
+ if (line != null) {
+ String pattern;
+ int index;
+ pattern = ") ERROR: ";
+ severity = IMarker.SEVERITY_ERROR;
+ index = line.indexOf(pattern);
+ if (index < 2) {
+ pattern = ") WARNING: ";
+ severity = IMarker.SEVERITY_WARNING;
+ index = line.indexOf(pattern);
+ }
+ if (index > 2) {
+
+ int i = index - 2;
+ while (line.charAt(i) != '(' && i >= 0) {
+ i--;
+ }
+
+ if (line.charAt(i) == '(') {
+ String lineNumberString = line.substring(i + 1, index);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ } else {
+ lineNumber = -1;
+ }
+ message = line.substring(index + pattern.length()).trim();
+
+ filePath = line.substring(0, i - 1);
+ markerAvailable = true;
+ }
+
+ }
+ }
+ }
+
+ /**
+ *
+ * From the MADS documentation
+ *
+ * .LAB file format
+ *
+ * As with XASM, the *.LAB file stores information about labels in the program. There are three columns:
+ * • The first column is the virtual bank number assigned to the label (if <>0).
+ * • The second column is the label value.
+ * • The third column is the label name.
+ *
+ * Virtual bank numbers with values >= $FFF9 have special meanings:
+ * • $FFF9 label for parameter in procedure defined by .PROC
+ * • $FFFA label for array defined by .ARRAY
+ * • $FFFB label for structured data defined by the pseudo-command DTA STRUCT_LABEL
+ * • $FFFC label for SpartaDOS X symbol defined by SMB
+ * • $FFFD label for macro defined by .MACRO directive
+ * • $FFFE label for structure defined by .STRUCT directive
+ * • $FFFF label for procedure defined by .PROC directive
+ *
+ *
+ * Characters with special meanings in label names:
+ * • label with two colons :: is defined in a macro
+ * • a dot ('.') separates the name of a scope (.MACRO, .PROC, .LOCAL, .STRUCT) from the field name in the scope
+ *
+ * The numeric value after :: is the number of the macro call. This is an example file:
+ *
+ * Mad-Assembler v1.4.2beta by TeBe/Madteam
+ * Label table:
+ * 00 0400 @STACK_ADDRESS
+ * 00 00FF @STACK_POINTER
+ * 00 2000 MAIN
+ * 00 2019 LOOP
+ * 00 201C LOOP::1
+ * 00 201C LHEX
+ * 00 0080 LHEX.HLP
+ * 00 204C LHEX.THEX
+ * 00 205C HEX
+ * 00 205C HEX.@GETPAR0.LOOP
+ * 00 2079 HEX.@GETPAR1.LOOP
+ *
+ */
+ @Override
+ // TODO Parser symbol type and add source tree object type for .DEFs
+ public void addCompilerSymbols(List compilerSymbols) throws CoreException {
+ if (compilerSymbols == null) {
+ throw new IllegalArgumentException("Parameter 'compilerSymbols' must not be null.");
+ }
+ String labelsFilePath = files.outputFilePathWithoutExtension + ".lab";
+ File labelsFile = new File(labelsFilePath);
+ if (labelsFile.exists()) {
+
+ String labelsFileContent = FileUtility.readString(labelsFile, FileUtility.MAX_SIZE_UNLIMITED);
+ String[] lines = labelsFileContent.split("[\\r\\n]+");
+ if (lines.length > 2 || lines[0].toLowerCase().startsWith("mads")
+ || lines[1].toLowerCase().startsWith("label table:")) {
+ for (int i = 2; i < lines.length; i++) {
+ String[] parts = lines[i].split("\\t");
+ if (parts.length == 3) {
+ int type = CompilerSymbolType.LABEL_DEFINITION;
+ String bankString = parts[0];
+
+ String name = parts[2];
+ String valueString = parts[1];
+ try {
+ long bank = Long.parseLong(bankString, 16);
+ int symbolBank;
+ if (bank >= 0 && bank < 0xfff9) {
+ symbolBank = (int) bank;
+ } else {
+ symbolBank = CompilerSymbol.UNDEFINED_BANK;
+ if (bank == 0xfff9) {
+ // Label for parameter in procedure defined
+ // by .PROC
+ // TODO: This would actually be a separate
+ // type
+ type = CompilerSymbolType.PROCEDURE_DEFINITION_SECTION;
+ } else if (bank == 0xfffa) {
+ // Label for array defined by .ARRAY
+ // TODO: This would actually be a separate
+ // type
+ type = CompilerSymbolType.LABEL_DEFINITION;
+ } else if (bank == 0xfffb) {
+ // Label for structured data defined by the
+ // pseudo-command DTA STRUCT_LABEL
+ type = CompilerSymbolType.STRUCTURE_DEFINITION_SECTION;
+ } else if (bank == 0xfffc) {
+ // Label for SpartaDOS X symbol defined by
+ // SMB
+ // TODO: This would actually be a separate
+ // type
+ type = CompilerSymbolType.LABEL_DEFINITION;
+ } else if (bank == 0xfffd) {
+ // Label for macro defined by .MACRO
+ // directive
+ // TODO: This would actually be a separate
+ // type
+ type = CompilerSymbolType.MACRO_DEFINITION_SECTION;
+ } else if (bank == 0xfffe) {
+ // Label for structure defined by .STRUCT
+ // directive
+ type = CompilerSymbolType.STRUCTURE_DEFINITION_SECTION;
+ } else if (bank == 0xffff) {
+ // Label for procedure defined by .PROC
+ // directive
+ type = CompilerSymbolType.PROCEDURE_DEFINITION_SECTION;
+ }
+ }
+ long value = Long.parseLong(valueString, 16);
+ CompilerSymbol compilerSymbol = CompilerSymbol.createNumberSymbol(type, name, symbolBank,
+ value);
+ compilerSymbols.add(compilerSymbol);
+ } catch (NumberFormatException ex) {
+ AssemblerPlugin.getInstance().logError("Cannot parse value {1} of symbol {0}.",
+ new Object[] { name, valueString }, ex);
+ }
+
+ }
+ }
+ }
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompilerSourceParser.java
new file mode 100644
index 00000000..21132606
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/mads/MadsCompilerSourceParser.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.mads;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link MadsCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class MadsCompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ if (instruction.equals("=") || instruction.equals("EQU")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+ }
+
+ } // Symbol not empty
+
+ // TODO Make .VAR an own type of instruction
+ if (instruction.equals(".VAR") || instruction.equals(".ZPVAR")) {
+ operand = operand.trim();
+ int index = operand.indexOf('=');
+ String variable;
+ String value;
+ if (index < 0) {
+ variable = operand;
+ value = "";
+ } else {
+ variable = operand.substring(0, index).trim();
+ value = operand.substring(index).trim();
+ if (value.startsWith("=")) {
+ value = value.substring(1).trim();
+ }
+ }
+ if (value.length() > 0) {
+ createEquateDefinitionChild(startOffset, startOffset + instructionOffset, variable, value, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + instructionOffset, variable, comment);
+ }
+
+ }
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32Compiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32Compiler.java
new file mode 100644
index 00000000..2084fc90
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32Compiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2016 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.merlin32;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for MERLIN32.
+ *
+ * @author Peter Dell
+ */
+public final class Merlin32Compiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public Merlin32Compiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new Merlin32CompilerSourceParser();
+ }
+
+ @Override
+ public final CompilerProcessLogParser createLogParser() {
+
+ return new Merlin32CompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32Compiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32Compiler.xml
new file mode 100644
index 00000000..6bb205de
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32Compiler.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32CompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32CompilerProcessLogParser.java
new file mode 100644
index 00000000..5baabfe4
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32CompilerProcessLogParser.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.merlin32;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link Merlin32Compiler}.
+ *
+ * @author Peter Dell
+ */
+final class Merlin32CompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private BufferedReader bufferedReader;
+
+ @Override
+ protected void initialize() {
+ bufferedReader = new BufferedReader(new StringReader(outputLog));
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ String line;
+ line = "";
+
+ while (line != null && !markerAvailable) {
+ try {
+ line = bufferedReader.readLine();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read line", ex);
+ }
+ if (line != null) {
+ String pattern;
+ int index;
+ pattern = ") ERROR: ";
+ severity = IMarker.SEVERITY_ERROR;
+ index = line.indexOf(pattern);
+ if (index < 2) {
+ pattern = ") WARNING: ";
+ severity = IMarker.SEVERITY_WARNING;
+ index = line.indexOf(pattern);
+ }
+ if (index > 2) {
+
+ int i = index - 2;
+ while (line.charAt(i) != '(' && i >= 0) {
+ i--;
+ }
+
+ if (line.charAt(i) == '(') {
+ String lineNumberString = line.substring(i + 1, index);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ } else {
+ lineNumber = -1;
+ }
+ message = line.substring(index + pattern.length()).trim();
+
+ filePath = line.substring(0, i - 1);
+ markerAvailable = true;
+ }
+
+ }
+ }
+ }
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) throws CoreException {
+ if (compilerSymbols == null) {
+ throw new IllegalArgumentException("Parameter 'compilerSymbols' must not be null.");
+ }
+// String labelsFilePath = files.outputFilePathWithoutExtension + ".lab";
+// File labelsFile = new File(labelsFilePath);
+// if (labelsFile.exists()) {
+//
+// String labelsFileContent = FileUtility.readString(labelsFile, FileUtility.MAX_SIZE_UNLIMITED);
+// String[] lines = labelsFileContent.split("[\\r\\n]+");
+// if (lines.length > 2 || lines[0].toLowerCase().startsWith("mads")
+// || lines[1].toLowerCase().startsWith("label table:")) {
+// for (int i = 2; i < lines.length; i++) {
+// String[] parts = lines[i].split("\\t");
+// if (parts.length == 3) {
+// int type = CompilerSymbolType.LABEL_DEFINITION;
+// String bankString = parts[0];
+//
+// String name = parts[2];
+// String valueString = parts[1];
+// try {
+// long bank = Long.parseLong(bankString, 16);
+// int symbolBank;
+// if (bank >= 0 && bank < 0xfff9) {
+// symbolBank = (int) bank;
+// } else {
+// symbolBank = CompilerSymbol.UNDEFINED_BANK;
+// if (bank == 0xfff9) {
+// // Label for parameter in procedure defined
+// // by .PROC
+// // TODO: This would actually be a separate
+// // type
+// type = CompilerSymbolType.PROCEDURE_DEFINITION_SECTION;
+// } else if (bank == 0xfffa) {
+// // Label for array defined by .ARRAY
+// // TODO: This would actually be a separate
+// // type
+// type = CompilerSymbolType.LABEL_DEFINITION;
+// } else if (bank == 0xfffb) {
+// // Label for structured data defined by the
+// // pseudo-command DTA STRUCT_LABEL
+// type = CompilerSymbolType.STRUCTURE_DEFINITION_SECTION;
+// } else if (bank == 0xfffc) {
+// // Label for SpartaDOS X symbol defined by
+// // SMB
+// // TODO: This would actually be a separate
+// // type
+// type = CompilerSymbolType.LABEL_DEFINITION;
+// } else if (bank == 0xfffd) {
+// // Label for macro defined by .MACRO
+// // directive
+// // TODO: This would actually be a separate
+// // type
+// type = CompilerSymbolType.MACRO_DEFINITION_SECTION;
+// } else if (bank == 0xfffe) {
+// // Label for structure defined by .STRUCT
+// // directive
+// type = CompilerSymbolType.STRUCTURE_DEFINITION_SECTION;
+// } else if (bank == 0xffff) {
+// // Label for procedure defined by .PROC
+// // directive
+// type = CompilerSymbolType.PROCEDURE_DEFINITION_SECTION;
+// }
+// }
+// long value = Long.parseLong(valueString, 16);
+// CompilerSymbol compilerSymbol = CompilerSymbol.createNumberSymbol(type, name, symbolBank,
+// value);
+// compilerSymbols.add(compilerSymbol);
+// } catch (NumberFormatException ex) {
+// AssemblerPlugin.getInstance().logError("Cannot parse value {1} of symbol {0}.",
+// new Object[] { name, valueString }, ex);
+// }
+//
+// }
+// }
+// }
+//
+// }
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32CompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32CompilerSourceParser.java
new file mode 100644
index 00000000..7e00fd21
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/merlin32/Merlin32CompilerSourceParser.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.merlin32;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link Merlin32Compiler}.
+ *
+ * @author Peter Dell
+ */
+final class Merlin32CompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ if (instruction.equals("=") || instruction.equals("EQU")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+ }
+
+ } // Symbol not empty
+
+ // TODO Implement macro and Lup handling
+// if (instruction.equals("<<<<")) {
+// endMacroDefinition();
+// } else if (instruction.equals(">>>>")) {
+// // Same as "PMC"
+// } else if (instruction.equals("--^")) {
+// endRepeatSection();
+// }
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompiler.java
new file mode 100644
index 00000000..97f95609
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompiler.java
@@ -0,0 +1,50 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.tass;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for ATASM.
+ *
+ * @author Peter Dell
+ */
+public final class TassCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public TassCompiler() {
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new TassCompilerSourceParser();
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new TassCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompiler.xml
new file mode 100644
index 00000000..6d4188ad
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompiler.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompilerProcessLogParser.java
new file mode 100644
index 00000000..cac2205c
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompilerProcessLogParser.java
@@ -0,0 +1,171 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.tass;
+
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link TassCompiler}.
+ *
+ *
+ * TODO Implement TASS Support
+ *
+ * @author Peter Dell
+ */
+final class TassCompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private Pattern pattern;
+ private String sourceFilePattern;
+
+ @Override
+ protected void initialize() {
+ pattern = Pattern.compile("In .* line ");
+ sourceFilePattern = "In " + mainSourceFilePath + ", line ";
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ int index;
+ String line;
+ boolean include;
+ String includeFile;
+ Matcher matcher = pattern.matcher(errorLog);
+
+ if (matcher.find()) {
+ index = matcher.start();
+ line = errorLog.substring(index);
+ if (line.startsWith(sourceFilePattern)) {
+ include = false;
+ includeFile = "";
+ } else {
+ include = true;
+ includeFile = line.substring(3, matcher.end() - matcher.start()
+ - 7);
+ }
+ index = matcher.end();
+ String lineNumberLine = errorLog.substring(index);
+ errorLog = lineNumberLine;
+ int numberEndIndex = lineNumberLine.indexOf("--");
+ if (numberEndIndex > 0) {
+ String lineNumberString;
+ lineNumberString = lineNumberLine.substring(0, numberEndIndex);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ int nextIndex = lineNumberLine.indexOf("\n");
+ if (index > 0) {
+ message = lineNumberLine.substring(nextIndex + 1);
+ int nextIndex2 = message.indexOf("\n");
+ if (nextIndex > 0) {
+ message = message.substring(0, nextIndex2 - 1);
+ }
+ message = message.trim();
+ }
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ }
+
+ if (message.startsWith("Error:")) {
+ severity = IMarker.SEVERITY_ERROR;
+ message = message.substring(6);
+ } else if (message.startsWith("Warning:")) {
+ severity = IMarker.SEVERITY_WARNING;
+ message = message.substring(8);
+ }
+
+ if (include) {
+ if (lineNumber >= 0) {
+ message = includeFile + " line " + lineNumber + ": "
+ + message;
+ } else {
+ message = includeFile + ": " + message;
+ }
+ lineNumber = -1;
+ }
+ message = message.trim();
+
+ // Message mapping.
+ if (severity == IMarker.SEVERITY_WARNING
+ && message.startsWith("Using bank")) {
+ severity = IMarker.SEVERITY_INFO;
+ }
+ markerAvailable = true;
+ }
+ }
+
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+ final String EQUATES = "Equates:";
+ final String SYMBOL = "Symbol";
+ final String TABLE = "table:";
+
+ String log;
+ int index;
+
+ log = outputLog;
+ index = log.indexOf(EQUATES);
+ if (index >= 0) {
+ log = log.substring(index + EQUATES.length());
+
+ StringTokenizer st = new StringTokenizer(log);
+ String token;
+ String name;
+ String hexValue;
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (token.equals(SYMBOL)) {
+ break;
+ }
+ name = token.substring(0, token.length() - 1);
+ hexValue = st.nextToken(); // Must be there
+ compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
+ }
+
+ if (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (token.equals(TABLE)) {
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (!token.endsWith(":")) {
+ break;
+ }
+ name = token.substring(0, token.length() - 1);
+ hexValue = st.nextToken(); // Must be there
+ compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
+ }
+ }
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompilerSourceParser.java
new file mode 100644
index 00000000..94188246
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/tass/TassCompilerSourceParser.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.tass;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link TassCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class TassCompilerSourceParser extends CompilerSourceParser {
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+
+ if (symbol.length() > 0) {
+
+ // Check for origin statement
+ if (symbol.equals("*")) {
+ beginImplementationSection(startOffset, startOffset + symbolOffset, operand, comment);
+
+ } else {
+ if (instruction.equals("=")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+
+ }
+ }
+
+ } // Symbol not empty
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompiler.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompiler.java
new file mode 100644
index 00000000..b6eac70e
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompiler.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.xasm;
+
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Compiler class for XASM.
+ *
+ * @author Peter Dell
+ */
+public final class XasmCompiler extends Compiler {
+
+ /**
+ * Creates a new instance.
+ */
+ public XasmCompiler() {
+
+ }
+
+ @Override
+ public CompilerSourceParser createSourceParser() {
+ return new XasmCompilerSourceParser();
+ }
+
+ @Override
+ public boolean isSuccessExitValue(int exitValue) {
+ // XASM returns 0 if there is no warning, 1 if there are only warnings,
+ // 2 if there is at least one error.
+ return exitValue == 0 || exitValue == 1;
+ }
+
+ @Override
+ public CompilerProcessLogParser createLogParser() {
+
+ return new XasmCompilerProcessLogParser();
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompiler.xml b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompiler.xml
new file mode 100644
index 00000000..14cb8415
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompiler.xml
@@ -0,0 +1,268 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompilerProcessLogParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompilerProcessLogParser.java
new file mode 100644
index 00000000..fec3ba1b
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompilerProcessLogParser.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.xasm;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
+import com.wudsn.ide.asm.compiler.CompilerSymbol;
+
+/**
+ * Process log parser for {@link XasmCompiler}. Identical to
+ * MadsCompilerProcessLogParser, except that it is based on the errorLog.
+ *
+ * @author Peter Dell
+ */
+final class XasmCompilerProcessLogParser extends CompilerProcessLogParser {
+
+ private BufferedReader bufferedReader;
+
+ @Override
+ protected void initialize() {
+ bufferedReader = new BufferedReader(new StringReader(errorLog));
+ }
+
+ @Override
+ protected void findNextMarker() {
+
+ String line;
+ line = "";
+
+ while (line != null && !markerAvailable) {
+ try {
+ line = bufferedReader.readLine();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read line", ex);
+ }
+ if (line != null) {
+ String pattern;
+ int index;
+ pattern = ") ERROR: ";
+ severity = IMarker.SEVERITY_ERROR;
+ index = line.indexOf(pattern);
+ if (index < 2) {
+ pattern = ") WARNING: ";
+ severity = IMarker.SEVERITY_WARNING;
+ index = line.indexOf(pattern);
+ }
+ if (index > 2) {
+
+ int i = index - 2;
+ while (line.charAt(i) != '(' && i >= 0) {
+ i--;
+ }
+
+ if (line.charAt(i) == '(') {
+ String lineNumberString = line.substring(i + 1, index);
+
+ try {
+ lineNumber = Integer.parseInt(lineNumberString);
+ } catch (NumberFormatException ex) {
+ lineNumber = -1;
+ severity = IMarker.SEVERITY_ERROR;
+ message = ex.getMessage();
+ }
+ } else {
+ lineNumber = -1;
+ }
+ message = line.substring(index + pattern.length()).trim();
+ filePath = line.substring(0, i - 1);
+ markerAvailable = true;
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public void addCompilerSymbols(List compilerSymbols) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompilerSourceParser.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompilerSourceParser.java
new file mode 100644
index 00000000..1aacc209
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/compiler/xasm/XasmCompilerSourceParser.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.xasm;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Source parser for {@link XasmCompiler}.
+ *
+ * @author Peter Dell
+ */
+final class XasmCompilerSourceParser extends CompilerSourceParser {
+
+ /**
+ * Creation is package local.
+ */
+ XasmCompilerSourceParser() {
+
+ }
+
+ @Override
+ protected void parseLine(int startOffset, String symbol, int symbolOffset, String instruction,
+ int instructionOffset, String operand, String comment) {
+ if (symbol.length() > 0) {
+
+ if (instruction.equals("EQU")) {
+ createEquateDefinitionChild(startOffset, startOffset + symbolOffset, symbol, operand, comment);
+
+ } else {
+ createLabelDefinitionChild(startOffset, startOffset + symbolOffset, symbol, comment);
+ }
+
+ } // Symbol not empty
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/acme/AcmeEditor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/acme/AcmeEditor.java
new file mode 100644
index 00000000..7e03eab7
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/acme/AcmeEditor.java
@@ -0,0 +1,37 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.acme;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class AcmeEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public AcmeEditor() {
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.ACME;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/asm6/Asm6Editor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/asm6/Asm6Editor.java
new file mode 100644
index 00000000..525506ea
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/asm6/Asm6Editor.java
@@ -0,0 +1,37 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.asm6;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class Asm6Editor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public Asm6Editor() {
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.ASM6;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/atasm/AtasmEditor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/atasm/AtasmEditor.java
new file mode 100644
index 00000000..d89fb2b5
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/atasm/AtasmEditor.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.atasm;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class AtasmEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public AtasmEditor() {
+ }
+
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.ATASM;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/dasm/DasmEditor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/dasm/DasmEditor.java
new file mode 100644
index 00000000..de597fc6
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/dasm/DasmEditor.java
@@ -0,0 +1,37 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.dasm;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class DasmEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public DasmEditor() {
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.DASM;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/kickass/KickAssEditor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/kickass/KickAssEditor.java
new file mode 100644
index 00000000..f5edf71c
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/kickass/KickAssEditor.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.kickass;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class KickAssEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public KickAssEditor() {
+
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.KICKASS;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/mads/MadsEditor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/mads/MadsEditor.java
new file mode 100644
index 00000000..006cfa3a
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/mads/MadsEditor.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.mads;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class MadsEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public MadsEditor() {
+
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.MADS;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/merlin32/Merlin32Editor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/merlin32/Merlin32Editor.java
new file mode 100644
index 00000000..5b693050
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/merlin32/Merlin32Editor.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.merlin32;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class Merlin32Editor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public Merlin32Editor() {
+
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.MERLIN32;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/tass/TassEditor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/tass/TassEditor.java
new file mode 100644
index 00000000..9a12756d
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/tass/TassEditor.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.tass;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class TassEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public TassEditor() {
+
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.TASS;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/xasm/XasmEditor.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/xasm/XasmEditor.java
new file mode 100644
index 00000000..1e713dfe
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/editor/xasm/XasmEditor.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor.xasm;
+
+import com.wudsn.ide.asm.compiler.CompilerId;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+public final class XasmEditor extends AssemblerEditor {
+
+ /**
+ * Creation is public. Called by the extension "org.eclipse.ui.editors".
+ */
+ public XasmEditor() {
+
+ }
+
+ @Override
+ public String getCompilerId() {
+ return CompilerId.XASM;
+ }
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesApple2CompilersPage.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesApple2CompilersPage.java
new file mode 100644
index 00000000..b57f5e55
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesApple2CompilersPage.java
@@ -0,0 +1,42 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.preferences;
+
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesCompilersPage;
+
+/**
+ * Visual editor page for the assembler preferences regarding Apple 2 compilers.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerPreferencesApple2CompilersPage extends
+ AssemblerPreferencesCompilersPage {
+
+ /**
+ * Create is public. Used by extension point
+ * "org.eclipse.ui.preferencePages".
+ */
+ public AssemblerPreferencesApple2CompilersPage() {
+ super(Hardware.APPLE2);
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari2600CompilersPage.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari2600CompilersPage.java
new file mode 100644
index 00000000..df0a6dcb
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari2600CompilersPage.java
@@ -0,0 +1,42 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.preferences;
+
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesCompilersPage;
+
+/**
+ * Visual editor page for the assembler preferences regarding Apple 2 compilers.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerPreferencesAtari2600CompilersPage extends
+ AssemblerPreferencesCompilersPage {
+
+ /**
+ * Create is public. Used by extension point
+ * "org.eclipse.ui.preferencePages".
+ */
+ public AssemblerPreferencesAtari2600CompilersPage() {
+ super(Hardware.ATARI2600);
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari7800CompilersPage.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari7800CompilersPage.java
new file mode 100644
index 00000000..190d8f7e
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari7800CompilersPage.java
@@ -0,0 +1,42 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.preferences;
+
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesCompilersPage;
+
+/**
+ * Visual editor page for the assembler preferences regarding Apple 2 compilers.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerPreferencesAtari7800CompilersPage extends
+ AssemblerPreferencesCompilersPage {
+
+ /**
+ * Create is public. Used by extension point
+ * "org.eclipse.ui.preferencePages".
+ */
+ public AssemblerPreferencesAtari7800CompilersPage() {
+ super(Hardware.ATARI7800);
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari8CompilersPage.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari8CompilersPage.java
new file mode 100644
index 00000000..9d207e4b
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesAtari8CompilersPage.java
@@ -0,0 +1,43 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.preferences;
+
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesCompilersPage;
+
+/**
+ * Visual editor page for the assembler preferences regarding Atari 8-bit
+ * compilers.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerPreferencesAtari8CompilersPage extends
+ AssemblerPreferencesCompilersPage {
+
+ /**
+ * Create is public. Used by extension point
+ * "org.eclipse.ui.preferencePages".
+ */
+ public AssemblerPreferencesAtari8CompilersPage() {
+ super(Hardware.ATARI8BIT);
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesC64CompilersPage.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesC64CompilersPage.java
new file mode 100644
index 00000000..71396673
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesC64CompilersPage.java
@@ -0,0 +1,42 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.preferences;
+
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesCompilersPage;
+
+/**
+ * Visual editor page for the assembler preferences regarding C64 compilers.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerPreferencesC64CompilersPage extends
+ AssemblerPreferencesCompilersPage {
+
+ /**
+ * Create is public. Used by extension point
+ * "org.eclipse.ui.preferencePages".
+ */
+ public AssemblerPreferencesC64CompilersPage() {
+ super(Hardware.C64);
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesNESCompilersPage.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesNESCompilersPage.java
new file mode 100644
index 00000000..7cf380d8
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/preferences/AssemblerPreferencesNESCompilersPage.java
@@ -0,0 +1,42 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.preferences;
+
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesCompilersPage;
+
+/**
+ * Visual editor page for the assembler preferences regarding NES compilers.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerPreferencesNESCompilersPage extends
+ AssemblerPreferencesCompilersPage {
+
+ /**
+ * Create is public. Used by extension point
+ * "org.eclipse.ui.preferencePages".
+ */
+ public AssemblerPreferencesNESCompilersPage() {
+ super(Hardware.NES);
+
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/runner/atari8/Altirra.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/runner/atari8/Altirra.java
new file mode 100644
index 00000000..fbcf910b
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/runner/atari8/Altirra.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.runner.atari8;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+import com.wudsn.ide.asm.compiler.CompilerFiles;
+import com.wudsn.ide.asm.editor.AssemblerBreakpoint;
+import com.wudsn.ide.asm.runner.Runner;
+
+/**
+ * Runner for Altirra 2.0 and above which support source line breakpoints.
+ *
+ * @author Peter Dell
+ * @since 1.6.1
+ */
+public final class Altirra extends Runner {
+
+ @Override
+ public File createBreakpointsFile(CompilerFiles files) {
+ if (files == null) {
+ throw new IllegalArgumentException("Parameter 'files' must not be null.");
+ }
+ return new File(files.outputFilePathWithoutExtension + ".atdbg");
+ }
+
+ @Override
+ public int createBreakpointsFileContent(AssemblerBreakpoint[] breakpoints, StringBuilder breakpointBuilder) {
+ if (breakpoints == null) {
+ throw new IllegalArgumentException("Parameter 'breakpoints' must not be null.");
+ }
+ int activeBreakpoints = 0;
+ breakpointBuilder.append(".sourcemode on\n");
+ breakpointBuilder.append(".echo\n");
+ breakpointBuilder.append(".echo \"Loading executable...\"\n");
+ breakpointBuilder.append(".echo\n");
+ breakpointBuilder.append("bc *\n");
+ breakpointBuilder.append(".onexerun .echo \"Launching executable...\"\n");
+ for (IBreakpoint breakpoint : breakpoints) {
+ try {
+ if (breakpoint.isEnabled()) {
+ AssemblerBreakpoint assemberBreakpoint = (AssemblerBreakpoint) breakpoint;
+ IMarker marker = breakpoint.getMarker();
+ String sourceFilePath = marker.getResource().getLocation().toOSString();
+ breakpointBuilder
+ .append("bp \"`" + sourceFilePath + ":" + assemberBreakpoint.getLineNumber() + "`\"\n");
+ activeBreakpoints++;
+ }
+ } catch (CoreException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ }
+ return activeBreakpoints;
+ }
+
+}
diff --git a/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/runner/atari8/Atari800Win.java b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/runner/atari8/Atari800Win.java
new file mode 100644
index 00000000..690b0c71
--- /dev/null
+++ b/com.wudsn.ide.asm.compilers/src/com/wudsn/ide/asm/runner/atari8/Atari800Win.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.runner.atari8;
+
+import com.wudsn.ide.asm.runner.Runner;
+
+/**
+ * Runner for Atar800Win.
+ *
+ * @author Peter Dell
+ * @since 1.7.0.
+ */
+public final class Atari800Win extends Runner {
+
+}
diff --git a/com.wudsn.ide.asm/.classpath b/com.wudsn.ide.asm/.classpath
new file mode 100644
index 00000000..8a8f1668
--- /dev/null
+++ b/com.wudsn.ide.asm/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/.project b/com.wudsn.ide.asm/.project
new file mode 100644
index 00000000..b53cba16
--- /dev/null
+++ b/com.wudsn.ide.asm/.project
@@ -0,0 +1,28 @@
+
+
+ com.wudsn.ide.asm
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/com.wudsn.ide.asm/.settings/org.eclipse.core.resources.prefs b/com.wudsn.ide.asm/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000..e0a59bd1
--- /dev/null
+++ b/com.wudsn.ide.asm/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+#Thu Jun 28 19:08:33 CEST 2012
+eclipse.preferences.version=1
+encoding//help/create-links.bat=ISO-8859-1
+encoding/help=UTF-8
diff --git a/com.wudsn.ide.asm/.settings/org.eclipse.jdt.core.prefs b/com.wudsn.ide.asm/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..54e493c0
--- /dev/null
+++ b/com.wudsn.ide.asm/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/com.wudsn.ide.asm/.settings/org.eclipse.jdt.ui.prefs b/com.wudsn.ide.asm/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000..9985b1d5
--- /dev/null
+++ b/com.wudsn.ide.asm/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,4 @@
+#Wed Feb 08 19:13:41 CET 2006
+eclipse.preferences.version=1
+internal.default.compliance=default
+org.eclipse.jdt.ui.text.custom_code_templates=
diff --git a/com.wudsn.ide.asm/META-INF/MANIFEST.MF b/com.wudsn.ide.asm/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..0ce7ce4d
--- /dev/null
+++ b/com.wudsn.ide.asm/META-INF/MANIFEST.MF
@@ -0,0 +1,81 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: WUDSN IDE Assembler Plug-in
+Bundle-SymbolicName: com.wudsn.ide.asm;singleton:=true
+Bundle-Version: 1.7.0.qualifier
+Bundle-Activator: com.wudsn.ide.asm.AssemblerPlugin
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.core.runtime;visibility:=reexport,
+ org.eclipse.core.resources;visibility:=reexport,
+ org.eclipse.core.filesystem,
+ org.eclipse.jface.text;visibility:=reexport,
+ org.eclipse.ui;visibility:=reexport,
+ org.eclipse.ui.console,
+ org.eclipse.ui.editors;visibility:=reexport,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.ui.views,
+ org.eclipse.e4.ui.di;bundle-version="1.0.0",
+ org.eclipse.e4.ui.model.workbench;bundle-version="1.0.1",
+ org.eclipse.help,
+ com.wudsn.ide.base;visibility:=reexport,
+ com.wudsn.ide.dsk,
+ com.wudsn.ide.gfx,
+ org.eclipse.debug.core;visibility:=reexport,
+ org.eclipse.debug.ui;visibility:=reexport,
+ org.eclipse.ui.workbench
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: Peter Dell
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: com.wudsn.ide.asm;
+ uses:="org.eclipse.osgi.util,
+ org.eclipse.core.runtime,
+ com.wudsn.ide.base.common,
+ org.osgi.framework,
+ com.wudsn.ide.asm.runner,
+ com.wudsn.ide.asm.preferences,
+ com.wudsn.ide.asm.compiler",
+ com.wudsn.ide.asm.compiler;
+ uses:="org.eclipse.jface.text,
+ org.eclipse.ui.console,
+ org.eclipse.jface.viewers,
+ com.wudsn.ide.asm,
+ org.eclipse.jface.text.rules",
+ com.wudsn.ide.asm.compiler.parser,
+ com.wudsn.ide.asm.editor;
+ uses:="org.eclipse.jface.text,
+ org.eclipse.core.runtime,
+ org.eclipse.core.commands,
+ org.eclipse.jface.text.rules,
+ org.eclipse.debug.core.model,
+ org.eclipse.jface.action,
+ org.eclipse.ui.views.contentoutline,
+ org.eclipse.core.resources,
+ org.eclipse.jface.viewers,
+ com.wudsn.ide.asm,
+ com.wudsn.ide.asm.compiler,
+ com.wudsn.ide.asm.preferences,
+ org.eclipse.jface.text.hyperlink,
+ org.eclipse.ui.texteditor,
+ org.eclipse.jface.text.reconciler,
+ org.eclipse.jface.text.source,
+ org.eclipse.jface.resource,
+ org.eclipse.ui,
+ org.eclipse.jface.text.contentassist,
+ org.eclipse.debug.ui.actions,
+ org.eclipse.jface.preference,
+ org.eclipse.jface.text.presentation,
+ org.eclipse.swt.graphics,
+ org.eclipse.jface.util,
+ org.eclipse.swt.widgets,
+ org.eclipse.ui.editors.text",
+ com.wudsn.ide.asm.preferences;
+ uses:="org.eclipse.jface.text,
+ org.eclipse.jface.preference,
+ org.eclipse.ui,
+ org.eclipse.swt.graphics,
+ org.eclipse.jface.viewers,
+ com.wudsn.ide.asm,
+ org.eclipse.core.runtime.preferences,
+ org.eclipse.swt.widgets",
+ com.wudsn.ide.asm.runner;uses:="com.wudsn.ide.asm"
diff --git a/com.wudsn.ide.asm/WUDSN-IDE (de).launch b/com.wudsn.ide.asm/WUDSN-IDE (de).launch
new file mode 100644
index 00000000..481beba3
--- /dev/null
+++ b/com.wudsn.ide.asm/WUDSN-IDE (de).launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/WUDSN-IDE (pl).launch b/com.wudsn.ide.asm/WUDSN-IDE (pl).launch
new file mode 100644
index 00000000..a6360938
--- /dev/null
+++ b/com.wudsn.ide.asm/WUDSN-IDE (pl).launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/WUDSN-IDE.launch b/com.wudsn.ide.asm/WUDSN-IDE.launch
new file mode 100644
index 00000000..66779f82
--- /dev/null
+++ b/com.wudsn.ide.asm/WUDSN-IDE.launch
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/bin/.gitignore b/com.wudsn.ide.asm/bin/.gitignore
new file mode 100644
index 00000000..43e58b99
--- /dev/null
+++ b/com.wudsn.ide.asm/bin/.gitignore
@@ -0,0 +1 @@
+/com
diff --git a/com.wudsn.ide.asm/build.properties b/com.wudsn.ide.asm/build.properties
new file mode 100644
index 00000000..21624a63
--- /dev/null
+++ b/com.wudsn.ide.asm/build.properties
@@ -0,0 +1,16 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin.properties,\
+ icons/,\
+ help/,\
+ src/,\
+ plugin_de_DE.properties,\
+ build.properties,\
+ .classpath,\
+ .project,\
+ schema/
+bin.excludes = help/productions/java/ide/downloads/
+
diff --git a/com.wudsn.ide.asm/help/create-links.bat b/com.wudsn.ide.asm/help/create-links.bat
new file mode 100644
index 00000000..2711a1d8
--- /dev/null
+++ b/com.wudsn.ide.asm/help/create-links.bat
@@ -0,0 +1,21 @@
+echo off
+rem
+rem The image and file resource files for the IDE help are original in the "site\productions\java\ide" folder.
+rem The are linked into the "com.wudsn.ide.asm/help/productions/java/ide project" folder via a symbolic link.
+rem This way, the Eclipse build uses the latest versions automatically.
+rem The HTML files for the online help are original in the com.wudsn.ide.asm/help" folder.
+rem They have to be copied into the Joomla using the "export.bat" script when something is changed.
+rem
+rem Important: Run this script in an Administrator shell.
+rem
+
+echo on
+setlocal
+set WORKSPACE=C:\jac\system\Java\Programming\Workspaces\WUDSN-IDE
+set SITE=C:\jac\system\WWW\Sites\www.wudsn.com
+set SYMBOLIC_LINK=%WORKSPACE%\com.wudsn.ide.asm\help\productions\java\ide
+set REAL_FOLDER=%SITE%\productions\java\ide
+echo on
+rmdir %SYMBOLIC_LINK%
+mklink /D %SYMBOLIC_LINK% %REAL_FOLDER%
+pause
diff --git a/com.wudsn.ide.asm/help/ide-credits.section.html b/com.wudsn.ide.asm/help/ide-credits.section.html
new file mode 100644
index 00000000..c7aa0923
--- /dev/null
+++ b/com.wudsn.ide.asm/help/ide-credits.section.html
@@ -0,0 +1,204 @@
+
+A project like WUDSN IDE is not possible and not worth anything without the contributions provided by others. So here's
+the list of credits of all involved people and related projects.
+
+
diff --git a/com.wudsn.ide.asm/help/ide-faq.section.html b/com.wudsn.ide.asm/help/ide-faq.section.html
new file mode 100644
index 00000000..f48f1653
--- /dev/null
+++ b/com.wudsn.ide.asm/help/ide-faq.section.html
@@ -0,0 +1,500 @@
+
+Here you can find the answers to some frequently asked questions. If your question is not answered here, please have a look at
+the video tutorials or contact me.
+
+ If you are not familiar with Eclipse at all, make sure that you have installed the
+ Eclipse platform distribution
+ only - without Java or J2EE tools. This distribution is much smaller (normally around 50-70 MB instead of 170 MD) and will not
+ confuse you with tons of features and buttons you do not need at all. See the section "Installing Eclipse" on the tab
+ "Installation" for the required steps. If you use Windows, you can use one of the zero installation distributions of WUDSN IDE
+ which are linked on the tab "Installation". They are simply ".zip" archives that already contain Eclipse and everything else."
+
+
+
+
When I try to start Eclipse is get an error like "Failed to load the JNI shared library 'C:\Program Files
+ (x86)\Java\jre6\bin\client\jvm.dll'". What is wrong?
+
+
The Eclipse version and the Java version on your system are not compatible. The Eclipse is not pure Java, but uses platform
+ specific native libraries to run and debug Java efficiently. For example you must install the 64-bit version Java (JRE or JDK)
+ if you want to use the 64-bit version of the Eclipse. This is a frequent issue under Windows 7, because be default there is
+ only the 32-bit version of Java installed. See the section "Installing Eclipse" on the tab "Installation" for the required
+ steps.
+
+
+
+
How to I use Eclipse at all?
+
Start the build-in help of Eclipse via the menu "Help/Help Content" and read the section "Workbench User Guide".
+
+
+
+
+
Why is WUDSN IDE not available via the update site?
+
Most likely you typed in the wrong update site URL, for example using "wusdn" instead of "wudsn". The correct URL is
+ "http://www.wudsn.com/update". In addition you should disable the checkbox "Hide items that are already installed", so you see
+ what really is there. See the section "Installing WUDSN IDE" the tab "Installation" for the required steps.
+
+
+
+
+
Why do I get "Unable to read repository at ... Read timed out" when accessing the update site?
+
This error message indicates the the Eclipse program is somehow blocked from accessing the site. If you are behind a proxy
+ server, check the general proxy server setttings in the Eclipse preferences. If you use a firewall or internet security tool,
+ make sure "Eclipse.exe", "java.exe", "javaw.exe" or the corresponding program on your host platform are allowed to cannot to
+ the internet. Maybe you have to change the settings, so you are prompted to allow access interactively.
+
+
+
+
Why is the "Assembler" section not visible in the preferences?
+
+ If the WUDSN IDE specific sections and features are not visible after a successful installation, you are probably using an
+ outdated Java version. For example Java 1.6 is
+ out of maintenance since 2013/02
+ . This seems to be a common problem on Mac OS X even in Mavericks (10.9), which still uses Java 1.6 by default. Make sure you
+ have at least the Java version that is mentioned in the installation section for the IDE installed and that Eclipse is
+ actually started using that version.
+
+
+
Configuration
+
+
Why do I see wrong messages in the "Problems" view?
+
The default configuration of the "Problems" view show all error from all files in the current project. While this is a good
+ default for Java programming, it does not fit at all for compiling single independent assembler files. Therefore you have to
+ configure the "Problems" view accordingly. See the section "Installing Eclipse" on the tab "Installation" for the required
+ steps.
+
+
+
+
How to I associate my source file extensions with the correct editor?
+
+ The IDE support many different compilers and provides a specialized editor for each of them. Typically you have some preferred
+ source file extension (".asm" or ".a") and a preferred compiler. The procedure to associate the file extension with the editor
+ via the preferences is described in this video tutorial
+ WUDSN IDE Tutorial 3: Setting up Editors and File Extensions correctly
+ .
+
+
+
+
Why do I have to put ;@com.wudsn.ide.asm.hardware=...in the source file?
+
The association with the file extension with the editor for your compiler (that is done in the preferences, see before)
+ does not determine for which platform you want to create output. Therefore this additional annotation in the main source file
+ is required used to tell the IDE which is the target platform. It is used to fine the correct compiler and emulator setting,
+ which can be different per platform. Every compiler has a default platform (see the online help in the IDE) but can also be
+ used to every other platform. Therefore you have to specify the target platform in the main source file, if you use a
+ non-default platform.
+
+
+
Editing
+
+
Why is editing sometimes slow or even everything is blocked showing the wait cursor?
+
The core of WUDSN IDE uses the Eclipse Platform Runtime only and does not require any additional plugins. It starts and runs
+ very fast with that configuration and I personally used it one daily basis. So if you experience performance problems, try to
+ download and run the zero installation distribution of WUDSN IDE. Performance problem they are very likely caused by
+ additional plugins or themes installed. Often these plugins are not only slow, but broken. Check the ".metadata/.log" file in
+ the workspace folder. In some Eclipse versions, this is also available via "Window/Show View.../Error Log".
+
+
+
+
Is there support for source version control?
+
Yes, there are several plugins available to connect Eclipse to CVS or subversion. Also the "Local History" feature is
+ installed by default. You can configure it in the preferences. It automatically records all changes to the source file and
+ let's you compare versions in-place.
+
+
+
+
+
Is there support for block selection mode?
+
Yes, there is a toolbar button and the shortcut "ALT+SHIFT+A" to toggle block selection mode in all text editors. This can
+ be very useful for adding and removing common prefixes such as line numbers.
+
+
+
In case the toolbar button is not visible, you have to set it to visible via the menu entry "Customize Perspective" in the
+ context menu of the main toolbar. In the customizing dialog you have to activate the commend group "Editor Presentation" and
+ then the toolbar entries you want to see.
+
+
+
+
+
Why does CTRL-Space not open content assist?
+
There is a known key conflict when using Messenger Plus Live! v4.85.0.386 with Microsoft Messenger 2009 on Windows 7
+ Ultimate. This may also occur in other version of course. Justin Payne has provided the following description of the solution.
+
+
+
Start up and log into MS Messenger.
+
From the main window, hit the ALT key to bring up the main menu and select "Plus! | Preferences & Options".
+
+
From the Preferences Windows, Select the Messenger tab and uncheck "Activate Messenger Lock with a system-wide shortcut"
+ OR change the value in it's text box to something other than "CTRL + Space"
+
+
Select OK button.
+
+
+
Why do CTRL-SHIFT-0/9 and other key combinations not work?
+
You probably have another program outside of Eclipse that has already captured these keys or key combinations. A frequent
+ problem is the Windows Input Methods Editor (IME) which is used to switch keyboard layouts. For example if you are using
+ multiple keyboard layouts, the CTRL-Space is mapped to allow you to cycle between the different keyboard regional layouts.
+ You should probably be aware of how to turn the feature off since you're probably using this features, but if you don't...
+
+
Windows 7
+
+
Within "Windows Control Panel", open "Region and Settings".
+
Select the "Keyboard and Languages" tab, select "Change Keyboards...".
+
In the "Text Services and Input Languages" windows, select "Advanced Key Settings".
+
In the "Hot Keys for input languages" list box, select "Between input languages" and then select "Change Key Sequence..."
+
+
In the "Change Key Sequence" window, choose another radio button other than the one next to CTRL+Shift. At best you
+ choose "(None)".
+
+
Click OK until you closed all popup windows.
+
+
Windows 10
+
+
Open "Control Panel\Clock, Language, and Region\Language\Advanced settings.
+
Click "Change Language bar hot keys".
+
Set all key sequences to "(None)".
+
Click OK until you closed all popup windows.
+
+
+ Of course, this is Windows 7/10 and we know how Microsoft loves to change their layouts and names, but for fact this option
+ is available back to Windows XP.
+
+
+
+
+
Compiling
+
+
Why is MADS the primary compiler?
+
When I started with WUDSN IDE, ATASM was the first supported compiler. The reason was simple: 90% of my sources are in
+ ATASM format. ATASM is very comprehensive and fast. Its capabilities to define constants an byte sequence is very complete
+ (".BYTE", ".WORD", ".DBYTE", ".FLOAT", ."SBYTE" for ATASCII, ".CBYTE" for terminated strings, separate offset for all
+ constants). Over time additional platform compilers haven been added and support for them will be completed step by step.
+ When the support for MADS was rather complete, I found that it is the most powerful compiler I have ever seen and used. The
+ support for ".PROC/.ENDPROC" has revolutionized the way I write assembler code now. It allows logical structuring and
+ visibility control without any runtime overhead. At the same time MADS is compatible to MAC/65 and XASM and even ATASM
+ sources can be adapted to MADS with a few minor changes described below. Therefore MADS is the primary compiler since WUDSN
+ IDE version 1.6.0.
+
+
+
+
Why do I get the error "No ORG defined" when compiling the example from the tutorial?
+
Since WUDSN IDE version 1.6.0 MADS is the primary compiler which is registered for the file extensions ".asm" upon
+ installation. You are trying to run the code example for version 1.5.0 or before, which is in ATASM format. Therefore you can
+ either
+
Why are the errors and warnings from an include file assigned to the main source file in the problems view?
+
You use a case-insensitive file system and have used different upper or lower case writing in the source include statement
+ than in the actual file system. For example you have written "ICL 'example.asm'" for a file named "Example.asm" on the file
+ system. In Eclipse the file names of all resources are treated as case-sensitive, even if the underlying file system is
+ case-insensitive. Therefore the file name issued by the compiler will no match with the file name of the source include. As a
+ fall-back, the IDE assigns the error message to the main source file. To fix this, you have to adapt the spelling of the file
+ name in the source include statement.
+
+
+
+
How to I convert an ATASM source for to MADS format?
+
Because both ATASM and MADS syntax are based on the MAC/65 syntax, there are not really many differences. Therefore manual
+ conversion using "Find/Replace (CTRL-F)" is very easy.
+
+
+
Replace the origin definition "* = address" by "ORG address".
+
Replace ".INCLUDE" by "ICL" for source includes.
+
Replace ".INCBIN" by "INS" for binary includes.
+
Replace "* = $2E0;.WORD address" by "RUN address" to specify the run address.
+
Replace "* = $2E2;.WORD address" by "INI address" to specify the init address.
+
Check the quotes of ".BYTE" and "DTA" statements. In MADS, single quotes result in ASCII codes, double quotes in ATARI
+ screen codes.
+
+
Remove all ".BANK" statements. While ATASM sorts and merges all segments within one bank statement, MADS simply uses the
+ order of segments as defined in the source file. Every "ORG" statement automatically generates new file segment.
+
+
+
+
+
How does ATASM generate segments in executable files?
+
A helpful feature for small projects is that by default ATASM sorts the segments by address and warns if the same address
+ is overwritten by code or data. Since version 1.05 the ".BANK" directive is available, which allows you to create COM files
+ with "INITAD" segments and arbitrary segment counts. If you don't use the ".BANK" directive, ATASM will sort the segments by
+ their address and will put consecutive blocks into a single segment by default. While this saves some bytes, it might be
+ confusing if you are used to other assemblers. Note that you have to use the ".SET 6" directive to set the assembler origin
+ offset in every bank if you use it in one of the banks.
+
Plain ROM Images do not have header bytes by default, or at least they do not have the same header bytes as executable
+ files. In order to create raw object files without headers, compiler specific options have to be used. Some cases are listed
+ below. See the manual of the specific compiler for more details.
+
+
+
+ ACME: Use the compiler parameter "
+ -f plain
+ " instead of "-f cbm" (default) to switch to "plain" mode without header
+
+
+ ATASM: Extend the compiler parameter "-o${outputFilePath}" to "
+ -r
+ -o${outputFilePath}" to switch to "raw" mode without header
+
+
+ MADS: Use "
+ OPT h-f+
+ " at the very beginning of the source file disables header and enabled "fill" mode, i.e. no segments are created if there
+ are gaps in the object code
+
+
+
+
+
How do I compile into disk images?
+
Atari 8-bit
+
+ For Atari 8-bit, the ATASM compiler has dedicated parameter to write the executable file directly into ".ATR" or ".XFD" disk
+ images. The disk image must be formatted with Atari DOS 2.0S, Atari DOS DOS 2.5 or a compatible DOS. All Atari 8-bit disk
+ formats can be created using the "dir2atr.exe" tool of the
+ AtariSIO tools
+ by Matthias Reichl (hias). The tool can create a complete disk image with arbitrary DOS (Atari DOS 2.5, MyDos, SpartaDOS) and
+ size based on a folder which contains "DOS.SYS", "DUP.SYS" (or the equivalent files of the respective DOS) and all other
+ files requires. I have packaged an example including the "dir2atr" tool, a batch script to call the tool and the emulator and
+ the "files" folder in this
+ archive
+ . Unpack the archive to your output folder. Double-click "makefile.bat" to see how the disk image is created and started.
+ Read section
+ How to run a makefile script instead of an emulator?
+ for the details how to configure the call to "makefile.bat". For productive usage you should of course put the "hias" folder
+ into a central location and use the most recent version from hias' site. For MacOS X users, the download also contains a
+ "makefile.sh" script and MacOS X binaries of Matthias Reichl's tools. The binaries have been provided by Fredrick Holst
+ (freetz) and you can find the latest versions on his
+ web site
+ .
+
+
Apple II
+
+ For Apple II, WUDSN IDE automatically generates a bootable AppleDos 3.3 disk image with extension ".dsk" if one of the
+ predefined emulators is used for execution. If you want to use another DOS or disk size or if you want to but more files into
+ the disk after compilation, you can use the command line version of
+ AppleCommander
+ to achieve this. Create a makefile script and configured it as described in
+ How to run a makefile script instead of an emulator?
+ . In case of Apple Disk images always remember using the correct the file content/load/run address. The IDE needs to know the
+ load address of an executable file in order to store this information in the directory entry. To detect the load address from
+ the executable file, the IDE evaluate the file extension. Supported extensions are ".b", ".prg" and ".xex". Here's the logic
+ begin the built in disk image creation:
+
+ If you find a tool similar to "dir2atr.exe" for the Atari 8-bit or "AppleCommander" for the Apple II, you can use create your
+ own script an run it as described in
+ How to run a makefile script instead of an emulator?
+ .
+
+
+
+
How can I run a makefile or script instead of an emulator?
+
+ Sometimes it is useful to run a makefile script instead of the emulator, for example if the output file shall be combined
+ with other files into a single ATR file. To execute a such a script select "User Defined Application" as the "Default
+ Application to open Output File". Specify the path to the shell as "Path to Application". In the command line you can then
+ use the standard variables to start the shell, pass the name of the script and pass the file path of the compiled output
+ file. Since the working directory at the time of execution is the output folder of the compiler you must place the script
+ file there or you must specify the script file with its absolute path. If you are using Windows and "cmd.exe" as shell, you
+ must specify "/c" before the name of the script to prevent "cmd.exe" from remaining as process after the script has finished.
+ The resulting command line is "${runnerExecutablePath} /c makefile.bat ${outputFilePath}", assuming "makefile.bat" is located
+ in the output folder". See
+ How do I compile into disk images?
+ for the example how to use this for compiling complete disk images.
+
+
+
+
Emulation
+
+
How can I use other emulators?
+
You can "re-use" the existing tabs and simply specify another emulators' executable. If you use "User Defined
+ Application", you can specify whatever you want. When using "User Defined Application", no disk image is created or updated.
+ You can use this setting to have you own script which put the executable file onto a disk image of your choice using
+ additional tools like "dir2atr.exe" or "AppleCommander" for example.
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/help/ide-features.section.html b/com.wudsn.ide.asm/help/ide-features.section.html
new file mode 100644
index 00000000..734aa16e
--- /dev/null
+++ b/com.wudsn.ide.asm/help/ide-features.section.html
@@ -0,0 +1,1014 @@
+
+The latest version contains the following features:
+
+
+ The Eclipse platform contains editors like for example the generic text editor. Editors can support one or more
+ content types identified by file extensions. One editor can be the default for a specific file extension. WUDSN IDE
+ provides an assembler
+ editor and a corresponding content type for every compiler. Every assembler
+ editor has a default compiler associated which in turn defines via the preferences which application is used to run the
+ output file.
+
+
+
+
+ New content types and file associations for Atari 2600 compilers
+
+
DASM Source File (*.asm)
+
+
+
+ New content types and file associations for Atari 8-bit compilers
+
+
ATASM Source File (*.asm)
+
MADS Source File (*.asm, default)
+
XASM Source File (*.asx, default)
+
+
+
+ New content types and file associations for C64 compilers
+
+
ACME Source File (*.a, default)
+
+
+
+ New content types and file associations for NES compilers
+
+
ASM6 Source File (*.asm)
+
+
+
+ The default editor for an extension can be configured in section "File Associations" of the preferences with the
+ button "Default"
+
+
+
+
Syntax highlighting colors and styles for comments, directives, all types of identifiers, legal opcodes, illegal
+ opcodes, pseudo opcodes and strings
+
+
Single line comments for the current line selection can be toggled using "CTRL-7" or the editor context menu entry
+ "Toggle Comment"
+
+ Adding support for new compilers and application is possible via Eclipse extension points
+
+
+
+
Compile or compile and run with a single key stroke or via menu
+
Toolbar button for "Compile and Run" which adapts to the hardware of the currently opened editor, for example it
+ will show a C64 icon when using the "ACME (C64)" editor
+
+
+ The toolbar button for "Compile and Run" offers a pulldown menu which allows to run the output file with any of the
+ applications configured in the preferences. This way you can run the output file easily with different emulators
+ without changing the
+ preferences. That can be very helpful if one emulator show a different behaviour than another or
+ in case you have specified a build script as user defined application in the preferences
+
+
+
+
+
+
Open source and output folder directly from menu
+
+ Open compiler help directly from menu if the documentation is available in the default folder structure of the
+ compiler executable
+
+
+
+
Complete list of compiler error and warning messages in the problems view
+
Direct navigation to the source location of the via double click on the problem message
+
+ Problem markers in the scroll area including tooltip with problem message
+
+
+
+
+ German localization for all Eclipse plugin texts. The original compiler messages are not translated but some are
+ mapped automatically
+
+
+
ATASM ".bank" warnings are mapped to info messages
+
+
+
+ Console view with original compiler output opens automatically in the background after compiling which useful in
+ cases where the plugin is not yet complete. The "Compiler Console" is automatically brought to front when the
+ compiler starts. This prevents
+ the compiler output from being hidden behind other consoles in the console view
+
+
+
Activated via the standard menu "Window/Show View/Outline"
+
Automated asynchronous parsing while typing
+
Automated recursive parsing of source includes and merge with current outline
+
Positioning in the content outline remains stable while typing unless structure changes appear
+
Folding is active automatically when outline is visible
+
Folding for if/else/endif blocks
+
Outline and folding for definition section and implementation sections
+
Outline for equate definitions (including defining expression), label definitions and variable definitions
+
Outline and folding for enum and struct definitions
+
Outline and folding for macros definitions
+
Outline and folding for repeat sections
+
Outline and folding for procedure definitions
+
Outline and folding for local sections
+
Outline for source includes and binary includes
+
Type specific outline icons
+
Nested folding with tooltip for folded sections
+
Line end comment is used as short description
+
+ Toolbar with button to toggle the sorting order of the sections and labels. The state of the button is persisted
+ automatically along with the respective source file. For files which do not have a setting yet, the setting from the
+ currently opened file
+ will be used
+
+
+
+
+
Content assist by pressing CTRL-Space for directives, legal opcode, illegal opcodes and pseudo opcodes
+
The content assist also recognizes if there is already and instruction in the current line and suggests the
+ available identifiers instead if this is the case. This is the first version and it supports global identifiers in
+ the current source file and
+ source file included from there. Scoped identifiers of the form "a.b" are not yet
+ supported
+
+
Completion proposal auto activation without pressing CTRL-Space after typing compiler dependent characters, for
+ example "." in ATASM, "." or "#" in MADS and "!" in ACME
+
+
Type specific icon and mnemonic highlighting
+
Progressive filtering as you type
+
Automatic detection of lower case / upper case based on current input
+
Default case configurable in preferences
+
Illegal opcodes can be hidden via preferences
+
+ 16-bit opcodes of 65816 can hidden via preferences
+
+
+
+
+ Multi-line content completion and explicit cursor positioning, for example ".MA" becomes ".MACRO <cursor is
+ here> <newline> .ENDM"
+
+
+
Hyperlink navigation via CTRL-click to source includes and binary includes
+
Support for relative and absolute file paths
+
Source file are always opened with the same assembler editor, irrespective of the extension
+
The ".asm" extension for "ICL" source includes is appended automatically in MADS, if it is missing
+
The ".asx" extension for "ICL" source includes is appended automatically in XASM, if it is missing
+
+ Choice for binary includes to open the file with
+
+
the build in hex editor
+
the build in graphics editor
+
the default Eclipse editor (e.g. a text editor)
+
system editor (e.g. an emulator or a paint program)
+
+
+
+ Hyperlink navigation via CTRL-click to labels, equates, local definitions, macro definitions and procedure
+ definitions. In case there is only one target, direct navigation takes place. In case there is more than one possible
+ target, the type and line
+ number of the target are displayed in a hyperlink popup. All included source files are also
+ taken into account like in the content outline. In case there are targets from different files, the file name is also
+ displayed as differentiator in the hyperlink
+ popup.
+
+
+
+
+
+
+
+
+ Available via context menu including multi-file-selection to open several files at once
+
+
+
+
The "Open With Hex Editor" menu entry closes an existing editor in case the file is already opened and thereby
+ forces the file to be opened with the hex editor. In addition the hex editor is set as the default editor this one
+ file. As a consequence
+ double clicking the file in the package explorer will open it automatically with the hex
+ editor, no matter which type of file is actually is. This saves you from always using the context menu, just because
+ the file has no known file type. You can change
+ the default editor again by just using the "Open With" context menu
+ entry
+
+
Available via hyperlink navigation for binary includes
+
+ Context menu to copy parts of the file into the clipboard in different formats:
+
+
hex values (".byte $01,$02,...")
+
decimal values (".byte 1,2,...")
+
ASCII string
+
+ This is very helpful to turn parts of a file into source code. The possibility to copy/paste into the binary file
+ itself in order to modify is prepared but not working yet and will be completed later.
+
+
+
+
+ Support for binary files, Atari COM files and Atari Disk Images
+
+
+
+
The possible file modes for a binary file are computed automatically and used as default when opening the file
+
+
Unsupported file modes are detected and cannot be used
+
Files with a block structure get an outline in the outline view
+
+ Files with a corrupted block structure are detected and displayed as good as possible
+
+
+
+
+
+ Viewer for binary files and 8-bit image files.
+
+ The most suitable supported converter and the corresponding default parameters are computed based on the file
+ content, size and extension.
+
+ The converters for the Atari standard image formats are based on
+ FAIL
+ , the excellent First Atari Image Library created by Piotr Fusik and Adrian Matoga.
+
+
+
+
Platform
+
File Extension
+
File Format
+
+
+
Atari 8-bit
+
AP3
+
80x192, 256 colors, interlaced
+
+
+
Atari 8-bit
+
APC
+
Any Point, Any Color, 80x96, 256 colors, interlaced
+ Available via context menu including multi-file-selection to open several files at once
+
+
+
+
The "Open With Graphics Editor" menu entry closes an existing editor in case the file is already opened and
+ thereby forces the file to be opened with the graphics editor. In addition the graphics editor is set as the default
+ editor this one file. As a
+ consequence double clicking the file in the package explorer will open it automatically
+ with the graphics editor, no matter which type of file is actually is. This saves you from always using the context
+ menu, just because the file has no known file
+ type. You can change the default editor again by just using the "Open
+ With" context menu entry
+
+
Available via hyperlink navigation for binary includes
+
+ Conversion from binary files or 8-bit images files to GIF/JPG/BMP/PNG images
+
+
Up to different 3 source files depending on the converter
+
Configurable start offset for every source file, useful for extracting character sets
+
Configurable palette via the Image Palette view
+
Configurable number of rows and columns
+
Configurable spacing width for and spacing color to separate tiles and unused areas
+
Separate aspect ratio for display and saving the image file
+
+
+
+
+ Conversion from GIF/JPG/BMP/PNG images to binary files or 8-bit images using JavaScript.
+
+
Separate aspect ratio for loading and displaying the image file
+
Default scripts are included. They can adjusted and saved along with the other parameters
+
+
+
+
+
+ The image palette view associated with the graphics editor displays the palette entries and the color histogram. It
+ supports filtering of unused colors, sorting by index and color frequencies, pre-settings and editing the palette
+ when displaying 8-bit
+ images
+
+
+
+
Conversion files with extension ".cnv" are used to save the conversion direction and all conversion parameters
+
+
Support for relative file paths. If the file path is in the same folder as the ".cnv" file, it it automatically
+ converted to a relative file path when the file name is defaulted or picked from the file browser dialog. This allows
+ to move the ".cnv"
+ file and the referenced source files around together without breaking the saved paths
+
Available via entry "Preferences" from the menu "Window" (in Windows and Linux) or the menu "Eclipse" (in Mac OS
+ X)
+
+
Configuration of syntax highlighting colors and styles for comments, directives, all types of identifiers, legal
+ opcodes, illegal opcodes, numbers, pseudo opcodes and strings
+
+
For non unique identifiers, the syntax highlighting will try to be a best guess
+
+ Configuration of default case in content assist
+
+
+
Available via entry "Preferences" from the menu "Window" (in Windows and Linux) or the menu "Eclipse" (in Mac OS
+ X)
+
+
Separate compiler preferences page for every type of hardware, i.e. Atari 8-bit and C64; Apple 2 support is in
+ development by Nick Westgate
+
+
Preferences can be maintained for all compilers in parallel
+
Upon opening the compiler preferences, the tab for the compiler of the active editor is activated automatically
+
+
+ Configuration of illegal opcodes and 65816 opcodes support in syntax highlighting and content assist
+
+ The configuration is offered only if the compiler supports the respective feature
+
+
Download links, configurable paths and default parameters for all compilers
+
The default file extension filter is set to "*.exe" on Windows and "*.*" on all other operating systems
+
The button "Apply Defaults" does explicitly not reset the paths to the executables
+
+ Configuration of parameters per compiler including predefined defaults to run out-of-the-box
+
+ Possible variables are:
+
+
{$sourceFolderPath} The absolute path to the source folder
+
{$sourceFilePath} The absolute path to the source file
+
{$outputFolderPath} The absolute path to the output folder
+
{$outputFilePath} The absolute path to the output file
+
{$outputFileName} The name of the output file including its extension, for example "TestFile123.asm"
+
{$outputFileNameWithoutExtension} The name of the output file without extension, for example "TestFile123"
+
{$outputFileNameShortWithoutExtension} The name of the output file without extension shortened to 8 alphanumeric
+ characters, for example "TESTFILE"
+
+
+ Make sure that you don't remove parameters when you specify your own values
+
+ If not, either creating the label definition file or parsing the compiler log may fail
+
+
ATASM requires the "-s" parameter to be present"
+
MADS requires the "-p" parameter to be present
+
ACME requires the "!to" directive in the source to be commented out to ensure the output file name from the
+ command line is used
+
+
+
+
+ Preferences can be maintained for all possible applications of all compilers in parallel
+
+
+ Possibility to use the "Operating Sytem Default Application" of the platform to open the output file
+
+ For Windows and Mac OS X choosing the "Operating Sytem Default Application" means that for ".xex" file the emulator will be started
+ automatically without any further configuration
+
+
Possibility to use one of the pre-defined applications and optionally change the command line
+
Possibility to use a user defined application to open the output file
+
+ Possible variables are:
+
+
{$runnerExecutablePath} The absolute path to the executable of the application
+
{$sourceFolderPath} The absolute path to the source folder
+
{$sourceFilePath} The absolute path to the source file
+
{$outputFolderPath} The absolute path to the output folder
+
{$outputFilePath} The absolute path to the output file
+
{$outputFileName} The name of the output file including its extension, for example "TestFile123.asm"
+
{$outputFileNameWithoutExtension} The name of the output file without extension, for example "TestFile123"
+
+
{$outputFileNameShortWithoutExtension} The name of the output file without extension shortened to 8
+ alphanumeric characters, for example "TESTFILE"
+
+
+
+
+
+
Download links, configurable paths and default command lines for Atari++, Atari800Win, Atari800MacX emulators per
+ compiler
+
+
+ The default file extension filter is set to "*.exe" on Windows and "*.*" on all other operating systems
+
+
+
For most use-cases, the defaults provided for the compilers and in the preferences are sufficient. But if you want have develop in parallel in multiple projects, for different platforms (Apple II and Atari 8-bit) or in different output formats
+ (".XEX" and ".BIN") with the same compiler it may become cumbersome to change the preferences every time. Therefore WUDSN IDE offers annotations which you can put into the source code files. These annotations override the defaults and the preferences.
+
+
All annotations start with the prefix "@com.wudsn.ide.asm." followed by the lower case name of the annotation, an equals sign and the unquoted value. Example: "@com.wudsn.ide.asm.hardware=ATARI8BIT"
+
All annotations can be placed in comment lines at the begin of a source file. Some of the annotations are only relevant for the main source file, some are only relevant in include source files, some are
+ relevant for all source files.
+
+
+ @com.wudsn.ide.asm.hardware
+
+
Defines the target hardware for which the preferences shall be evaluated, in particular which emulator is used to run the output file.
+
Allowed values are "APPLE2", "ATARI2600", "ATARI7800", "ATARI8BIT", "C64", "NES".
+
This annotation is relevant for all source files.
+
This annotation is only evaluated when a file is opened. So if you add this annotation or change its value, you have to close and re-open the file once.
+
Example: @com.wudsn.ide.asm.hardware=ATARI8BIT
+
+
+
+ @com.wudsn.ide.asm.mainsourcefile
+
+
Defines the main source file to which the current include source file belongs. When the "Compile" action is executed, the main source file is compiler instead of the current file.
+
Allowed values are file paths relative to the folder of the current include source file and absolute file paths.
+
This annotation is only relevant for include source files.
+ @com.wudsn.ide.asm.outputfile (planned for 1.7.0)
+
+
Overrides the "Output Folder", "Output File Extension" from the preferences and the automatic computation of the out file name based on the main source file name.
+
Allowed values are file paths relative to the folder of the main source file and absolute file paths.
+
This annotation is only relevant for the main source file.
Automatic creation of ".DSK" disk images for Apple II now works correctly
+
+
Dirty indicator in Graphics Editor is now updated correctly
+
+
+
+
+ 1.6.4
+
+
+
The toolbar icons now work correctly with newer Eclipse versions
+
Atari 8-bit Graphics 12 Converter works again
+
Graphics editor now properly closes input stream for image files
+
Empty selection and too large numbers no longer lead to exceptions when opening the context menu for "Convert..."
+
Pressing refresh in the graphics converter now always updates the image pane correctly and not only if the size has changed
+
Inline repeats like ":64" in MADS are no longer detected as labels
+
Hex Editor now correctly detects erroneous COM files in case the segment length exceeds the file length (by one)
+
Disk images (for Apple II) are now updated also if only "Compile" instead of "Compile and Run" is used
+
Apple Commander integration is now part of the installation, as it should have been with 1.6.3
+
+ The HELLO program generated for the auto-start disk images of Apple II now displays a title and uses "BLOAD/CALL" instead of "BRUN" because of this
+ bug in Apple DOS
+
First character of numbers is now correctly highlighted in #123
+
Source file includes via "INCSRC" are now correctly detected for ASM6
+
+
+
+ 1.6.2
+
+
+
Typing a "." to trigger the automatic content assist no longer locks-up
+
Default color for illegal opcodes changed to red as it was intended
+
German localization for the graphics editor is finally completed
+
Sorting of application in the preferences now is "Default, A...Z, User Defined" also in non English localizations
+
+
+
+ 1.6.1
+
+
+
Clicking in the outline always positions the cursor correctly in the source, not only the first time
+
All names of content types are now translated correctly in the preferences
+
"Open Folder" command now also works for objects which are no resource or file themselves but can be adapted to one of these types. For example project explorer entries for Java classes
+
+
+
+ 1.6.0
+
+
+
Hyperlink navigation now also works for labels which contain an underscore
+
The key binding for the "Compile" menu is now "Shift-Ctrl-9" because it turned out that "Ctrl-0" is not available in all cases
+
The HexEditor is now also detecting the situation that the first block of a COM file is incorrect and display this correctly
+
Content assist has now correct new lines when inserting #IF, #WHILE and .TEST
+
Fonts and colors resources are disposed correctly now
+
Resetting to default syntax colors in the preferences works now
+
Elements of .ENUM are recognized as equates now also if they do not start of position 0
+
Elements of .STRUCT are recognized as labels now also if they do not start of position 0
+
Cursor is now positioned to the first character of an equate or label also if it is not defined starting at position 0
+
Cursor is now positioned to the first character of an equate or label also if it is not defined starting at position
+ 0
+
+
+
+
+ 1.5.0
+
+
+
+
Syntax highlighting remains active now also after "Save as..."
+
Cursor is now placed correctly by content assist
+
The key binding for the "Compile" menu is now "Ctrl-0" instead of "Ctrl-Alt-0", so entering "}" is now possible again
+
XASM editor now correctly detects the "ORG" directive
+
The assembler editor toolbar contribution now also displays the label "Assembler" in the customizing dialog for the perspective
+
+
+
+ 1.4.4
+
+
+
The directive ".LOCAL" in ATASM is a normal directive now and does not start a folding section while in MADS it is
+ really is a folding section from ".LOCAL" to ".ENDL"
+
+
"SIN()" and "RND()" in MADS are now recognized correctly even if there are no spaces before or after the directive
+
+
".EN" and ."END" in MADS are now recognized correctly
+
Labels in "ORG" lines are now recognized correctly and rendered as separate tree entries
+
Preferences for lower/upper case instructions in content assist are now also evaluated if the for directives which
+ do not start with letters like ".end"
+
+
When opening a file which is located outside of the workspace, the action to open folders and to compile the file
+ are now not doing anything and will not cause exceptions. They will also be disabled once the new Eclipse version is
+ mandatory
+
+
The 16 bytes per row in the hex editor are now separated by a space
+
+
+
+ 1.4.3
+
+
+
The output file is not opened anymore in case it has been there before but was not updated by the compiler due to
+ compiler errors
+
+
The scroll bar and cursor in the editor are now stable also in the cases when the outline is changed by the latest
+ user input
+
+
The hex editor now gets the focus correctly also when clicking on already opened files
+
+
+
+ 1.4.2
+
+
+
The folder which contains the output file and the symbols file is refreshed automatically after compiling to
+ ensure that the Eclipse resource cache is in sync with the file system
+
+
Line end comments are now used as description for source and binary includes in the content outline
+
The "Open Folder" context menu entry works again, bug was introduced in version 1.4.0
+
+
+
+ 1.4.0
+
+
+
The "Assembler" menu is visible now only if an Assembler editor is active. The contained entries and their short
+ cuts are now disabled if no Assembler editor is active
+
+
The output file is not deleted anymore before the compiler is started, instead it is only checked for being
+ writeable. This allows for direct compilation into an existing ATR image
+
+
The name of the application used to open the output file is now included in the info message
+
+
+
+ 1.3.2
+
+
+
The content outline sometimes only found the first macro definition
+
Folding did not show up in all situations
+
+ Under Mac OS X, the file select dialog can now choose an "*.app" application like "Atari800MacX.app" since this is
+ folder. The solution is a workaround to the a general Eclipse problem under MacOS X, see
+ BUG 82155
+
+
+
+
+ Before 1.3.2
+
+
+
The "OK" and "Apply" buttons in the preferences are now always enabled, irrespective of the specified compiler and
+ emulator paths
+
+
The focus is not back in editor window after compiling
+
The syntax highlighting of illegal opcodes fixed, now also uses the preferences setting
+
On German operating systems, the properties for the correct locale are now found
+ See the table below for the current feature set for the features which depend on the compiler.
+
+ Features which are not supported by the compiler itself and hence cannot be supported by the IDE are marked as "n/a".
+
+
+
+
Compiler
+
Default Hardware
+
Auto Completion Activation
+
Single-Line Comments
+
Block Comments
+
Strings
+
Opcodes
+
Directives
+
Compile Log Parsing
+
Include Log Parsing
+
Content Outline
+
Label Definition File Format
+
+
+
ACME
+
C64
+
Yes: !
+
Yes: ;|
+
n/a
+
Yes: "
+
Yes
+
+ Partly
+
+
Yes
+
TBD
+
+ Partly
+
+
ACME
+
+
+
ATASM
+
Atari 8-bit
+
Yes: .
+
Yes: ;
+
n/a
+
Yes: "
+
Yes
+
Yes
+
Yes
+
TBD
+
Yes
+
XASM 3.0.1
+
+
+
MADS
+
Atari 8-bit
+
Yes: . #
+
Yes: ; * //
+
Yes
+
Yes: ' "
+
Yes
+
Yes
+
Yes
+
TBD
+
Yes
+
MADS
+
+
+
XASM
+
Atari 8-bit
+
n/a
+
Yes: ; * |
+
n/a
+
Yes: ' "
+
Yes
+
Yes
+
+ Planned
+
+
TBD
+
Yes
+
XASM 3.0.1
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/help/ide-installation.section.html b/com.wudsn.ide.asm/help/ide-installation.section.html
new file mode 100644
index 00000000..1e557552
--- /dev/null
+++ b/com.wudsn.ide.asm/help/ide-installation.section.html
@@ -0,0 +1,548 @@
+
+There are two ways of installing WUDSN IDE. If you are using a Windows operating system, I recommend downloading the ready to run zero installation distribution:
+
+
+It contains the Eclipse Platform, the Java Runtime Environment, the latest stable version of the WUDSN IDE plugin, all supported compilers and an emulator for
+each supported platform. All paths to folders, compilers and emulators are pre-configured. Unpack the content of this archive to
+the directory "C:\jac\wudsn" and click the "WUDSN IDE" link. Eclipse will open with the predefined workspace that contains
+"Hello World" examples for different platforms.
+
+
+If you use another operating system, or want to use the latest version of WUDSN or want to install compilers and emulators more
+selectively, read the descriptions of the installation steps below. In addition, the following previous versions of the zero installation distribution are available
+
+ If you don't know which version to take, use
+ Eclipse 4.3.2
+ Platform Runtime Binary (61 MB)
+ .
+
+ This is a minimum size installation which does not include the Java Development Toolkit (JDT). WUDSN IDE has no dependency to
+ the JDT but of course to the Java Runtime Environment (JRE). Make sure you also have the 64-bit version of the JRE installed
+ if you want to use the 64-bit version of Eclipse.
+
+
Unzip the downloaded archive file and store the contained folder "eclipse" where you want Eclipse to be located on you
+ local hard drive.
+
Start the Eclipse executable from that folder.
+
Upon the first start you are prompted to specify the folder where the workspace shall be located.
+
Normally a start link a created to this end. You can use the parameter "-nl" to specify the locale if you want. Use "en_US"
+ for English or "de_DE" for German. Example: "C:\Program Files\Eclipse\4.3.1\eclipse\eclipse.exe" -Xmx512M -nl en_US"
+
It is recommended to create the workspace folder in your home directory.
+
After you have read the welcome page and got familiar with the Eclipse UI, just switch to the Resource perspective.
+
+ Open the view "Problems" via the menu "Window/Show View/Problems" and then click the entry "Configure Contents..." from its
+ view menu.
+
+
+
+
+ Select the configuration "All Errors", the radio button "On selected element and its children" and the check boxes ""Error",
+ "Warning" and "Info".
+
+
+
+
+ Now Eclipse itself is ready and you can proceed with step
+ Installing WUDSN IDE
+ .
+
Select the entry "Install New Software..." from the menu "Help".
+
Enter "http://www.wudsn.com/update" in the "Work with" field and press ENTER.
+
+ Select the latest version of the feature "WUDSN IDE" for in and press the button "Next".
+
+ You don't need to install the "General Eclipse Enhancements" feature as it is already included in the "WUDSN IDE" feature".
+
+
Review the installation details and press the button "Next".
+
Read the license agreement, choose the option "I accept..." and press the button "Finish".
+
In case you get a security warning that the content is unsigned, confirm the warning by pressing the button "OK".
+
When you are prompted to restart Eclipse now, press the button "Yes".
+
+ As always with updates, it may happen that the update fails for whatever reason or the installed version turns out to have
+ severe issues. For example the required Java Version might not be available on your machine. In this case you can uninstall it
+ via the link "What is already installed" in the "Install New Software..." dialog and restart the IDE. Then you can reinstall
+ the latest version from "http://www.wudsn.com/update" or previously released versions from the locations listed in the
+ "Releases" chapter.
+
+
+
+
+
+ Installing compilers like ATASM, MADS, XASM... Â
+ » top
+
+
+
Start Eclipse
+
Select the entry "Preferences" from the menu "Window" (in Windows and Linux) or the menu "Eclipse" (in Mac OS X)
+
Open the preferences page "Assembler/Atari 8-bit Compilers" or the respective page for your platform.
+
+ Select the tab for the compiler of your choice.
+
+ The following compilers are or will be supported:
+
+
+
+
+
Compiler
+
Default Target Platform
+
+
+
ACME
+
C64
+
+
+
ASM6
+
NES
+
+
+
ATASM
+
Atari 8-bit
+
+
+
DASM
+
Atari 2600
+
+
+
KickAss
+
C64
+
+
+
MADS
+
Atari 8-bit
+
+
+
XASM
+
Atari 8-bit
+
+
+
TASS
+
C64 (in preparation)
+
+
+
+
+
Click the "Download"" link to open the home page of the compiler.
+
Follow the instruction on the download site for install the compiler to the folder of your choice.
+
+ Alternatively, you can download the single
+ archive containing all supported 6502
+ compilers
+ including the Linux and Mac OS X versions where available. The archive contains a readme file with the date of the last update
+ and the included compiler versions.Â
+
+
+
+
+
Compiler
+
Operating System
+
Architecture
+
Compiler Version
+
Executable Path
+
Compile Date
+
Compiled By
+
+
+
ACME
+
Windows
+
Intel - 32 bit
+
0.90
+
ACME / acme.exe
+
2006-03-19
+
Krzysztof Dabrowski
+
+
+
ASM6
+
Windows
+
Intel - 32 bit
+
1.6
+
ASM6 / asm6.exe
+
2011-03-11
+
loopy
+
+
+
ATASM
+
Windows
+
Intel - 32 bit
+
1.07 (non-final)
+
ATASM / atasm.exe
+
2010-05-10
+
M. Schmelzenbach
+
+
+
ATASM
+
Mac OS X
+
Intel
+
1.07 (non-final)
+
ATASM / atasm.macosx-i386
+
2015-05-01
+
JAC!
+
+
+
ATASM
+
Mac OS X
+
PowerPC
+
1.07 (non-final)
+
ATASM / atasm.macosx-powerpc
+
2015-05-01
+
JAC!
+
+
+
ATASM
+
Linux
+
Intel - 32 bit
+
1.07 (non-final)
+
ATASM / atasm.linux-i386
+
2015-05-01
+
JAC!
+
+
+
ATASM
+
Linux
+
Intel - 64 bit
+
1.07 (non-final)
+
ATASM / atasm.linux-x86-64
+
2015-05-01
+
JAC!
+
+
+
DASM
+
Windows
+
Intel - 32 bit
+
2.20.11
+
DASM / bin / dasm.exe
+
2015-05-08
+
JAC!
+
+
+
DASM
+
Mac OS X
+
Intel
+
2.20.11
+
DASM / bin / dasm.macosx-i386
+
2015-05-01
+
JAC!
+
+
+
DASM
+
Mac OS X
+
PowerPC
+
2.20.11
+
DASM / bin / dasm.macosx-powerpc
+
2015-05-01
+
JAC!
+
+
+
DASM
+
Linux
+
Intel 32-bit
+
2.20.11-20140304
+
DASM / bin / dasm.linux-i386
+
2015-05-01
+
JAC!
+
+
+
DASM
+
Linux
+
Intel 64-bit
+
2.20.11-20140304
+
DASM / bin / dasm.linux-x86-64
+
2015-05-01
+
JAC!
+
+
+
KickAss
+
All
+
Java
+
V3.39
+
KICKASS / KickAss.jar
+
2015-03-26
+
Mads Nielsen
+
+
+
MADS
+
Windows
+
Intel - 32 bit
+
2.0.7Â (new features since 1.9.0 are not fully supported in WUDSN IDE yet)
+
MADS / mads.exe
+
2014-05-20
+
JAC!
+
+
+
MADS
+
Mac OS X
+
Intel
+
2.0.7Â (new features since 1.9.0 are not fully supported in WUDSN IDE yet)
+
MADS / mads.macosx-i386
+
2017-11-05
+
JAC!
+
+
+
MADS
+
Mac OS X
+
PowerPC
+
2.0.7Â (new features since 1.9.0 are not fully supported in WUDSN IDE yet)
+
MADS / mads.macosx-powerpc
+
2017-11-05
+
JAC!
+
+
+
MADS
+
Linux
+
Intel - 32 bit
+
2.0.7Â (new features since 1.9.0 are not fully supported in WUDSN IDE yet)
+
MADS / mads.linux-i386
+
2017-11-05
+
JAC!
+
+
+
TASS
+
Windows
+
Intel - 32 bit
+
1.46 r38
+
TASS / 64tass.exe
+
2011-07-03
+
Soci
+
+
+
XASM
+
Windows
+
Intel - 32 bit
+
3.1.0
+
XASM / xasm.exe
+
2014-07-20
+
0xF
+
+
+
XASM
+
Linux
+
Intel - 32 bit
+
3.1.0
+
XASM / xasm.linux-i386
+
2014-07-20
+
0xF
+
+
+
XASM
+
Mac OS X
+
Intel - 32 bit
+
3.1.0
+
XASM / xasm.macosx-i386
+
2014-07-20
+
0xF
+
+
+
+
+
In the section "Browse..." button for the field "Path to Compiler" to locate the executable. Note that under Mac OS-X, you
+ must specify the path to the actual executable inside the ".app" folder.
+
+
If not explicit compiler parameters are specified, the default parameters are used.
+
If explicit compiler parameters are specified, the default parameters are ignored.
+
+ The variable "${sourceFilePath}" is replaced by the absolute path to the source file.
+
+ The variable "${outputFilePath}" is replaced by the absolute path to the output file.
+
+ For more variables see section
+ preferences for compiling.
+
+
Choose if you want to use the source folder or the temporary folder as output folder.
+
Choose the file extension for the output file, for example ".xex" or ".bin"
+
Press the button "OK".
+
+ Using the button "Restore Defaults" all values are reset, except for the paths to the compilers.
+
+
+
+
+
+ Using the button "Default" in the "File Associations" preferences you can set the default editor for a file extension, for
+ example "MADS" for "*.asm".
+
+
+
+
+
+ Installing Atari800Win and other emulators Â
+ » top
+
+
+
Start Eclipse.
+
Select the entry "Preferences" from the menu "Window" (for Windows and Linux) or "Eclipse" (for Mac OS X).
+
Open the preferences page "Assembler/Atari 8-bit Compilers" and select to tab for your compiler.
+
+ The field "Default Application to open Output File" is defaulted to "Operating Sytstem Default Application".
+
+
If you have the emulator registered as default application for the extension of the output file, for example
+ "Atari800Win" or "Atari800MacX" for ".xex", you don't need to configure anything in addition and can skip the steps below.
+
+
If your operating system, like for example Linux, does not support default applications or if you need a special output
+ file extension and special parameters to open the output file in the emulator you can choose the emulator in the field
+ "Application to open Output File" and configure the command line on the corresponding tab.
+
+
You can also use the "User Defined Application" for open the output file with and arbitrary application like a script,
+ linker or whatever.
+
+
+
If you have not yet downloaded the corresponding emulator, you can use the download link on the tab of the emulator and
+ follow the instruction on the download site for install the emulator
+
Use the "Browse..." button for the field "Path to Application" to locate the executable. If required you can specify your
+ own command line based on the default command line displayed. Note that under Mac OS-X, you must specify the path to the
+ actual executable inside the ".app" folder.
+
+
If not explicit command line is specified, the default command line is used.
+
If an explicit command line is specified, the default command line is ignored.
+
+ The variable "${runnerExecutablePath}" is replaced by the path to the application executable.
+
+ The variable "${outputFilePath}" is replaced by the absolute path to the output file.
+
+ For more variables see section
+ preferences for compiling.
+
+
Press the button "OK"
+
+ In case you also need the Atari ROM files, you can find them in the file
+ PCXF380.ZIP
+ which is available at
+ http://www.emulators.com
+
+
+ The patch to convert the English version into a German version including a German keyboard layout is available from
+ ABBUC
+ . It also contains the ROM files
+
+
+
+
+
+ Creating and compiling an example project Â
+ » top
+
+
+
Start Eclipse.
+
Select the entry "New/Project" from the menu "File".
+
Select the wizard "General/Project" and press the button "Next".
+
Enter the project name "Atari800" and press the button "Finish".
+
The new project will appear in the "Project Explorer".
+
Select the newly created project and open its context menu.
+
Select the entry "New/File", enter the file name "Example.asm" and press the button "Finish".
+
The new empty file will now be opened in the MADS editor.
+
+ Copy the following source text and paste it into the file:
+
+
+
+ ; WUDSN IDE Atari Rainbow Example - MADS syntax
+
+
+ Â Â Â Â Â Â org $4000 ;Start of code
+
+
+ start lda #0 ;Disable screen DMA
+
+ Â Â Â Â Â Â sta 559
+
+ loop  lda $d40b ;Load VCOUNT
+
+ Â Â Â Â Â clc
+
+ Â Â Â Â Â Â adc 20 ;Add counter
+
+ Â Â Â Â Â Â sta $d40a
+
+ Â Â Â Â Â Â sta $d01a ;Change background color
+
+ Â Â Â Â Â Â jmp loop
+
+
+ Â Â Â Â Â Â run start ;Define run address
+
+
+
Select the entry "Compile and run" from the menu "Assembler" or press "SHIFT-CTRL-0".
+
Enjoy your famous first rainbow effect.
+
+ In case of problems, open the view "Problems" and the output of the view "Console" for details and post a message with the
+ screenshots in the
+ English AtariAge forum
+ if you get stuck:
+
+
+
+
+
+
+ Further information on assembler programming Â
+ » top
+
+
+
+ Source includes with equates for hardware registers and operating system for
+ Atari 8-bit
+ and
+ Atari VCS
+ in MADS format.
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/help/ide-releases.section.html b/com.wudsn.ide.asm/help/ide-releases.section.html
new file mode 100644
index 00000000..87bbd698
--- /dev/null
+++ b/com.wudsn.ide.asm/help/ide-releases.section.html
@@ -0,0 +1,201 @@
+
+The following table lists all releases of WUDSN IDE, the required minimum Java and Eclipse version the link to the release news
+article and release new video. For releases before 1.6.0 no downloads and no videos are offered. The latest version is always
+available via the update site "http://www.wudsn.com/update". Older versions are available via version specific update sites
+listed below.
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/help/ide-tutorials-videos.html b/com.wudsn.ide.asm/help/ide-tutorials-videos.html
new file mode 100644
index 00000000..aef0fe15
--- /dev/null
+++ b/com.wudsn.ide.asm/help/ide-tutorials-videos.html
@@ -0,0 +1,42 @@
+
+Cheat sheet for creating video screen shots - Do not format the source!
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/help/ide-tutorials.section.html b/com.wudsn.ide.asm/help/ide-tutorials.section.html
new file mode 100644
index 00000000..5ea869e5
--- /dev/null
+++ b/com.wudsn.ide.asm/help/ide-tutorials.section.html
@@ -0,0 +1,85 @@
+
+When I was thinking about creating tutorials, I decided not to simply write text but to create short videos instead.
+They are best viewed in full screen mode and in HD video resolution.
+I think this is the best way to show how things are intended to be
+used. On the other hand, these tutorials cannot
+tackle every detail of a supported feature. So please also check the features section.
+
+
+
+
+
+ Part 1: Introduction, Installation and Use
+
+
+
+
+
+
+ Part 2: Setting up Perspective, Views and Editors
+
+
+
+
+
+
+
+
+ Part 3: Setting up Editors and File Extensions correctly
+
+
+
+
+
+
+ Part 4: Syntax highlighting and Content Assist
+
+
+
+
+
+
+
+
+ Part 5: Working with Projects, Folders and Files
+
+
+
+
+
+
+ Part 6: Content Outline and Navigation - the Heart of the IDE
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/help/productions/java/.gitignore b/com.wudsn.ide.asm/help/productions/java/.gitignore
new file mode 100644
index 00000000..92ae9f65
--- /dev/null
+++ b/com.wudsn.ide.asm/help/productions/java/.gitignore
@@ -0,0 +1 @@
+/ide
diff --git a/com.wudsn.ide.asm/help/productions/java/ide.txt b/com.wudsn.ide.asm/help/productions/java/ide.txt
new file mode 100644
index 00000000..daec6b32
--- /dev/null
+++ b/com.wudsn.ide.asm/help/productions/java/ide.txt
@@ -0,0 +1 @@
+This "ide" folder is only symbolic link.
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/help/www.oxyron.de/html/opcodes.html b/com.wudsn.ide.asm/help/www.oxyron.de/html/opcodes.html
new file mode 100644
index 00000000..3017746b
--- /dev/null
+++ b/com.wudsn.ide.asm/help/www.oxyron.de/html/opcodes.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+65xx processor series opcodes
+
+
+
+
+
Welcome to the 65xx resources.
+
Here you will find detailed information about some processors of the 65xx series. Especially the 6502
+document provides a deep look into the internal behaviour of the processor. Also you will find an illegal opcode list
+which has been validated for being 100% several times now. The other documents only extend the 6502 document with
+additional information. They do not completely describe all opcodes.
+
+
+"*" : add 1 cycle if page boundary is crossed.
+add 1 cycle on branches if taken.
+
+
+Logical and arithmetic commands:
+
+
+
Opcode
imp
imm
zp
zpx
+
zpy
izx
izy
abs
abx
+
aby
ind
rel
Function
+
N
V
B
D
I
Z
C
+
+
+
ORA
$09
$05
$15
+
$01
$11
$0D
$1D
+
$19
A:=A or {adr}
+
*
*
+
+
+
AND
$29
$25
$35
+
$21
$31
$2D
$3D
+
$39
A:=A&{adr}
+
*
*
+
+
+
EOR
$49
$45
$55
+
$41
$51
$4D
$5D
+
$59
A:=A exor {adr}
+
*
*
+
+
+
ADC
$69
$65
$75
+
$61
$71
$6D
$7D
+
$79
A:=A+{adr}
+
*
*
*
*
+
+
+
SBC
$E9
$E5
$F5
+
$E1
$F1
$ED
$FD
+
$F9
A:=A-{adr}
+
*
*
*
*
+
+
+
CMP
$C9
$C5
$D5
+
$C1
$D1
$CD
$DD
+
$D9
A-{adr}
+
*
*
*
+
+
+
CPX
$E0
$E4
+
$EC
+
X-{adr}
+
*
*
*
+
+
+
CPY
$C0
$C4
+
$CC
+
Y-{adr}
+
*
*
*
+
+
+
DEC
$C6
$D6
+
$CE
$DE
+
{adr}:={adr}-1
+
*
*
+
+
+
DEX
$CA
+
+
X:=X-1
+
*
*
+
+
+
DEY
$88
+
+
Y:=Y-1
+
*
*
+
+
+
INC
$E6
$F6
+
$EE
$FE
+
{adr}:={adr}+1
+
*
*
+
+
+
INX
$E8
+
+
X:=X+1
+
*
*
+
+
+
INY
$C8
+
+
Y:=Y+1
+
*
*
+
+
+
ASL
$0A
$06
$16
+
$0E
$1E
+
{adr}:={adr}*2
+
*
*
*
+
+
+
ROL
$2A
$26
$36
+
$2E
$3E
+
{adr}:={adr}*2+C
+
*
*
*
+
+
+
LSR
$4A
$46
$56
+
$4E
$5E
+
{adr}:={adr}/2
+
*
*
*
+
+
+
ROR
$6A
$66
$76
+
$6E
$7E
+
{adr}:={adr}/2+C*128
+
*
*
*
+
+
+
+
+Move commands:
+
+
+
Opcode
imp
imm
zp
zpx
+
zpy
izx
izy
abs
abx
+
aby
ind
rel
Function
+
N
V
B
D
I
Z
C
+
+
+
LDA
$A9
$A5
$B5
+
$A1
$B1
$AD
$BD
+
$B9
A:={adr}
+
*
*
+
+
+
STA
$85
$95
+
$81
$91
$8D
$9D
+
$99
{adr}:=A
+
+
+
+
LDX
$A2
$A6
+
$B6
$AE
+
$BE
X:={adr}
+
*
*
+
+
+
STX
$86
+
$96
$8E
+
{adr}:=X
+
+
+
+
LDY
$A0
$A4
$B4
+
$AC
$BC
+
Y:={adr}
+
*
*
+
+
+
STY
$84
$94
+
$8C
+
{adr}:=Y
+
+
+
+
TAX
$AA
+
+
X:=A
+
*
*
+
+
+
TXA
$8A
+
+
A:=X
+
*
*
+
+
+
TAY
$A8
+
+
Y:=A
+
*
*
+
+
+
TYA
$98
+
+
A:=Y
+
*
*
+
+
+
TSX
$BA
+
+
X:=S
+
*
*
+
+
+
TXS
$9A
+
+
S:=X
+
+
+
+
PLA
$68
+
+
A:=+(S)
+
*
*
+
+
+
PHA
$48
+
+
(S)-:=A
+
+
+
+
PLP
$28
+
+
P:=+(S)
+
*
*
*
*
*
*
+
+
+
PHP
$08
+
+
(S)-:=P
+
+
+
+
+
+Jump/Flag commands:
+
+
+
Opcode
imp
imm
zp
zpx
+
zpy
izx
izy
abs
abx
+
aby
ind
rel
Function
+
N
V
B
D
I
Z
C
+
+
+
BPL
+
+
$10
branch on N=0
+
+
+
+
BMI
+
+
$30
branch on N=1
+
+
+
+
BVC
+
+
$50
branch on V=0
+
+
+
+
BVS
+
+
$70
branch on V=1
+
+
+
+
BCC
+
+
$90
branch on C=0
+
+
+
+
BCS
+
+
$B0
branch on C=1
+
+
+
+
BNE
+
+
$D0
branch on Z=0
+
+
+
+
BEQ
+
+
$F0
branch on Z=1
+
+
+
+
BRK
$00
+
+
(S)-=:PC,P PC:=($FFFE)
+
1
1
+
+
+
RTI
$40
+
+
P,PC:=+(S)
+
*
*
*
*
*
*
+
+
+
JSR
+
$20
+
(S)-:=PC PC:={adr}
+
+
+
+
RTS
$60
+
+
PC:=+(S)
+
+
+
+
JMP
+
$4C
+
$6C
PC:={adr}
+
+
+
+
BIT
$24
+
$2C
+
N:=b7 V:=b6 Z:=A&{adr}
+
*
*
*
+
+
+
CLC
$18
+
+
C:=0
+
0
+
+
+
SEC
$38
+
+
C:=1
+
1
+
+
+
CLD
$D8
+
+
D:=0
+
0
+
+
+
SED
$F8
+
+
D:=1
+
1
+
+
+
CLI
$58
+
+
I:=0
+
0
+
+
+
SEI
$78
+
+
I:=1
+
1
+
+
+
CLV
$B8
+
+
V:=0
+
0
+
+
+
NOP
$EA
+
+
+
+
+
+
+
+Flags of the status register:
+
+The processor status register has 8 bits, where 7 are used as flags:
+
+N = negative flag (1 when result is negative)
+V = overflow flag (1 on signed overflow)
+# = unused (always 1)
+B = break flag (1 when interupt was caused by a BRK)
+D = decimal flag (1 when CPU in BCD mode)
+I = IRQ flag (when 1, no interupts will occur (exceptions are IRQs forced by BRK and NMIs))
+Z = zero flag (1 when all bits of a result are 0)
+C = carry flag (1 on unsigned overflow)
+
+¹ = unstable in certain matters
+² = highly unstable (results are not predictable on some machines)
+A = Akkumulator
+X = X-Register
+Y = Y-Register
+S = Stack-Pointer
+P = Status-Register
++(S) = Stack-Pointer relative with pre-increment
+(S)- = Stack-Pointer relative with post-decrement
+
+Combinations of two operations with the same addressing mode:
+
+SLO {adr} = ASL {adr} + ORA {adr}
+RLA {adr} = ROL {adr} + AND {adr}
+SRE {adr} = LSR {adr} + EOR {adr}
+RRA {adr} = ROR {adr} + ADC {adr}
+SAX {adr} = store A&X into {adr}
+LAX {adr} = LDA {adr} + LDX {adr}
+DCP {adr} = DEC {adr} + CMP {adr}
+ISC {adr} = INC {adr} + SBC {adr}
+
+note to SAX: the A&X operation is a result of A and X put onto the bus at the same time.
+
+Combinations of an immediate and an implied command:
+
+ANC #{imm} = AND #{imm} + (ASL)
+ANC #{imm} = AND #{imm} + (ROL)
+ALR #{imm} = AND #{imm} + LSR
+ARR #{imm} = AND #{imm} + ROR
+XAA #{imm} = TXA + AND #{imm}
+LAX #{imm} = LDA #{imm} + TAX
+AXS #{imm} = A&X minus #{imm} into X
+SBC #{imm} = SBC #{imm} + NOP
+
+note to ANC: this command performs an AND operation only, but bit 7 is put into the carry, as if the ASL/ROL would have been executed.
+note to ARR: part of this command are some ADC mechanisms. following effects appear after AND but before ROR:
+the V-Flag is set according to (A and #{imm})+#{imm}, bit 0 does NOT go into carry, but bit 7 is exchanged with the carry.
+note to XAA: DO NOT USE!!! Highly unstable!!!
+note to LAX: DO NOT USE!!! On my C128, this opcode is stable, but on my C64-II it loses bits so that the operation
+looks like this: ORA #? AND #{imm} TAX.
+note to AXS: performs CMP and DEX at the same time, so that the MINUS sets the flag like CMP, not SBC.
+
+Combinations of STA/STX/STY:
+
+AHX {adr} = stores A&X&H into {adr}
+SHX {adr} = stores X&H into {adr}
+SHY {adr} = stores Y&H into {adr}
+
+note: sometimes the &H drops off. Also page boundary crossing will not work as expected (the bank where the value is stored may be equal to the value stored).
+
+Combinations of STA/TXS and LDA/TSX:
+
+TAS {adr} = stores A&X into S and A&X&H into {adr}
+LAS {adr} = stores {adr}&S into A, X and S
+
+note to LAS: is called as "propably unreliable" in one source.
+
+Bit configuration does not allow any operation on these ones:
+
+NOP = has no effects
+NOP #{imm} = fetches #{imm} but has no effects
+NOP {adr} = fetches {adr} but has no effects
+
+KIL = halts the CPU. the data bus will be set to #$FF
+
+
+Aliases used in other illegal opcode sources:
+
+SLO = ASO
+SRE = LSE
+ISC = ISB
+ALR = ASR
+SHX = A11 (A11 was a result of only having tested this one on adress $1000)
+SHY = A11
+LAS = LAR
+KIL = JAM, HLT
+
+
+The 6502 bugs:
+
+Zeropage index will not leave zeropage when page boundary is crossed:
+
+LDX #$01
+LDA $FF,X
+
+...will fetch from adress $0000 and not $0100 as indexed.
+
+Indirect adressing modes are not able to fetch an adress which crosses the page boundary:
+
+Four examples to illustrate this:
+
+LDA ($FF),Y
+
+LDX #$00
+LDA ($FF,X)
+
+LDX #$FF
+LDA ($00,X)
+
+... will all fetch the low-byte from $00FF and the high-byte from $0000
+
+JMP ($12FF)
+
+... will fetch the low-byte from $12FF and the high-byte from $1200
+
+The N, V and Z flags do not work correctly in BCD mode:
+
+N will always carry bit 7.
+V will always be ((U eor N) nand (U eor V)) (while U is bit 7 of operand 1, V is bit 7 of operand 2 and N is the N flag after the ADC is performed).
+please note that SBC is truly ADC with an inverted operand!
+Z will be 0 when the non-BCD operation WOULD have resulted in $00, no matter what value the result of the BCD operation is.
+
+example to Z:
+
+SED
+CLC
+LDA #$80
+ADC #$80
+
+... results in A=$60, but the Z flag is 1.
+
+BCD and non BCD values:
+
+Since only nibble values from 0 to 9 are valid in BCD, it's interesting to see what happens when using A to F:
+
+$00+$0F=$15 (an easy way to convert a hex-digit into BCD...)
+$00+$1F=$25 (can be claimed as being "ok" since 10+$0F=25)
+$10+$1F=$35 ("ok")
+$05+$1F=$2A (a non-BCD result, still somewhat "ok" since 5+10+$0F=20+$0A)
+$0F+$0A=$1F ("ok", since $0F+$0A=$0F+10)
+$0F+$0B=$10 (now, this is plain bullshit!)
+
+
+Different versions of the 6502:
+
+In the C64/C128 series of computers, slightly modified versions of the 6502
+were used. The modifications did not affect the functional part of the processor
+itself. Only a so-called processor port was added.
+This port, in combination with an external PLA, was used to map ROM and I/O areas into the 64KB RAM of the C64.
+Also, some bits of the port were used for the legendary Datasette.
+
+The port can be accessed through memory adresses $0000 and $0001, while $0001
+is the port itself, and $0000 is the data direction register for it.
+
+Explanation for the bits of $0001:
+
+7 - unused (Flash 8: 0=8MHz/1=1MHz)
+6 - unused (C128: ASCII/DIN sense/switch (1=ASCII/0=DIN))
+5 - Cassette motor control (0 = motor on)
+4 - Cassette switch sense (0 = PLAY pressed)
+3 - Cassette write line
+2 - CHAREN (0=Character ROM instead of I/O area)
+1 - HIRAM ($E000-$FFFF)
+0 - LORAM ($A000-$BFFF)
+
+If HIRAM or LORAM is set, the I/O area is mapped to $D000-$DFFF.
+
+$0000 should always be set to $2F (%00101111)
+
+Note to bit 6: This bit is used to select either the ASCII or the DIN
+character ROM of a C128. When data direction is set to INPUT, the charset
+is selected externally with the ASCII/DIN key.
+
+CPU versions:
+
+6502: NMOS, used in Commodore disk drives, PET, various other 8 bit computers
+6502C: 6502 with additional HALT pin, used in Atari 8 bit computer range
+6510: 6502 with additional processor port, used in C64
+8500: CMOS version of the 6510, used in C64C and C64G
+8502: 2 MHz version of the 8500, used in C128
+7501: HMOS-1 version of the 6502, used in C16/C116/Plus4
+8501: HMOS-2 version of the 6502, used in C16/C116/Plus4
+
+All of these processors are the same concerning the software-side.
+
+Some processors of the family which are not 100% compatible:
+
+65C02: Extension of the 6502.
+65SC02: Small version of the 65C02 which lost a few opcodes again.
+65CE02: Extension of the 65C02, used in the C65.
+65816: Extended 6502 with new opcodes and 16 bit operation modes.
+
+Zeropage/Stack:
+
+The first 256 bytes of adressable memory are called Zeropage. The 6502
+processor family offers a wide selection of adressing modes to work with
+this part of the memory, which generally results in shorter and (even more
+important) faster code.
+
+Following the Zeropage, the next 256 bytes (located at $0100-$01FF) are
+used as processor stack. The stack function of this part is defined as
+it is in most other CPU's: Writing to stack will automatically decrement
+the stack pointer, while reading from it will increment it.
+
+
+"*" : add 1 cycle if page boundary is crossed.
+"#" : add 7 cycles for every byte moved and 1 cycle if page boundary is crossed.
+add 1 cycle if m=0: ADC, AND, BIT, CMP, EOR, LDA, ORA, PHA, PLA, SBC, STA, STZ
+add 2 cycles if m=0 (NOT the implied ones): ASL, DEC, INC, LSR, ROL, ROR, TRB, TSB
+add 1 cycle if x=0: CPX, CPY, LDX, LDY, STX, STY, PLX, PLY, PHX, PHY
+add 1 cycle if e=0: BRK, RTI
+add 1 cycle if direct page register is non zero on direct page adressing modes.
+add 1 cycle on conditional branches if taken.
+native 65816 only: branches do not take one additional cycle when page boundary is crossed.
+
+
+A = Akkumulator
+B = Akkumulator, upper 8 bits
+C = Akkumulator (but always 16 bit not depending on M)
+X = X-Register
+Y = Y-Register
+S = Stack-Pointer
+P = Status-Register
++(S) = Stack-Pointer relative with pre-increment
+(S)- = Stack-Pointer relative with post-decrement
+DBR = Data Bank Register (all data movements with 16 bit adresses will refer to this bank)
+DPR = Direct Page Register (all direct page accesses will use this as adress base)
+PBR = Program Bank Register (the bank the actual code is executed)
+
+Please note that 3 new flags have been added to the P: E, M and X.
+
+While E=1 the 65816 is in 6502 emulation mode and will act like a 6502 in all legal matters.
+DBR, DPR and PBR are still active! Take care: irq's will force PBR=0 without saving the PBR!
+While E=0 the 65816 is in native mode.
+While M=1 the Akku is 8 bits wide.
+While M=0 the Akku is 16 bits wide.
+While X=1 the X and Y registers are 8 bits wide.
+While X=0 the X and Y registers are 16 bits wide.
+
+Also note that the P has virtually lost the B flag in some matters.
+
+
+65816 opcodes:
+
+
+
Opcode
Function
+
E
N
V
M
X
D
I
Z
C
+
+
+
BRA
branch always
+
+
+
+
BRL
branch always (long)
+
+
+
+
COP
coprocessor enable
+
*
*
+
+
+
MVN
move block backward
+
+
+
+
MVP
move block forward
+
+
+
+
PEA
(S)-:=adr
+
+
+
+
PEI
(S)-:=adr
+
+
+
+
PER
(S)-:=adr
+
+
+
+
PHB
(S)-:=DBR
+
+
+
+
PHD
(S)-:=DPR
+
+
+
+
PHK
(S)-:=PBR
+
+
+
+
PHX
(S)-:=X
+
+
+
+
PHY
(S)-:=Y
+
+
+
+
PLB
DBR:=+(S)
+
*
*
+
+
+
PLD
DPR:=+(S)
+
*
*
+
+
+
PLX
X:=+(S)
+
*
*
+
+
+
PLY
Y:=+(S)
+
*
*
+
+
+
REP
P:=P nand #{imm}
+
?
?
?
?
?
?
?
?
+
+
+
SEP
P:=P or #{imm}
+
?
?
?
?
?
?
?
?
+
+
+
RTL
PC:=+(S) (long)
+
+
+
+
STP
stop CPU
+
+
+
+
WAI
wait for IRQ
+
+
+
+
STZ
{adr}:=0
+
+
+
+
TCD
DPR:=C
+
+
+
+
TDC
C:=DPR
+
*
*
+
+
+
TCS
S:=C
+
+
+
+
TSC
C:=S
+
*
*
+
+
+
TXY
Y:=X
+
*
*
+
+
+
TYX
X:=Y
+
*
*
+
+
+
XBA
exchange B with A
+
*
*
+
+
+
XCE
exchange C with E
+
*
*
+
+
+
TRB
{adr}:={adr} nand A
+
*
+
+
+
TSB
{adr}:={adr} or A
+
*
+
+
+
WDM
n/a
+
+
+
+
+note to STP, WAI: these opcodes need 3 cycles to shut down the CPU.
+
+
+
+
diff --git a/com.wudsn.ide.asm/help/www.oxyron.de/html/opcodesc02.html b/com.wudsn.ide.asm/help/www.oxyron.de/html/opcodesc02.html
new file mode 100644
index 00000000..c3a09d70
--- /dev/null
+++ b/com.wudsn.ide.asm/help/www.oxyron.de/html/opcodesc02.html
@@ -0,0 +1,492 @@
+
+
+
+
+
+
+65C02 Opcodes
+
+
+
+
+
+
+
+¹ - Only available on WDC 65C02
+
+"*" : add 1 cycle if page boundary is crossed.
+add 1 cycle if direct page register is non zero on direct page adressing modes.
+add 1 cycle on conditional branches if taken.
+add 1 cycle on these commands if D=1: ADC, SBC
+
+These things have changed from 6502 to 65C02:
+
+- new instructions.
+- new adressing modes for a few instrucions.
+- one adressing mode for fetch-modify-write instructions has been optimized, so it takes 1 less cycle in some cases.
+- flags now work correctly in BCD mode (takes 1 additional cycle).
+- absolute-indirect adressing mode now also works on a page boundary (also 1 additional cycle).
+- BRK also affects the decimal flag now.
+- illegal opcodes perform a NOP.
+
+
+65C02 opcodes:
+
+
+
Opcode
imp
imm
zp
zpx
+
zpy
izx
izy
abs
abx
+
aby
ind
rel
Function
+
N
V
B
D
I
Z
C
+
+
+
BRA
+
+
$80
branch always
+
+
+
+
PHX
$DA
+
+
(S)-:=X
+
+
+
+
PHY
$5A
+
+
(S)-:=Y
+
+
+
+
PLX
$FA
+
+
X:=+(S)
+
*
*
+
+
+
PLY
$7A
+
+
Y:=+(S)
+
*
*
+
+
+
STZ
$64
$74
+
$9C
$9E
+
{adr}:=0
+
+
+
+
TRB
$14
+
$1C
+
{adr}:={adr} nand A
+
*
+
+
+
TSB
$04
+
$0C
+
{adr}:={adr} or A
+
*
+
+
+
BBRn
+
+
$xF
branch on bit n reset
+
+
+
+
BBSn
+
+
$xF
branch on bit n set
+
+
+
+
RMBn
$x7
+
+
{adr}:={adr} nand 2^n
+
*
+
+
+
SMBn
$x7
+
+
{adr}:={adr} or 2^n
+
*
+
+
+
+
+The WDC 65C02 also includes the STP and WAI instructions known from the 65816.
+Another version of this processor, called 65SC02, doesn't have the single-bit instructions BBR/BBS/RMB/SMB.
+
+Changes on instructions of the 6502 instruction set:
+
+INC and DEC now have implied adressing modes.
+All major instructions (ORA, ADC, STA...) now also feature the indirect-zeropage adressing mode without index.
+JMP features a new absolute-indirect-indexed adressing mode.
+BIT now works with a few more adressing modes.
+
+
+
+"*" : add 1 cycle if page boundary is crossed.
+add 1 cycle if direct page register is non zero on direct page adressing modes.
+add 1 cycle on conditional branches if taken.
+add 1 cycle on these commands if D=1: ADC, SBC
+
+These things have changed from 65C02 to 65CE02:
+
+- new instructions.
+- new adressing modes for a few instrucions.
+- Z-Register is introduced.
+- with the introduction of the Z-Register, also the IZP adressing mode has been changed to IZZ.
+
+
+65CE02 opcodes:
+
+
+
Opcode
Function
+
N
V
B
D
I
Z
C
+
+
+
CPZ
Z-{adr}
+
*
*
*
+
+
+
DEC
A:=A-1
+
*
*
+
+
+
DEZ
Z:=Z-1
+
*
*
+
+
+
DEW
{adr}:={adr}-1 (16 bit)
+
*
*
+
+
+
INC
A:=A+1
+
*
*
+
+
+
INZ
Z:=Z+1
+
*
*
+
+
+
INW
{adr}:={adr}+1 (16 bit)
+
*
*
+
+
+
NEG
A:=0-A
+
*
*
+
+
+
ASR
{adr}:={adr}/2
+
*
*
*
+
+
+
ASW
{adr}:={adr}*2 (16 bit)
+
*
*
*
+
+
+
ROW
{adr}:={adr}*2+C (16 bit)
+
*
*
*
+
+
+
LDZ
Z:={adr}
+
*
*
+
+
+
STZ
{adr}:=Z
+
+
+
+
TAB
B:=A
+
*
*
+
+
+
TBA
A:=B
+
*
*
+
+
+
TAZ
Z:=A
+
*
*
+
+
+
TZA
A:=Z
+
*
*
+
+
+
TSY
Y:=S
+
*
*
+
+
+
TYS
S:=Y
+
+
+
+
PHW
(S)-:={adr} (16 bit)
+
+
+
+
PHX
(S)-:=X
+
+
+
+
PHY
(S)-:=Y
+
+
+
+
PHZ
(S)-:=Z
+
+
+
+
PLX
X:=+(S)
+
*
*
+
+
+
PLY
Y:=+(S)
+
*
*
+
+
+
PLZ
Z:=+(S)
+
*
*
+
+
+
TRB
{adr}:={adr} nand A
+
*
+
+
+
TSB
{adr}:={adr} or A
+
*
+
+
+
CLE
E:=0 ?
+
+
+
+
SEE
E:=1 ?
+
+
+
+
BRA
branch always
+
+
+
+
BSR
(S)-:=PC / branch always
+
+
+
+
BBRn
branch on bit n reset
+
+
+
+
BBSn
branch on bit n set
+
+
+
+
RMBn
{adr}:={adr} nand 2^n
+
*
+
+
+
SMBn
{adr}:={adr} or 2^n
+
*
+
+
+
MAP
?
+
+
+
+
+
+Warning! Some information is based on 65C02 documents, others is just
+guessed. There might be some mistakes in here.
+
+
+
+Frequency:
+
+The frequency registers of the SID are written with a 16 bit value which is added to the oscillator every
+clock cycle. Calculating a frequency register value for a given frequency can be done using these formulas:
+
+PAL: x = f * (18*2^24)/17734475 (0 - 3848 Hz)
+NTSC: x = f * (14*2^24)/14318318 (0 - 3995 Hz)
+
+
+Waveforms:
+
+The SID offers four basic waveforms which can be selected by the control register of each channel.
+
+
+
+
+Pulse width:
+
+The pulse waveform offers additional control via the 12 bit pulse width registers which are available for
+every channel. A value of $800 will result in a square wave.
+
+
+
+For the purposes of Stella programming, a single television "frame" consists
+of 262 horizontal lines, and each line is divided by 228 clock counts
+(3.58MHz). The actual TV picture is drawn line by line from the top down
+60 times a second, and actaully consists of only a portion of the entire
+"frame" (see diag. #1). A typical frame will consists of 3 vertical sync
+(VSYNC) lines*, 37 vertical blank (VBLANK) lines, 192 TV picture lines,
+and 30 overscan lines. Atari's research has shown that this pattern will
+work on all types of TV sets. Each scan lines starts with 68 clock counts of
+horizontal blank (not seen on the TV screen) followed by 160 clock counts to
+fully scan one line of TV picture. When the electron beam reaches the end
+of a scan line, it returns to the left side of the screen, waits for the 68
+horizontal blank clock counts, and proceeds to draw the next line below.
+
+All horizontal timing is taken care of by hardware, but the microprocessor
+must "manually" control vertical timing to signal the start of the next
+frame. When the last line of the previous frame is detected, the
+microprocessor must generate 3 lines of VSYNC, 37 lines of VBLANK, 192
+lines of actual TV picture, and 30 lines of overscan. Fortunately, both
+VSYNC and VBLANK can simply be turned on and off at the appropriate
+times, freeing the microprocessor for other activities during their execution.
+
+
+* (to signal the TV set to start a new frame)
+
+
+The actual TV picture is drawn one line at a time by having the
+microprocessor enter the data for that line into the Television Interface
+Adaptor (TIA) chip, which then converts the data into video signals. The
+TIA can only have data in it that pertains to the line being currently drawn,
+so the microprocessor must be "one step ahead" of the electron beam on each
+line. Since one microprocessor machine cycle occurs every 3 clock counts,
+the programmer has only 76 machine cycles per line (228/3 = 76) to
+construct the actual picture (actually less because the microprocessor must
+be ahead of the raster). To allow more time for the software, it is customary
+(but not required) to update the TIA every two scan lines. The portion of
+the program that constructs this TV picture is referred to as the "Kernel", as
+it is the essence or kernel of the game.
+
+
+In general, the remaining 70 scan lines (3 for VSYNC, 37 for VBLANK, and
+30 for overscan) will provides 5,320 machine cycles (70 lines x 76 machine
+cycles) for housekeeping and game logic. Such activities as calculating the
+new position of a player, updating the score, and checking for new inputs
+are typically done during this time.
+
+
+The TIA is a custom IC designed to create the TV picture and sound from
+the instructions sent to it by the microprocessor. It converts the 8 bit
+parallel data from the microprocessor into signals that are sent to video
+modulation circuits which combine and shape those signals to be compatible
+with ordinary TV reception. A "playfield" and 5 moveable objects can be
+created and manipulated by software.
+
+A playfield consisting of walls, clouds, barriers, and other seldom moved
+objects can be created over a colored background. The 5 moveable objects
+can be positioned anywhere, and consists of 2 players, 2 missiles, and a ball.
+The playfield, players, missiles, and ball are created and manipulated by a
+series of registers in the TIA that the microprocessor can address and write
+into. Each type of object has certain defined capabilities. For example, a
+player can be moved with one instruction, but the playfield must be
+completely re-drawn in order to make it "move".
+
+Color and luminosity (brightness) can be assigned to the background,
+playfield, and 5 moveable objects. Sound can also be generated and
+controlled for volume, pitch, and type of sound. Collisions between the
+various objects on the TV screen are detected by the TIA and can be read by
+the microprocessor . Input ports which can be read by the microprocessor
+give the status of some of the various hand held controllers.
+
+
+
+2.0 The Registers
+
+
+All instructions to the TIA are achieved by addressing and writing to
+various registers in the chip. A key point to remember is data written in a
+register is latched an retained until altered by another write operation into
+that register. For example, if the color register for a player is set for red,
+that player will be red every time it is drawn until that color register is
+changed. All of the registers are addressed by the microprocessor as part of
+the overall RAM/ROM memory space.
+
+All registers have fixed address locations and pre-assigned address names for handy
+reference. Many registers do not use all 8 data bits, and some registers are used to
+"strobe" or trigger events. A "strobe" register executes its function the instant it is
+written to (the data written is ignored). The only registers the microprocessor can read
+are the collision registers and input port registers. These registers are conveniently
+arranged so that the data bits of interest always appear as data bits 6 or 7 for easy access.
+
+
+
+
+
+3.0 Synchronization
+
+
+
+3.1 Horizontal Timing
+
+ When the electron beam scans across the TV screen and reaches the right
+ edge, it must be turned off and moved back to the left edge of the screen to
+ begin the next scan line. The TIA takes care of this automatically,
+ independent of the microprocessor. A 3.58 MHz oscillator generates clock
+ pulses called "color clocks" which go into a pulse counter in the TIA. This
+ counter allows 160 color clocks for the beam to reach the right edge, then
+ generates a horizontal sync signal (HSYNC) to return the beam to the left
+ edge. It also generates the signal to turn the beam off (horizontal blanking)
+ during its return time of 68 color clocks. Total round trip for the electron
+ beam is 160 + 68 = 228 color clocks. Again, all the horizontal timing is
+ taken care of by the TIA without assistance from the microprocessor.
+
+
+
+3.2 Microprocessor Synchronization
+
+ The microprocessor's clock is the 3.58 MHz oscillator divided by 3, so one
+ machine cycle is 3 color clocks. Therefore, one complete scan line of 228
+ color clocks allows only 76 machine cycles (228/3 = 76) per scan line. The
+ microprocessor must be synchronized with the TIA on a line-by-line basis,
+ but program loops and branches take unpredictable lengths of time. To
+ solve this software sync. problem, the programmer can use the WSYNC
+ (Wait for SYNC) strobe register. Simply writing to the WSYNC causes the
+ microprocessor to halt until the electron beam reaches the right edge of the
+ screen, then the microprocessor resumes operation at the beginning of the
+ 68 color clocks for horizontal blanking. Since the TIA latches all
+ instructions until altered by another write operation, it could be updated
+ every 2 or 3 lines. The advantage is the programmer gains more time to
+ execute software, but at a price paid with lower vertical resolution in the
+ graphics.
+
+ NOTE: WSYNC and all the following addresses' bit structures are itemized
+ in the TIA hardware manual. The purpose of this document is to make
+ them understandable.
+
+
+
+3.3 Vertical timing
+
+ When the electron beam has scanned 262 lines, the TV set must be signaled
+ to blank the beam and position it at the top of the screen to start a new
+ frame. This signal is called vertical sync, and the TIA must transmit this
+ signal for at least 3 scan lines. This is accomplished by writing a "1" in D1
+ of VSYNC to turn it on, count at least 2 scan lines, then write a "0" to D1 of
+ VSYNC to turn it off.
+
+ To physically turn the beam off during its repositioning time, the TV set
+ needs 37 scan lines of vertical blanks signal from the TIA. This is
+ accomplished by writing a "1" in D1 of VBLANK to turn it on, count 37
+ lines, then write a "0" to D1 of VBLANK to turn it off. The microprocessor
+ is of course free to execute other software during the vertical timing
+ commands, VSYNC and VBLANK.
+
+
+
+
+4.0 Color and Luminosity
+
+
+ Color and luminosity can be assigned to the background (BK), playfield
+ (PF), ball (BL), player 0 (P0), player 1(P1), missile 0 (M0), and missile 1
+ (M1). There are only four color-lum registers for these 7 objects, so the
+ objects are paired to share the same register according to the following list:
+
+
+
+
+
color-lum register
Objects colored
+
COLUMP0
P0, M0 (player 0, missile 0)
+
COLUMP1
P1, M1 (player 1, missile 1)
+
COLUMPF
PF, BL (playfield, ball)
+
COLUMBK
BK (background)
+
+
+
+ For example, if the COLUMP0 register is set for light red, both P0 and M0
+ will be light red when drawn.
+
+ A color-lum register is set for both color and luminosity by writing a single 7
+ bit instruction to that register. Four of the bits select one of the 16
+ available colors, and the other 3 bits select one of 8 levels of luminosity
+ (brightness). The specific codes required to create specific color and lum are
+ listed in the Detailed Address List of the TIA hardware manual. As with all
+ registers (except the "strobe" registers), the data written to them is latched
+ until altered by another write operation.
+
+(These registers are referred to here as COLUMxx, but everywhere else
+they are COLUxx, including later in this document. --BW)
+
+
+5.0 Playfield
+
+
+ The PF register is used to create a playfield of walls, clouds, barriers, etc., that are
+ seldom moved. This low resolution register is written into to draw the left half of the
+ TV screen only. The right half of the screen is drawn by software selection of whether a
+ duplication or a reflection of the right half.
+
+ The PF register is 20 bits wide, so the 20 bits are written into 3 addresses:
+ PF0, PF1, and PF2. PF0 is only 4 bits wide and constructs the first 4 "bits"
+ of the playfield, starting at the left edge of the TV screen. PF1 constructs
+ the next 8 "bits", and PF2 the last 8 bits" which end at the center of the
+ screen. The PF register is scanned from left to right and where a "1" is
+ found the PF color is drawn, and where a "0" is found, the BK color is
+ drawn. To clear the playfield, obviously zeros must be written into PF0,
+ PF1, and PF2.
+
+ To make the right half of the playfield into a duplication or copy of the left
+ half, a "0" is written to D0 of the CTLPF (control playfield) register.
+ Writing a "1" will cause the reflection to be displayed.
+
+
+
+6.0 The Moveable Objects Graphics
+
+
+ All 5 moveable objects (P0, M0, P1, M1, BL) can be assigned a horizontal
+ location on the screen and moved left or right relative to their location.
+ Vertical positions, however, are treated in an entirely different manner. In
+ principle, these objects appear at whatever scan lines their graphics
+ registers are enabled. For example, let us assume the ball is to be
+ positioned vertically in the center of the screen. The screen has 192 scan
+ lines and we want the ball to be 2 scan lines "thick". The ball graphics
+ would be disabled until scan line 96, enabled for 2 scan lines, then disabled
+ for the rest of the frame. Each type of object (players, missiles, and ball)
+ has its own characteristics and limitations.
+
+
+
+6.1 Missile Graphics (M0, M1)
+
+ The two missile graphics registers will draw a missile on any scan line by
+ writing a "1" to the one bit enable missile registers (ENAM0, ENAM1).
+ Writing a "0" to these registers will disable the graphics. The missiles' left
+ edge is positioned by a horizontal position register, but the right edge is a
+ function of how wide the missile is make. Width of a missile is controlled by
+ writing into bits D4 and D5 of the number-size registers (NUSIZ0,
+ NUSIZ1). This has the effect of "stretching" the missile out over 1,2,4, or 8
+ color clock counts (a full scan line is 160 color clocks).
+
+
+
+6.2 Ball Graphics (BL)
+
+ The ball graphics register works just like the missile registers. Writing a
+ "1" to the enable ball register (ENABL) enables the ball graphics until the
+ register is disabled. The ball can also be "stretched" to widths of 1, 2, 4, or 8
+ color clock counts by writing to bits D4 and D5 of the CTRLPF register.
+
+ The ball can also be vertically delayed one can line. For example, if the ball
+ graphics were enabled on scan line 95, it could be delayed to not display on
+ the screen until scan line 96 by writing a "1" to D0 of the vertical delay
+ (VDELBL) register. The reason for having a vertical delay capability is
+ because most programs will update the TIA every 2 lines. This confines all
+ vertical movements of objects to 2 scan line "jumps". The use of vertical
+ delay allows the objects to move one scan line at a time.
+
+
+
+6.3 Player Graphics (P0, P1)
+
+ The player graphics are the most sophisticated of all the moveable objects.
+ They have all the capabilities of the missile and ball graphics, plus three
+ move capabilities. Players can take on a "shape" such as a man or an
+ airplane, and the player can easily be flipped over horizontally to display
+ the mirror image (reflection) instead of the original image, plus multiple
+ copies of the players can be created.
+
+ The player graphics are drawn line-by-line like all other graphics. The
+ difference here is each scan line of the player is 8 "bits" wide, whereas the
+ missiles and ball are one "bit" wide. Therefore, a player can be though of as
+ being drawn of graph paper 8 squares wide and as tall as desired. To "color
+ in the squares" of this imaginary graph paper, 8 data bits are written into
+ the players graphics registers (GP0, GP1). This 8 bit register is scanned
+ from D7 to D0, and wherever a "1" is found that "square" gets the players'
+ color (from the color-lum register) and where a "0" is found that "square"
+ gets the background color. To position a player vertically, simply leave all
+ "0's" in the graphics registers (GP0, GP1) until the electron beam is on the
+ scan line desired, write to the graphics register line-by-line describing the
+ player, then write all "0's" to turn off the players' graphics until the end of
+ that frame.
+
+ To display a mirror image (reflection) instead of the original figure, write a
+ "1" to D3 of the one bit reflection register (REFP0, REFP1). A "0" written to
+ these registers restores the original figure.
+
+ Multiple copies of players as well as their size are controlled by writing 3
+ bits (D0, D1, D2) into the number-size registers (NUSIZ0, NUSIZ1). These
+ three bits select from 1 to 3 copies of the player, spacing of those copies, as
+ well as the size of the player (each "square" of the player can be 1, 2, or 4
+ clocks wide). Whenever multiple copies are selected, the TIA automatically
+ creates the same number of copies of the missile for that player. Again, the
+ specifics of all this are laid out in the TIA hardware manual.
+
+ Vertical delay for the players works exactly like the ball by writing a "1" to
+ D0 in the players' vertical delay registers (VDELP0, VDELP1). Writing a
+ "0" to these locations disables the vertical delay.
+
+
+
+7.0 Horizontal Positioning
+
+
+ The horizontal position of each object is set by writing to its associated reset
+ register (RESP0, RESP1, RESM0, RESM1, RESBL) which are all "strobe"
+ registers (they trigger their function as soon as they are addressed). That
+ causes the object to be positioned wherever the electron bean was in its
+ sweep across the screen when the register was reset. for example, if the
+ electron beam was 60 color clocks into a scan line when RESP0 was written
+ to, player 0 would be positioned 60 color clocks "in" on the next scan line.
+ Whether or not P0 is actually drawn on the screen is a function of the data
+ in the GP0 register, but if it were drawn, it would show up at 60. Resets to
+ these registers anywhere during horizontal blanking will position objects at
+ the left edge of the screen (color clock 0). Since there are 3 color clocks per
+ machine cycle, and it can take up to 5 machine cycles to write the register,
+ the programmer is confined to positioning the objects at 15 color clock
+ intervals across the screen. This "course" positioning is "fine tuned" by the
+ Horizontal Motion, explained in section 8.0.
+
+ Missiles have an additional positioning command. Writing a "1" to D1 of
+ the reset missile-to-player register (RESMP0, RESMP1) disables that
+ missiles' graphics (turns it off) and repositions it horizontally to the center
+ of its associated player. Until a "0" is written to the register, the missile's
+ horizontal position is locked to the center of its player in preparation to be
+ fired again.
+
+
+
+8.0 Horizontal Motion
+
+
+ Horizontal motion allows the programmer to move any of the 5 graphics
+ objects relative to their current horizontal position. Each object has a 4 bit
+ horizontal motion register (HMP0, HMP1, HMM0, HMM1, HMBL) that can
+ be loaded with a value in the range of +7 to -8 (negative values are
+ expressed in two's complement from). This motion is not executed until the
+ HMOVE register is written to, at which time all motion registers move their
+ respective objects. Objects can be moved repeatedly by simply executing
+ HMOVE. Any object that is not to move must have a 0 in its motion
+ register. With the horizontal positioning command confined to positioning
+ objects at 15 color clock intervals, the motion registers fills in the gaps by
+ moving objects +7 to -8 color clocks. Objects can not be placed at any color
+ clock position across the screen. All 5 motion registers can be set to zero
+ simultaneously by writing to the horizontal motion clear register (HMCLR).
+
+ There are timing constraints for the HMOVE command. The HMOVE
+ command must immediately follow a WSYNC (Wait for SYNC) to insure the
+ HMOVE operation occurs during horizontal blanking. This is to allow
+ sufficient time for the motion registers to do their thing before the electron
+ beam starts drawing the next scan line. Also, for mysterious internal
+ hardware considerations, the motion registers should not be modified for at
+ least 24 machine cycles after an HMOVE command.
+
+
+
+9.0 Object Priorities
+
+
+ Each object is assigned a priority so when any two objects overlap the one
+ with the highest priority will appear to move in front of the other. To
+ simplify hardware logic, the missiles have the same priority as their
+ associated player, and the ball has the same priority as the playfield. The
+ background, of course, has the lowest priority. The following table
+ illustrates the normal (default) priority assignments.
+
+
+
+
Priority
Objects
+
1
P0, M0
+
2
P1, M1
+
3
BL, PF
+
4
BK
+
+
+
+ This priority assignment means that players and missiles will move in front
+ of the playfield. To make the players and missiles move behind the
+ playfield, a "1" must be written to D2 of the CTRLPF register. The
+ following table illustrates how the priorities are affected:
+
+
+
+
Priority
Objects
+
1
BL, PF
+
2
P0, M0
+
3
P1, M1
+
4
BK
+
+
+
+ One more priority control is available to be used for displaying the score.
+ When a "1" is written to D1 of the CTRLPF register, the left half of the
+ playfield takes on the color of player 0, and the right half the color of player
+ 1. The game score can now be displayed using the PF graphics register, and
+ the score will be in the same color as its associated player.
+
+
+
+10.0 Collisions
+
+
+ The TIA detects collisions between any of the 6 objects it generates (the
+ playfield and 5 moveable objects). There are 15 possible two-object
+ collisions which are stored in 15 one bit latches. Each collision register
+ contains two of these latches which are read by the microprocessor on D6
+ and D7 of the data bus for easy access. A "1" on the data line indicates the
+ collision it records has occurred. The collision registers could be read at any
+ time but is usually done during vertical blank after all possible collisions
+ have occurred. The collision registers are all reset simultaneously by
+ writing to the collision reset register (CXCLR).
+
+
+
+11.0 Sound
+
+
+ There are two audio circuits for generating sound. They are identical but
+ completely independent and can be operated simultaneously to produce
+ sound effects through the TV speaker. Each audio circuit has three
+ registers that control a noise-tone generator (what kind of sound), a
+ frequency selection (high or low pitch of the sound), and a volume control.
+
+
+11.1 Tone
+
+ The noise-tone generator is controlled by writing to the 4 bit audio control
+ registers (AUDC0, AUDC1). The values written cause different kinds of
+ sounds to be generated. Some are pure tones like a flute, others have
+ various "noise" content like a rocket motor or explosion. Even though the
+ TIA hardware manual lists the sounds created by each value, some
+ experimentation will be necessary to find "your sound".
+
+
+
+11.2 Frequency
+
+ Frequency selection is controlled by writing to a 5 bit audio frequency
+ register (AUDF0, AUDF1). The value written is used to divide a 30KHz
+ reference frequency creating higher or lower pitch of whatever type of sound
+ is created by the noise-tone generator. By combining the pure tones
+ available from the noise-tone generator with frequency selection a wide
+ range of tones can be generated.
+
+
+
+11.3 Volume
+
+ Volume is controlled by writing to a 4 bit audio volume register (AUDV0,
+ AUDV1). Writing 0 to these registers turns sound off completely, and
+ writing any value up to 15 increases the volume accordingly.
+
+
+
+
+12.0 Input Ports
+
+
+ There are six input ports whose logic states can be read on D7 by reading
+ the input port addresses (INPT0, thru INPT5). These six ports are divided
+ into two types, "dumped" and "latched".
+
+
+12.1 Dumped Input Ports (INPT0 thru INPT3)
+
+ These four ports are used to read up to four paddle controllers. Each paddle controller
+ contains an adjustable pot controlled by the knob on the controller. The output of the
+ pot is used to charge a capacitor in the console, and when the capacitor is charged the
+ input port goes HI. The microprocessor discharges this capacitor by writing a "1" to D7
+ of VBLANK then measures the time it takes to detect a logic one at that port. This
+ information can be used to position objects on the screen based on the position of the
+ knob on the paddle controller.
+
+
+
+12.2 Latched Input Ports (INPT4, INPT5)
+
+ These two ports have latches that are both enabled by writing a "1" or
+ disabled by writing a "0" to D6 of VBLANK. When disabled the
+ microprocessor reads the logic level of the port directly. When enabled, the
+ latch is set for logic one and remains that way until its port goes LO. When
+ the port goes LO the latch goes LO and remains that way regardless of what
+ the port does. The trigger buttons of the joystick controllers connect to
+ these ports.
+
+
+
+
+
+
THE PIA (6532)
+
+
+1.0 General
+
+
+ The PIA chip is an off-the-shelf 6532 Peripheral Interface Adaptor which
+ has three functions: a programmable timer, 128 bytes of RAM, and two 8
+ bit parallel I/O ports.
+
+
+
+2.0 Interval timer
+
+
+ The PIA uses the same clock as the microprocessor so that one PIA cycle
+ occurs for each machine cycle. The PIA can be set for one of four different
+ "intervals", where each interval is some multiple of the clock (and therefore
+ machine cycles). A value from 1 to 255 is loaded into the PIA which will be
+ decremented by one at each interval. The timer can now be read by the
+ microprocessor to determine elapsed time for timing various software
+ operations and keep them synchronized with the hardware (TIA chip).
+
+
+2.1 Setting the timer
+
+ The timer is set by writing a value or count (from 1 to 255) to the address of
+ the desired interval setting according to the following table :
+
+
+
+
Hex Address
Interval
Mnemonic
+
294
1 clock
TIM1T
+
295
8 clocks
TIM8T
+
296
64 clocks
TIM64T
+
297
1024 clocks
T1024T
+
+
+
+ For example, if the value of 100 were written to TIM64T (HEX address 296)
+ the timer would decrement to 0 in 6400 clocks (64 clocks per interval x 100
+ intervals) which would also be 6400 microprocessor machine cycles.
+
+
+
+2.2 Reading the timer
+
+ The timer may be read any number of times after it is loaded of course, but
+ the programmer is usually interested in whether or not the timer has
+ reached 0. The timer is read by reading INTIM at hex address 284.
+
+
+
+2.3 When the timer reaches zero
+
+ The PIA decrements the value or count loaded into it once each interval
+ until it reaches 0. It holds that 0 counts for one interval, then the counter
+ flips to FF(HEX) and decrements once each clock cycle, rather than once per
+ interval. The purpose of this feature is to allow the programmer to
+ determine how long ago the timer zeroed out in the event the timer was
+ read after it passed zero.
+
+
+
+
+3.0 RAM
+
+
+ The PIA has 128 bytes of RAM located in the Stella memory map from HEX
+ address 80 to FF. The microprocessor stack is normally located from FF on
+ down, and variables are normally located from 80 on up (hoping the two
+ never meet).
+
+
+
+4.0 The I/O ports
+
+
+ The two ports (Port A and Port B) are 8 bits wide and can be set for either
+ input or output. Port A is used to interface to carious hand-held controllers
+ but Port B is dedicated to reading the status of the Stella console switches.
+
+
+4.1 Port B - Console Switches (read only)
+
+ Port B is hardwired to be an input port only that is read by addressing
+ SWCHB (HEX 282) to determine the status of all the console switches
+ according to the following table:
+
+
+
+
Data Bit
Switch
Bit Meaning
+
D7
P1 difficulty
0 = amateur (B), 1 = pro (A)
+
D6
P0 difficulty
0 = amateur (B), 1 = pro (A)
+
D5/D4
(not used)
+
D3
color - B/W
0 = B/W, 1 = color
+
D2
(not used)
+
D1
game select
0 = switch pressed
+
D0
game reset
0 = switch pressed
+
+
+
+
+
+
+5.0 Port A - Hand Controllers
+
+
+ Port A is under full software control to be configured as an input or an
+ output port. It can then be used to read or control various hand-head
+ controllers with the data bits defined differently depending on the type of
+ controller used.
+
+
+5.1 Setting for input or output
+
+ Port A has an 8 bit wide Data Direction Register (DDR) that is written to at
+ SWACNT (HEX 281) to set each individual pin of Port A to either input or
+ output. The Port A pins are labeled PA0 thru PA7, and writing a "0" to a
+ pins' DDR bit sets that pin as input, and a "1" sets it as an output. For
+ example, writing all 0's to SWACNT (the DDR for Port A) sets PA0 thru
+ PA7 (all 8 pins of Port A) as inputs. If F0 (11110000) were written to
+ SWACNT then PA7, PA6, PA5 & PA4 would be outputs, and PA3, PA2, PA1
+ & PA0 would be inputs.
+
+
+
+5.2 Inputting and Outputting
+
+ Once the DDR has set the pins of Port A for input or output they may be
+ read or written to by addressing SWCHA (HEX 280).
+
+
+
+5.3 Joystick Controllers
+
+ Two joysticks can be read by configuring the entire port as input and
+ reading the data at SWCHA according to the following table:
+
+
+
+
Data Bit
Direction
Player
+
D7
right
P0
+
D6
left
P0
+
D5
down
P0
+
D4
up
P0
+
D3
right
P1
+
D2
left
P1
+
D1
down
P1
+
D0
up
P1
+
+ (P0 = left player, P1 = right player)
+
+
+ A "0" in a data bit indicates the joystick has been moved to close that
+ switch. All "1's" in a player's nibble indicates that joystick is not moving.
+
+
+
+ 5.4 Paddle (pot) controllers
+
+ Only the paddle triggers are read from the PIA. The paddles themselves
+ are read at INP0 thru INPT3 of the TIA. The paddle triggers can be read at
+ SWCHA according to the following table :
+
+
+
+
Data Bit
Paddle #
+
D7
P0
+
D6
P1
+
D5/D4
(not used)
+
D3
P2
+
D2
P3
+
D1/D0
(not used)
+
+
+
+
+
+5.5 Keyboard controllers
+
+ The keyboard controller has 12 buttons arranged into 4 rows and 3 columns.
+ A signal is sent to a row, then the columns are checked to see if a button is
+ pushed, then the next row is signaled and all columns sensed, etc. until the
+ entire keyboard is scanned and sensed. The PIA sends the signals to the
+ rows, and the columns are sensed by reading INPT0, INPT1, and INPT4 of
+ the TIA. With Port A configured as an output port, the data bits will send a
+ signal to the keyboard controller rows according to the following table :
+
+
+
+
Data Bit
Keyboard Row
Player
+
D7
bottom
P0
+
D6
third
P0
+
D5
second
P0
+
D4
top
P0
+
D3
bottom
P1
+
D2
third
P1
+
D1
second
P1
+
D0
top
P1
+
+(P0 = left player, P1 = right player)
+
+ NOTE : a delay of 400 microseconds is necessary between writing to this
+ port and reading the TIA input ports.
+
+
+
+
+
+6.0 Address summary table
+
+
+
+
Hex Address
Mnemonic
Purpose
+
280
SWCHA
Port A; input or output (read or write)
+
281
SWACNT
Port A DDR, 0= input, 1=output
+
282
SWCHB
Port B; console switches (read only)
+
283
SWBCNT
Port B DDR (hardwired as input)
+
284
INTIM
Timer output (read only)
+
294
TIM1T
set 1 clock interval (838 nsec/interval)
+
295
TIM8T
set 8 clock interval (6.7 usec/interval)
+
296
TIM64T
set 64 clock interval (53.6 usec/interval)
+
297
T1024T
set 1024 clock interval (858.2 usec/interval)
+
+
+ NOTE: one clock is also one microprocessor machine cycle
+
+
+
+
+
PAL/SECAM CONVERSIONS
+
+PAL
+
+1. The number of scan lines, and therefore the frame time increases from
+ NTSC to PAL according to the following table:
+
+
+
+
+
NTSC
+
PAL
+
+
+
scanlines
+
microseconds
+
scanlines
+
microseconds
+
+
+
VBLANK
+
40
+
2548
+
48
+
3085
+
+
+
KERNEL
+
192
+
12228
+
228
+
14656
+
+
+
OVERSCAN
+
30
+
1910
+
36
+
2314
+
+
+
FRAME
+
262
+
16686
+
312
+
20055
+
+
+
+
+
+ 2. Sounds will drop a little in pitch (frequency) because of a slower crystal
+ clock. Some sounds may need the AUDF0/AUDF1 touched up.
+
+ 3. PAL operates at 50 Hz compared to NTSC 60Hz, a 17% reduction. If
+ game play speed is based on frames per second, it will slow down by 17%.
+ This can be disastrous for most skill/action carts. If the NTSC version is
+ designed with 2 byte fractional addition techniques (or anything not based
+ on frames per second) to move objects, then PAL conversion can be as
+ simple as changing the fraction tables, avoiding major surgery on the
+ program.
+
+
+SECAM
+
+1. SECAM is a little weird. It takes the PAL software, but the console
+ color/black & white switch is hardwired as black & white. Therefore, it
+ reads the PAL black & white tables in software and assigns a fixed color to
+ each lum of black & white according to the following table:
+
+
+
+
Lum
Color
+
0
Black
+
2
Blue
+
4
Red
+
6
Magenta
+
8
green
+
A
cyan
+
C
yellow
+
E
white
+
+
+
+ There is a trap here: the manual is the same for NTSC, PAL, & SECAM.
+ This means that the descriptions for black & white must jive between NTSC
+ & PAL. If you make major changes to PAL black & white to achieve good
+ SECAM color, NTSC black & white must be made similar.
+
+ 2. PAL sounds work fine on SECAM with one exception: when a sound is to
+ be turned off, it must be done by setting AUDV0/AUDV1 to 0, not by setting
+ AUDC0/AUDC1 to 0. Otherwise, you get an obnoxious background sound.
+
+
+
+
+
TIA 1A - TELEVISION INTERFACE ADAPTOR (MODEL 1A)
+
+
+GENERAL DESCRIPTION
+
+
+ The TIA is an MOS integrated circuit designed to interface between an
+ eight (8) bit microprocessor and a television video modulator and to convert
+ eight (8) bit parallel data into serial outputs for the color, luminosity, and
+ composite sync required by a video modulator.
+
+ This circuit operates on a line by line basis, always outputting the same
+ information every television line unless new data is written into it by the
+ microprocessor.
+
+ A hardware sync counter produces horizontal sync timing independent of
+ the microprocessor. Vertical sync timing is supplied to this circuit by the
+ microprocessor and combined into composite sync.
+
+ Horizontal position counters are used to trigger the serial output of five (5)
+ horizontally movable objects; two players, two missiles and a ball. The
+ microprocessor can add or subtract from these position counters to move
+ these objects right or left.
+
+ The microprocessor determines all vertical position and motion by writing
+ zeros or ones into object registers before each appropriate horizontal line.
+
+ Walls, clouds and other seldom moved objects are produced by a low
+ resolution data register called the playfield register.
+
+ A fifteen (15) bit collision register detects all fifteen possible two object
+ collisions between these six (6) objects (five moveable and one playfield).
+ This collision register can be read and reset by the microprocessor. Six input
+ ports are also provided on this chip that can be read by the microprocessor.
+ These input ports and the collision register are the only chip addresses that
+ can be read by the microprocessor. All other addresses are write only.
+
+ Color luminosity registers are included that can be programmed by the
+ microprocessor with eight (8) luminosity and fifteen (15) color values. A
+ digital phase shifter is included on this chip to provide a single color output
+ with fifteen (15) phase angles.
+
+ Two (2) independent audio generating circuits are included, each with
+ programmable frequency, noise content, and volume control registers.
+
+
+
+DETAILED DESCRIPTION
+
+
+
+1. Data and addressing
+
+
+ Registers on this chip are addressed by the microprocessor as part of its
+ overall RAM-ROM memory space. The attached table of read-write
+ addresses summarizes the addressable functions. There are no registers
+ that are both read and write. Some addresses however are both read and
+ write, with write data going into one register and read data returning from
+ a different register.
+
+ If the read-write line is low, the data bits indicated in this table will be
+ written into the addressed write location when the 02 clock goes from high
+ to low. Some registers are eight bits wide, some only one bit, and some
+ (strobes) have no bits, performing only control functions (such as resets)
+ when their address is written.
+
+ If the read-write line is high, the addressed location can be read by the
+ microprocessor on data lines 6 and 7 while the 02 clock is high.
+
+ The addresses given in the table refer only to the six (6) real address lines.
+ If any of the four (4) chip select lines are used for addressing, the addresses
+ must be modified accordingly.
+
+
+
+2. Synchronization
+
+
+ A. Horizontal Timing
+
+ A hardware counter on this chip produces all horizontal timing (such as
+ sync, blank, burst) independent of the microprocessor, This counter is
+ driven from an external 3.58 Mhz oscillator and has a total count of 228.
+ Blank is decoded as 68 counts and sync and color burst as 16 counts.
+
+
+ B. Vertical Timing
+
+ There are one bit, addressable registers on this chip for vertical sync and
+ vertical blank. The timing for these functions is established by the
+ microprocessor by writing zero or one into these bits. (VSYNC, VBLANK )
+
+
+ C. Composite Sync
+
+ Horizontal sync and the output of the vertical sync bit are combined
+ together to produce composite sync. This composite sync signal drives a
+ chip output pad to an external composite video resistor network.
+
+
+ D. Microprocessor Synchronization
+
+ The 3.58 MHz oscillator also clocks a divide by three counter on this chip
+ whose output (1.19 Mhz) is buffered to drive an output pad called 00. This
+ pad provides the input phase zero clock to the microprocessor which then
+ produces the system 02 clock (1.19 Mhz).
+ Software program loops require different lengths of time to run depending
+ on branch decisions made within the program. Additional synchronization
+ between the software and hardware. This is done with a one bit latch called
+ WSYNC (wait for sync). When the microprocessor finishes a routine such
+ as loading registers for a horizontal line, or computing new vertical
+ locations during vertical blank, it can address WSYNC, setting this latch
+ high. When this latch is high, it drives an output pad to zero connected to
+ the microprocessor ready line (RDY). A zero on this line causes the
+ microprocessor to halt and wait. As shown in figure 2, WSYNC latch is
+ automatically reset to zero by the leading edge of the next horizontal blank
+ timing signal, releasing the RDY line, allowing the microprocessor to begin
+ its computation and register writing for this horizontal television line or
+ line pair.
+
+
+
+
+3. Playfield graphics Register
+
+
+ A. Description
+
+ Objects such as walls, clouds, and score) which are not required to move, are
+ written into a 20 bit register called the playfield register. This register
+ (Figure 5) is loaded from the data bus by three separate write addresses
+ (PF0, PFl, PF2). Playfield may be loaded at any time. To clear the playfield,
+ zeros must be written into all three addresses.
+
+
+ B. Normal Serial Output
+
+ The playfield register is automatically scanned (and converted to serial
+ output) by a bi-directional shift register clocked at a rate which spreads the
+ twenty (20) bits out over the left half of a horizontal line. This scanning is
+ initiated by the end of horizontal blank (left edge of television screen).
+ Normally the same scan is then repeated, duplicating the same twenty (20)
+ bit sequence over the right half of the horizontal line.
+
+
+ C. Reflected Serial Output
+
+ A reflected playfield may be requested by writing a one into bit zero of the
+ playfield control register (CTRLPF). When this bit is true the scanning
+ shift register will scan the opposite direction during the right half of the
+ horizontal line, reversing the twenty (20) bit sequence.
+
+
+ D. Timing Constraints
+
+ Even though the playfield bytes (PF0, PFl, PF2) may be written to any time,
+ if one of them is changed while being serially scanned, part of the new value
+ may both show up on the television horizontal line.
+
+
+
+
+4. Horizontal Position Counters
+
+
+ A. Description
+
+ The playfield is a fixed graphics register, always starting its serial output
+ when triggered by the beginning of each television line. This chip also
+ includes five "moveable" graphics registers, whose serial outputs are
+ triggered by five separate horizontal position counters every time these
+ counters pass through zero count. These position counters are clocked
+ continuously during the unblanked portion of every horizontal line and
+ their count length is exactly equal to the normal number of clocks supplied
+ to them during this time. They will therefore pass through zero at the same
+ time during each horizontal television line and the triggered outputs will
+ have no horizontal motion. A typical horizontal counter is shown in figure 4.
+
+ If extra clocks are supplied to these counters (or normal clocks suppressed)
+ the zero crossing time will shift and the object will have moved left (extra
+ clocks) or right (fewer clocks). Some position counters have extra decoders
+ (in addition to a zero decode) to trigger multiple copies of the same object
+ across a horizontal line.
+
+ All position counters can be reset to zero count by the microprocessor at any
+ time, by a write instruction to the reset addresses (RESBL, RESM0, RESMl,
+ RESP0, RESPl). If reset occurs during horizontal blank, the object will
+ appear at the left side of the television screen. Properly timed resets may
+ position an object at any horizontal location consistent with the
+ microprocessor cycle time.
+
+
+ B. Ball position Counter
+
+ The ball position counter has only the zero crossing decode and therefore
+ cannot trigger multiple copies of the ball graphics.
+
+
+ C. Player Position Counters
+
+ Each player position counter has three decodes in addition to the zero
+ crossing decode. These decodes are controlled by bits 0,1,2 of the number
+ size control registers (NUSIZ0, NUSIZ1), and trigger 1,2, or 3 copies of the
+ player (at various spacings) across a horizontal line as shown on page ___.
+ These same control bits are used for the decodes on the missile position
+ counter, insuring an equal number of players and missiles.
+
+ D. Missile Position Counters
+
+ Missile position counters are identical to player position counters except
+ that they have another type of reset in addition to the previously discussed
+ horizontal position reset. These extra reset addresses (RESMP0, RESMP1)
+ write data bit 1 into a one bit register whose output is used to position the
+ missile (horizontally) directly on top of its corresponding player, and to
+ disable the missile serial output.
+
+
+
+
+5. Horizontal Motion Registers
+
+
+ A. General Description
+
+ There are five write only registers on this chip that contain the horizontal
+ motion values for each of the five moving objects. A typical horizontal
+ motion register is shown in figure 4 . The data bus (bits 4 through 7) is
+ written into these addresses (HMP0, HMPl, HMM0, HMMl, HMBL) to load
+ these registers with motion values. These registers supply extra (or fewer)
+ clocks to the horizontal position counters only when commanded to do so by
+ an HMOVE address from the microprocessor. These registers may all be
+ cleared to zero (no motion) simultaneously by an HMCLR command from
+ the microprocessor, or individually by loading zeros into each register.
+ These registers are each four bits in length and may be loaded with positive
+ (left motion), negative (right motion) or zero (no motion) values. Negative
+ values are represented in twos complement format.
+
+
+ B. Timing constraints
+
+ These registers may be loaded or cleared at almost any time. The motion
+ values they contain will be used only when an HMOVE command is
+ addressed, and then all five motion values will be used simultaneously into
+ all five horizontal position counters once. The only timing constraint on this
+ operation involves the HMOVE command. The HMOVE command must be
+ located in the microprocessor program immediately after a wait for sync
+ (WSYNC) command. This assures that the HMOVE operation begins at the
+ leading edge of horizontal blank, and has the full blank time to supply extra
+ or fewer clocks to the horizontal position counters. These registers should
+ not be modified for at least 24 Computer cycles after the HMOVE command.
+
+
+
+
+6. Moving Object Graphics Registers
+
+
+ A. General Description
+
+ There are five graphics registers for moving objects on this chip. These
+ graphics registers are loaded (written) in parallel by the microprocessor and
+ like the playfield register are scanned and converted to serial output.
+ Unlike the playfield register, which is always scanned beginning at the left
+ side of each horizontal line, moving object graphics registers are scanned
+ only when triggered by a start decode from their horizontal position
+ counter. A typical graphics register is shown in figure 4 .
+
+
+ B. Missile Graphics
+
+ The graphics registers for both missiles are identical and very simple. They
+ each consist of a one bit register called missile enable (ENAM0, ENAM1).
+ This graphics bit is scanned (outputted) only when triggered by its
+ corresponding position counter. There are control bits (bits 4, 5, of NUSIZ0,
+ NUSIZ1) that can stretch this single graphics bit out over widths of 1, 2, 4,
+ or 8 clocks of horizontal line time. (A full line is 160 clocks).
+
+
+ C. Player Graphics
+
+ The graphics registers for both players are identical and are rather complex.
+ They each consist of eight bit parallel registers (GRP0, GRP1) and a bi-
+ directional parallel to serial scan counter that converts the parallel data
+ into serial output. A one bit control register (REFP0, REFP1) determines
+ the direction (reflection) of the parallel to serial scan, outputing either D7
+ through D0, or D0 though D7. This allows reflection (horizontal flipping) of
+ player serial graphics data without having to flip the microprocessor data.
+
+ The clock into the scan counter can be controlled (three bits of NUSIZ0 and
+ NUSIZ1) to slow the scan rate and stretch the eight bits of serial graphics
+ out over widths of 8, 16, or 32 clocks of horizontal line time. These same
+ control bits are used in the player-missile motion counters to control
+ multiple copies, so only three player widths ( scan
+ rates) are available.
+
+
+ D. Vertical Delay
+
+ Each of the player graphics registers actually consists of two 8 bit parallel
+ registers. The first (GRP0, GRP1) is loaded (written) from the
+ microprocessor 8 bit data bus. The second is automatically loaded from the
+ output of the first. The reason for this is a complex subject called vertical
+ delay. A large amount of microprocessor time is required to generate
+ player, missile and playfield graphics (table look up, masking, comparisons,
+ etc.) and load these into this chip's registers. For most game programs this
+ time is just too large to fit into one horizontal line time. In fact for most
+ games it will barely fit into two line times (127 microseconds). Therefore,
+ individual graphics registers are loaded (written) every two lines, and used
+ twice for serial output between loads. This type of programing will
+ obviously limit the vertical height resolution of objects to multiples of two
+ lines. It also will limit the resolution of vertical motion to two lines jumps.
+ Nothing can be done about the vertical height resolution; however, vertical
+ motion can be resolved to a single line by addition of a second graphics
+ register that is automatically parallel loaded from the output of the first,
+ one line time after the first was loaded from the data bus. This second
+ graphics register output is therefore always delayed vertically by one line. A
+ control bit called vertical delay (VDEL0, VDEL1) selects which of these two
+ registers is to be used for serial output. If this control bit is set by the
+ microprocessor between picture frames, the object will be moved down
+ (delayed) by one line during the next frame. In most programming
+ applications player 0 graphics and player 1 graphics are loaded (written)
+ alternately, during the blank time just prior to each line as shown in (figure
+ 1). Since GRP0 and GRP1 addresses from the microprocessor alternate,
+ they are delayed by one line from each other. The GRP0 address decode can
+ therefore be used to load the delayed graphics register for player 1, and
+ GRP1 likewise to load the delayed graphics register for player 0. The two
+ vertical delay bits (VDEL0, VDELl) then select delayed or undelayed
+ registers for player 0 and player 1 as serial outputs.
+
+
+ E. Ball Graphics
+
+ The ball graphics register is almost identical to the missile graphics
+ register. It also consists of a single enable bit (ENABL) whose output is
+ triggered by the ball position counter. It also has two control bits (bits 4, 5
+ of CTRLPF) that can stretch this single graphics bit out over widths of 1, 2,
+ 4, or 8 clocks of horizontal line time. Unlike the missile graphics; however,
+ the ball graphics register has capability for vertical delay similar to the
+ player graphics. A second graphics (enable) bit is alternately loaded from
+ the output of the first, one line after the first was loaded from the data bus.
+ A ball vertical delay bit (VDELBL) selects which of these two graphics bits
+ is used for the ball serial output. The first graphics bit (ENABL) should be
+ loaded during the same horizontal blank time as player 0 (GRP0), because
+ GRP1 is used to load the second enable bit from the output of the first on
+ alternate lines.
+
+
+
+
+7. Collision Detection Latches
+
+
+ A. Definitions
+
+ The serial outputs from all the graphics registers represent real time
+ horizontal location of objects on the television screen. If any of these outputs
+ occur at the same time, they will overlap (collide) on the screen. There are
+ six objects generated on this chip (five moving and playfield) allowing
+ fifteen possible two object collisions. These overlaps (collisions) are detected
+ by fifteen "and" gates whenever they occur, and are stored in fifteen
+ individual latch register bits, as shown in figure 6.
+
+
+ B. Reading Collision
+
+ The microprocessor can read these fifteen collision bits on data lines 6 and 7
+ by addressing them two at a time. This could be done at any time but is
+ usually done between frames (during vertical blank) after all possible
+ collisions have serially occurred.
+
+
+ C. Reset
+
+ All collision bits are reset simultaneously by the microprocessor using the
+ reset address CXCLR. This is usually done near the end of vertical blank,
+ after collisions have been tested.
+
+
+
+
+
+8. Input ports
+
+
+ A. General Description
+
+ There are 6 input ports on this chip whose logic state may be read on data
+ line 7 with read addresses INPT0 through INPT5. These 6 ports are
+ divided into two types, "dumped" and "latched". See Figure 8.
+
+
+ B. Dumped Input Ports (I0 through I3)
+
+ These 4 input ports are normally used to read paddle position from an
+ external potentiometer-capacitor circuit. In order to discharge these
+ capacitors each of these input ports has a large transistor, which may be
+ turned on (grounding the input ports) by writing into bit 7 of the register
+ VBLANK. When this control bit is cleared the potentiometers begin to
+ recharge the capacitors and the microprocessor measures the time required
+ to detect a logic 1 at each input port.
+
+ As long as bit 7 of register VBLANK is zero, these four ports are general
+ purpose high impedance input ports. When this bit is a 1 these ports are
+ grounded.
+
+
+ C. Latched Input ports (I4, I5)
+
+ These two input ports have latches which can be enabled or disabled by
+ writing into bit 6 of register VBLANK.
+
+ When disabled, these latches are removed from the circuit completely and
+ these ports become two general purpose input ports, whose present logic
+ state can be read directly by the microprocessor.
+
+ When enabled, these latches will store negative (zero logic level) signals
+ appearing on these two input ports, and the input port addresses will read
+ the latches instead of the input ports.
+
+ When first enabled these latches will remain positive as long as the input
+ ports remain positive (logic one). A zero input port signal will clear a latch
+ value to zero, where it will remain (even after the port returns positive)
+ until disabled. Both latches may be simultaneously disabled by writing a
+ zero into bit 6 of register VBLANK.
+
+
+
+
+8.5 Priority Encoder
+
+
+ A. Purpose
+
+ As discussed in the section on collisions, simultaneous serial outputs from
+ the graphics registers represent overlap on the television screen. In order to
+ have color-luminosity values assigned to individual objects it is necessary to
+ establish priorities between objects when overlapped. The priority encoder
+ is shown in figure 3.
+
+
+ B. Priority Assignment
+
+ The lack of any objects results in a color-lum value called the background.
+ The background (BK) has lowest priority and only appears when no objects
+ are outputing. In order to simplify the logic, each missile is given the same
+ color-lum value and priority as its corresponding player (P0, M0) and the
+ ball is given the same color-lum value and priority as the playfield (PF, BL).
+
+ The following table illustrates the normal priority assignment:
+
+
+
+
Highest Priority
P0, M0
+
Second Highest
P1, M1
+
Third Highest
PF, BL
+
Lowest Priority
BK
+
+
+
+ Objects with higher priority will appear to move in front of objects with
+ lower priority. Players will therefore move in front of playfield (clouds,
+ walls, etc.).
+
+
+ C. Priority Control
+
+ There are two playfield control bits that affect priority, one called playfield
+ priority (PFP) (bit 2 of CTRLPF) and one called score (bit 1 of CTRLPF).
+ When a one is written into the PFP bit the priority assignment is modified
+ as shown below.
+
+
+
+
Highest Priority
PF, BL
+
Second Highest
P0, M0
+
Third Highest
P1, M1
+
Lowest Priority
BK
+
+
+
+ Players will then move behind playfield (clouds, wall, etc.). When a one is
+ written into the score control bit, the playfield is forced to take the color-lum
+ of player 0 in the left half of the screen and player 1 in the right half of the
+ screen. This is used when displaying score and identifies the score with the
+ correct player. The priority encoder produces 4 register select lines shown
+ in figure 3) that are mutually exclusive. These 4 lines select either
+ background, player 0, player 1 or playfield, and only one of them can be
+ true at a time.
+
+
+
+
+9. Color Luminance Registers
+
+
+ A. Description
+
+ There are four registers (shown in figure 3) that contain color-lum codes.
+ Four bits of color code and three its of luminance code may be written into
+ each of these registers (COLUP0, COLUP1, COLUPF, COLUBK) by the
+ microprocessor at any time. These codes (representing 16 color values and 8
+ luminance values) are given in the Detailed Address List.
+
+
+ B. Multiplexing
+
+ The serial graphics output from all six objects is examined by the priority
+ encoder which activates one of the four select lines into a 4 x 7 multiplexer.
+ This multiplexer (shown in figure 3) then selects one of the four color-lum
+ registers as a 7 line output. Three of these lines are binary coded
+ luminosity and go directly to chip output pads. The other four lines go to the
+ color phase shifter.
+
+
+
+
+10. Color Phase Shifter
+
+
+ This portion of the chip (shown in figure 3) produces a reference color
+ output (color burst) during horizontal blank and then during the unblanked
+ portion of the line it produces a color output shifted in phase with respect to
+ the color burst. The amount of phase shift determines the color and is
+ selected by the four color code lines from the Color-lum multiplexer. Binary
+ code 0 selects no color. Code 1 selects gold (same phase as color burst).
+ Codes 2 (0010) through 15 (1111) shift the phase from zero through almost
+ 360 degrees allowing selection of 15 total colors around the television color
+ wheel.
+
+
+
+11. Audio Circuits
+
+
+ Two audio circuits are incorporated on this chip. They are identical and
+ completely independent, although their outputs could be combined
+ externally into one speaker. Each audio circuit consists of parts described
+ below, and in figure 7.
+
+ A. Frequency Select
+
+ Clock pulses (at approximately 30 KHz) from the horizontal sync counter
+ pass through a divide by N circuit which is controlled by the output code
+ from a five bit frequency register (AUDF). This register can be loaded
+ (written) by the microprocessor at any time, and causes the 30 KHz clocks
+ to be divided by 1 (code 00000) through 32 (code 11111). This produces
+ pulses that are digitally adjustable from approximately 30 KHz to 1 KHz
+ and are used to clock the noise-tone generator.
+
+ B. Noise-Tone Generator
+
+ This circuit contains a nine bit shift counter which may be controlled by the
+ output code from a four bit audio control register(AUDC), and is clocked by
+ the frequency select circuit. The control register can be loaded by the
+ microprocessor at any time, and selects different shift counter feedback taps
+ and count lengths to produce a variety of noise and tone qualities.
+
+
+ C. Volume Select
+
+ The shift counter output is used to drive the audio output pad through four
+ driver transistors that are graduated in size. Each transistor is twice as
+ large as the previous one and is enable by one bit from the audio volume
+ register (AUDV). This audio volume register may be loaded by the
+ microprocessor at any time. As binary codes 0 through 15 are loaded, the
+ pad drive transistors are enabled in a binary sequence. The shift counter
+ output therefore can pull down on the audio output pad with 16 selectable
+ impedance levels.
+
+ This address halts microprocessor by clearing RDY latch to zero. RDY is set true again
+ by the leading edge of horizontal blank.
+
+ Data bits not used
+
+
+RSYNC (reset sync)
+
+ This address resets the horizontal sync counter to define the beginning of horizontal
+ blank time, and is used in chip testing.
+
+ Data bits not used.
+
+
+VSYNC
+
+This address controls vertical sync time by writing D1 into the VSYNC latch
+
+
+
D1
+
0
Stop vertical sync
+
1
Start vertical sync
+
+
+
+
+VBLANK
+
+ This address controls vertical blank and the latches and dumping transistors on the input
+ ports by writing into bits D7, D6 and D1 of the VBLANK register.
+
+
+
Data Bit
Value
Effect
+
D1
0
Stop vert. blank
+
1
Start vert. blank
+
D6
0
Disable INPT4, INPT5 latches
+
1
Enable INPT4, INPT5 latches
+
D7
0
Remove INPT1,2,3,6 dump path to ground
+
1
Dump INPT1,2,3,6 to ground
+
+ Note : Disable latches (D6 = 0) also resets latches to logic true
+
+
+
+PF0 (PF1, PF2)
+
+ These addresses are used to write into playfield registers
+
+
+
PF0
D7
D6
D5
D4
(not used)
+
PF1
D7
D6
D5
D4
D3
D2
D1
D0
+
PF2
D7
D6
D5
D4
D3
D2
D1
D0
+
+
+
+
+ PLAYFIELD REGISTERS SERIAL OUTPUT
+
+
+
1 horizontal line ( 160 clocks)
Playfield Reflect Control
+
4..7
7......0
0......7
4..7
7......0
0......7
REF = 0
+
PF0
PF1
PF2
PF0
PF1
PF2
+
center
+
+
+
4..7
7......0
0......7
7......0
0......7
7..4
REF = 1
+
PF0
PF1
PF2
PF2
PF1
PF0
+
+
+ each bit = 4 clocks
+
+
+CTRLPF
+
+ This address is used to write into the playfield control register
+(a logic 1 causes action as described below)
+
+
+
D0
REF (reflect playfield)
+
D1
SCORE (left half of playfield gets color of player 0, right half gets color of player
+
D2
PFP (playfield gets priority over players so they can move behind the playfield)
+
D4
Ball Size (see next table)
+
D5
+
+
+
+ D4 & D5 = BALL SIZE
+
+
D5
D4
Width
+
0
0
1 clock
+
0
1
2 clocks
+
1
0
4 clocks
+
1
1
8 clocks
+
+
+
+
+NUSIZ0 (NUSIZ1)
+
+ These addresses control the number and size of players and missiles.
+
+ Missile Size
+
+
D5
D4
Width
+
0
0
1 clock
+
0
1
2 clocks
+
1
0
4 clocks
+
1
1
8 clocks
+
+
+Player-Missile number & player size
+
+
D2
D1
D0
1/2 television line (80 clocks) 8 clocks per square
Description
+
0
0
0
+
X
+
+
+
+
+
+
+
+
+
one copy
+
0
0
1
+
X
+
+
X
+
+
+
+
+
+
+
two copies - close
+
0
1
0
+
X
+
+
+
+
X
+
+
+
+
+
two copies - med
+
0
1
1
+
X
+
+
X
+
+
X
+
+
+
+
+
three copies - close
+
1
0
0
+
X
+
+
+
+
+
+
+
+
X
+
two copies - wide
+
1
0
1
+
+
X
+
X
+
+
+
+
+
+
+
+
double size player
+
1
1
0
+
+
X
+
+
+
+
X
+
+
+
+
X
+
3 copies medium
+
1
1
1
+
+
X
+
X
+
X
+
X
+
+
+
+
+
+
quad sized player
+
+
+
+
+
+
+RESP0 (RESP1, RESM0, RESM1, RESBL)
+
+ These addresses are used to reset players, missiles and the ball. The object will begin its
+ serial graphics at the time of a horizontal line at which the reset address occurs.
+
+ No data bits are used
+
+
+RESMP0 (RESMP1)
+
+ These addresses are used to reset the horiz. location of a missile to the center of its
+ corresponding player. As long as this control bit is true (1) the missile will remain
+ locked to the center of its player and the missile graphics will be disabled. When a
+ zero is written into this location, the missile is enabled, and can be moved independently
+ from the player.
+
+
+ D1 = RESMP (missile-player reset)
+
+
+
+HMOVE
+
+ This address causes the horizontal motion register values to be acted upon during the
+ horizontal blank time in which it occurs. It must occur at the beginning of horiz. blank in
+ order to allow time for generation of extra clock pulses into the horizontal position
+ counters if motion is desired this command must immediately follow a WSYNC
+ command in the program.
+
+ No data bits are used.
+
+
+HMCLR
+
+This address clears all horizontal motion registers to zero (no motion).
+ No data bits are used.
+
+
+
+
+HMP0 (HMP1, HMM0, HMM1, HMBL)
+
+ These addresses write data (horizontal motion values) into the horizontal motion
+ registers. These registers will cause horizontal motion only when commanded to do so
+ by the horiz. move command HMOVE.
+ The motion values are coded as shown below :
+
+
+
D7
D6
D5
D4
Clocks
Effect
+
0
1
1
1
+7
Move left indicated number of clocks
+
0
1
1
0
+6
+
0
1
0
1
+5
+
0
1
0
0
+4
+
0
0
1
1
+3
+
0
0
1
0
+2
+
0
0
0
1
+1
+
0
0
0
0
0
No Motion
+
1
1
1
1
-1
Move right indicated number of clocks
+
1
1
1
0
-2
+
1
1
0
1
-3
+
1
1
0
0
-4
+
1
0
1
1
-5
+
1
0
1
0
-6
+
1
0
0
1
-7
+
1
0
0
0
-8
+
+
+ WARNING : These motion registers should not be modified during the 24 computer
+ cycles immediately following an HMOVE command. Unpredictable motion values may
+ result.
+
+
+
+ENAM0 (ENAM1, ENABL)
+
+ These addresses write D1 into the 1 bit missile or ball graphics registers.
+
+
+
D1
+
0
Disables object
+
1
Enables object
+
+
+
+
+GRP0 (GRP1)
+
+ These addresses write data into the player graphics registers.
+
+
+
D7
D6
D5
D4
D3
D2
D1
D0
+
Graphics Data
+
+
+ Note: serial output begins with D7, unless REFP0 (REFP1) = 1
+
+
+REFP0 (REFP1)
+
+ These addesses write D3 into the 1 bit player reflect registers
+
+
+
D3
+
0
no reflect, D7 of GRPx on left
+
1
reflect, D0 of GRPx on left
+
+
+
+
+
+VDELP0 (VDELP1, VDELBL)
+
+ These addresses write D0 into the 1 bit vertical delay registers, to delay players or ball by
+ one vertical line.
+
+
+
D0
+
0
no delay
+
1
delay
+
+
+
+
+CXCLR
+
+This adderess clears all collision latches to zero (no collision).
+ No data bits are used.
+
+
+COLUP0 (COLUP1, COLUPF, COLUBK)
+
+ These addresses write data into the player, playfield, and background color-luminance
+ registers
+
+
+
+
COLOR
D7
D6
D5
D4
D3
D2
D1
LUM
+
grey - gold
0
0
0
0
0
0
0
black
+
0
0
0
1
0
0
1
dark grey
+
orange, brt-org
0
0
1
0
0
1
0
+
0
0
1
1
0
1
1
grey
+
pink - purple
0
1
0
0
1
0
0
+
0
1
0
1
1
0
1
+
purp-blue, blue
0
1
1
0
1
1
0
light grey
+
0
1
1
1
1
1
1
white
+
blue - lt. blue
1
0
0
0
+
1
0
0
1
+
torq. - grn. blue
1
0
1
0
+
1
0
1
1
+
grn. - yel. grn.
1
1
0
0
+
1
1
0
1
+
org. grn - lt org.
1
1
1
0
+
1
1
1
1
+
+
+
+
+AUDF0 (AUDF1)
+
+ These addresses write data into the audio frequency divider registers.
+
+
+
+
D4
D3
D2
D1
D0
30KHz divided by
+
0
0
0
0
0
no division
+
0
0
0
0
1
divide by 2
+
0
0
0
1
0
divide by 3
+
...
...
...
...
...
...
+
1
1
1
1
0
divide by 31
+
1
1
1
1
1
divide by 32
+
+
+
+
+AUDC0 (AUDC1)
+
+ These addresses write data into the audio control registers which control the noise
+ content and additional division of the audio output.
+
+
+
+
D3
D2
D1
D0
Type of noise or division
+
0
0
0
0
set to 1
+
0
0
0
1
4 bit poly
+
0
0
1
0
div 15 -> 4 bit poly
+
0
0
1
1
5 bit poly -> 4 bit poly
+
0
1
0
0
div 2 : pure tone
+
0
1
0
1
div 2 : pure tone
+
0
1
1
0
div 31 : pure tone
+
0
1
1
1
5 bit poly -> div 2
+
1
0
0
0
9 bit poly (white noise)
+
1
0
0
1
5 bit poly
+
1
0
1
0
div 31 : pure tone
+
1
0
1
1
set last 4 bits to 1
+
1
1
0
0
div 6 : pure tone
+
1
1
0
1
div 6 : pure tone
+
1
1
1
0
div 93 : pure tone
+
1
1
1
1
5 bit poly div 6
+
+
+
+
+AUDV0 (AUDV1)
+
+ These addresses write data into the audio volume registers which set the pull down
+ impedance driving the audio output pads.
+
+(This section is *not* part of the manual, so you can ignore it if
+you want! --BW)
+
+I did this HTML version of the Stella Programming Guide for a couple of
+reasons:
+
+
+The existing PDF version is great, but I really hate having to use a PDF
+reader to read it. HTML is (supposedly) cross-platform, and since I already
+keep 10-15 browser windows open at any given time, I'd rather use the same
+GUI for reading the Stella docs as I do for everything else that's graphical.
+
+The existing plain-text version I found is ok, but it's missing all the
+diagrams (of course), and some of the text formatting is a bit strange.
+
+I tried numerous programs that claim to convert PDF (or PostScript) to HTML,
+but they all produced ugly, unusable results.
+
+I wanted internal links in the document, such as the table of contents. The
+existing PDF version doesn't seem to have them. The next version of this
+document will probably have links to external `how-to' docs, with code
+snippets and such.
+
+The Stella/Atari development community are some of the nicest people I've
+ever met, and this is my attempt to give back to the community in some small
+way.
+
+Finally, I needed an excuse to procrastinate... my poor 2600 game is in a
+nasty state of disrepair, and I'm at the point where I'd be better starting
+from scratch. Taking a break from 6502 asm and writing in a `language' like
+HTML gives me a much-needed breather.
+
+
+The original PDF version has a few typos. I don't know if those are in the
+original paper version, or mistakes in the transcription, but I fixed as many
+of them as I could find (most of them were silly, like it's instead of
+its, or sidable for disable). Also, I didn't try to
+format the tables exactly as they appear in the PDF version, since HTML isn't
+much good for that sort of thing anyway. I did my best to preserve the content,
+but took a few liberties with the presentation.
+
+Although I have tried to avoid it, I'm sure I introduced a few errors and
+typos of my own. If anybody spots one, let me know, and I'll fix it ASAP.
+
+As far as copyright goes, who knows what the official, legal status of the
+Stella Programmer's Guide is? I sure don't. But this HTML version is free for
+anyone to use and/or redistribute, as much as the original version is. If
+you modify this version, I'd really appreciate it if you'd clearly mark your
+new version as modified. Better yet, if you fix some of my mistakes, show me
+what I did wrong so I can learn from them!
+
+I looked at this in Netscape 4.7, Opera 5.0b6, and Konqueror 2.1 on Linux, and IE 5.0 on Win98; it looks OK on all of them.
+If you have any problems with the HTML formatting, please let me know. I tried to
+use `bog standard' HTML as much as possible, so it should work OK on any
+browser, on any OS, but if it doesn't, I'll fix it the best I am able.
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/sizes.txt b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/sizes.txt
new file mode 100644
index 00000000..2aabc284
--- /dev/null
+++ b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/sizes.txt
@@ -0,0 +1,1966 @@
+
+ Cart Information
+ ---- -----------
+
+
+
+ Info about cart sizes and bankswitching methods
+
+
+
+ By Kevin Horton
+ khorton@iquest.net
+
+
+V6.00
+Last modified on 4/18/97
+(614 images)
+
+Copyright 1997 K Horton, all rights reserved! You may copy and distribute
+this file as long as it remains intact and un-modified.
+
+
+This text has been modified to be machine-readable by Bankzilla's database
+generator. This includes the '####Data Start####' and '####Data End####'
+flags, as well as including an 'overflow' category and including controller
+type.
+
+
+ How Bankswitching Works
+ --- ------------- -----
+
+Bankswitching allows game programmers to include more data into a cartridge,
+therefore making (hopefully) a better game with more graphics/ levels.
+
+Bankswitching works under similar principals in all cases. Basically, by
+reading a certain location in ROM switches banks.
+
+
+(this is the F8-style of bankswitching)
+
+Bank #1 Bank #2
+--------------------------------------------------------------
+1000 JSR $1800 (do subroutine) .
+1003 (program continues) 1200 _subroutine goes here_
+. 1209 RTS
+. .
+1800 LDA $1FF9 (switch to bank 2) 1802 (rest of program)
+1803 NOP 1803 JSR $1200
+1804 NOP .
+1805 NOP .
+1806 NOP 1806 LDA $1FF8 (Switch back to bank 1)
+1807 NOP .
+1808 NOP .
+1809 RTS (We're done w/ routine) 1809 (rest of program)
+
+OK, we start out in bank #1 and we want to run a subroutine in bank #2.
+
+What happens is this- the processor starts at 1000h in bank #1. We call
+our subroutine from here. 1800h: We do a read to change us to bank #2.
+Remember that when we change banks, we are basically doing a ROM swap.
+(You can think of bankswitching as 'hot-swapping' ROMs) Now that we're
+in bank #2, the processor sees that JSR to $1200, which is the subroutine
+that we wanted to execute. We execute the subroutine and exit it with an
+RTS. This brings us back to 1806h. We then do another read to select bank
+#1. After this instruction finishes, the processor is now in bank #1, with
+the program counter pointing to 1809, which is an RTS which will take us
+back to 1003 and let us continue on with our program.
+
+
+ Extra RAM in Carts
+ ----- --- -- -----
+
+Some carts have extra RAM; There are three known formats for this:
+
+Atari's 'Super Chip' is nothing more than a 128-byte RAM chip that maps
+itsself in the first 256 bytes of cart memory. (1000-10FFh)
+The first 128 bytes is the write port, while the second 128 bytes is the
+read port. This is needed, because there is no R/W line to the cart.
+
+CBS RAM Plus (RAM+) This maps in 256 bytes of RAM in the first 512 bytes
+of the cart; 1000-11FF. The lower 256 addresses are the write port, while
+the upper 256 addresses are the read port. To store a byte and retrieve it:
+
+LDA #$69 ; byte to store
+STA $1000 ; store it
+.
+. ; rest of program goes here
+.
+LDA $1100 ; read it back
+. ; acc=$69, which is what we stored here earlier.
+
+
+M-network (AFAIK it has no name)
+
+OK, the RAM setup in these carts is very complex. There is a total of 2K
+of RAM broken up into 2 1K pieces. One 1K piece goes into 1000-17FF
+if the bankswitch is set to $1FE7. The other is broken up into 4 256-byte
+parts.
+
+You select which part to use by issuing a fake read to 1FE8-1FEB. The
+RAM is then available for use by all banks at 1800-19FF.
+
+Similar to other schemes, 1800-18FF is write while 1900-19FF is read.
+Low RAM uses 1000-13FF for write and 1400-17FF for read.
+
+
+Note that the 256-byte banks and the large 1K bank are seperate entities.
+The M-Network carts are about as complex as it gets.
+
+
+ Descriptions of the Various Bankswitch Modes
+ --------------------------------------------
+
+2K:
+
+ -These carts are not bankswitched, however the data repeats twice in the
+ 4K address space. You'll need to manually double-up these images to 4K
+ if you want to put these in say, a 4K cart.
+
+4K:
+
+ -These images are not bankswitched.
+
+6K:
+
+ -AR: The Arcadia (aka Starpath) Supercharger uses 6K of RAM to store the
+ games loaded from tape.
+
+8K:
+
+ -F8: This is the 'standard' method to implement 8K carts. There are two
+ addresses which select between two unique 4K sections. They are 1FF8
+ and 1FF9. Any access to either one of these locations switches banks.
+ Accessing 1FF8 switches in the first 4K, and accessing 1FF9 switches in
+ the last 4K. Note that you can only access one 4K at a time!
+
+ -FE: Used only on two carts (Robot Tank and Decathlon). You select banks
+ via accesses to the stack. You set the stack pointer to FF, and then a
+ JSR switches banks one way, while RTS switches you back to the original
+ bank (both banks are 4K). This allows the programmers to perform
+ 'automatic' bankswitching. All the subroutines are in one bank, while
+ all the game code is in another. When you perform a JSR; you switch banks
+ to the bank containg the subroutines. Upon encoutering an RTS, the bank
+ is switched back to the original calling bank. Pretty spiffy!
+
+ -E0: Parker Brothers was the main user of this method. This cart is
+ segmented into 4 1K segments. Each segment can point to one 1K slice of
+ the ROM image. You select the desired 1K slice by accessing 1FE0 to 1FE7
+ for the first 1K (1FE0 selects slice 0, 1FE1 selects slice 1, etc).
+ 1FE8 to 1FEF selects the slice for the second 1K, and 1FF0 to 1FF8 selects
+ the slice for the third 1K. The last 1K always points to the last 1K
+ of the ROM image so that the cart always starts up in the exact same place.
+
+ -3F: Tigervision was the only user of this intresting method. This works
+ in a similar fashion to the above method; however, there are only 4 2K
+ segments instead of 4 1K ones, and the ROM image is broken up into 4 2K
+ slices. As before, the last 2K always points to the last 2K of the image.
+ You select the desired bank by performing an STA $3F instruction. The
+ accumulator holds the desired bank number (0-3; only the lower two bits
+ are used). Any STA in the $00-$3F range will change banks. This appears to
+ interfere with the TIA addresses, which it does; however you just use
+ $40 to $7F instead! :-) $3F does not have a corresponding TIA register, so
+ writing here has no effect other than switching banks. Very clever;
+ especially since you can implement this with only one chip! (a 74LS173)
+
+12K:
+
+ -FA: Used only by CBS. Similar to F8, except you have three 4K banks
+ instead of two. You select the desired bank via 1FF8, 1FF9, and 1FFA.
+ These carts also have 256 bytes of RAM mapped in at 1000-11FF. 1000-10FF
+ is the write port while 1100-11FF is the read port.
+
+16K:
+
+ -F6: The 'standard' method for implementing 16K of data. It is identical
+ to the F8 method above, except there are 4 4K banks. You select which
+ 4K bank by accessing 1FF6, 1FF7, 1FF8, and 1FF9.
+
+ -E7: Only M-Network used this scheme. This has to be the most complex
+ method used in any cart! :-) It allows for the capability of 2K of RAM;
+ although it doesn't have to be used (in fact, only one cart used it-
+ Burgertime). This is similar to the 3F type with a few changes. There are
+ now 8 2K banks, instead of 4. The last 2K in the cart always points to
+ the last 2K of the ROM image, while the first 2K is selectable. You
+ access 1FE0 to 1FE6 to select which 2K bank. Note that you cannot select
+ the last 2K of the ROM image into the lower 2K of the cart! Accessing
+ 1FE7 selects 1K of RAM at 1000-17FF instead of ROM! The 2K of RAM is
+ broken up into two 1K sections. One 1K section is mapped in at 1000-17FF
+ if 1FE7 has been accessed. 1000-13FF is the write port, while 1400-17FF
+ is the read port. The second 1K of RAM appears at 1800-19FF. 1800-18FF
+ is the write port while 1900-19FF is the read port. You select which
+ 256 byte block appears here by accessing 1FF8 to 1FFB.
+
+32K
+
+ -F4: The 'standard' method for implementing 32K. Only one cart is known
+ to use it- Fatal Run. Like the F6 method, however there are 8 4K
+ banks instead of 4. You use 1FF4 to 1FFB to select the desired bank.
+
+64K
+
+ -F0: Only used one cart, AFAIK. (the 'Megaboy' cart from Dynacom) It
+ has 16 4K banks. Accessing 1FF0 will increment the current bank. The
+ program uses location 1FEC to tell it which bank it's in. There's a
+ little loop at 1FE0 that checks this location against the accumulator,
+ and if they're equal it does an RTS. Otherwise it does an STA 1FF0
+ and repeats the loop.
+
+
+ /-----------------------------------------------------------------------\
+ | KEY |
+ | --- |
+ | Name - Game Name |
+ | Part # - Part Number of the actual cart |
+ | RA - Rarity, according to VGR's guide and my observations |
+ | SZ - Size of the ROM image in K |
+ | SC - If the cart has a Special Chip |
+ | BS - Bankswitch method used (see below) |
+ | IM - 'X'ed if I have the image |
+ | SP - Special Attribute (See the end of a section for details) |
+ | CT - Controller type (See below) |
+ | Filename - The filename of the ROM image |
+ | |
+ | Bankswitch Types: |
+ | ----------------- |
+ | (See above for full descriptions) |
+ | |
+ | - (nothing); Not bankswitched (2K and 4K only) |
+ | F8 - 'Standard' 8K; uses 1FF8 and 1FF9 |
+ | F6 - 'Standard' 16K; uses 1FF6 to 1FF9 |
+ | F4 - 'Standard' 32K; uses 1FF4 to 1FFB |
+ | F0 - Megaboy 64K; uses 1FF0 to increment bank # |
+ | SC - Superchip; 128 bytes of RAM @ 1000-10FF (i.e. F8+SC, F4+SC) |
+ | FA - 'RAM+' 12K; uses 1FF8 to 1FFA; 256 bytes of RAM @ 1000 to 11FF |
+ | FE - 'Activision' 8K; uses 01FE and 01FF to determine bank |
+ | E0 - 'Parker Brothers' 8K; uses 1FE0 to 1FF7 |
+ | E7 - 'M-Network' 16K; Uses 1FE0 to 1FE7 and 2K of RAM at 1800-19FF |
+ | 3F - 'Tigervision' 8K; Uses STA $3F to determine bank # |
+ | AR - 'Arcadia' 6K; Used on the Supercharger |
+ | ?? - Unknown at this time |
+ | |
+ | Controller Types: |
+ | ----------------- |
+ | |
+ | - (nothing); Unknown at this time |
+ | J - Joystick |
+ | P - Paddles |
+ | K - Keypad |
+ | JK - Joystick and keypad (Star Raiders) |
+ | D - Driving Controllers |
+ | B - Joystick plus Booster Grip (Omega Race) |
+ | T - Track & Field controller |
+ | O - Other |
+ | L - Light Gun |
+ | |
+ | |
+ | I have added two new categories to the rarity rating: |
+ | |
+ | PR - This was only available as a prototype |
+ | DM - This image is only a demo, and not really a game |
+ | |
+ \-----------------------------------------------------------------------/
+
+
+
+
+ Hot Wants (that I know I probably won't get :-)
+ -----------------------------------------------
+
+
+Tempest (Atari)
+Good Luck, Charlie Brown (Atari)
+Miss Piggy's Wedding (exists?) (Atari)
+Wizard (Atari)
+BMX Airmaster (atari ver) (Atari)
+White Water Madness (exists?) (Atari)
+Rodeo (Atari)
+Rabbit Transit (Atari)
+Nightmare Manor (Atari)
+Pink Panther (Probe 2000)
+The Impossible Game (Telesys)
+Ewoks Adventure (Parker Bros)
+Thwoker (Activision)
+Out of Control (Avalon Hill)
+Berenstein Bears (Coleco)
+Video Life (Commavid)
+Aerial Ace (exist?) (Imagic)
+Lady in Wading (Playaround)
+Snowplow (Sunrise)
+Noah and the Ark (Sunrise)
+Meltdown (exist?) (20th cent.)
+Tomarc the Barabrrian (exist?) (Xonox)
+Motocross Racer (exist?) (Xonox)
+
+
+
+Anything by Action Hi-tech
+
+
+
+
+
+####Data Start####
+
+
+***********************************
+* Atari *
+***********************************
+
+[If SC is marked, cart uses a 'Super Chip'; aka CO20231]
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Combat CX2601 C 2 X J COMBAT
+Air-Sea Battle CX2602 U 2 X J AIR_SEA
+Star Ship CX2603 R 2 X STARSHIP
+Space War CX2604 U 2 X SPACEWAR
+Outlaw CX2605 U 2 X J OUTLAW
+Slot Racers CX2606 U 2 X SLOTRACE
+Canyon Bomber CX2607 U 2 X CANYONB
+Super Breakout CX2608 U 4 X P SUPERB
+Defender CX2609 C 4 X J DEFENDER
+Warlords CX2610 U 4 X P WARLORDS
+Indy 500 CX2611 U 2 X D INDY_500
+Street Racer CX2612 U 2 X STRTRACE
+Adventure CX2613 C 4 X J ADVNTURE
+Steeple Chase CX2614 NR 2 X P STEPLCHS
+Demons to Diamonds CX2615 U 4 X DEMONDIM
+Hot Rox CX2615 NR 4 X DEMONDIM
+Pele's Soccer CX2616 C 4 X PELE
+Backgammon CX2617 U 4 X BACKGAM
+3D- Tic-Tac-Toe CX2618 U 2 X J 3D_TIC
+Stellar Track CX2619 NR 4 X STELRTRK
+BASIC Programming CX2620 R 4 X K BASIC
+Video Olympics CX2621 C 2 X P VID_OLYM
+Breakout CX2622 C 2 X P BREAKOUT
+Homerun CX2623 C 2 X HOMERUN
+Basketball CX2624 C 2 X BASKETBL
+Football CX2625 C 2 X FOOTBALL
+Minature Golf CX2626 U 2 X MIN_GOLF
+Human Cannonball CX2627 U 2 X HUMAN_CB
+Bowling CX2628 C 2 X J BOWLING
+Sky Diver CX2629 U 2 X SKYDIVER
+Circus Atari CX2630 C 4 X P CIRCATRI
+Superman CX2631 C 4 X J SUPRMAN1
+Space Invaders CX2632 C 4 X J SPCINVAD
+Night Driver CX2633 C 2 X NIGHTDRV
+Golf CX2634 C 2 X GOLF
+Maze Craze CX2635 U 4 X J MAZECRZ
+Video Checkers CX2636 R 4 X J CHECKERS
+Dodge 'Em CX2637 U 4 X DODGE_EM
+Missile Command CX2638 C 4 X J MISSCOMM
+Othello CX2639 R 2 X OTHELLO
+Realsports Baseball CX2640 U 8 F8 X RS_BASEB
+Surround CX2641 C 2 X J SURROUND
+A Game of Concentration CX2642 C 2 X CONCENTR
+Code Breaker CX2643 U 2 X CODEBRK
+Flag Capture CX2644 U 2 X FLAGCAP
+Video Chess CX2645 U 4 X VIDCHESS
+Pac-Man CX2646 C 4 X J PACMAN
+Submarine Commander CX2647 PR 4 X J SUBCOMDR
+Video Pinball CX2648 U 4 X J VIDPIN
+Asteroids CX2649 C 8 F8 X J ASTEROID
+Berzerk CX2650 C 4 X J BERZERK
+Blackjack CX2651 R 2 X BLACK_J
+Casino CX2652 U 4 X CASINO
+Slot Machine CX2653 R 2 X SLOTMACH
+Haunted House CX2654 C 4 X J HAUNTHSE
+Yar's Revenge CX2655 C 4 X J YAR_REV
+Swordquest Earthworld CX2656 C 8 F8 X J SQ_EARTH
+Swordquest Fireworld CX2657 C 8 F8 X J SQ_FIRE
+Math Gran Prix CX2658 C 4 X J MATH_GPX
+Raiders of the Lost Ark CX2659 C 8 F8 X J RAIDERS
+Star Raiders CX2660 U 8 F8 X JK STARRAID
+Basic Math CX2661 C 2 X J BASMATH
+Hangman CX2662 U 4 X J HANGMAN
+Road Runner CX2663 ER 16 F6 X J ROADRUNR
+Brain Games CX2664 U 2 X BRAINGMS
+Frog Pond CX2665 PR 8 F8 X J FROGPOND
+Realsports Volleyball CX2666 U 4 X RS_VOLLY
+Realsports Soccer CX2667 U 8 F8 X RSSOCCER
+Realsports Football CX2668 C 8 F8 X RS_FOOTB
+Vanguard CX2669 C 8 F8 X VANGUARD
+Atari Video Cube CX2670 R 4 X J VIDCUBE
+Swordquest Waterworld CX2671 UR 8 F8 X J SQ_WATER
+Swordquest Airworld CX2672 NR ?? ---No Known Copies Exist---
+Phoenix CX2673 C 8 F8 X J PHOENIX
+E.T. The Extra-Terrestrial CX2674 C 8 F8 X J E_T
+Ms. Pac-Man CX2675 C 8 F8 X J MSPACMAN
+Centipede CX2676 C 8 F8 X J CENTIPED
+Dig Dug CX2677 U 16 X F6 X J DIGDUG
+Dukes of Hazzard CX2678 PR 16 F6 X J DUKES
+Realsports Basketball CX2679 NR ?? ---No Known Copies Exist---
+Realsports Tennis CX2680 U 8 F8 X J RSTENNIS
+Battlezone CX2681 U 8 F8 X J BATLZONE
+Krull CX2682 R 8 F8 X J KRULL
+Crazy Climber CX2683 ER 8 F8 X J CRAZCLMB
+Galaxian CX2684 U 8 F8 X J GALAXIAN
+Gravitar CX2685 U 8 F8 X J GRAVITAR
+Quadrun CX2686 ER 8 F8 X J QUADRUN
+Tempest CX2687 PR ?? ---A Few Proto's Exist---
+Junglehunt CX2688 U 8 F8 X J JNGLHUNT
+Kangaroo CX2689 U 8 F8 X J KANGAROO
+Pengo CX2690 ER 8 F8 X J PENGO
+Joust CX2691 C 8 F8 X J JOUST
+Moon Patrol CX2692 U 8 F8 X J MOONPTRL
+Food Fight CX2693 NR ?? ---No Known Copies Exist---
+Pole Position CX2694 C 8 F8 X J POLEPSN
+Xevious CX2695 PR 8 F8 X J XEVIOUS
+Asterix CX2696 ER 8 F8 X J ASTERPAL
+Mario Bros. CX2697 U 8 F8 X J MARIOBRO
+Rubik's Cube CX2698 ER 4 X J RUBIKS
+Taz CX2699 R 8 F8 X J TAZ
+Oscar's Trash Race CX26101 R 8 F8 X K OSCAR
+Cookie Monster Crunch CX26102 R 8 F8 X K COOKMONS
+Alpha-Beam with Ernie CX26103 R 8 F8 X K ALPHBEAM
+Big Bird's Egg Catch CX26104 R 8 F8 X K EGGCATCH
+3-D Asteroids CX26105 NR ??
+Grover's Music Maker CX26106 PR 8 F8 X GROVER
+Snow White CX26107 NR ??
+Donald Duck's Speedboat CX26108 PR 8 F8 X J DDUCKSBT
+Sourcerer's Apprentice CX26109 R 8 F8 X J SORCAPRN
+Crystal Castles CX26110 U 16 X F6 X J XTALCAST
+Snoopy and the Red Barron CX26111 R 8 F8 X J SNOOPY
+Good Luck; Charlie Brown CX26112 PR ?? ---One Proto Exists---
+Miss Piggie's Wedding CX26113 UR ??
+Pigs in Space CX26114 ER 8 F8 X J PIGSPACE
+Dumbo's Flying Circus CX26115 PR 8 F8 X J DUMBO_N
+Galaga CX26116 NR ??
+Obelix CX26117 ER 8 F8 X J OBELIX
+Millipede CX26118 R 16 X F6 X J MILLIPED
+Saboteur CX26119 PR 8 F8 X J SABOTEUR
+Star Gate CX26120 U 8 X F8 X J STARGATE
+Defender ][ CX26120 R 8 X F8 X J DEFENDR2
+Zookeeper CX26121 NR ??
+Sinistar CX26122 PR 8 F8 X J SINISTAR
+Jr. Pac-Man CX26123 U 16 X F6 X J JRPACMAN
+Choplifter CX26124 NR ??
+Track & Field CX26125 R 16 F6 X T TRACK
+Elevator Action CX26126 NR ??
+Gremlins CX26127 ER 8 F8 X J GREMLINS
+Boing CX26128 NR ??
+Midnight Magic CX26129 R 16 F6 X J MIDNIGHT
+Honker Bonker CX26130 NR ??
+Monstercise CX26131 PR 8 F8 X MONS
+Garfield CX26132 NR ??
+The A-Team CX26133 PR 8 F8 X J ATEAM
+The Last Starfighter CX26134 NR ??
+Star Raiders ][ CX26134 NR ??
+Realsports Boxing CX26135 U 16 F6 X J RSBOXING
+Solaris CX26136 U 16 F6 X J SOLARIS
+Peek-A-Boo CX26137 PR 4 X PEEKABOO
+Super Soccer CX26138 NR ??
+Crossbow CX26139 U 16 F6 X J CROSSBOW
+Desert Falcon CX26140 C 16 X F6 X J DSRTFALC
+Motor Psycho CX26141 NR ??
+Crack'ed CX26142 ??
+Donkey Kong CX26143 U 4 X J DK
+Donkey Kong Jr. CX26144 R 8 F8 X J DKJR
+Venture CX26145 R 4 X J VENTURE
+Mousetrap CX26146 R 4 X J MOUSETRP
+Frogger CX26147 NR 4 X J FROGGER
+Turbo CX26148 NR ??
+Zaxxon CX26149 NR ??
+Q*Bert CX26150 R 4 X J QBERT_PB
+Dark Chambers CX26151 U 16 X F6 X X3 J DARKC
+Super Baseball CX26152 U 16 F6 X J SUPBBALL
+Super Football CX26154 U 16 X F6 X J SPRFOOTB
+Sprintmaster CX26155 R 16 X F6 X J SPRNMAST
+Combat II (Wizard?) CX26156 NR ??
+ CX26157 ??
+Surround II CX26158 NR ??
+Double Dunk CX26159 R 16 F6 X J DOUBDUNK
+ CX26160 ??
+ CX26161 ??
+Fatal Run CX26162 UR 32 X F4 X J FATALRUN
+32-in-1 CX26163 ER 64 32 banks of 2K -- 32IN1
+ CX26164 ??
+Jinks CX26165 NR ??
+ CX26166 ??
+Street Fight CX26167 ??
+Off the Wall CX26168 ER 16 X F6 X J OFTHWALL
+Shooting Arcade CX26169 PR 16 X F6 X L SHOOTING
+Secret Quest CX26170 R 16 X F6 X J SECRETQ
+Motorodeo CX26171 UR 16 F6 X J MOTOR
+Xenophobe CX26172 ER 16 F6 X J XENOPHOB
+ CX26173 ??
+ CX26174 ??
+ CX26175 ??
+Radar Lock CX26176 R 16 X F6 X J RADARLOK
+Ikari Warriors CX26177 R 16 F6 X J IKARIWAR
+Save Mary! CX26178 PR 16 X F6 X J SAVEMARY
+ CX26179 ??
+ CX26180 ??
+ CX26181 ??
+ CX26182 ??
+Sentinel CX26183 R 16 F6 X L SENTINEL
+White Water Madness CX26184 UR ??
+ CX26185 ??
+ CX26186 ??
+ CX26187 ??
+ CX26188 ??
+ CX26189 ??
+BMX Airmaster CX26190 ER ??
+ CX26191 ??
+KLAX CX26192 ER 16 X F6 X X2 J KLAXNTSC
+
+
+Aquaventure CX26??? PR 8 F8 X J AQUAVENT
+Bionic Breakthrough CX26??? PR 8 F8 X O MINDLINK
+Bugs Bunny CX26??? PR 8 F8 X J BUGSBUN
+Coke Wins! CX26??? UR 4 X J COKEWINS
+Holy Moley CX26??? PR 8 F8 X HOLEMOLE
+Polo CX26??? PR 2 X J POLO
+Rodeo CX26??? PR ??
+Rabbit Transit CX26??? PR ??
+Standalone Test Tape MAO17600 DM 2 X -- MAO17600
+Nightmare Manor CX26??? PR ??
+Super Stunt Cycle PR 2 X J STUNT-1
+Dukes of Hazzard (not CX2678) PR 2 X J STUNT-2
+
+X2: Special Best Prototype NTSC version.
+
+X3: Doesn't like my test cart; have to disable SC for it to start. I
+ can then re-enable the SC and it'll work. Also, the cart itsself
+ doesn't work on my 7800 (or my test cart for that matter).
+
+
+***********************************
+* Action Hi-Tech *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Crab Control 605077 UR ??
+F-18 vs. Aliens ???? UR ??
+Galaxy Invader ???? UR ??
+Space Grid ???? UR ??
+Tank City ???? UR ??
+War Zone ???? UR ??
+
+
+***********************************
+* Activision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Dragster AG-001 U 2 X J DRAGSTER
+Boxing AG-002 U 2 X J BOXING
+Checkers AG-003 ER 2 X J CHECKERA
+Fishing Derby AG-004 U 2 X J FISHDRBY
+Skiing AG-005 U 2 X J SKIING
+Bridge AX-006 U 4 X J BRIDGE
+Tennis AG-007 C 2 X J TENNIS
+Laser Blast AG-008 C 2 X J LASRBLST
+Freeway AG-009 U 2 X J FREEWAY
+Kaboom AG-010 U 2 X P KABOOM
+Stampede AG-011 U 2 X J STAMPEDE
+Ice hockey AX-012 U 4 X J ICEHOCKY
+Barnstroming AX-013 U 4 X J BARNSTRM
+Gran Prix AX-014 U 4 X J GRANDPRX
+Chopper Command AX-015 U 4 X J CHOPRCMD
+Starmaster AX-016 U 4 X J STARMAST
+Megamania AX-017 U 4 X J MEGAMAN
+Pitfall AX-018 C 4 X J PITFALL
+Sky Jinks AG-019 R 2 X J SKYJINKS
+River Raid AX-020 U 4 X J RIVERAID
+Spider Fighter AX-021 U 4 X J SPIDRFTR
+Seaquest AX-022 R 4 X J SEAQUEST
+Oink! AX-023 R 4 X J OINK
+Dolphin AX-024 R 4 X J DOLPHIN
+Keystone Kapers AX-025 U 4 X J KEYSTONE
+Enduro AX-026 U 4 X J ENDURO_A
+Plaque Attack AX-027 R 4 X J PLAQATTK
+Robot Tank AZ-028 R 8 F8 X X2 J ROBO_FIX
+Crackpots AX-029 R 4 X J CRACKPOT
+Decathlon AZ-030 R 8 FE X J DECATHLN
+Frostbite AX-031 R 4 X J FROSTBIT
+Pressure Cooker AZ-032 R 8 F8 X J PRESSURE
+Space Shuttle AZ-033 R 8 F8 X J SPCSHUTL
+Private Eye AG-034-04 R 8 F8 X J PRIVEYE
+Pitfall ][: Lost Caverns AB-035-04 R 8 F8 X X1 J PITFALL2
+H.E.R.O. AZ-036-04 R 8 F8 X J HERO
+Beamrider AZ-037-04 R 8 F8 X J BEAMRIDE
+Cosmic Commuter AG-038 R 4 X J CSMCOMTR
+Kung-Fu Master AX-039 R 8 F8 X J KUNG_FU
+Contenders AK-041 ---Never Released by Activision---
+Commando AK-043 R 16 F6 X J COMMANDO
+Fighter Pilot AK-046 UR 16 F6 X J FIGHTERP
+River Raid ][ AK-048-04 ER 16 F6 X J RIVRAID2
+Rampage AK-049 R 16 F6 X J RAMPAGE
+Double Dragon AK-050-04 R 16 F6 X J DBLDRAGN
+Ghostbusters AZ-108-04 R 8 F8 X J GHOSTBST
+Ghostbusters ][ A?-??? NR ?? ---See Salu---
+Dreadnaught Factor A?-??? NR ??
+Wing War A?-??? NR ?? ---See Imagic---
+Thwocker A?-??? PR ?? ---Proto Exists---
+Zenji A?-??? NR ??
+
+
+X1: Uses Activision's version of the 'Super Chip' No extra RAM this time,
+ however it does have extra ROM! Does three-channel sound, and even
+ includes several random # generators.
+
+
+X2: This used to be an FE cart, but has been fixed to run as an F8.
+
+***********************************
+* Absolute Entertainment *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Title Match Pro Wresting AG-041 R 8 F8 X J PROWREST
+Skateboardin' AG-042 R 8 F8 X J SKATEBRD
+Pete Rose Baseball AK-045 R 16 F6 X J PETEROSE
+Tomcat F-14 Simulator AK-046 ER 16 F6 X X1 J FIGHTERP
+My Golf A?-??? ER 8 F8 X J MYGOLF
+
+X1: This is identical to the Activision one. I read both in and compared;
+they are byte-for-byte identical.
+
+***********************************
+* American Videogame *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Tax Avoiders ???? R 8 F8 X J TAXAVOID
+
+
+***********************************
+* Amiga *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Mogul Maniac 3120 ER 4 X J MOGULMAN
+Surf's Up 3125 PR 8 F8 X J SURF_FIX
+Off your Rocker 3130 PR 4 X J OFFROCKR
+
+
+***********************************
+* Answer Software *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Malagai ASC1001 UR 4 X J MALAGAI
+Gauntlet ASC1002 UR 4 X J GAUNTLET
+Confrontation ASC2001 UR ??
+Personal Game Programmer PGP-1 UR XX ---Hardware---
+
+
+***********************************
+* Artic *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Space Robot SM8001 UR 4 X J SPCROBOT
+Astrowar SM8002 UR 4 X J ASTROWAR
+
+
+***********************************
+* Apollo *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Skeet Shoot AP 1001 R 2 X SKEETSHT
+Spacechase AP 2001 U 4 X SPACHASE
+Space Cavern AP 2002 U 4 X SPACECAV
+Racquetball AP 2003 U 4 X RACQUETB
+Lost Luggage AP 2004 U 4 X J LOSTLUGG
+Lochjaw AP 2005 ER 4 X J LOCHJAW
+Shark Attack AP 2005 U 4 X J SHARKATK
+Infiltrate AP 2006 U 4 X J INFILTRT
+Kyphus AP 2007 R ??
+Guardian AP 2008 R 4 X GUARDIAN
+Final Approach AP 2009 R 4 X J FINLAPCH
+Wabbit AP 2010 R 4 X J WABBIT
+Pompeii AP 2011 R ??
+Squoosh AP 2012 PR ??
+
+
+***********************************
+* Avalon Hill *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Death Trap 50010 UR 4 X J DETHTRAP
+London Blitz 50020 ER 4 X J LONDBLTZ
+Wall Ball 50030 ER 4 X J WALLBALL
+Shuttle Orbiter 50040 UR 4 X J SHTLORBT
+Out of Control 50050 UR ?? Need!
+
+
+***********************************
+* Bit Corp. *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Sea Monster PG201 R 4 X SEAMNSTR
+Space Tunnel PG202 R 4 X SPACT_TW
+Phantom Tank PG203 R 4 X PHANTOMT
+Open Sesame PG204 R 4 X OPENSESM
+Dancing Plate PG205 R 4 X DANCPLAT
+Bobby is Going Home PG206 R 4 X J BOBBY
+Mission 3000 AD PG207 R 4 X MISN3000
+Snail Against Squirrel PG208 R 4 X SNALSQRL
+Mr. Postman PG209 R 4 X MRPOSTMN
+Superman (CCE) ???? ?? 4 X SUPERCCE
+
+***********************************
+* Bob Colbert *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Okie Dokie (Lights Out) ???? -- 2 X J OKIEDOKE
+
+
+***********************************
+* Bomb *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Assault CA281 ER 4 X J ASSAULT
+Great Escape CA282 ER 4 X J GRESCAPE
+Z-Tack CA283 ER 4 X J Z_TACK
+Wall Defender CA285 ER 4 X J WALLDFND
+
+
+***********************************
+* CBS Electronics *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Wizard of Wor M8774 R 4 X J WIZRDWOR
+Gorf M8793 U 4 X J GORF
+Blueprint 4L-2486 U 8 F8 X J BLUEPRNT
+Solar Fox 4L-2487 U 8 F8 X J SOLARFOX
+Tunnel Runner 4L-2520 R 12 FA X J TUNLRUNR
+Omega Race 4L-2737 U 12 FA X B OMEGARAC
+Mountain King 4L-2738 R 12 FA X J MTNKING
+Wings ???? NR ?? ??
+
+'SC' in this case refers to RAM+
+
+***********************************
+* Coleco *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Donkey Kong 2451 C 4 X J DK
+Zaxxon 2454 U 8 F8 X J ZAXXON
+Venture 2457 C 4 X J VENTURE
+Mouse Trap 2459 U 4 X J MOUSETRP
+Lady Bug 2463 UR ??
+Cosmic Avenger 2464 UR ??
+Smurf: RIGC 2465 U 8 F8 X J SMURFRES
+Carnival 2468 U 4 X J CARNIVAL
+Smurfs Save the Day 2511 UR 8 F8 X J SMRFSAVE
+Donkey Kong Jr. 2653 R 8 F8 X J DKJR
+Mr. Do! 2656 R 8 F8 X J MRDO
+Berinstein Bears 2658 UR ??
+Time Pilot 2663 R 8 F8 X J TIMEPLT
+Front Line 2665 R 8 F8 X J FRNTLINE
+Roc 'N Rope 2667 R 8 F8 X J ROCNROPE
+
+
+
+*addendum*
+Got Mr. Do! to read out, and Time Pilot seems to have read out correctly,
+yet it doesn't play on the emu. I'm going to pull the EPROM off the board
+and read it directly!
+*end*
+
+*addendum2*
+Pulled the EPROM and copied it. Just as I suspected, it did indeed read out
+correctly. Guess the emu isn't as good as the Real Thing. :-) I'll try it
+out on the real hardware RSN.
+*end*
+
+*addendum3*
+The saga continues. I tried the ROM image of Time Pilot out on the Real
+Thing, and it behaved the exact same way that it did on the emu. It appears
+that the RC delay in the cart is required so it doesn't switch banks
+immediately. I hope I can fix it so it can work as a normal F8 cart.
+*end*
+
+*addendum4*
+Yes! I got Time Pilot to work! This is intresting. The bank is *only*
+flipped in two parts of the cart- once at the beginning of bank0 and once
+at the beginning of bank1. The tip-off was bank #0 had a BIT $1FF8
+instruction and bank #1 had a BIT $1FF9 instruction! This of course will
+*not* flip banks!!! I changed the 4K blocks around, ran it on the emu, and
+it worked perfectly!
+*end*
+
+*addendum5*
+Finally figured out what was wrong with Smurfs Save the Day. The places
+in the code that switch banks was right on top of each other. (the
+STA $1FFx instructions were at the same addresses in diffrent banks)
+As a result, there were only STA $1FF8 instructions rather than both
+STA $1FF8 and STA $1FF9 instructions. Fixing these resulted in a working
+ROM image!!!!!! Now all I need is Berinstein Bears to round out the
+Coleco Collection.
+*end*
+
+***********************************
+* CommaVid *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+MagiCard CM-001 UR ?? ----Hardware----
+Video Life CM-002 UR ??
+Cosmic Swarm CM-003 R 2 X J COSMSWRM
+Room of Doom CM-004 ER 4 X J ROOMDOOM
+Mines of Minos CM-005 ER 4 X MINEMNOS
+Cakewalk CM-008 ER 4 X J CAKEWALK
+Stronghold CM-009 ER 4 X STRNGHLD
+
+
+***********************************
+* Data Age *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Encounter at L-5 DA 1001 U 4 X ENCONTL5
+Warplock DA 1002 C 4 X WARPLOCK
+SSSnake DA 1003 C 4 X SSSNAKE
+Airlock DA 1004 C 4 X AIRLOCK
+Bugs DA 1005 U 4 X P BUGS
+Journey Escape 112-006 C 4 X J JRNYESCP
+Rock 'n Roll Escape 112-006 R 4 X X1 J JRNYESCP
+Bermuda Triangle 112-007 R 4 X J BERMDTRI
+Frankenstein's Monster 112-008 R 4 X J FRANKMON
+Secret Agent ???? UR ??
+
+
+X1: This is the same as Journey Escape.
+
+
+***********************************
+* DSD/Camelot *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Tooth Protectors ???? UR 8 E0 X X1 J TOOTHPRO
+
+
+X1: Intresting!!! This cart uses the Parker Bros. 8K bankswitch!!! It's
+the only non-PB cart to use this format.
+
+
+
+***********************************
+* Dynacom *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Mega Boy ???? ?? 64 F0 X J MEGABOY
+
+
+This is a very intresting cart. It's designed as an educational product!
+It was only test-marketed in Brazil, and most of it is in Portugese. It
+contains several different learning tools- Math, English, Games, and Music!
+This cart goes with a hand-held 2600 called the 'Mega Boy'... it's similar
+to a TV Boy except it can accept regular 2600 carts! It runs on batteries
+and transmits through the air to a TV in a similar fashion to a TV Boy. All
+in all a very cool device.
+
+
+
+***********************************
+* Ed Fendermyer *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+SoundX ???? ER 4 X J SOUNDX
+EdTris ???? ER 4 X J EDTRIS
+
+
+***********************************
+* Emag *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+I Want My Mommy GN-010 ER 4 X IWANTMOM
+Dishaster GN-020 ER 4 X J DISHASTR
+Tanks But No Tanks GN-030 ER 4 X TANKSBUT
+Cosmic Corridor GN-040 ER 4 X COSMCORR
+Pizza Chef GN-050 ER 4 X J PIZZA
+Immies & Aggies GN-060 ER 4 X IMMIES
+A Mysterious Thief GN-070 ER ??
+Fire Spinner GN-080 ER 4 X FIRESPIN
+
+
+***********************************
+* Epyx *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Summer Games 8056100250 R 16 F6 X J SUMMERGA
+Winter Games 8056100251 R 16 F6 X J WINTERGA
+California Games 8056100286 R 16 F6 X J CALIFGMS
+Super Cycle ???? ??
+
+
+***********************************
+* Exus *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Video Jogger ???? ?? 4 X O VIDJOGGR
+Video Reflex ???? ?? 4 X O VIDREFLX
+
+***********************************
+* First Star Software *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Boing! ???? ER 4 X J BOING
+
+***********************************
+* Froggo *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Karate FG 1001 R 4 X J KARATE
+Spiderdroid FG 1002 R 4 X J SPIDROID
+Task Force FG 1003 R 4 X J TASKFORC
+Cruise Missile FG 1007 R 4 X J CRUSMISL
+Sea Hawk FG 1008 R 4 X J SEAHWK_F
+Sea Hunt FG 1009 R 4 X J SEA_HUNT
+
+
+***********************************
+* Funvision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Ocean City Defender ???? ?? 4 X J OCEANCTY
+Spider Maze ???? ?? 4 X J SPDRMAZE
+
+
+***********************************
+* HES *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Challenge ???? ?? 8 F8 X J CHALLANG
+My Golf 535 ?? 8 F8 X J MYGOLF
+Pigs 'n Wolf ???? ?? ??
+Star Warrior ???? ?? ??
+
+Go for the Gold Pak (really two carts)
+ -Winter Games ?? 16 F6 X J WINTERG2
+ -Summer Games ?? 16 F6 X J SUMMERG2
+
+****
+Special menued multicarts:
+****
+
+Super Action Pak 223 ?? 16 F6 X J SUPERACT
+ -Pitfall
+ -Grand Prix
+ -Laser Blast
+ -Barnstorming
+Smash Hit Pak 498 ?? 16 F6 X J SMASHHIT
+ -Frogger
+ -Stampede
+ -Seaquest
+ -Boxing
+ -Skiing
+Hot Action Pak 542 ?? 16 F6 X J HOTPAK
+ -Ghostbusters
+ -Plaque Attack
+ -Tennis
+Rad Action Pak 559 ?? 16 F6 X J RADACT
+ -Kung-Fu Master
+ -Frostbite
+ -Freeway
+Mega Fun Pak ???? ?? ?? F6 X J MEGAPAK
+ -Gorf
+ -Planet Patrol
+ -Pac-Man
+ -Skeet Shoot
+Sports Action Pak ???? ?? 16 F6 X J SPORTACT
+ -Enduro
+ -Ice hockey
+ -Fishing Derby
+ -Dragster
+Super Hit Pak ???? ?? 16 F6 X J SUPERHIT
+ -River Raid
+ -Grand Prix
+ -Fishing Derby
+ -Jink
+ -Checkers
+2 Pak Special #1 ???? ?? 16 F6 X J P0
+ -Dungeon Master - Venture
+ -Creature Strike - Demon Attack
+2 Pak Special #2 ???? ?? 16 F6 X J P1
+ -Star Warrior - Starwars: Empire Strikes Back
+ -Frogger
+2 Pak Special #3 ???? ?? 16 F6 X J P2
+ -Wall Defender
+ -Planet Patrol
+2 Pak Special #4 ???? ?? 16 F6 X J P3
+ -Space Voyage - Starmaster
+ -Fire Alert - Fire Fighter
+2 Pak Special #5 ???? ?? ??
+ -Alien Force
+ -Hoppy
+2 Pak Special #6 ???? ?? ??
+ -Cavern Blaster
+ -City War
+2 Pak Special #7 ???? ?? ??
+ -Challenge
+ -Surfing
+2 Pak Special #8 ???? ?? ??
+ -Dolphin
+ -Pigs 'n Wolf
+2 Pak Special #9 ???? ?? ??
+ -Motocross
+ -Boom Bang
+
+
+Notes about menued carts: These are very intresting! They consist of
+several games in seperate banks of a 16K F6 bankswitched ROM. There's a
+very slick looking menu that comes up displaying the co's logo (HES), and
+to press the fire button. After doing so, the user is given a choice of
+what game to play. The choices are actually written out onto the screen in
+hi-res text! You highlight the desired game and hit the button. The tech
+behind it is pretty simple, yet clever. On startup, the bank is pointed to
+the menu system's bank, and then is run just like any other F6 cart. The
+games are stored in seperate banks, or the upper 2K of a 4K block with the
+lower 2K being the menuing program. When the user selects a game, a small
+'stub' of code is written to RAM then executed; this stub is usually
+something like this:
+
+0080: LDA $1FF8 ;change banks
+0083: JMP $1000 ;run game
+
+So that when 0080 is called, the cart is switched to bank #2, and then the
+game in said bank will be run. Pretty nifty! Note that since this is
+already a bankswitched game, 8K bankswitched games can be run in it, as well
+as non-bankswitched games. Check out the game linup on the 'Hot Action Pak'.
+It is:
+
+Ghost Busters 8K
+Plaque Attack 4K
+Tennis 2K
+
+Total: 14K
+
+That gives us the extra 2K for the menuing system.
+
+On those '2 Pak Special' carts, they are still 16K, but almost half of this
+goes to waste; they could've made '3 Pak Specials' to use up most of the
+space no problem. I still don't know why they didn't do this. Examining the
+ROM shows almost half of it is 'FF'. What a waste! :-)
+
+
+***********************************
+* Homevision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+
+Robot Fight 1 ER 4 X J ROBOFGHT
+War 2000 2 ??
+Gogo? Home Monster 3 ??
+World? Trap? 9 ??
+Asteroid Fire 11 ??
+Sky Alien 12 ??
+Base Attack 13 4 X BASEATTK
+Wall Break 14 ??
+Lilly Adventure 17 4 X J LILLY
+Col 'N' ???? 4 X J COLN
+Cosmic War ???? ??
+Frisco ???? ??
+IQ 180 ???? 4 X J IQ180
+Magic Carpet ???? ??
+Panda Chase ???? 4 X J PANDCHSE
+Parachute ???? 4 X PARCHUTE
+Plate Mania ???? ??
+Racing Car ???? ??
+Repro Cart 83014 ??
+Tanks War ???? ??
+Teddy Apple ???? ??
+Tennis Topsy ???? ??
+Zoo Fun ???? 4 X J ZOOFUN
+
+
+***********************************
+* Imagic *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Trick Shot IA3000 R 4 X J TRICKSHT
+Demon Attack IA3200 C 4 X J DEMONATK
+Star Voyager IA3201 C 4 X STARVYGR
+Atlantis IA3203 U 4 X J ATLANTIS
+Cosmic Ark IA3204 U 4 X COSMCARK
+No Escape! IA3312 R 4 X NOESCAPE
+Fire Fighter IA3400 R 4 X J FIREFITE
+Aerial Ace IA3409 ER ??
+Shootin' Gallery IA3410 ER 4 X J SHOOTIN
+Riddle of the Sphinx IA3600 U 4 X J RIDDLE
+Dragon Fire IA3611 C 4 X J DRGNFIRE
+Fathom O3205 R 8 F8 X J FATHOM
+Solar Storm O3206 R 4 X SOLRSTRM
+Moonsweeper O3207 ER 8 F8 X J MOONSWEP
+Laser Gates O3208 U 4 X J LASRGATE
+Quick Step O3211 R 4 X J QUICKSTP
+Subterra O3213 R 8 F8 X J SUBTERRA
+Wing War EIZ-002-04 ER 8 F8 X J WINGWAR
+Cubicolour ???? UR 4 X J CUBICOL
+Imagic Selector ???? DM 4 X -- IMAGSLCT
+
+
+***********************************
+* ITT *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Aliens Return ???? ?? 4 X J ALIENRET
+Fire Birds ???? ?? 4 X J FIREBIRD
+Meteor Defence ???? ?? 4 X J METDEF
+
+***********************************
+* Konami *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Pooyan 001 ER 4 X POOYAN
+Strategy X 010 ER 4 X STRATGYX
+Marine Wars 011 ER 4 X MARINWAR
+
+Note: The part numbers are labelled in binary notation. :-)
+
+***********************************
+* M-Network *
+***********************************
+
+[If SC is marked, chip uses an extra RAM, #TMM2009P-25. It's
+really a 6116 in disguise]
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Star Strike MT4313 R 4 X J STARSTRK
+Adventures of TRON MT4317 U 4 X J ADVNTRON
+MOTU: Power of He-Man MT4319 R 16 E7 X J HE_MAN
+Burgertime MT4518 R 12 X E7 X J BURGTIME
+Kool-Aid man MT4648 U 4 X J KOOLAIDE
+SC Football MT5658 C 4 X J SUPRFOOT
+Space Attack MT5659 C 4 X J SPACATTK
+Armour Ambush MT5661 C 4 X J ARMAMBSH
+TRON Deadly Discs MT5662 U 4 X J TRONDEAD
+Lock 'n Chase MT5663 C 4 X J LOCKCHSE
+Frogs and Flies MT5664 U 4 X J FROGFLYS
+SC Baseball MT5665 C 4 X J SUPRBASE
+Astroblast MT5666 U 4 X J ASTRBLST
+Dark Cavern MT5667 U 4 X J DARKCVRN
+International Soccer MT5687 U 4 X J INTRSCCR
+Air Raiders MT5861 R 4 X J AIRAIDRS
+Bump 'n Jump MT7045 R 8 E7 X J BNJ
+
+
+'SC' in this case refers to extra RAM in the cart.
+
+Notes:
+
+All three E7 carts have been read in as 16K. This makes it much easier
+to write emulators and build hardware, as there's just one standard
+size. The RAM can still be included in any cart; however it has no
+effect in Bump 'n Jump or He-Man. Fortunately, it doesn't hinder operation
+either, so I chose to just include the extra RAM under the E7 label.
+
+
+
+***********************************
+* Milton Bradley *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Survival Run 4362 R 4 X J SURVLRUN
+Spitfire Attack 4363 U 4 X J SPITFIRE
+
+
+***********************************
+* Mystique (hehe!) *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Custer's Revenge 1001 ER 4 X J CUSTEREV
+Bachelor Party 1002 ER 4 X P BACHELOR
+Beat 'em and Eat 'em 1003 ER 4 X P BEATEM
+Bachelorette Party 1004 ER 4 X P BACHLRTT
+Gigolo 1009 ER 4 X J GIGOLO
+Jungle Fever 1011 ER 4 X J JNGLFEVR
+Burning Desire ???? ER 4 X J BURNDESR
+Cathouse Blues ???? ER 4 X J CATHOUSE
+Knight on the Town ???? ER 4 X J KNIGHTWN
+Lady in Wading ???? ER ??
+Philly Flasher ???? ER 4 X P PHILLY
+
+
+***********************************
+* Mythicon *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Sourcerer MA-1001 U 4 X J SORCERER
+Fire Fly MA-1002 U 4 X J FIREFLY
+Star Fox MA-1003 U 4 X J STARFOX
+
+***********************************
+* Panda Inc. *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Space Canyon 100 R 4 X J SPACANYN
+Tank Brigade 101 R 4 X TANKBRIG
+Scuba Diver 104 R 4 X J SCUDIV_P
+Stuntman 105 R 4 X J STNTMAN
+Dice Puzzle 106 R 4 X J DICEPUZL
+Sea Hawk 108 R 4 X SEAHWK_P
+Exocet 109 R 4 X EXOCET
+Harbour Escape 110 R 4 X J HARBRESC
+
+
+***********************************
+* Parker Bros. *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+SW: Jedi Arena PB5000 R 4 X P JEDIAREN
+SW: Empire Strikes Back PB5050 C 4 X J STAREMPR
+SW: Death Star Battle PB5060 R 8 E0 X J DETHSTAR
+SW: Ewok Adventure PB5065 PR ?? ---Proto Exists---
+Gyruss PB5080 R 8 E0 X J GYRUSS
+James Bond 007 PB5110 R 8 E0 X J JAMEBOND
+Frogger PB5300 C 4 X J FROGGER
+Amidar PB5310 U 4 X J AMIDAR
+Super Cobra PB5320 U 8 E0 X J SPRCOBRA
+Reactor PB5330 U 4 X J REACTOR
+Tutankham PB5340 U 8 E0 X J TUTANK
+Sky Skipper PB5350 R 4 X SKYSKIPR
+Q*Bert PB5360 C 4 X J QBERT_PB
+Popeye PB5370 C 8 E0 X J POPEYE
+SW: Arcade Game PB5540 ER 8 E0 X J SWARCADE
+Q*Bert's Qubes PB5550 ER 8 E0 X J QBRTQUBE
+Frogger ][: Threeedeep PB5590 ER 8 E0 X J FROGGER2
+Circus Charlie PB5750 ?? ---No Known Copies Exist---
+Montezuma's Revenge PB5760 ER 8 E0 X J MONTZREV
+Mr. Do's Castle PB5820 ER 8 E0 X J DOCASTLE
+Spider-Man PB5900 R 4 X J SPIDRMAN
+Strawberry Shortcake PB5910 U 4 X J STRWBERY
+GI Joe: Cobra Strike PB5920 U 4 X J GIJOE
+Action Force PB5920 ER 4 X J ACTIONMN
+Lord of the Rings PB???? UR ?? ---No Known Copies Exist---
+McDonald's PB???? UR ?? ---No Known Copies Exist---
+
+
+***********************************
+* Playaround *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+See Mystique for #201-205
+
+/General retreat 206 ER ??
+\Westward Ho 206 ER ??
+
+
+***********************************
+* Puzzy *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Seesaw ???? ER 4 X J SEESW_TW
+Football ???? ER 4 X FB_PIR8
+Earth Attack ???? ER ??
+Puzzled World ???? ER 4 X PUZZL_TW
+Chess ???? ER ??
+Boom Bang ???? ER 4 X J BOOMBANG
+Pitfall ???? ER ??
+Spider ???? ER ??
+Tennis ???? ER ??
+Pyramid War ???? ER 4 X PYRMDWAR
+Bobby is Going Home ???? ER 4 X J BOBBY
+Mr. Postman ???? ER 4 X MRPOSTMN
+Space Tunnel ???? ER 4 X SPACTUNL
+Fancy Car ???? ER ??
+My Way ???? ER ??
+S.O.S. ???? ER ??
+Frogger ???? ER ??
+Fishing ???? ER ??
+Cross Force ???? ER 4 X CROSFRCE
+Farmer Dan ???? ER ??
+Dancing Plate ???? ER 4 X DANCPLAT
+Volley Ball ???? ER ??
+Little Bear ???? ER ??
+
+
+***********************************
+* Rainbow Vision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Pac-Kong 55-003 R 4 X PACKONG
+Netmaker 55-006 R ??
+Mafia 55-010 R ??
+Hey! Stop! 55-012 R 4 X J HEY_STOP
+Bi! Bi! 55-013 R 4 X BIBI
+Catch Time 55-015 R ??
+Boom Bang 55-016 R 4 X BOOMBANG
+Mariana 55-017 R ??
+Curtiss 55-019 R ??
+Tuby Bird 55-020 R 4 X TUBYBIRD
+Tomboy 55-??? R 4 X J TOMBOY
+
+
+***********************************
+* Salu *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Acid Drop ???? ER 16 F6 X J ACIDDROP
+Ghostbusters ][ ???? ER 16 F6 X J GHOSTBS2
+Pick 'N' Pile ???? ER 16 F6 X J PICKPILE
+
+
+***********************************
+* Sancho *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Exocet TEC001 ER ??
+Sea Hawk TEC002 ER ??
+Skin Diver TEC003 ER 4 X SKINDIVR
+Nightmare TEC004 ER 4 X NGHTMARE
+Dice Puzzle TEC005 ER 4 X DICEPUZL
+Forest TEC006 ER 4 X FOREST
+
+
+***********************************
+* Sega *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Tac-Scan 001-01 U 4 X TACSCAN
+Sub Scan 002-01 U 4 X SUBSCAN
+Thunderground 003-01 R 4 X THUNDGRD
+Star Trek: SOS 004-01 R 8 F8 X J STARTREK
+Buck Rodgers 005-01 U 8 F8 X J BUCKROG
+Congo Bongo 006-01 R 8 F8 X J CONGBONG
+Up 'n Down 009-01 ER 8 F8 X J UPNDOWN
+Tapper 010-01 ER 8 F8 X J TAPPER
+Spy Hunter 011-02 ER 8 F8 X J SPYHUNTR
+
+
+***********************************
+* Selchow & Righter *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Glib ???? UR 4 X GLIB
+
+
+***********************************
+* Simage *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Eli's Ladder ???? UR 4 X ELILADDR
+
+
+***********************************
+* Sparrow *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Music Machine GCG 1001T UR 4 X MUSCMACH
+
+
+***********************************
+* Spectravision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Gangster Alley SA-201 R 4 X J GANGALLY
+Planet Patrol SA-202 R 4 X J PLANTPAT
+Cross Force SA-203 R 4 X CROSFRCE
+Tape Worm SA-204 R 4 X J TAPEWORM
+China Syndrome SA-205 R 4 X CHINASYN
+The Challange of... Nexar SA-206 R 4 X NEXAR
+Master Builder SA-210 R 4 X J MASTBULD
+Galactic Tactic SA-211 R ??
+Mangia SA-212 R 4 X J MANGIA
+Gas Hog SA-217 ER 4 X J GASHOG
+Bumper Bash SA-218 ER 4 X J BUMPER
+Save the Whales SA-??? UR ??
+Cave-In SA-??? UR ??
+Chase the Chuckwagon SA-??? UR 4 X J CHUCKWGN
+
+
+***********************************
+* StarPath *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Supercharger BIOS ROM 330030 -- 2 X STARPATH
+Phasor Patrol RA-4000 R 6 AR X J PHASOR
+Communist Mutants RA-4001 R 6 AR X COMMIE
+Suicide Mission RA-4002 R 6 AR X J SUICIDE
+Killer Satellites RA-4103 R 6 AR X J KILLRSAT
+Rabbit Transit RA-4104 ER 6 AR X J RABBIT
+Frogger RA-4105 ER 6 AR X J FROGGER
+Escape from the Mindmaster RA-4200 ER 6*4 AR XXXX J MINDMAS1-4
+Sword of Saros RA-4201 ER 6 AR X SWOSAROS
+Excalibur RA-4201 PR ??
+Fireball RA-4300 R 6 AR X FIREBALL
+Party Mix RA-4302 ER 6*3 AR XXX PRTYMIX1-3
+Dragonstomper RA-4400 ER 6*3 AR XXX J DRAGON1-3
+Survival Island RA-4401 ER 6*3 AR XXX SURVIVAL1-3
+Sweat! RA-4??? PR 6*2 AR XX SWEAT1,2
+Comm. Mutants Demo ???? DM 6 AR X COMMDEMO
+Dragonstomper Demo ???? DM 6 AR X DRAGDEMO
+Fireball Demo ???? DM 6 AR X FIREDEMO
+Frogger Demo ???? DM 6 AR X FROGDEMO
+Killer Satellites Demo ???? DM 6 AR X KILLDEMO
+Esc. from Mindmaster Demo ???? DM 6 AR X MINDDEMO
+Party Mix Demo ???? DM 6 AR X PRTYDEMO
+Rabbit Transit Demo ???? DM 6 AR X RABTDEMO
+Suicide Mission Demo ???? DM 6 AR X SUICDEMO
+
+
+***********************************
+* Sunrise *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Quest for Quinta Roo 1603 ER 8 F8 X J QUINTROO
+Snowplow ???? ER ??
+Glacier Patrol ???? ER 4 X J GLACIER
+Noah and the Ark ???? ??
+
+
+***********************************
+* Suntek *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Time Race 1 ER ??
+Galactic 2 ER ??
+Pac-Kong 3 ER 4 X PACKONG
+Pyramid War 4 ER 4 X PYRMDWAR
+Netmaker 6 ER ??
+Bermuda 9 ER 4 X BERMUDA
+
+
+***********************************
+* Technovision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Adventures of GX-12 ???? ??
+Flipper ???? ??
+Formula I ???? ??
+Jungle Jim ???? ??
+Laser Raid ???? ??
+Moonbase ???? ??
+Motor Mouth ???? ??
+Mouse Highway ???? 4 X J CATMOUSE
+Nuts ???? 4 X NUTS
+Pharoah's Curse ???? 4 X PHARHCRS
+Save Our Ship ???? 4 X J SAVESHIP
+Silly Safari ???? ??
+Shoot-Out ???? ??
+Stone Age ???? ??
+Tachion Beam ???? ??
+
+
+***********************************
+* Tele-Games *
+***********************************
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+
+Bogey Blaster 5861 A030 R 4 X J BOGYBLST
+Night Stalker ???? R 4 X J NIGHTSTK
+Universal Chaos ???? 4 X J UNIVCHOS
+Bump 'n Jump ???? 8 F8 X X1 J BUMPHUMP
+
+
+X1: Intresting... uses F8 instead of E7 bankswitching!
+
+
+***********************************
+* Telesys *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Coco Nuts 1001 R 4 X J COCONUTS
+Cosmic Creeps 1002 R 4 X J COSMCREP
+Fast Food 1003 R 4 X J FASTFOOD
+Ram- It 1004 ER 4 X J RAMIT
+Star Gunner 1005 ER 4 X STARGN
+Demolition Herby 1006 ER 4 X J DEMOHRBY
+Bouncing Baby Monkeys ???? UR ??
+The Impossible Game ???? UR ??
+
+
+***********************************
+* Tigervision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+King Kong 7-001 R 4 X J KINGKONG
+Jawbreaker 7-002 R 4 X J JAWBREAK
+Threshold 7-003 R 4 X J THRSHOLD
+River Patrol 7-004 UR 8 3F X J RIVERP
+Marauder 7-005 ER 4 X J MARAUDER
+Springer 7-006 UR 8 3F X J SPRINGER
+Polaris 7-007 ER 8 3F X J POLARIS
+Miner 2049'er 7-008 ER 8 3F X J MNR2049R
+Intuition 7-009 NR ??
+Scraper Caper 7-010 NR ??
+Miner 2049'er Volume ][ 7-011 ER 8 3F X J MINRVOL2
+Espial 7-012 ER 8 3F X J ESPIAL
+
+***********************************
+* TNT Games *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+BMX Airmaster 26192 ER 16 F6 X J BMX_TNT
+
+***********************************
+* 20th Century Fox *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Worm War I 11001 U 4 X J WORMWAR1
+Beany Bopper 11002 R 4 X J BEANYBOP
+Fast Eddie 11003 U 4 X FASTEDIE
+Deadly Duck 11004 R 4 X J DEADDUCK
+Mega Force 11005 R 4 X MEGAFRCE
+Alien 11006 R 4 X J ALIEN
+Turmoil 11007 U 4 X J TURMOIL
+Fantastic Voyage 11008 R 4 X FANTCVOY
+Crypts of Chaos 11009 R 4 X CRPTCHOS
+M*A*S*H 11011 U 4 X J MASH
+Bank Heist 11012 R 4 X BANKHEST
+Porky's 11013 R 8 F8 X J PORKYS
+Flash Gordon 11015 R 4 X FLASHGRD
+Revenge of the BS Tomatoes 11016 R 4 X J REVNGTOM
+The Earth Dies Screaming 11020 R 4 X J EARTHDIE
+Spacemaster X-7 11022 ER 4 X SPACMAST
+Meltdown 11029 ER ?? Need!
+Crash Dive 11031 ER 4 X CRSHDIVE
+Alligator People ????? PR 4 X J ALIGPEPL
+
+***********************************
+* U.S. Games *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Space Jockey VC 1001 C 2 X J SPACJOCK
+Sneak 'n Peek VC 1002 R 4 X SNEKPEEK
+Word Zapper VC 1003 U 4 X J WORDZAPR
+Commando Raid VC 1004 R 4 X COMANDRD
+"Name This Game" VC 1007 R 4 X X1 J NAMEGAME
+Octopus VC 1007 ER 4 X X1 J NAMEGAME
+Towering Inferno VC 1009 U 4 X J TOWERINF
+M.A.D VC 1012 R 4 X J M_A_D
+Gopher VC 2001 R 4 X J GOPHER
+Squeeze Box VC 2002 ER 4 X J SQUEEZBX
+Eggomania VC 2003 R 4 X P EGGOMANA
+Picnic VC 2004 ER 4 X P PICNIC
+Piece 'o Cake VC 2005 ER 4 X P PIECECKE
+Raft Rider VC 2006 ER 4 X J RAFTRIDR
+Entombed VC 2007 ER 4 X J ENTOMBED
+
+
+X1: These two carts are the same except the name.
+
+
+***********************************
+* Universal Gamex *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+X-Man GX-001 UR 4 X J XMAN
+
+
+***********************************
+* Venturevision *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Rescue Terra I VV2001 ER 4 X RESCTER1
+Inner Space ????
+
+
+***********************************
+* Video Gems *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Missile Control ???? ER 4 X MISLCONT
+Mission Survive ???? ER
+Steeple Chase ???? ER
+Surfer's Paradise ???? ER 4 X SURFPRDS
+Treasure Below ???? ER
+
+
+***********************************
+* Wizard Video *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Texas Chainsaw Massacre 008 ER 4 X J TXSCHAIN
+Halloween 007 ER 4 X J HALOWEEN
+
+
+***********************************
+* Xonox *
+***********************************
+
+Note: No repeats are listed (i.e. when the same game is on two double-enders)
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Spike's Peak 99001 ER 8 F8 X J SPIKE_PK
+Ghost Manor 99002 ER 8 F8 X J GHOSTMAN
+Chuck Norris Super Kicks 99003 ER 8 F8 X J CHUCKICK
+Artillery Duel 99004 ER 8 F8 X J ART_DUEL
+Robin Hood 99005 ER 8 F8 X J ROBH_P
+Sir Lancelot 99006 ER 8 F8 X J SIRL_N
+Tomarc the Barbarrian 99007 R ??
+Motocross Racer 99008 R ??
+
+
+***********************************
+* Zellers *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Time Warp ???? ER 4 X TIMEWARP
+
+***********************************
+* Zimag *
+***********************************
+
+
+See Emag
+
+
+***********************************
+* Un-marked / Other *
+***********************************
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Dragon Defender TP-605 ER 4 X DRGNDFND
+Hole Hunter TP-606 ER 4 X HOLEHUNT
+Farmyard Fun TP-617 ER 4 X FARMYARD
+16 Games in 1 ???? ER ??
+Brick Kick ???? ER 4 X J BRICKICK
+Challange ???? ER 4 X CHALENGE
+Clown Down Town ???? ER 4 X CLWNDOWN
+Criminal Pursuit ???? ER 4 X CRIMLPUR
+Dragon Treasure ???? ER ??
+Frontline ???? ER ??
+Inca Gold ???? ER ??
+laser Volley ???? ER 4 X LASRVOLY
+Ski Run ???? ER 4 X SKI_RUN
+Lie Low ???? ER ??
+Lost and Found ???? ER ??
+Missile Attack ???? ER ??
+Oops ???? ER ??
+Planet Protector ???? ER ??
+Ski Hunt ???? ER 4 X SKIHUNT
+Super-Ferrari ???? ER 4 X SUPFERRI
+Tom Boy ???? ER 4 X J TOMBOY
+UFO Patrol ???? ER 4 X UFOPATRL
+Wolf Fighting ???? ER ??
+Pink Panther / Probe 2000 ???? PR ?? ---One Proto Exists---
+
+
+**********************************************
+* Odd proto's and other intresting things *
+**********************************************
+
+ Name / Description SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Air Raid (Not Air Raiders! By Men-A-Vision) 4 X AIR_RAID
+Bira Bira (modified Burning Desire) 4 X J BIRABIRA
+Challange of Nexar (Changed GFX) 4 X NEXAR-CH
+Circus Atari (Uses joysticks) 4 X J CIRCUS-J
+Colourbar Generator 4 X -- COLORBAR
+Condor (Similar to Condor Attack) 4 X CONDOR
+Donkey Kong (Changed GFX) 4 X J DK-CH
+Duck Shot (Positively Weird!) 4 X DUCKSHOT
+Elk Attack (Mark R. Hahn; 1987) 8 F8 X ELK
+Fishing Derby (changed GFX; from 32-in-1) 2 X J FISHN-CH
+Freeway (Changed GFX; from the 32-in-1) 2 X J FREWY-CH
+Galaga (River Raid ripoff) 4 X J GALAGA
+Joust Hack (#1) 8 F8 X J J_HCK1
+Joust Hack (#2) 8 F8 X J J_HCK2
+Joust; Super (modified) 8 F8 X J SJOUST
+Marflegr (PAL version of Sea Hawk) 4 X MARFLEGR
+MASH w/ subs (Modified GFX) 4 X J MASH_SUB
+Missile Command (Changed GFX) 4 X J MC-CH
+Pac-Kong (Changed GFX) 4 X J PK-CH
+Snail Against Squirrel (Changed GFX) 4 X J SVS-CH
+Space Raid (Vaguely Threshold-like) 4 X SPACRAID
+Test (Neat little TIA test) 4 X -- TEST
+Traffic (Dunno; intresting) 4 X J TRAFFIC
+World End (I Believe this is World? Trap?) 4 X J WORLDEND
+Galactic (Starsoft title; not a pirate) 4 X J GALACTIC
+Air-sea Battle (changed GFX) 2 X J AIRSEA2
+Space Invaders (changed GFX) 4 X J SPACE2
+Magazine Demo 4 X -- MAGDEMO
+4-game ROM... uses F6 bankswitch 16 F6 X J GORF_RIP
+
+***********************************
+* Overflow *
+***********************************
+
+Used to keep Bankzilla's database program happy (mainly PAL versions and
+game revisions. Prevents cluttering up the main listing)
+
+
+ Name Part # RA SZ SC BS IM SP CT Filename
+---------------------------------------------------------------------------
+
+Pal version of Pele's Soc. CX2616 ?? 4 X J CX2616PL
+Taiwanese Enduro ???? ?? 4 X J ENDRO_TW
+Taiwanese Pele's ???? ?? 4 X J PELE_TW
+CCE version of Pitfall ???? ?? 4 X J PITF_CCE
+Taiwanese River Raid ???? ?? 4 X J RIVER_TW
+Diagnostic Program ???? ?? 4 X -- SALTDIAG
+Superman; revision 2 ???? ?? 4 X J SUPRMAN2
+Dunno ???? ?? 2 X -- XX
+Pal version of KLAX ???? ?? 16 X F6 X J KLAX
+Okie Dokie; Limited ???? ?? 4 X J OKIEDLIM
+Robot Tank; F8-fixed ---- -- 8 F8 X J ROBO_FIX
+Surf's Up; original ---- -- 8 F8 X J SURFSUP
+Dumbo's F. Circ.; PAL ???? PR 8 F8 X J DUMBO_P
+Sir Lancelot; NTSC ???? ?? 8 F8 X J SIRL_P
+Smurf Rescue; PAL ???? ?? 8 F8 X J SMURF_PL
+'Chess'; Taiwanese ???? ?? 2 X J CHESS_TW
+Outerspace; Sears ???? ?? 2 X J OUTERSPC
+Okie Dokie Proto ---- -- 2 X J LT
+Taiwanese Bowling ???? ?? 2 X J BOWLG_TW
+
+*Not* a ROM image! **** ** ** ** ** X -- EMPTY
+
+####Data End####
+
+***********************************
+* World of Dead ROM Images *
+***********************************
+
+Yeppers, some ROM images are better off dead. Either they're exact copies,
+damaged, or just plain DOA.
+
+XTACK Same as Z-Tack by Bomb.
+POLEPOS Pole Position... bad read. 5 bytes bad.
+ASTROSMS Same as M-net's Astroblast
+
+***********************************
+* Proto's Read *
+***********************************
+
+
+Thanks to many people, I have been able to read some prototype carts in!
+However, the data contained on the carts is identical to the production
+ones.
+
+Bermuda Triangle, #371
+Pac-Man, in an Imagic case!! The board has been wave-soldered; said board
+ is an actual Imagic board, and the chip is a ROM.
diff --git a/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/stella.pdf b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/stella.pdf
new file mode 100644
index 00000000..5a76bc1b
Binary files /dev/null and b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/stella.pdf differ
diff --git a/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/stella.txt b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/stella.txt
new file mode 100644
index 00000000..e9eb92c9
--- /dev/null
+++ b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/stella.txt
@@ -0,0 +1,1938 @@
+TABLE OF CONTENTS 4
+
+
+
+
+
+
+ STELLA
+
+ PROGRAMMER'S
+
+ GUIDE
+
+
+
+
+
+
+
+
+
+ by
+ Steve Wright
+ 12/03/79
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (Reconstructed by Charles Sinnett 6/11/93 Internet:
+ cas@mentor.cc.purdue.edu)
+
+Table of Contents
+
+
+TELEVISION PROTOCOL 1
+ Diagram 1 - Atari TV Frame 2
+The TIA (as seen by the programmer) 3
+ 1.0 General Description 3
+ 2.0 The Registers 3
+ 3.0 Synchronization 4
+ 3.1 Horizontal Timing 4
+ 3.2 Microprocessor Synchronization 4
+ 3.3 Vertical timing 4
+ 4.0 Color and Luminosity 5
+ 5.0 Playfield 5
+ 6.0 The Moveable Objects Graphics 6
+ 6.1 Missile Graphics (M0, M1) 6
+ 6.2 Ball Graphics (BL) 6
+ 6.3 Player Graphics (P0, P1) 7
+ 7.0 Horizontal Positioning 8
+ 8.0 Horizontal Motion 8
+ 9.0 Object Priorities 9
+ 10.0 Collisions 10
+ 11.0 Sound 10
+ 11.1 Tone 10
+ 11.2 Frequency 10
+ 11.3 Volume 10
+ 12.0 Input Ports 11
+ 12.1 Dumped Input Ports (INPT0 thru INPT3) 11
+ 12.2 Latched Input Ports (INPT4, INPT5) 11
+
+THE PIA (6532) 12
+ 1.0 General 12
+ 2.0 Interval timer 12
+ 2.1 Setting the timer 12
+ 2.2 Reading the timer 12
+ 2.3 When the timer reaches zero 12
+ 3.0 RAM 13
+ 4.0 The I/O ports 13
+ 4.1 Port B - Console Switches (read only) 13
+ 5.0 Port A - Hand Controllers 13
+ 5.1 Setting for input or output 13
+ 5.2 Inputting and Outputting 14
+ 5.3 Joystick Controllers 14
+ 5.4 Paddle (pot) controllers 14
+ 5.5 Keyboard controllers 15
+ 6.0 Address summary table 15
+
+
+PAL/SECAM CONVERSIONS 16
+ PAL 16
+ SECAM 16
+
+
+TIA 1A - TELEVISION INTERFACE ADAPTOR (MODEL 1A) 17
+ GENERAL DESCRIPTION 17
+ DETAILED DESCRIPTION 18
+ 1. Data and addressing 18
+ 2. Synchronization 18
+ A. Horizontal Timing 18
+ B. Vertical Timing 18
+ C. Composite Sync 18
+ D. Microprocessor Synchronization 19
+ 3. Playfield graphics Register 19
+ A. Description 19
+ B. Normal Serial Output 19
+ C. Reflected Serial Output 19
+ D. Timing Constraints 20
+ 4. Horizontal Position Counters 20
+ A. Description 20
+ B. Ball position Counter 20
+ C. Player Position Counters 20
+ D. Missile Position Counters 21
+ 5. Horizontal Motion Registers 21
+ A. General Description 21
+ B. Timing constraints 21
+
+ 6. Moving Object Graphics Registers 22
+ A. General Description 22
+ B. Missile Graphics 22
+ C. Player Graphics 22
+ D. Vertical Delay 23
+ E. Ball Graphics 24
+ 7. Collision Detection Latches 24
+ A. Definitions 24
+ B. Reading Collision 24
+ C. Reset 24
+ 8. Input ports 25
+ A. General Description 25
+ B. Dumped Input Ports (I0 through I3) 25
+ C. Latched Input ports (I4, I5) 25
+ 8.5 Priority Encoder 26
+ A. Purpose 26
+ B. Priority Assignment 26
+ C. Priority Control 26
+ 9 Color Luminance Registers 27
+ A. Description 27
+ B. Multiplexing 27
+ 10. Color Phase Shifter 27
+ 11. Audio Circuits 27
+ A. Frequency Select 27
+ B. Noise-Tone Generator 28
+ C. Volume Select 28
+
+ Figure 1. Vertical Delay 29
+ Figure 2. Synchronization 30
+ Figure 3. Color-Luminance 30
+ Figure 4. Typical Horizontal Motion Circuit 31
+ Figure 5. Playfield Graphics 32
+ Figure 6. Collision Detection 33
+ Figure 7. Audio Circuit 34
+ Figure 8. Input Ports 35
+ Figure 9. Game System 36
+
+Write Address Detailed Functions 37
+ WSYNC (wait for sync) 37
+ RSYNC (reset sync) 37
+ VSYNC 37
+ VBLANK 37
+ PJ0 (PF1, PF2) 38
+ PLAYFIELD REGISTERS SERIAL OUTPUT 38
+ CTRLPF 38
+ NUSIZ0 (NUSIZ1) 39
+ RESP0 (RESP1, RESM0, RESM1, RESBL) 39
+ RESMP0 (RESMP1) 39
+ HMOVE 40
+ HMCLR 40
+ HMP0 (HMP1, HMM0, HMM1, HMBL) 40
+ ENAM0 (ENAM1, ENABL) 41
+ GRP0 (GRP1) 41
+ REFP0 (REFP1) 41
+ VDELP0 (VDELP1, VDELBL) 41
+ CXCLR 41
+ COLUP0 (COLUP1, COLUPF, COLUBK) 42
+ AUDF0 (AUDF1) 42
+ AUDC0 (AUDC1) 43
+ AUDV0 (AUDV1) 43
+ WRITE ADDRESS SUMMARY 44
+ READ ADDRESS SUMMARY 45
+
+ TIA O0..02 AND LUM TIMING 46
+ TIA WRITE TIMING CHARACTERISTICS 47
+ TIA READ TIMING CHARACTERISTICS 48
+ TIA COMP-SYN AND READY TIMING 49
+ RSYNC, RES0O, H01, H02, SHB, 02, 0O 50
+ TIA RSYNC AND BLANK AND READY TIMING 51
+
+
+
+TELEVISION PROTOCOL
+ (The TV picture according to Atari)
+
+ For the purposes of Stella programming, a single television
+ “frame” consists of 262 horizontal lines, and each line is
+ divided by 228 clock counts (3.58MHz). The actual TV
+ picture is drawn line by line from the top down 60 times a
+ second, and actaully consists of only a portion of the
+ entire “frame” (see diag. #1). A typical frame will
+ consists of 3 vertical sync (VSYNC) lines*, 37 vertical
+ blank (VBLANK) lines, 192 TV picture lines, and 30 overscan
+ lines. Atari’s research has shown that this pattern will
+ work on all types of TV sets. Each scan lines starts with
+ 68 clock counts of horizontal blank (not seen on the TV
+ screen) followed by 160 clock counts to fully scan one line
+ of TV picture. When the electron beam reaches the end of a
+ scan line, it returns to the left side of the screen, waits
+ for the 68 horizontal blank clock counts, and proceeds to
+ draw the next line below.
+
+ All horizontal timing is taken care of by hardware, but the
+ microprocessor must “manually” control vertical timing to
+ signal the start of the next frame. When the last line of
+ the previous frame is detected, the microprocessor must
+ generate 3 lines of VSYNC, 37 lines of VBLANK, 192 lines of
+ actual TV picture, and 30 lines of overscan. Fortunately,
+ both VSYNC and VBLANK can simply be turned on and off at
+ the appropriate times, freeing the microprocessor for other
+ activities during their execution.
+
+ * (to signal the TV set to start a new frame)
+
+ The actual TV picture is drawn one line at a time by having
+ the microprocessor enter the data for that line into the
+ Television Interface Adaptor (TIA) chip, which then
+ converts the data into video signals. The TIA can only
+ have data in it that pertains to the line being currently
+ drawn, so the microprocessor must be “one step ahead” of
+ the electron beam on each line. Since one microprocessor
+ machine cycle occurs every 3 clock counts, the programmer
+ has only 76 machine cycles per line (228/3 = 76) to
+ construct the actual picture (actually less because the
+ microprocessor must be ahead of the raster). To allow more
+ time for the software, it is customary (but not required)
+ to update the TIA every two scan lines. The portion of the
+ program that constructs this TV picture is referred to as
+ the “Kernel”, as it is the essence or kernel of the game.
+
+ In general, the remaining 70 scan lines (3 for VSYNC, 37
+ for VBLANK, and 30 for overscan) will provides 5,320
+ machine cycles (70 lines x 76 machine cycles) for
+ housekeeping and game logic. Such activities as
+ calculating the new position of a player, updating the
+ score, and checking for new inputs are typically done
+ during this time.
+Diagram 1 - Atari TV Frame
+
+
+
+
+The TIA (as seen by the programmer)
+1.0 General Description
+
+ The TIA is a custom IC designed to create the TV picture
+ and sound from the instructions sent to it by the
+ microprocessor. It converts the 8 bit parallel data from
+ the microprocessor into signals that are sent to video
+ modulation circuits which combine and shape those signals
+ to be compatible with ordinary TV reception. A “playfield”
+ and 5 moveable objects can be created and manipulated by
+ software.
+
+ A playfield consisting of walls, clouds, barriers, and
+ other seldom moved objects can be created over a colored
+ background. The 5 moveable objects can be positioned
+ anywhere, and consists of 2 players, 2 missiles, and a
+ ball. The playfield, players, missiles, and ball are
+ created and manipulated by a series of registers in the TIA
+ that the microprocessor can address and write into. Each
+ type of object has certain defined capabilities. For
+ example, a player can be moved with one instruction, but
+ the playfield must be completely re-drawn in order to make
+ it “move”.
+
+ Color and luminosity (brightness) can be assigned to the
+ background, playfield, and 5 moveable objects. Sound can
+ also be generated and controlled for volume, pitch, and
+ type of sound. Collisions between the various objects on
+ the TV screen are detected by the TIA and can be read by
+ the microprocessor . Input ports which can be read by the
+ microprocessor give the status of some of the various hand
+ held controllers.
+
+2.0 The Registers
+
+ All instructions to the TIA are achieved by addressing and
+ writing to various registers in the chip. A key point to
+ remember is data written in a register is latched an
+ retained until altered by another write operation into that
+ register. For example, if the color register for a player
+ is set for red, that player will be red every time it is
+ drawn until that color register is changed. All of the
+ registers are addressed by the microprocessor as part of
+ the overall RAM/ROM memory space.
+
+ All registers have fixed address locations and pre-assigned
+ address names for handy reference. Many registers do not
+ use all 8 data bits, and some registers are used to
+ “strobe” or trigger events. A “strobe” register executes
+ its function the instant it is written to (the data written
+ is ignored). The only registers the microprocessor can
+ read are the collision registers and input port registers.
+ These registers are conveniently arranged so that the data
+ bits of interest always appear as data bits 6 or 7 for easy
+ access.
+
+3.0 Synchronization
+
+ 3.1 Horizontal Timing
+ When the electron beam scans across the TV screen and
+ reaches the right edge, it must be turned off and moved
+ back to the left edge of the screen to begin the next scan
+ line. The TIA takes care of this automatically, independent
+ of the microprocessor. A 3.58 MHz oscillator generates
+ clock pulses called “color clocks” which go into a pulse
+ counter in the TIA. This counter allows 160 color clocks
+ for the beam to reach the right edge, then generates a
+ horizontal sync signal (HSYNC) to return the beam to the
+ left edge. It also generates the signal to turn the beam
+ off (horizontal blanking) during its return time of 68
+ color clocks. Total round trip for the electron beam is
+ 160 + 68 = 228 color clocks. Again, all the horizontal
+ timing is taken care of by the TIA without assistance from
+ the microprocessor.
+
+ 3.2 Microprocessor Synchronization
+ The microprocessor’s clock is the 3.58 MHz oscillator
+ divided by 3, so one machine cycle is 3 color clocks.
+ Therefore, one complete scan line of 228 color clocks
+ allows only 76 machine cycles (228/3 = 76) per scan line.
+ The microprocessor must be synchronized with the TIA on a
+ line-by-line basis, but program loops and branches take
+ unpredictable lengths of time. To solve this software
+ sync. problem, the programmer can use the WSYNC (Wait for
+ SYNC) strobe register. Simply writing to the WSYNC causes
+ the microprocessor to halt until the electron beam reaches
+ the right edge of the screen, then the microprocessor
+ resumes operation at the beginning of the 68 color clocks
+ for horizontal blanking. Since the TIA latches all
+ instructions until altered by another write operation, it
+ could be updated every 2 or 3 lines. The advantage is the
+ programmer gains more time to execute software, but at a
+ price paid with lower vertical resolution in the graphics.
+
+ NOTE: WSYNC and all the following addresses’ bit
+ structures are itemized in the TIA hardware manual. The
+ purpose of this document is to make them understandable.
+
+ 3.3 Vertical timing
+ When the electron beam has scanned 262 lines, the TV set
+ must be signaled to blank the beam and position it at the
+ top of the screen to start a new frame. This signal is
+ called vertical sync, and the TIA must transmit this signal
+ for at least 3 scan lines. This is accomplished by writing
+ a “1” in D1 of VSYNC to turn it on, count at least 2 scan
+ lines, then write a “0” to D1 of VSYNC to turn it off.
+
+ To physically turn the beam off during its repositioning
+ time, the TV set needs 37 scan lines of vertical blanks
+ signal from the TIA. This is accomplished by writing a “1”
+ in D1 of VBLANK to turn it on, count 37 lines, then write a
+ “0” to D1 of VBLANK to turn it off. The microprocessor is
+ of course free to execute other software during the
+ vertical timing commands, VSYNC and VBLANK.
+
+4.0 Color and Luminosity
+
+ Color and luminosity can be assigned to the background
+ (BK), playfield (PF), ball (BL), player 0 (P0), player
+ 1(P1), missile 0 (M0), and missile 1 (M1). There are only
+ four color-lum registers for these 7 objects, so the
+ objects are paired to share the same register according to
+ the following list:
+
+ color-lum register Objects colored
+ COLUMP0 P0, M0 (player 0, missile 0)
+ COLUMP1 P1, M1 (player 1, missile 1)
+ COLUMPF PF, BL (playfield, ball)
+ COLUMBK BK (background)
+
+ For example, if the COLUMP0 register is set for light red,
+ both P0 and M0 will be light red when drawn.
+
+ A color-lum register is set for both color and luminosity
+ by writing a single 7 bit instruction to that register.
+ Four of the bits select one of the 16 available colors, and
+ the other 3 bits select one of 8 levels of luminosity
+ (brightness). The specific codes required to create
+ specific color and lum are listed in the Detailed Address
+ List of the TIA hardware manual. As with all registers
+ (except the “strobe” registers), the data written to them
+ is latched until altered by another write operation.
+
+5.0 Playfield
+
+ The PF register is used to create a playfield of walls,
+ clouds, barriers, etc., that are seldom moved. This low
+ resolution register is written into to draw the left half
+ of the TV screen only. The right half of the screen is
+ drawn by software selection of whether a duplication or a
+ reflection of the right half.
+
+ The PF register is 20 bits wide, so the 20 bits are written
+ into 3 addresses: PF0, PF1, and PF2. PF0 is only 4 bits
+ wide and constructs the first 4 “bits” of the playfield,
+ starting at the left edge of the TV screen. PF1 constructs
+ the next 8 “bits”, and PF2 the last 8 bits” which end at
+ the center of the screen. The PF register is scanned from
+ left to right and where a “1” is found the PF color is
+ drawn, and where a “0” is found, the BK color is drawn. To
+ clear the playfield, obviously zeros must be written into
+ PF0, PF1, and PF2.
+
+ To make the right half of the playfield into a duplication
+ or copy of the left half, a “0” is written to D0 of the
+ CTLPF (control playfield) register. Writing a “1” will
+ cause the reflection to be displayed.
+
+6.0 The Moveable Objects Graphics
+
+ All 5 moveable objects (P0, M0, P1, M1, BL) can be assigned
+ a horizontal location on the screen and moved left or right
+ relative to their location. Vertical positions, however,
+ are treated in an entirely different manner. In principle,
+ these objects appear at whatever scan lines their graphics
+ registers are enabled. For example, let us assume the ball
+ is to be positioned vertically in the center of the screen.
+ The screen has 192 scan lines and we want the ball to be 2
+ scan lines “thick”. The ball graphics would be disabled
+ until scan line 96, enabled for 2 scan lines, then disabled
+ for the rest of the frame. Each type of object (players,
+ missiles, and ball) has its’ own characteristics and
+ limitations.
+
+ 6.1 Missile Graphics (M0, M1)
+ The two missile graphics registers will draw a missile on
+ any scan line by writing a “1” to the one bit enable
+ missile registers (ENAM0, ENAM1). Writing a “0” to these
+ registers will disable the graphics. The missiles’ left
+ edge is positioned by a horizontal position register, but
+ the right edge is a function of how wide the missile is
+ make. Width of a missile is controlled by writing into
+ bits D4 and D5 of the number-size registers (NUSIZ0,
+ NUSIZ1). This has the effect of “stretching” the missile
+ out over 1,2,4, or 8 color clock counts (a full scan line
+ is 160 color clocks).
+
+ 6.2 Ball Graphics (BL)
+ The ball graphics register works just like the missile
+ registers. Writing a “1” to the enable ball register
+ (ENABL) enables the ball graphics until the register is
+ disabled. The ball can also be “stretched” to widths of 1,
+ 2, 4, or 8 color clock counts by writing to bits D4 and D5
+ of the CTRLPF register.
+
+ The ball can also be vertically delayed one can line. For
+ example, if the ball graphics were enabled on scan line 95,
+ it could be delayed to not display on the screen until scan
+ line 96 by writing a “1” to D0 of the vertical delay
+ (VDELBL) register. The reason for having a vertical delay
+ capability is because most programs will update the TIA
+ every 2 lines. This confines all vertical movements of
+ objects to 2 scan line “jumps”. The use of vertical delay
+ allows the objects to move one scan line at a time.
+
+ 6.3 Player Graphics (P0, P1)
+ The player graphics are the most sophisticated of all the
+ moveable objects. They have all the capabilities of the
+ missile and ball graphics, plus three move capabilities.
+ Players can take on a “shape” such as a man or an airplane,
+ and the player can easily be flipped over horizontally to
+ display the mirror image (reflection) instead of the
+ original image, plus multiple copies of the players can be
+ created.
+
+ The player graphics are drawn line-by-line like all other
+ graphics. The difference here is each scan line of the
+ player is 8 “bits” wide, whereas the missiles and ball are
+ one “bit” wide. Therefore, a player can be though of as
+ being drawn of graph paper 8 squares wide and as tall as
+ desired. To “color in the squares” of this imaginary graph
+ paper, 8 data bits are written into the players graphics
+ registers (GP0, GP1). This 8 bit register is scanned from
+ D7 to D0, and wherever a “1” is found that “square” gets
+ the players’ color (from the color-lum register) and where
+ a “0” is found that “square” gets the background color. To
+ position a player vertically, simply leave all “0’s” in the
+ graphics registers (GP0, GP1) until the electron beam is on
+ the scan line desired, write to the graphics register line-
+ by-line describing the player, then write all “0’s” to turn
+ off the players’ graphics until the end of that frame.
+
+ To display a mirror image (reflection) instead of the
+ original figure, write a “1” to D3 of the one bit
+ reflection register (REFP0, REFP1). A “0” written to these
+ registers restores the original figure.
+
+ Multiple copies of players as well as their size are
+ controlled by writing 3 bits (D0, D1, D2) into the number-
+ size registers (NUSIZ0, NUSIZ1). These three bits select
+ from 1 to 3 copies of the player, spacing of those copies,
+ as well as the size of the player (each “square” of the
+ player can be 1, 2, or 4 clocks wide). Whenever multiple
+ copies are selected, the TIA automatically creates the same
+ number of copies of the missile for that player. Again,
+ the specifics of all this are laid out in the TIA hardware
+ manual.
+
+ Vertical delay for the players works exactly like the ball
+ by writing a “1” to D0 in the players’ vertical delay
+ registers (VDELP0, VDELP1). Writing a “0” to these
+ locations disables the vertical delay.
+
+7.0 Horizontal Positioning
+
+ The horizontal position of each object is set by writing to
+ its’ associated reset register (RESP0, RESP1, RESM0, RESM1,
+ RESBL) which are all “strobe” registers (they trigger their
+ function as soon as they are addressed). That causes the
+ object to be positioned wherever the electron bean was in
+ its sweep across the screen when the register was reset.
+ for example, if the electron beam was 60 color clocks into
+ a scan line when RESP0 was written to, player 0 would be
+ positioned 60 color clocks "in” on the next scan line.
+ Whether or not P0 is actually drawn on the screen is a
+ function of the data in the GP0 register, but if it were
+ drawn, it would show up at 60. Resets to these registers
+ anywhere during horizontal blanking will position objects
+ at the left edge of the screen (color clock 0). Since
+ there are 3 color clocks per machine cycle, and it can take
+ up to 5 machine cycles to write the register, the
+ programmer is confined to positioning the objects at 15
+ color clock intervals across the screen. This “course”
+ positioning is “fine tuned” by the Horizontal Motion,
+ explained in section 8.0.
+
+ Missiles have an additional positioning command. Writing a
+ “1” to D1 of the reset missile-to-player register (RESMP0,
+ RESMP1) disables that missiles’ graphics (turns it off) and
+ repositions it horizontally to the center of its’
+ associated player. Until a “0” is written to the register,
+ the missiles’ horizontal position is locked to the center
+ of its’ player in preparation to be fired again.
+
+8.0 Horizontal Motion
+
+ Horizontal motion allows the programmer to move any of the
+ 5 graphics objects relative to their current horizontal
+ position. Each object has a 4 bit horizontal motion
+ register (HMP0, HMP1, HMM0, HMM1, HMBL) that can be loaded
+ with a value in the range of +7 to -8 (negative values are
+ expressed in two’s complement from). This motion is not
+ executed until the HMOVE register is written to, at which
+ time all motion registers move their respective objects.
+ Objects can be moved repeatedly by simply executing HMOVE.
+ Any object that is not to move must have a 0 in its motion
+ register. With the horizontal positioning command confined
+ to positioning objects at 15 color clock intervals, the
+ motion registers fills in the gaps by moving objects +7 to
+ -8 color clocks. Objects can not be placed at any color
+ clock position across the screen. All 5 motion registers
+ can be set to zero simultaneously by writing to the
+ horizontal motion clear register (HMCLR).
+
+ There are timing constraints for the HMOVE command. The
+ HMOVE command must immediately follow a WSYNC (Wait for
+ SYNC) to insure the HMOVE operation occurs during
+ horizontal blanking. This is to allow sufficient time for
+ the motion registers to do their thing before the electron
+ beam starts drawing the next scan line. Also, for
+ mysterious internal hardware considerations, the motion
+ registers should not be modified for at least 24 machine
+ cycles after an HMOVE command.
+
+9.0 Object Priorities
+
+ Each object is assigned a priority so when any two objects
+ overlap the one with the highest priority will appear to
+ move in front of the other. To simplify hardware logic,
+ the missiles have the same priority as their associated
+ player, and the ball has the same priority as the
+ playfield. The background, of course, has the lowest
+ priority. The following table illustrates the normal
+ (default) priority assignments.
+
+ Priority Objects
+ 1 P0, M0
+ 2 P1, M1
+ 3 BL, PF
+ 4 BK
+
+ This priority assignment means that players and missiles
+ will move in front of the playfield. To make the players
+ and missiles move behind the playfield, a "1" must be
+ written to D2 of the CTRLPF register. The following table
+ illustrates how the priorities are affected:
+
+ Priority Objects
+ 1 PF, BL
+ 2 P0, M0
+ 3 P1, M1
+ 4 BK
+
+ One more priority control is available to be used for
+ displaying the score. When a "1" is written to D1 of the
+ CTRLPF register, the left half of the playfield takes on
+ the color of player 0, and the right half the color of
+ player 1. The game score can now be displayed using the PF
+ graphics register, and the score will be in the same color
+ as its associated player.
+
+10.0 Collisions
+
+ The TIA detects collisions between any of the 6 objects it
+ generates (the playfield and 5 moveable objects). There
+ are 15 possible two-object collisions which are stored in
+ 15 one bit latches. Each collision register contains two
+ of these latches which are read by the microprocessor on D6
+ and D7 of the data bus for easy access. A "1" on the data
+ line indicates the collision it records has occurred. The
+ collision registers could be read at any time but is
+ usually done during vertical blank after all possible
+ collisions have occurred. The collision registers are all
+ reset simultaneously by writing to the collision reset
+ register (CXCLR).
+
+11.0 Sound
+
+ There are two audio circuits for generating sound. They
+ are identical but completely independent and can be
+ operated simultaneously to produce sound effects through
+ the TV speaker. Each audio circuit has three registers
+ that control a noise-tone generator (what kind of sound), a
+ frequency selection (high or low pitch of the sound), and a
+ volume control.
+
+ 11.1 Tone
+ The noise-tone generator is controlled by writing to the 4
+ bit audio control registers (AUDC0, AUDC1). The values
+ written cause different kinds of sounds to be generated.
+ Some are pure tones like a flute, others have various
+ "noise" content like a rocket motor or explosion. Even
+ though the TIA hardware manual lists the sounds created by
+ each value, some experimentation will be necessary to find
+ "your sound".
+
+ 11.2 Frequency
+ Frequency selection is controlled by writing to a 5 bit
+ audio frequency register (AUDF0, AUDF1). The value written
+ is used to divide a 30KHz reference frequency creating
+ higher or lower pitch of whatever type of sound is created
+ by the noise-tone generator. By combining the pure tones
+ available from the noise-tone generator with frequency
+ selection a wide range of tones can be generated.
+
+ 11.3 Volume
+ Volume is controlled by writing to a 4 bit audio volume
+ register (AUDV0, AUDV1). Writing 0 to these registers
+ turns sound off completely, and writing any value up to 15
+ increases the volume accordingly.
+
+12.0 Input Ports
+
+ There are six input ports whose logic states can be read on
+ D7 by reading the input port addresses (INPT0, thru INPT5).
+ These six ports are divided into two types, "dumped" and
+ "latched".
+
+ 12.1 Dumped Input Ports (INPT0 thru INPT3)
+ These four ports are used to read up to four paddle
+ controllers. Each paddle controller contains an adjustable
+ pot controlled by the knob on the controller. The output
+ of the pot is used to charge a capacitor in the console,
+ and when the capacitor is charged the input port goes HI.
+ The microprocessor discharges this capacitor by writing a
+ "1" to D7 of VBLANK then measures the time it takes to
+ detect a logic one at that port. This information can be
+ used to position objects on the screen based on the
+ position of the knob on the paddle controller.
+
+ 12.2 Latched Input Ports (INPT4, INPT5)
+ These two ports have latches that are both enabled by
+ writing a "1" or disabled by writing a "0" to D6 of VBLANK.
+ When disabled the microprocessor reads the logic level of
+ the port directly. When enabled, the latch is set for
+ logic one and remains that way until its' port goes LO.
+ When the port goes LO the latch goes LO and remains that
+ way regardless of what the port does. The trigger buttons
+ of the joystick controllers connect to these ports.
+
+THE PIA (6532)
+
+1.0 General
+
+ The PIA chip is an off-the-shelf 6532 Peripheral Interface
+ Adaptor which has three functions: a programmable timer,
+ 128 bytes of RAM, and two 8 bit parallel I/O ports.
+
+2.0 Interval timer
+
+ The PIA uses the same clock as the microprocessor so that
+ one PIA cycle occurs for each machine cycle. The PIA can
+ be set for one of four different "intervals", where each
+ interval is some multiple of the clock (and therefore
+ machine cycles). A value from 1 to 255 is loaded into the
+ PIA which will be decremented by one at each interval. The
+ timer can now be read by the microprocessor to determine
+ elapsed time for timing various software operations and
+ keep them synchronized with the hardware (TIA chip).
+
+ 2.1 Setting the timer
+ The timer is set by writing a value or count (from 1 to
+ 255) to the address of the desired interval setting
+ according to the following table :
+
+ Hex Address Interval Mnemonic
+ 294 1 clock TIM1T
+ 295 8 clocks TIM8T
+ 296 64 clocks TIM64T
+ 297 1024 clocks T1024T
+
+ For example, if the value of 100 were written to TIM64T
+ (HEX address 296) the timer would decrement to 0 in 6400
+ clocks (64 clocks per interval x 100 intervals) which would
+ also be 6400 microprocessor machine cycles.
+
+ 2.2 Reading the timer
+ The timer may be read any number of times after it is
+ loaded of course, but the programmer is usually interested
+ in whether or not the timer has reached 0. The timer is
+ read by reading INTIM at hex address 284.
+
+ 2.3 When the timer reaches zero
+ The PIA decrements the value or count loaded into it once
+ each interval until it reaches 0. It holds that 0 counts
+ for one interval, then the counter flips to FF(HEX) and
+ decrements once each clock cycle, rather than once per
+ interval. The purpose of this feature is to allow the
+ programmer to determine how long ago the timer zeroed out
+ in the event the timer was read after it passed zero.
+
+3.0 RAM
+
+ The PIA has 128 bytes of RAM located in the Stella memory
+ map from HEX address 80 to FF. The microprocessor stack is
+ normally located from FF on down, and variables are
+ normally located from 80 on up (hoping the two never meet).
+
+4.0 The I/O ports
+
+ The two ports (Port A and Port B) are 8 bits wide and can
+ be set for either input or output. Port A is used to
+ interface to carious hand-held controllers but Port B is
+ dedicated to reading the status of the Stella console
+ switches.
+
+ 4.1 Port B - Console Switches (read only)
+ Port B is hardwired to be an input port only that is read
+ by addressing SWCHB (HEX 282) to determine the status of
+ all the console switches according to the following table:
+
+ Data Bit Switch Bit Meaning
+ D7 P1 difficulty 0 = amateur (B), 1 = pro (A)
+ D6 P0 difficulty 0 = amateur (B), 1 = pro
+ (A)
+ D5/D4 (not used)
+ D3 color - B/W 0 = B/W, 1 = color
+ D2 (not used)
+ D1 game select 0 = switch pressed
+ D0 game reset 0 = switch pressed
+
+5.0 Port A - Hand Controllers
+
+ Port A is under full software control to be configured as
+ an input or an output port. It can then be used to read or
+ control various hand-head controllers with the data bits
+ defined differently depending on the type of controller
+ used.
+
+ 5.1 Setting for input or output
+ Port A has an 8 bit wide Data Direction Register (DDR) that
+ is written to at SWACNT (HEX 281) to set each individual
+ pin of Port A to either input or output. The Port A pins
+ are labeled PA0 thru PA7, and writing a "0" to a pins' DDR
+ bit sets that pin as input, and a "1" sets it as an output.
+ For example, writing all 0's to SWACNT (the DDR for Port A)
+ sets PA0 thru PA7 (all 8 pins of Port A) as inputs. If F0
+ (11110000) were written to SWACNT then PA7, PA6, PA5 & PA4
+ would be outputs, and PA3, PA2, PA1 & PA0 would be inputs.
+
+ 5.2 Inputting and Outputting
+ Once the DDR has set the pins of Port A for input or output
+ they may be read or written to by addressing SWCHA (HEX
+ 280).
+
+ 5.3 Joystick Controllers
+ Two joysticks can be read by configuring the entire port as
+ input and reading the data at SWCHA according to the
+ following table:
+
+ Data Bit Direction Player
+ D7 right P0
+ D6 left P0
+ D5 down P0
+ D4 up P0
+ D3 right P1
+ D2 left P1
+ D1 down P1
+ D0 up P1
+
+ (P0 = left player, P1 = right player)
+
+ A "0" in a data bit indicates the joystick has been moved
+ to close that switch. All "1's" in a player's nibble
+ indicates that joystick is not moving.
+
+ 5.4 Paddle (pot) controllers
+ Only the paddle triggers are read from the PIA. The
+ paddles themselves are read at INP0 thru INPT3 of the TIA.
+ The paddle triggers can be read at SWCHA according to the
+ following table :
+
+ Data Bit Paddle #
+ D7 P0
+ D6 P1
+ D5/D4 (not used)
+ D3 P2
+ D2 P3
+ D1/D0 (not used)
+
+ 5.5 Keyboard controllers
+ The keyboard controller has 12 buttons arranged into 4 rows
+ and 3 columns. A signal is sent to a row, then the columns
+ are checked to see if a button is pushed, then the next row
+ is signaled and all columns sensed, etc. until the entire
+ keyboard is scanned and sensed. The PIA sends the signals
+ to the rows, and the columns are sensed by reading INPT0,
+ INPT1, and INPT4 of the TIA. With Port A configured as an
+ output port, the data bits will send a signal to the
+ keyboard controller rows according to the following table :
+
+ Data Bit Keyboard Row Player
+ D7 bottom P0
+ D6 third P0
+ D5 second P0
+ D4 top P0
+ D3 bottom P1
+ D2 third P1
+ D1 second P1
+ D0 top P1
+ (P0 = left player, P1 = right player)
+
+ NOTE : a delay of 400 microseconds is necessary between
+ writing to this port and reading the TIA input ports.
+
+6.0 Address summary table
+
+ Hex Address Mnemonic Purpose
+ 280 SWCHA Port A; input or output (read or
+ write)
+ 281 SWACNT Port A DDR, 0= input, 1=output
+ 282 SWCHB Port B; console switches (read only)
+ 283 SWBCNT Port B DDR (hardwired as input)
+ 284 INTIM Timer output (read only)
+ 294 TIM1T set 1 clock interval (838
+ nsec/interval)
+ 295 TIM8T set 8 clock interval (6.7
+ usec/interval)
+ 296 TIM64T set 64 clock interval (53.6
+ usec/interval)
+ 297 T1024T set 1024 clock interval (858.2
+ usec/interval)
+
+ NOTE: one clock is also one microprocessor machine cycle
+
+PAL/SECAM CONVERSIONS
+
+PAL
+ 1. The number of scan lines, and therefore the frame time
+ increases from NTSC to PAL according to the following
+ table:
+
+ NTSC PAL
+ scan micro scan micro
+ lines seconds lines seconds
+ VBLANK 40 2548 48 3085
+ KERNAL 192 12228 228 14656
+ OVERSCAN 30 1910 36 2314
+ FRAME 262 16686 312 20055
+
+ 2. Sounds will drop a little in pitch (frequency) because
+ of a slower crystal clock. Some sounds may need the
+ AUDF0/AUDF1 touched up.
+
+ 3. PAL operates at 50 Hz compared to NTSC 60Hz, a 17%
+ reduction. If game play speed is based on frames per
+ second, it will slow down by 17%. This can be disastrous
+ for most skill/action carts. If the NTSC version is
+ designed with 2 byte fractional addition techniques (or
+ anything not based on frames per second) to move objects,
+ then PAL conversion can be as simple as changing the
+ fraction tables, avoiding major surgery on the program.
+
+SECAM
+ 1. SECAM is a little weird. It takes the PAL software, but
+ the console color/black & white switch is hardwired as
+ black & white. Therefore, it reads the PAL black & white
+ tables in software and assigns a fixed color to each lum of
+ black & white according to the following table:
+
+ Lum Color
+ 0 Black
+ 2 Blue
+ 4 Red
+ 6 Magenta
+ 8 green
+ A cyan
+ C yellow
+ E white
+
+ There is a trap here: the manual is the same for NTSC,
+ PAL, & SECAM. This means that the descriptions for black &
+ white must jive between NTSC & PAL. If you make major
+ changes to PAL black & white to achieve good SECAM color,
+ NTSC black & white must be made similar.
+
+ 2. PAL sounds work fine on SECAM with one exception: when a
+ sound is to be turned off, it must be one by setting
+ AUDV0/AUDV1 to 0, not by setting AUDC0/AUDC1 to 0.
+ Otherwise, you get an obnoxious background sound.
+
+
+TIA 1A - TELEVISION INTERFACE ADAPTOR (MODEL 1A)
+
+GENERAL DESCRIPTION
+
+ The TIA is an MOS integrated circuit designed to interface
+ between an eight (8) bit microprocessor and a television
+ video modulator and to convert eight (8) bit parallel data
+ into serial outputs for the color, luminosity, and
+ composite sync required by a video modulator.
+
+ This circuit operates on a line by line basis, always
+ outputting the same information every television line
+ unless new data is written into it by the microprocessor.
+
+ A hardware sync counter produces horizontal sync timing
+ independent of the microprocessor. Vertical sync timing is
+ supplied to this circuit by the microprocessor and combined
+ into composite sync.
+
+ Horizontal position counters are used to trigger the serial
+ output of five (5) horizontally movable objects; two
+ players, two missiles and a ball. The microprocessor can
+ add or subtract from these position counters to move these
+ objects right or left.
+
+ The microprocessor determines all vertical position and
+ motion by writing zeros or ones into object registers
+ before each appropriate horizontal line.
+
+ Walls, clouds and other seldom moved objects are produced
+ by a low resolution data register called the playfield
+ register.
+
+ A fifteen (15) bit collision register detects all fifteen
+ possible two object collisions between these six (6)
+ objects (five moveable and one playfield). This collision
+ register can be read and reset by the microprocessor. Six
+ input ports are also provided on this chip that can be read
+ by the microprocessor. These input ports and the collision
+ register are the only chip addresses that can be read by
+ the microprocessor. All other addresses are write only.
+
+ Color luminosity registers are included that can be
+ programmed by the microprocessor with eight (8) luminosity
+ and fifteen (15) color values. A digital phase shifter is
+ included on this chip to provide a single color output with
+ fifteen (15) phase angles.
+
+ Two (2) independent audio generating circuits are included,
+ each with programmable frequency, noise content, and volume
+ control registers.
+
+
+DETAILED DESCRIPTION
+
+1. Data and addressing
+
+ Registers on this chip are addressed by the microprocessor
+ as part of its overall RAM-ROM memory space. The attached
+ table of read-write addresses summarizes the addressable
+ functions. There are no registers that are both read and
+ write. Some addresses however are both read and write,
+ with write data going into one register and read data
+ returning from a different register.
+
+ If the read-write line is low, the data bits indicated in
+ this table will be written into the addressed write
+ location when the 02 clock goes from high to low. Some
+ registers are eight bits wide, some only one bit, and some
+ (strobes) have no bits, performing only control functions
+ (such as resets) when their address is written.
+
+ If the read-write line is high, the addressed location can
+ be read by the microprocessor on data lines 6 and 7 while
+ the 02 clock is high.
+
+ The addresses given in the table refer only to the six (6)
+ real address lines. If any of the four (4) chip select
+ lines are used for addressing, the addresses must be
+ modified accordingly.
+
+2. Synchronization
+
+ A. Horizontal Timing
+ A hardware counter on this chip produces all horizontal
+ timing (such as sync, blank, burst) independent of the
+ microprocessor, This counter is driven from an external
+ 3.58 Mhz oscillator and has a total count of 228. Blank is
+ decoded as 68 counts and sync and color burst as 16 counts.
+
+ B. Vertical Timing
+ There are one bit, addressable registers on this chip for
+ vertical sync and vertical blank. The timing for these
+ functions is established by the microprocessor by writing
+ zero or one into these bits. (VSYNC, VBLANK )
+
+ C. Composite Sync
+ Horizontal sync and the output of the vertical sync bit are
+ combined together to produce composite sync. This
+ composite sync signal drives a chip output pad to an
+ external composite video resistor network.
+
+ D. Microprocessor Synchronization
+ The 3.58 MHz oscillator also clocks a divide by three
+ counter on this chip whose output (1.19 Mhz) is buffered to
+ drive an output pad called 00. This pad provides the input
+ phase zero clock to the microprocessor which then produces
+ the system 02 clock (1.19 Mhz).
+ Software program loops require different lengths of time to
+ run depending on branch decisions made within the program.
+ Additional synchronization between the software and
+ hardware. This is done with a one bit latch called WSYNC
+ (wait for sync). When the microprocessor finishes a
+ routine such as loading registers for a horizontal line, or
+ computing new vertical locations during vertical blank, it
+ can address WSYNC, setting this latch high. When this
+ latch is high, it drives an output pad to zero connected to
+ the microprocessor ready line (RDY). A zero on this line
+ causes the microprocessor to halt and wait. As shown in
+ figure 2, WSYNC latch is automatically reset to zero by the
+ leading edge of the next horizontal blank timing signal,
+ releasing the RDY line, allowing the microprocessor to
+ begin its computation and register writing for this
+ horizontal television line or line pair.
+
+3. Playfield graphics Register
+
+ A. Description
+ Objects such as walls, clouds, and score) which are not
+ required to move, are written into a 20 bit register called
+ the playfield register. This register (Figure 5) is loaded
+ from the data bus by three separate write addresses (PF0,
+ PFl, PF2). Playfield may be loaded at any time. To clear
+ the playfield, zeros must be written into all three
+ addresses.
+
+ B. Normal Serial Output
+ The playfield register is automatically scanned (and
+ converted to serial output) by a bi-directional shift
+ register clocked at a rate which spreads the twenty (20)
+ bits out over the left half of a horizontal line. This
+ scanning is initiated by the end of horizontal blank (left
+ edge of television screen). Normally the same scan is then
+ repeated, duplicating the same twenty (20) bit sequence
+ over the right half of the horizontal line.
+
+ C. Reflected Serial Output
+ A reflected playfield may be requested by writing a one
+ into bit zero of the playfield control register (CTRLPF).
+ When this bit is true the scanning shift register will scan
+ the opposite direction during the right half of the
+ horizontal line, reversing the twenty (20) bit sequence.
+
+ D. Timing Constraints
+ Even though the playfield bytes (PF0, PFl, PF2) may be
+ written to any time, if one of them is changed while being
+ serially scanned, part of the new value may both show up on
+ the television horizontal line.
+
+4. Horizontal Position Counters
+
+ A. Description
+ The playfield is a fixed graphics register, always starting
+ its serial output when triggered by the beginning of each
+ television line. This chip also includes five "moveable"
+ graphics registers, whose serial outputs are triggered by
+ five separate horizontal position counters every time these
+ counters pass through zero count. These position counters
+ are clocked continuously during the unblanked portion of
+ every horizontal line and their count length is exactly
+ equal to the normal number of clocks supplied to them
+ during this time. They will therefore pass through zero at
+ the same time during each horizontal television line and
+ the triggered outputs will have no horizontal motion. A
+ typical horizontal counter is shown in figure 4.
+
+ If extra clocks are supplied to these counters (or normal
+ clocks suppressed) the zero crossing time will shift and
+ the object will have moved left (extra clocks) or right
+ (fewer clocks). Some position counters have extra decoders
+ (in addition to a zero decode) to trigger multiple copies
+ of the same object across a horizontal line.
+
+ All position counters can be reset to zero count by the
+ microprocessor at any time, by a write instruction to the
+ reset addresses (RESBL, RESM0, RESMl, RESP0, RESPl). If
+ reset occurs during horizontal blank, the object will
+ appear at the left side of the television screen. Properly
+ timed resets may position an object at any horizontal
+ location consistent with the microprocessor cycle time.
+
+ B. Ball position Counter
+ The ball position counter has only the zero crossing decode
+ and therefore cannot trigger multiple copies of the ball
+ graphics.
+
+ C. Player Position Counters
+ Each player position counter has three decodes in addition
+ to the zero crossing decode. These decodes are controlled
+ by bits 0,1,2 of the number size control registers (NUSIZ0,
+ NUSIZ1), and trigger 1,2, or 3 copies of the player (at
+ various spacings) across a horizontal line as shown on page
+ ___. These same control bits are used for the decodes on
+ the missile position counter, insuring an equal number of
+ players and missiles.
+
+ D. Missile Position Counters
+ Missile position counters are identical to player position
+ counters except that they have another type of reset in
+ addition to the previously discussed horizontal position
+ reset. These extra reset addresses (RESMP0, RESMP1) write
+ data bit 1 into a one bit register whose output is used to
+ position the missile (horizontally) directly on top of its
+ corresponding player, and to disable the missile serial
+ output.
+
+5. Horizontal Motion Registers
+
+ A. General Description
+ There are five write only registers on this chip that
+ contain the horizontal motion values for each of the five
+ moving objects. A typical horizontal motion register is
+ shown in figure 4 . The data bus (bits 4 through 7) is
+ written into these addresses (HMP0, HMPl, HMM0, HMMl, HMBL)
+ to load these registers with motion values. These registers
+ supply extra (or fewer) clocks to the horizontal position
+ counters only when commanded to do so by an HMOVE address
+ from the microprocessor. These registers may all be cleared
+ to zero (no motion) simultaneously by an HMCLR command from
+ the microprocessor, or individually by loading zeros into
+ each register. These registers are each four bits in
+ length and may be loaded with positive (left motion),
+ negative (right motion) or zero (no motion) values.
+ Negative values are represented in twos complement format.
+
+ B. Timing constraints
+ These registers may be loaded or cleared at almost any
+ time. The motion values they contain will be used only when
+ an HMOVE command is addressed, and then all five motion
+ values will be used simultaneously into all five horizontal
+ position counters once. The only timing constraint on this
+ operation involves the HMOVE command. The HMOVE command
+ must be located in the microprocessor program immediately
+ after a wait for sync (WSYNC) command. This assures that
+ the HMOVE operation begins at the leading edge of
+ horizontal blank, and has the full blank time to supply
+ extra or fewer clocks to the horizontal position counters.
+ These registers should not be modified for at least 24
+ Computer cycles after the HMOVE command.
+
+6. Moving Object Graphics Registers
+
+ A. General Description
+ There are five graphics registers for moving objects on
+ this chip. These graphics registers are loaded (written) in
+ parallel by the microprocessor and like the playfield
+ register are scanned and converted to serial output.
+ Unlike the playfield register, which is always scanned
+ beginning at the left side of each horizontal line, moving
+ object graphics registers are scanned only when triggered
+ by a start decode from their horizontal position counter.
+ A typical graphics register is shown in figure 4 .
+
+ B. Missile Graphics
+ The graphics registers for both missiles are identical and
+ very simple. They each consist of a one bit register called
+ missile enable (ENAM0, ENAM1). This graphics bit is scanned
+ (outputted) only when triggered by its corresponding
+ position counter. There are control bits (bits 4, 5, of
+ NUSIZ0, NUSIZ1) that can stretch this single graphics bit
+ out over widths of 1, 2, 4, or 8 clocks of horizontal line
+ time. (A full line is 160 clocks).
+
+ C. Player Graphics
+ The graphics registers for both players are identical and
+ are rather complex. They each consist of eight bit parallel
+ registers (GRP0, GRP1) and a bi-directional parallel to
+ serial scan counter that converts the parallel data into
+ serial output. A one bit control register (REFP0, REFP1)
+ determines the direction (reflection) of the parallel to
+ serial scan, outputing either D7 through D0, or D0 though
+ D7. This allows reflection (horizontal flipping) of player
+ serial graphics data without having to flip the
+ microprocessor data.
+
+ The clock into the scan counter can be controlled (three
+ bits of NUSIZ0 and NUSIZ1) to slow the scan rate and
+ stretch the eight bits of serial graphics out over widths
+ of 8, 16, or 32 clocks of horizontal line time. These same
+ control bits are used in the player-missile motion counters
+ to control multiple copies, so only three player widths (
+ scan
+ rates) are available.
+
+ D. Vertical Delay
+ Each of the player graphics registers actually consists of
+ two 8 bit parallel registers. The first (GRP0, GRP1) is
+ loaded (written) from the microprocessor 8 bit data bus.
+ The second is automatically loaded from the output of the
+ first. The reason for this is a complex subject called
+ vertical delay. A large amount of microprocessor time is
+ required to generate player, missile and playfield graphics
+ (table look up, masking, comparisons, etc.) and load these
+ into this chip's registers. For most game programs this
+ time is just too large to fit into one horizontal line
+ time. In fact for most games it will barely fit into two
+ line times (127 microseconds). Therefore, individual
+ graphics registers are loaded (written) every two lines,
+ and used twice for serial output between loads. This type
+ of programing will obviously limit the vertical height
+ resolution of objects to multiples of two lines. It also
+ will limit the resolution of vertical motion to two lines
+ jumps. Nothing can be done about the vertical height
+ resolution; however, vertical motion can be resolved to a
+ single line by addition of a second graphics register that
+ is automatically parallel loaded from the output of the
+ first, one line time after the first was loaded from the
+ data bus. This second graphics register output is
+ therefore always delayed vertically by one line. A control
+ bit called vertical delay (VDEL0, VDEL1) selects which of
+ these two registers is to be used for serial output. If
+ this control bit is set by the microprocessor between
+ picture frames, the object will be moved down (delayed) by
+ one line during the next frame. In most programming
+ applications player 0 graphics and player 1 graphics are
+ loaded (written) alternately, during the blank time just
+ prior to each line as shown in (figure 1). Since GRP0 and
+ GRP1 addresses from the microprocessor alternate, they are
+ delayed by one line from each other. The GRP0 address
+ decode can therefore be used to load the delayed graphics
+ register for player 1, and GRP1 likewise to load the
+ delayed graphics register for player 0. The two vertical
+ delay bits (VDEL0, VDELl) then select delayed or undelayed
+ registers for player 0 and player 1 as serial outputs.
+
+ E. Ball Graphics
+ The ball graphics register is almost identical to the
+ missile graphics register. It also consists of a single
+ enable bit (ENABL) whose output is triggered by the ball
+ position counter. It also has two control bits (bits 4, 5
+ of CTRLPF) that can stretch this single graphics bit out
+ over widths of 1, 2, 4, or 8 clocks of horizontal line
+ time. Unlike the missile graphics; however, the ball
+ graphics register has capability for vertical delay similar
+ to the player graphics. A second graphics (enable) bit is
+ alternately loaded from the output of the first, one line
+ after the first was loaded from the data bus. A ball
+ vertical delay bit (VDELBL) selects which of these two
+ graphics bits is used for the ball serial output. The first
+ graphics bit (ENABL) should be loaded during the same
+ horizontal blank time as player 0 (GRP0), because GRP1 is
+ used to load the second enable bit from the output of the
+ first on alternate lines.
+
+7. Collision Detection Latches
+
+ A. Definitions
+ The serial outputs from all the graphics registers
+ represent real time horizontal location of objects on the
+ television screen. If any of these outputs occur at the
+ same time, they will overlap (collide) on the screen.
+ There are six objects generated on this chip (five moving
+ and playfield) allowing fifteen possible two object
+ collisions. These overlaps (collisions) are detected by
+ fifteen "and" gates whenever they occur, and are stored in
+ fifteen individual latch register bits, as shown in figure
+ 6.
+
+ B. Reading Collision
+ The microprocessor can read these fifteen collision bits on
+ data lines 6 and 7 by addressing them two at a time. This
+ could be done at any time but is usually done between
+ frames (during vertical blank) after all possible
+ collisions have serially occurred.
+
+ C. Reset
+ All collision bits are reset simultaneously by the
+ microprocessor using the reset address CXCLR. This is
+ usually done near the end of vertical blank, after
+ collisions have been tested.
+
+8. Input ports
+
+ A. General Description
+ There are 6 input ports on this chip whose logic state may
+ be read on data line 7 with read addresses INPT0 through
+ INPT5. These 6 ports are divided into two types, "dumped"
+ and "latched". See Figure 8.
+
+ B. Dumped Input Ports (I0 through I3)
+ These 4 input ports are normally used to read paddle
+ position from an external potentiometer-capacitor circuit.
+ In order to discharge these capacitors each of these input
+ ports has a large transistor, which may be turned on
+ (grounding the input ports) by writing into bit 7 of the
+ register VBLANK. When this control bit is cleared the
+ potentiometers begin to recharge the capacitors and the
+ microprocessor measures the time required to detect a logic
+ 1 at each input port.
+
+ As long as bit 7 of register VBLANK is zero, these four
+ ports are general purpose high impedance input ports. When
+ this bit is a 1 these ports are grounded.
+
+ C. Latched Input ports (I4, I5)
+ These two input ports have latches which can be enabled or
+ disabled by writing into bit 6 of register VBLANK.
+
+ When disabled, these latches are removed from the circuit
+ completely and these ports become two general purpose input
+ ports, whose present logic state can be read directly by
+ the microprocessor.
+
+ When enabled, these latches will store negative (zero logic
+ level) signals appearing on these two input ports, and the
+ input port addresses will read the latches instead of the
+ input ports.
+
+ When first enabled these latches will remain positive as
+ long as the input ports remain positive (logic one). A zero
+ input port signal will clear a latch value to zero, where
+ it will remain (even after the port returns positive) until
+ disabled. Both latches may be simultaneously disabled by
+ writing a zero into bit 6 of register VBLANK.
+
+8.5 Priority Encoder
+
+ A. Purpose
+ As discussed in the section on collisions, simultaneous
+ serial outputs from the graphics registers represent
+ overlap on the television screen. In order to have color-
+ luminosity values assigned to individual objects it is
+ necessary to establish priorities between objects when
+ overlapped. The priority encoder is shown in figure 3.
+
+ B. Priority Assignment
+ The lack of any objects results in a color-lum value called
+ the background. The background (BK) has lowest priority and
+ only appears when no objects are outputing. In order to
+ simplify the logic, each missile is given the same color-
+ lum value and priority as it's corresponding player (P0,
+ M0) and the ball is given the same color-lum value and
+ priority as the playfield (PF, BL).
+
+ The following table illustrates the normal priority
+ assignment:
+
+ Highest Priority P0, M0
+ Second Highest P1, M1
+ Third Highest PF, BL
+ Lowest Priority BK
+
+ Objects with higher priority will appear to move in front
+ of objects with lower priority. Players will therefore move
+ in front of playfield (clouds, walls, etc.).
+
+ C. Priority Control
+ There are two playfield control bits that affect priority,
+ one called playfield priority (PFP) (bit 2 of CTRLPF) and
+ one called score (bit 1 of CTRLPF). When a one is written
+ into the PFP bit the priority assignment is modified as
+ shown below.
+
+ Highest Priority PF, BL
+ Second Highest P0, M0
+ Third Highest P1, M1
+ Lowest Priority BK
+
+
+ Players will then move behind playfield (clouds, wall,
+ etc.). When a one is written into the score control bit,
+ the playfield is forced to take the color-lum of player 0
+ in the left half of the screen and player 1 in the right
+ half of the screen. This is used when displaying score and
+ identifies the score with the correct player. The priority
+ encoder produces 4 register select lines shown in figure 3)
+ that are mutually exclusive. These 4 lines select either
+ background, player 0, player 1 or playfield, and only one
+ of them can be true at a time.
+
+9 Color Luminance Registers
+
+ A. Description
+ There are four registers (shown in figure 3) that contain
+ color-lum codes. Four bits of color code and three its of
+ luminance code may be written into each of these registers
+ (COLUP0, COLUP1, COLUPF, COLUBK) by the microprocessor at
+ any time. These codes (representing 16 color values and 8
+ luminance values) are given in the Detailed Address List.
+
+ B. Multiplexing
+ The serial graphics output from all six objects is examined
+ by the priority encoder which activates one of the four
+ select lines into a 4 x 7 multiplexer. This multiplexer
+ (shown in figure 3) then selects one of the four color-lum
+ registers as a 7 line output. Three of these lines are
+ binary coded luminosity and go directly to chip output
+ pads. The other four lines go to the color phase shifter.
+
+10. Color Phase Shifter
+
+ This portion of the chip (shown in figure 3) produces a
+ reference color output (color burst) during horizontal
+ blank and then during the unblanked portion of the line it
+ produces a color output shifted in phase with respect to
+ the color burst. The amount of phase shift determines the
+ color and is selected by the four color code lines from the
+ Color-lum multiplexer. Binary code 0 selects no color.
+ Code 1 selects gold (same phase as color burst). Codes 2
+ (0010) through 15 (1111) shift the phase from zero through
+ almost 360 degrees allowing selection of 15 total colors
+ around the television color wheel.
+
+11. Audio Circuits
+
+ Two audio circuits are incorporated on this chip. They are
+ identical and completely independent, although their
+ outputs could be combined externally into one speaker.
+ Each audio circuit consists of parts described below, and
+ in figure 7.
+
+ A. Frequency Select
+ Clock pulses (at approximately 30 KHz) from the horizontal
+ sync counter pass through a divide by N circuit which is
+ controlled by the output code from a five bit frequency
+ register (AUDF). This register can be loaded (written) by
+ the microprocessor at any time, and causes the 30 KHz
+ clocks to be divided by 1 (code 00000) through 32 (code
+ 11111). This produces pulses that are digitally adjustable
+ from approximately 30 KHz to 1 KHz and are used to clock
+ the noise-tone generator.
+
+ B. Noise-Tone Generator
+ This circuit contains a nine bit shift counter which may be
+ controlled by the output code from a four bit audio control
+ register(AUDC), and is clocked by the frequency select
+ circuit. The control register can be loaded by the
+ microprocessor at any time, and selects different shift
+ counter feedback taps and count lengths to produce a
+ variety of noise and tone qualities.
+
+ C. Volume Select
+ The shift counter output is used to drive the audio output
+ pad through four driver transistors that are graduated in
+ size. Each transistor is twice as large as the previous one
+ and is enable by one bit from the audio volume register
+ (AUDV). This audio volume register may be loaded by the
+ microprocessor at any time. As binary codes 0 through 15
+ are loaded, the pad drive transistors are enabled in a
+ binary sequence. The shift counter output therefore can
+ pull down on the audio output pad with 16 selectable
+ impedance levels.
+
+
+
+
+Figure 1. Vertical Delay
+
+
+
+
+
+
+Figure 2. Synchronization
+
+
+
+Figure 3. Color-Luminance
+
+
+
+
+Figure 4. Typical Horizontal Motion Circuit
+
+
+
+
+
+
+
+
+Figure 5. Playfield Graphics
+
+
+
+
+
+Figure 6. Collision Detection
+
+
+
+
+
+
+Figure 7. Audio Circuit
+
+
+
+
+
+Figure 8. Input Ports
+
+
+
+
+
+Figure 9. Game System
+
+
+
+Write Address Detailed Functions
+
+
+WSYNC (wait for sync)
+ This address halts microporcessor by clearing RDY latch to
+ zero. RDY is set true again by the leading edge of
+ horizontal blank.
+
+ Data bits not used
+
+
+RSYNC (reset sync)
+ This address resets the horizontal sync counter to define
+ the beginning of horizontal blank time, and is used in chip
+ testing.
+
+ Data bits not used
+
+
+VSYNC
+ This address controls vertical sync time by writing D1 into
+ the VSYNC latch
+
+ D1 [1 = start vert sync, 0 = stop vertical sync]
+
+VBLANK
+ This address controls vertical blank and the latches and
+ dumping transistors on the input ports by writing into bits
+ D7, D6 and D1 of the VBLANK register.
+
+ D1 [ 1 = start vert. blank, 0 = stop vert. blank]
+ D6 [ 1 = Enable I4 I5 latches, 0 = disable I4 I5 latches]
+ D7 [ 1 = dump I6I1I2I3 ports to ground, 0 = remove dump
+ path to ground]
+ Note : Disable latches (D6 = 0) also resets latches to
+ logic true
+
+PJ0 (PF1, PF2)
+ These addresses are used to write into playfield registers
+
+
+ PLAYFIELD REGISTERS SERIAL OUTPUT
+
+ 1 horizontal line ( 160 clocks)
+ Playfield
+ Reflect Control
+ PF0 PF1 PF2 PF0 PF1 PF2
+
+ center
+
+ PF0 PF1 PF2 PF2 PF1
+ PF0
+
+ each bit = 4 clocks
+
+CTRLPF
+ This address is uded to write into the playfield control
+ register (a logic 1 causes action as described below)
+
+ D0 = REF (reflect playfield)
+ D1 = SCORE (left half of playfield gets color of player 0,
+ right half gets color of player 1)
+ D2 = PFP (playfield gets priority over players so they can
+ move behind the playfield)
+ D4 & D5 = BALL SIZE
+ D5 D4 Width
+ 0 0 1 clock
+ 0 1 2 clocks
+ 1 0 4 clocks
+ 1 1 8 clocks
+
+NUSIZ0 (NUSIZ1)
+ These addresses control the number and size of players and
+ missiles.
+
+ Missile Size D5 D4 Width
+ 0 0 1 clock
+ 0 1 2 clocks
+ 1 0 4 clocks
+ 1 1 8 clocks
+
+ Player-Missile number & player size
+
+ 1/2 television line (80 clocks)
+ 8 clocks per square
+
+
+RESP0 (RESP1, RESM0, RESM1, RESBL)
+ These addresses are used to reset players, missiles and the
+ ball. The object will begin its serial graphics at the
+ time of a horizontal line at which the reset address
+ occurs.
+
+ No data bits are used
+
+
+RESMP0 (RESMP1)
+ These addresses are used to reset the hoiz. location of a
+ missile to the center of it’s corresponding player. As
+ long as this control bit is true (1) the missile will
+ remain locked to the center of it’s player and the missile
+ graphics will be siddabled. When a zero is written into
+ this location, the missile is enabled, and can be moved
+ independently from the player.
+
+ D1 = RESMP (missile-player reset)
+HMOVE
+ This address causes the horizontal motion register values
+ to be acted upon during the horizontal blank time in which
+ it occurs. It must occur at the beginning of horiz. blank
+ in order to allow time for generation of extra clock pulses
+ into the horizontal position counters if motion is desired
+ this command must immediately follow a WSYNC command in the
+ program.
+
+ No data bits are used
+
+
+HMCLR
+ This address clears all horizontal motion registers to zero
+ (no motion)
+
+ No data bits are used
+
+
+HMP0 (HMP1, HMM0, HMM1, HMBL)
+ These addresses write data (horizontal motion values) into
+ the horizontal motion registers. These registers will
+ cause horizontal motion only when commanded to do so by the
+ horiz. move command HMOVE.
+ The motion values are coded as shown below :
+
+ D7 D6 D5 D4
+ 0 1 1 1 +7
+ 0 1 1 0 +6
+ 0 1 0 1 +5 Move left
+ 0 1 0 0 +4 indicated number
+ 0 0 1 1 +3 of clocks
+ 0 0 1 0 +2
+ 0 0 0 1 +1
+ 0 0 0 0 0 No Motion
+ 1 1 1 1 -1
+ 1 1 1 0 -2
+ 1 1 0 1 -3
+ 1 1 0 0 -4 move right
+ 1 0 1 1 -5 indicated number
+ 1 0 1 0 -6 of clocks
+ 1 0 0 1 -7
+ 1 0 0 0 -8
+
+ WARNING : These motion registers should not be modified
+ during the 24 computer cycles immediately following an
+ HMOVE command. Unpredictable motion values may result.
+ENAM0 (ENAM1, ENABL)
+ These addresses write D1 into the 1 bit missile or ball
+ graphics registers.
+
+ D1 - [0 = dissables object, 1 = enables object]
+
+
+GRP0 (GRP1)
+ These addresses write data into the player graphics
+ registers.
+
+ Note: serial output begins with D7, unless REFP0 (REFP1) =
+ 1
+
+REFP0 (REFP1)
+ These addesses write D3 into the 1 bit player reflect
+ registers
+
+ D3 - [ 0 = no reflect, D7 of GRP on left, 1 = reflect, D0
+ of GRP on left]
+
+VDELP0 (VDELP1, VDELBL)
+ These addresses write D0 into the 1 bit vertical delay
+ registers, to delay players or ball by one vertical line.
+
+ D0 - [0 = no delay, 1 = delay]
+
+CXCLR
+ This adderess clears all collision latches to zero (no
+ collision)
+
+ No data bits are used
+
+COLUP0 (COLUP1, COLUPF, COLUBK)
+ These addresses write data into the player, playfield, adn
+ background color-luminance registers
+
+ COLOR D7 D6 D5 D4 D3 D2 D1 LUM
+ grey - gold 0 0 0 0 0 0 0 black
+ 0 0 0 1 0 0 1 dark grey
+ orange, brt-0 0 1 0 0 1 0
+ org
+ 0 0 1 1 0 1 1 grey
+ pink - 0 1 0 0 1 0 0
+ purple
+ 0 1 0 1 1 0 1
+ purp-blue, 0 1 1 0 1 1 0 light gret
+ blue
+ 0 1 1 1 1 1 1 white
+ blue - lt. 1 0 0 0
+ blue
+ 1 0 0 1
+ torq. - 1 0 1 0
+ grn. blue
+ 1 0 1 1
+ grn. - yel. 1 1 0 0
+ grn.
+ 1 1 0 1
+ org. grn - 1 1 1 0
+ lt org.
+ 1 1 1 1
+
+AUDF0 (AUDF1)
+ These addresses write data into the audio frequency divider
+ registers.
+
+ D4 D3 D2 D1 D0 30KHz divided
+ by
+ 0 0 0 0 0 no division
+ 0 0 0 0 1 divide by 2
+ 0 0 0 1 0 divide by 3
+ .. .. .. .. .. ...
+ . . . . .
+ 1 1 1 1 0 divide by 31
+ 1 1 1 1 1 divide by 32
+
+AUDC0 (AUDC1)
+ These addresses write data into the audio control registers
+ which control the noise content and additional division of
+ the audio output.
+
+ D3 D2 D1 D0 Type of noise
+ or division
+ 0 0 0 0 set to 1
+ 0 0 0 1 4 bit poly
+ 0 0 1 0 div 15 -> 4
+ bit poly
+ 0 0 1 1 5 bit poly ->
+ 4 bit poly
+ 0 1 0 0 div 2 : pure
+ tone
+ 0 1 0 1 div 2 : pure
+ tone
+ 0 1 1 0 div 31 : pure
+ tone
+ 0 1 1 1 5 bit poly ->
+ div 2
+ 1 0 0 0 9 bit poly
+ (white noise)
+ 1 0 0 1 5 bit poly
+ 1 0 1 0 div 31 : pure
+ tone
+ 1 0 1 1 set last 4
+ bits to 1
+ 1 1 0 0 div 6 : pure
+ tone
+ 1 1 0 1 div 6 : pure
+ tone
+ 1 1 1 0 div 93 : pure
+ tone
+ 1 1 1 1 5 bit poly div
+ 6
+
+
+AUDV0 (AUDV1)
+ These addresses write data into the audio volume registers
+ which set the pull down impedance driving the audio output
+ pads.
+
+ D3 D2 D1 D0 Audio Output
+ Pull down
+ current
+ 0 0 0 0 No output
+ current
+ 0 0 0 1 lowest
+ 0 0 1 0
+ .. .. .. ..
+ . . . .
+ 1 1 1 0
+ 1 1 1 1 highest
+
+
+WRITE ADDRESS SUMMARY
+ 6 bit Address 7 6 5 4 3 2 1 0 Function
+ addres Name
+ s
+ 00 VSYNC 1 vertical sync set-clear
+ 01 VBLANK 1 1 1 vertical blank set-
+ clear
+ 02 WSYNC s t r o b e wait for leading edge
+ of horizontal blank
+ 03 RSYNC s t r o b e reset horizontal sync
+ counter
+ 04 NUSIZ0 1 1 1 1 1 1 number-size player-
+ missile 0
+ 05 NUSIZ1 1 1 1 1 1 1 number-size player-
+ missile 1
+ 06 COLUP0 1 1 1 1 1 1 1 color-lum player 0
+ 07 COLUP1 1 1 1 1 1 1 1 color-lum player 1
+ 08 COLUPF 1 1 1 1 1 1 1 color-lum playfield
+ 09 COLUBK 1 1 1 1 1 1 1 color-lum background
+ 0A CTRLPF 1 1 1 1 1 control playfield ball
+ size & collisions
+ 0B REFP0 1 reflect player 0
+ 0C REFP1 1 reflect player 1
+ 0D PF0 1 1 1 1 playfield register byte
+ 0
+ 0E PF1 1 1 1 1 1 1 1 1 playfield register byte
+ 1
+ 0F PF2 1 1 1 1 1 1 1 1 playfield register byte
+ 2
+ 10 RESP0 s t r o b e reset player 0
+ 11 RESP1 s t r o b e reset player 1
+ 12 RESM0 s t r o b e reset missile 0
+ 13 RESM1 s t r o b e reset missile 1
+ 14 RESBL s t r o b e reset ball
+ 15 AUDC0 1 1 1 1 audio control 0
+ 16 AUDC1 1 1 1 1 1 audio control 1
+ 17 AUDF0 1 1 1 1 1 audio frequency 0
+ 18 AUDF1 1 1 1 1 audio frequency 1
+ 19 AUDV0 1 1 1 1 audio volume 0
+ 1A AUDV1 1 1 1 1 audio volume 1
+ 1B GRP0 1 1 1 1 1 1 1 1 graphics player 0
+ 1C GRP1 1 1 1 1 1 1 1 1 graphics player 1
+ 1D ENAM0 1 graphics (enable)
+ missile 0
+ 1E ENAM1 1 graphics (enable)
+ missile 1
+ 1F ENABL 1 graphics (enable) ball
+ 20 HMP0 1 1 1 1 horizontal motion
+ player 0
+ 21 HMP1 1 1 1 1 horizontal motion
+ player 1
+ 22 HMM0 1 1 1 1 horizontal motion
+ missile 0
+ 23 HMM1 1 1 1 1 horizontal motion
+ missile 1
+ 24 HMBL 1 1 1 1 horizontal motion ball
+ 25 VDELP0 1 vertical delay player 0
+ 26 VDEL01 1 vertical delay player 1
+ 27 VDELBL 1 vertical delay ball
+ 28 RESMP0 1 reset missile 0 to
+ player 0
+ 29 RESMP1 1 reset missile 1 to
+ player 1
+ 2A HMOVE s t r o b e apply horizontal motion
+ 2B HMCLR s t r o b e clear horizontal motion
+ registers
+ 2C CXCLR s t r o b e clear collision latches
+
+READ ADDRESS SUMMARY
+
+ 6 bit Address 7 6 5 4 3 2 1 0 Function
+ addres Name
+ s D7 D6
+ 0 CXM0P 1 1 read MO P1 M0 P0
+ collision
+ 1 CXM1P 1 1 read M1 P0 M1 P1
+ collision
+ 2 CXP0FB 1 1 read P0 PF P0 BL
+ collision
+ 3 CXP1FB 1 1 read P1 PF P1 BL
+ collision
+ 4 CXM0FB 1 1 read M0 PF M0 BL
+ collision
+ 5 CXM1FB 1 1 read M1 PF M1 BL
+ collision
+ 6 CXBLPF 1 read BL PF unuse
+ collision d
+ 7 CXPPMM 1 1 read P0 P1 M0 M1
+ collision
+ 8 INPT0 1 read pot port
+ 9 INPT1 1 read pot port
+ A INPT2 1 read pot port
+ B INPT3 1 read pot port
+ C INPT4 1 read input
+ D INPT5 1 read input
+ Note : I0, I2, I2, I3
+ can be grounded under
+ software control.
+ I4, I5 can be converted
+ to latched inputs under
+ software control
+
+TIA O0..02 AND LUM TIMING
+TIA WRITE TIMING CHARACTERISTICS
+TIA READ TIMING CHARACTERISTICS
+
+TIA COMP-SYN AND READY TIMING
+
+RSYNC, RES0O, H01, H02, SHB, 02, 0O
+TIA RSYNC AND BLANK AND READY TIMING
+
diff --git a/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/tia_color.html b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/tia_color.html
new file mode 100644
index 00000000..75bfc32a
--- /dev/null
+++ b/com.wudsn.ide.asm/help/www.qotile.net/minidig/docs/tia_color.html
@@ -0,0 +1,898 @@
+
+TIA Color Charts
+
+
+
+
+
+
+
NTSC TIA colors (128 unique colors)
+
+
HUE
+
+
L U M
+
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
A
+
B
+
C
+
D
+
E
+
F
+
+
0-1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2-3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
4-5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
6-7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
8-9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A-B
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
C-D
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
E-F
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
PAL TIA colors (104 unique colors)
+
+
HUE
+
+
L U M
+
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
A
+
B
+
C
+
D
+
E
+
F
+
+
0-1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2-3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
4-5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
6-7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
8-9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A-B
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
C-D
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
E-F
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SECAM TIA colors (8 unique colors)
+
+
HUE
+
+
L U M
+
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
A
+
B
+
C
+
D
+
E
+
F
+
+
0-1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2-3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
4-5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
6-7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
8-9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A-B
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
C-D
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
E-F
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/icons/brkp_obj.gif b/com.wudsn.ide.asm/icons/brkp_obj.gif
new file mode 100644
index 00000000..a831fe72
Binary files /dev/null and b/com.wudsn.ide.asm/icons/brkp_obj.gif differ
diff --git a/com.wudsn.ide.asm/icons/brkpd_obj.gif b/com.wudsn.ide.asm/icons/brkpd_obj.gif
new file mode 100644
index 00000000..74b26c31
Binary files /dev/null and b/com.wudsn.ide.asm/icons/brkpd_obj.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-apple2-16x16.gif b/com.wudsn.ide.asm/icons/hardware-apple2-16x16.gif
new file mode 100644
index 00000000..9755078c
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-apple2-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-atari2600-16x16.gif b/com.wudsn.ide.asm/icons/hardware-atari2600-16x16.gif
new file mode 100644
index 00000000..ab28795f
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-atari2600-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-atari7800-16x16.gif b/com.wudsn.ide.asm/icons/hardware-atari7800-16x16.gif
new file mode 100644
index 00000000..2079858c
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-atari7800-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-atari8bit-16x16.gif b/com.wudsn.ide.asm/icons/hardware-atari8bit-16x16.gif
new file mode 100644
index 00000000..c93689bf
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-atari8bit-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-atari8bit-32x32.gif b/com.wudsn.ide.asm/icons/hardware-atari8bit-32x32.gif
new file mode 100644
index 00000000..1845df70
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-atari8bit-32x32.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-c64-16x16.gif b/com.wudsn.ide.asm/icons/hardware-c64-16x16.gif
new file mode 100644
index 00000000..c58eaa56
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-c64-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-generic-16x16.gif b/com.wudsn.ide.asm/icons/hardware-generic-16x16.gif
new file mode 100644
index 00000000..b58a71de
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-generic-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-nes-16x16.gif b/com.wudsn.ide.asm/icons/hardware-nes-16x16.gif
new file mode 100644
index 00000000..3269e0a1
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-nes-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/hardware-test-16x16.gif b/com.wudsn.ide.asm/icons/hardware-test-16x16.gif
new file mode 100644
index 00000000..a5bb5a8c
Binary files /dev/null and b/com.wudsn.ide.asm/icons/hardware-test-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/help-16x16.gif b/com.wudsn.ide.asm/icons/help-16x16.gif
new file mode 100644
index 00000000..86550fe9
Binary files /dev/null and b/com.wudsn.ide.asm/icons/help-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/help-topic-pdf-small.gif b/com.wudsn.ide.asm/icons/help-topic-pdf-small.gif
new file mode 100644
index 00000000..9591e124
Binary files /dev/null and b/com.wudsn.ide.asm/icons/help-topic-pdf-small.gif differ
diff --git a/com.wudsn.ide.asm/icons/help-topic-small.gif b/com.wudsn.ide.asm/icons/help-topic-small.gif
new file mode 100644
index 00000000..1cfe6f3a
Binary files /dev/null and b/com.wudsn.ide.asm/icons/help-topic-small.gif differ
diff --git a/com.wudsn.ide.asm/icons/instruction-type-directive-16x16.gif b/com.wudsn.ide.asm/icons/instruction-type-directive-16x16.gif
new file mode 100644
index 00000000..12d90bea
Binary files /dev/null and b/com.wudsn.ide.asm/icons/instruction-type-directive-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/instruction-type-illegal-opcode-16x16.gif b/com.wudsn.ide.asm/icons/instruction-type-illegal-opcode-16x16.gif
new file mode 100644
index 00000000..da0e61ca
Binary files /dev/null and b/com.wudsn.ide.asm/icons/instruction-type-illegal-opcode-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/instruction-type-legal-opcode-16x16.gif b/com.wudsn.ide.asm/icons/instruction-type-legal-opcode-16x16.gif
new file mode 100644
index 00000000..ef6f72a7
Binary files /dev/null and b/com.wudsn.ide.asm/icons/instruction-type-legal-opcode-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/instruction-type-pseudo-opcode-16x16.gif b/com.wudsn.ide.asm/icons/instruction-type-pseudo-opcode-16x16.gif
new file mode 100644
index 00000000..92d2f6f7
Binary files /dev/null and b/com.wudsn.ide.asm/icons/instruction-type-pseudo-opcode-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-binary-include-16x16.gif b/com.wudsn.ide.asm/icons/outline-binary-include-16x16.gif
new file mode 100644
index 00000000..b7db9168
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-binary-include-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-binary-output-16x16.gif b/com.wudsn.ide.asm/icons/outline-binary-output-16x16.gif
new file mode 100644
index 00000000..a61ee2d3
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-binary-output-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-constant-definition-16x16.gif b/com.wudsn.ide.asm/icons/outline-constant-definition-16x16.gif
new file mode 100644
index 00000000..bb6ec29c
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-constant-definition-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-default-16x16.gif b/com.wudsn.ide.asm/icons/outline-default-16x16.gif
new file mode 100644
index 00000000..7d24707e
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-default-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-definition-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-definition-section-16x16.gif
new file mode 100644
index 00000000..7d24707e
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-definition-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-diamond.gif b/com.wudsn.ide.asm/icons/outline-diamond.gif
new file mode 100644
index 00000000..36b7561b
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-diamond.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-enum-definition-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-enum-definition-section-16x16.gif
new file mode 100644
index 00000000..3f8a0dba
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-enum-definition-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-equate-definition-16x16.gif b/com.wudsn.ide.asm/icons/outline-equate-definition-16x16.gif
new file mode 100644
index 00000000..a610743c
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-equate-definition-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-implementation-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-implementation-section-16x16.gif
new file mode 100644
index 00000000..49ccefda
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-implementation-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-label-definition-16x16.gif b/com.wudsn.ide.asm/icons/outline-label-definition-16x16.gif
new file mode 100644
index 00000000..8adce954
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-label-definition-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-local-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-local-section-16x16.gif
new file mode 100644
index 00000000..86df7aae
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-local-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-macro-definition-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-macro-definition-section-16x16.gif
new file mode 100644
index 00000000..05f3a129
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-macro-definition-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-pages-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-pages-section-16x16.gif
new file mode 100644
index 00000000..53ec9919
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-pages-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-procedure-definition-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-procedure-definition-section-16x16.gif
new file mode 100644
index 00000000..cbb53ccb
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-procedure-definition-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-repeat-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-repeat-section-16x16.gif
new file mode 100644
index 00000000..572f08fc
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-repeat-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-sort.gif b/com.wudsn.ide.asm/icons/outline-sort.gif
new file mode 100644
index 00000000..6311cc00
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-sort.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-source-include-16x16.gif b/com.wudsn.ide.asm/icons/outline-source-include-16x16.gif
new file mode 100644
index 00000000..ea94702c
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-source-include-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-structure-definition-section-16x16.gif b/com.wudsn.ide.asm/icons/outline-structure-definition-section-16x16.gif
new file mode 100644
index 00000000..871c78cf
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-structure-definition-section-16x16.gif differ
diff --git a/com.wudsn.ide.asm/icons/outline-variable-16x16 - Copy.gif b/com.wudsn.ide.asm/icons/outline-variable-16x16 - Copy.gif
new file mode 100644
index 00000000..61c98fcf
Binary files /dev/null and b/com.wudsn.ide.asm/icons/outline-variable-16x16 - Copy.gif differ
diff --git a/com.wudsn.ide.asm/icons/sample.gif b/com.wudsn.ide.asm/icons/sample.gif
new file mode 100644
index 00000000..34fb3c9d
Binary files /dev/null and b/com.wudsn.ide.asm/icons/sample.gif differ
diff --git a/com.wudsn.ide.asm/icons/topic.gif b/com.wudsn.ide.asm/icons/topic.gif
new file mode 100644
index 00000000..fbd1394c
Binary files /dev/null and b/com.wudsn.ide.asm/icons/topic.gif differ
diff --git a/com.wudsn.ide.asm/plugin.properties b/com.wudsn.ide.asm/plugin.properties
new file mode 100644
index 00000000..959f4286
--- /dev/null
+++ b/com.wudsn.ide.asm/plugin.properties
@@ -0,0 +1,52 @@
+com.wudsn.ide.asm.Hardware.GENERIC=Generic
+com.wudsn.ide.asm.Hardware.APPLE2=Apple 2
+com.wudsn.ide.asm.Hardware.ATARI2600=Atari 2600
+com.wudsn.ide.asm.Hardware.ATARI7800=Atari 7800
+com.wudsn.ide.asm.Hardware.ATARI8BIT=Atari 8-bit
+com.wudsn.ide.asm.Hardware.C64=C64
+com.wudsn.ide.asm.Hardware.NES=NES
+com.wudsn.ide.asm.Hardware.TEST=Test
+
+com.wudsn.ide.asm.CPU.MOS6502=6502
+com.wudsn.ide.asm.CPU.MOS6502_ILLEGAL=6502 with illegal opcodes
+com.wudsn.ide.asm.CPU.MOS65C02=65C02
+com.wudsn.ide.asm.CPU.MOS6502_DTV=6502 DTV
+com.wudsn.ide.asm.CPU.MOS65816=65816
+
+com.wudsn.ide.asm.compiler.AssemblerSourceFile.name=Assembler Source File
+
+com.wudsn.ide.asm.editor.AssemblerEditorAssemblerMenu.label=Assembler
+com.wudsn.ide.asm.editor.AssemblerEditorAssemblerMenu.mnemonic=A
+
+com.wudsn.ide.asm.editor.AssemblerEditorAssemblerToolbar.label=Assembler
+
+com.wudsn.ide.asm.editor.AssemblerEditorCommands.name=Assembler Editor Commands
+com.wudsn.ide.asm.editor.AssemblerEditorOpenSourceFolderCommand.name=Open Source Folder
+com.wudsn.ide.asm.editor.AssemblerEditorOpenSourceFolderCommand.mnemonic=S
+com.wudsn.ide.asm.editor.AssemblerEditorOpenOutputFolderCommand.name=Open Output Folder
+com.wudsn.ide.asm.editor.AssemblerEditorOpenOutputFolderCommand.mnemonic=O
+com.wudsn.ide.asm.editor.AssemblerEditorCompileCommand.name=Compile
+com.wudsn.ide.asm.editor.AssemblerEditorCompileCommand.mnemonic=C
+com.wudsn.ide.asm.editor.AssemblerEditorCompileAndRunCommand.name=Compile and Run
+com.wudsn.ide.asm.editor.AssemblerEditorCompileAndRunWithCommand.name=Compile and Run with...
+com.wudsn.ide.asm.editor.AssemblerEditorCompileAndRunCommand.mnemonic=R
+com.wudsn.ide.asm.editor.AssemblerEditorCompilerHelpCommand.name=Compiler Help
+com.wudsn.ide.asm.editor.AssemblerEditorCompilerHelpCommand.mnemonic=H
+com.wudsn.ide.asm.editor.AssemblerEditorToggleCommentCommand.name=Toggle Comment
+com.wudsn.ide.asm.editor.AssemblerEditorToggleBreakpointCommand.name=Toggle Breakpoint
+com.wudsn.ide.asm.editor.AssemblerEditorOpenDeclarationCommand.name=Open Declaration
+com.wudsn.ide.asm.editor.AssemblerEditorEnableDisableBreakpointCommand.name=Enable/Disable Breakpoint
+
+com.wudsn.ide.asm.editor.AssemblerHyperlinkDetector.name=Hyperlink Detector
+com.wudsn.ide.asm.editor.AssemblerHyperlinkDetectorEditorTarget.name=Assembler Editor
+
+com.wudsn.ide.asm.editor.AssemblerBreakpoint.name=Breakpoint
+
+com.wudsn.ide.asm.editor.CompilerSymbolsView.name=Symbols
+
+# Preferences
+com.wudsn.ide.asm.preferences.AssemblerPreferences.name=Assembler Preferences
+com.wudsn.ide.asm.preferences.AssemblerPreferencesPage.name=Assembler
+
+com.wudsn.ide.asm.runner.DefaultApplication.name=Operating System Default Application
+com.wudsn.ide.asm.runner.UserDefinedApplication.name=User Defined Application
diff --git a/com.wudsn.ide.asm/plugin.xml b/com.wudsn.ide.asm/plugin.xml
new file mode 100644
index 00000000..46fb9ff9
--- /dev/null
+++ b/com.wudsn.ide.asm/plugin.xml
@@ -0,0 +1,425 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ label="%com.wudsn.ide.asm.editor.AssemblerEditorAssemblerMenu.label"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/plugin_de_DE.properties b/com.wudsn.ide.asm/plugin_de_DE.properties
new file mode 100644
index 00000000..6c148013
--- /dev/null
+++ b/com.wudsn.ide.asm/plugin_de_DE.properties
@@ -0,0 +1,52 @@
+com.wudsn.ide.asm.Hardware.GENERIC=Generisch
+com.wudsn.ide.asm.Hardware.APPLE2=Apple 2
+com.wudsn.ide.asm.Hardware.ATARI2600=Atari 2600
+com.wudsn.ide.asm.Hardware.ATARI7800=Atari 7800
+com.wudsn.ide.asm.Hardware.ATARI8BIT=Atari 8-bit
+com.wudsn.ide.asm.Hardware.C64=C64
+com.wudsn.ide.asm.Hardware.NES=NES
+com.wudsn.ide.asm.Hardware.TEST=Test
+
+com.wudsn.ide.asm.CPU.MOS6502=6502
+com.wudsn.ide.asm.CPU.MOS6502_ILLEGAL=6502 mit illegalen Opcodes
+com.wudsn.ide.asm.CPU.MOS65C02=65C02
+com.wudsn.ide.asm.CPU.MOS6502_DTV=6502 DTV
+com.wudsn.ide.asm.CPU.MOS65816=65816
+
+com.wudsn.ide.asm.compiler.AssemblerSourceFile.name=Assembler Quell-Datei
+
+com.wudsn.ide.asm.editor.AssemblerEditorAssemblerMenu.label=Assembler
+com.wudsn.ide.asm.editor.AssemblerEditorAssemblerMenu.mnemonic=A
+
+com.wudsn.ide.asm.editor.AssemblerEditorAssemblerToolbar.label=Assembler
+
+com.wudsn.ide.asm.editor.AssemblerEditorCommands.name=Assembler Editor Befehle
+com.wudsn.ide.asm.editor.AssemblerEditorOpenSourceFolderCommand.name=Quell-Ordner öffnen
+com.wudsn.ide.asm.editor.AssemblerEditorOpenSourceFolderCommand.mnemonic=Q
+com.wudsn.ide.asm.editor.AssemblerEditorOpenOutputFolderCommand.name=Ausgabe-Ordner öffnen
+com.wudsn.ide.asm.editor.AssemblerEditorOpenOutputFolderCommand.mnemonic=A
+com.wudsn.ide.asm.editor.AssemblerEditorCompileCommand.name=Kompilieren
+com.wudsn.ide.asm.editor.AssemblerEditorCompileCommand.mnemonic=K
+com.wudsn.ide.asm.editor.AssemblerEditorCompileAndRunCommand.name=Kompilieren und Ausführen
+com.wudsn.ide.asm.editor.AssemblerEditorCompileAndRunWithCommand.name=Kompilieren und Ausführen mit ...
+com.wudsn.ide.asm.editor.AssemblerEditorCompileAndRunCommand.mnemonic=A
+com.wudsn.ide.asm.editor.AssemblerEditorCompilerHelpCommand.name=Kompiler Hilfe
+com.wudsn.ide.asm.editor.AssemblerEditorCompilerHelpCommand.mnemonic=H
+com.wudsn.ide.asm.editor.AssemblerEditorToggleCommentCommand.name=Kommentar umschalten
+com.wudsn.ide.asm.editor.AssemblerEditorToggleBreakpointCommand.name=Breakpoint umschalten
+com.wudsn.ide.asm.editor.AssemblerEditorOpenDeclarationCommand.name=Deklaration öffnen
+com.wudsn.ide.asm.editor.AssemblerEditorEnableDisableBreakpointCommand.name=Breakpoint ein/ausschalten
+
+com.wudsn.ide.asm.editor.AssemblerHyperlinkDetector.name=Hyperlink Detector
+com.wudsn.ide.asm.editor.AssemblerHyperlinkDetectorEditorTarget.name=Assembler Editor
+
+com.wudsn.ide.asm.editor.AssemblerBreakpoint.name=Unterbrechungspunkt
+
+com.wudsn.ide.asm.editor.CompilerSymbolsView.name=Symbole
+
+# Preferences
+com.wudsn.ide.asm.preferences.AssemblerPreferences.name=Assembler Einstellungen
+com.wudsn.ide.asm.preferences.AssemblerPreferencesPage.name=Assembler
+
+com.wudsn.ide.asm.runner.DefaultApplication.name=Standardanwendung des Betriebssystems
+com.wudsn.ide.asm.runner.UserDefinedApplication.name=Benutzerdefinierte Anwendung
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/schema/compilers.exsd b/com.wudsn.ide.asm/schema/compilers.exsd
new file mode 100644
index 00000000..fb88ff2b
--- /dev/null
+++ b/com.wudsn.ide.asm/schema/compilers.exsd
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+ This extension point allows for adding new 6502 assembler compilers to the WUDSN IDE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The technical id of the compiler. Must consist of lower case letters or digits.
+
+
+
+
+
+
+ Translatable name of the compiler. Typically contains only upper case letters.
+
+
+
+
+
+
+
+
+
+ The name of the compiler class.
+
+
+
+
+
+
+
+
+
+ Supported (minimum) version of the compiler. All compiler directives and major compiler features up to this version have been incorporated into this version of WUDSN IDE.
+
+
+
+
+
+
+ The absolute URL pointing to the homepage of the compiler where the latest version can be downloaded.
+
+
+
+
+
+
+ The relative paths to the help documents. Multiple paths are separated by comma. Each path is evluated based on the absolute path of the compiler executable in the preferences.
+
+
+
+
+
+
+ The default compiler parameters which are use if not other parameters are specified in the preferences.
+
+
+
+
+
+
+ The default hardware which is assumed, if no source annotation is found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WUDSN IDE 1.1.0
+
+
+
+
+
+
+
+
+
+ To implement this extension point, you have to create a sub-class of com.wudsn.ide.asm.compiler.Compiler, a sub-class of com.wudsn.ide.asm.compiler.parser.CompilerSourceParser and a sub-class of com.wudsn.ide.asm.compiler.CompilerLogParser. In the constructor of the compiler you have to set the source parser instance. In the "createLogParser" method of the compiler you have to create a new instance of the corresponding log parser.
+
+
+
+
+
+
+
+
+
+ (c) 2009 Peter Dell
+
+
+
+
diff --git a/com.wudsn.ide.asm/schema/runners.exsd b/com.wudsn.ide.asm/schema/runners.exsd
new file mode 100644
index 00000000..e7703290
--- /dev/null
+++ b/com.wudsn.ide.asm/schema/runners.exsd
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+ This extension point allows for adding new runner, for example runners, to the WUDSN IDE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Optional implementation class to provide runner specific breakouts, for example for creating breakpoint files.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WUDSN IDE 1.3.0
+
+
+
+
+
+
+
+
+
+
+
+ (c) 2009 Peter Dell
+
+
+
+
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Actions.properties b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Actions.properties
new file mode 100644
index 00000000..b9deb5e4
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Actions.properties
@@ -0,0 +1,3 @@
+# Used by AssemblerEditor
+com.wudsn.ide.asm.editor.ContentAssistProposal_label=Content Assist
+com.wudsn.ide.asm.editor.AssemblerEditorToggleCommentCommand_label=Toggle Comment2
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/AssemblerPlugin.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/AssemblerPlugin.java
new file mode 100644
index 00000000..735bfd0d
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/AssemblerPlugin.java
@@ -0,0 +1,305 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.jface.preference.JFacePreferences;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.osgi.framework.BundleContext;
+
+import com.wudsn.ide.asm.compiler.CompilerConsole;
+import com.wudsn.ide.asm.compiler.CompilerRegistry;
+import com.wudsn.ide.asm.preferences.AssemblerPreferences;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesChangeListener;
+import com.wudsn.ide.asm.preferences.AssemblerPreferencesConstants;
+import com.wudsn.ide.asm.runner.RunnerRegistry;
+import com.wudsn.ide.base.common.AbstractIDEPlugin;
+
+/**
+ * The main plugin class to be used in the desktop.
+ *
+ * @author Peter Dell
+ */
+public final class AssemblerPlugin extends AbstractIDEPlugin {
+
+ /**
+ * The plugin id.
+ */
+ public static final String ID = "com.wudsn.ide.asm";
+
+ /**
+ * The shared instance.
+ */
+ private static AssemblerPlugin plugin;
+
+ /**
+ * The preferences.
+ */
+ private AssemblerPreferences preferences;
+ private ListenerList preferencesChangeListeners;
+
+ /**
+ * The compiler registry.
+ */
+ private CompilerRegistry compilerRegistry;
+
+ /**
+ * The compiler console.
+ */
+ private CompilerConsole compilerConsole;
+
+ /**
+ * The runner registry.
+ */
+ private RunnerRegistry runnerRegistry;
+
+ /**
+ * The UI properties.
+ */
+ private Map properties;
+
+ /**
+ * Creates a new instance. Must be public for dynamic instantiation.
+ */
+ public AssemblerPlugin() {
+ preferences = null;
+ preferencesChangeListeners = new ListenerList(ListenerList.IDENTITY);
+ compilerRegistry = new CompilerRegistry();
+ compilerConsole = null;
+ runnerRegistry = new RunnerRegistry();
+ properties = new HashMap(10);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getPluginId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ preferences = new AssemblerPreferences(getPreferenceStore());
+ plugin = this;
+ try {
+ compilerRegistry.init();
+ } catch (Exception ex) {
+ logError("Cannot initialize compiler registry", null, ex);
+ throw ex;
+ }
+ compilerConsole = new CompilerConsole();
+ try {
+ runnerRegistry.init();
+ } catch (Exception ex) {
+ logError("Cannot initialize runner registry", null, ex);
+ throw ex;
+ }
+
+ // Register for global JFace preferences that also affect the editors.
+ JFacePreferences.getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
+ final static String BLOCK_SELECTION_MODE_FONT = "org.eclipse.ui.workbench.texteditor.blockSelectionModeFont";
+
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(JFaceResources.TEXT_FONT)
+ || event.getProperty().equals(BLOCK_SELECTION_MODE_FONT)) {
+ firePreferencesChangeEvent(AssemblerPreferencesConstants.EDITOR_TEXT_ATTRIBUTES);
+ }
+
+ }
+ });
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ plugin = null;
+ }
+
+ /**
+ * Gets the shared plugin instance.
+ *
+ * @return The plug-in, not null.
+ */
+ public static AssemblerPlugin getInstance() {
+ if (plugin == null) {
+ throw new IllegalStateException("Plugin not initialized or already stopped");
+ }
+ return plugin;
+ }
+
+ /**
+ * Gets the compiler registry for this plugin.
+ *
+ * @return The compiler registry, not null.
+ */
+ public CompilerRegistry getCompilerRegistry() {
+ if (compilerRegistry == null) {
+ throw new IllegalStateException("Field 'compilerRegistry' must not be null.");
+ }
+ return compilerRegistry;
+ }
+
+ /**
+ * Gets the compiler console for this plugin.
+ *
+ * @return The compiler console, not null.
+ */
+ public final CompilerConsole getCompilerConsole() {
+ if (compilerConsole == null) {
+ throw new IllegalStateException("Field 'compilerConsole' must not be null.");
+ }
+ return compilerConsole;
+ }
+
+ /**
+ * Gets the runner registry for this plugin.
+ *
+ * @return The runner registry, not null.
+ */
+ public RunnerRegistry getRunnerRegistry() {
+ if (runnerRegistry == null) {
+ throw new IllegalStateException("Field 'runnerRegistry' must not be null.");
+ }
+ return runnerRegistry;
+ }
+
+ /**
+ * Gets the preferences for this plugin.
+ *
+ * @return The preferences, not null.
+ */
+ public AssemblerPreferences getPreferences() {
+ if (preferences == null) {
+ throw new IllegalStateException("Field 'preferences' must not be null.");
+ }
+ return preferences;
+ }
+
+ /**
+ * Adds a listener for immediate preferences changes.
+ *
+ * @param listener
+ * The listener, not null.
+ * @since 1.6.3
+ */
+ public void addPreferencesChangeListener(AssemblerPreferencesChangeListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("Parameter 'listener' must not be null.");
+ }
+ preferencesChangeListeners.add(listener);
+ }
+
+ /**
+ * Removes a listener for immediate preferences changes.
+ *
+ * @param listener
+ * The listener, not null.
+ * @since 1.6.3
+ */
+ public void removePreferencesChangeListener(AssemblerPreferencesChangeListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("Parameter 'listener' must not be null.");
+ }
+ preferencesChangeListeners.remove(listener);
+ }
+
+ /**
+ * Fire the change events for all registered listeners.
+ *
+ * @param changedPropertyNames
+ * The set of property changed property names, not
+ * null.
+ *
+ * @since 1.6.3
+ */
+ public void firePreferencesChangeEvent(Set changedPropertyNames) {
+ if (changedPropertyNames == null) {
+ throw new IllegalArgumentException("Parameter 'changedPropertyNames' must not be null.");
+ }
+ if (!changedPropertyNames.isEmpty()) {
+
+ for (Object listener : preferencesChangeListeners.getListeners()) {
+ ((AssemblerPreferencesChangeListener) listener).preferencesChanged(preferences, changedPropertyNames);
+ }
+ }
+ }
+
+ /**
+ * Gets a UI property.
+ *
+ * @param key
+ * The property key, not null.
+ *
+ * @return The UI property, may be empty, not null.
+ */
+ public String getProperty(QualifiedName key) {
+ if (key == null) {
+ throw new IllegalArgumentException("Parameter 'key' must not be null.");
+ }
+
+ String result;
+ synchronized (properties) {
+ result = properties.get(key);
+ }
+ if (result == null) {
+ result = "";
+ }
+ return result;
+ }
+
+ /**
+ * Set a UI property.
+ *
+ * @param key
+ * The property key, not null.
+ *
+ * @param value
+ * The UI property, may be empty, not null.
+ */
+ public void setProperty(QualifiedName key, String value) {
+ if (key == null) {
+ throw new IllegalArgumentException("Parameter 'key' must not be null.");
+ }
+ if (value == null) {
+ throw new IllegalArgumentException("Parameter 'value' must not be null.");
+ }
+ synchronized (properties) {
+ properties.put(key, value);
+ }
+
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/AssemblerProperties.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/AssemblerProperties.java
new file mode 100644
index 00000000..ff051fc2
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/AssemblerProperties.java
@@ -0,0 +1,144 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.eclipse.core.resources.IMarker;
+
+import com.wudsn.ide.base.common.StringUtility;
+
+public final class AssemblerProperties {
+
+ /**
+ * A single key value pair.
+ *
+ * @since 1.6.1
+ */
+ public static final class AssemblerProperty {
+ public final String key;
+ public final String value;
+ public final int lineNumber;
+
+ AssemblerProperty(String key, String value, int lineNumber) {
+ this.key = key;
+ this.value = value;
+ this.lineNumber = lineNumber;
+ }
+
+ @Override
+ public String toString() {
+ return key + "=" + value + " in line " + lineNumber;
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public final static class InvalidAssemblerPropertyException extends Exception {
+ public final AssemblerProperty property;
+ public final IMarker marker;
+
+ public InvalidAssemblerPropertyException(AssemblerProperty property, IMarker marker) {
+ if (property == null) {
+ throw new IllegalArgumentException("Parameter 'property' must not be null.");
+ }
+ this.property = property;
+ this.marker = marker;
+ }
+ }
+
+ /**
+ * Source code constants.
+ */
+ public final static String PREFIX = "@com.wudsn.ide.asm.";
+ public final static String HARDWARE = "@com.wudsn.ide.asm.hardware";
+ public final static String MAIN_SOURCE_FILE = "@com.wudsn.ide.asm.mainsourcefile";
+ public final static String OUTPUT_FOLDER_MODE = "@com.wudsn.ide.asm.outputfoldermode";
+ public final static String OUTPUT_FOLDER = "@com.wudsn.ide.asm.outputfolder";
+ public final static String OUTPUT_FILE_EXTENSION = "@com.wudsn.ide.asm.outputfileextension";
+ public final static String OUTPUT_FILE = "@com.wudsn.ide.asm.outputfile";
+
+ private Map properties;
+
+ /**
+ * Creation is public.
+ */
+ public AssemblerProperties() {
+ properties = new TreeMap();
+ }
+
+ /**
+ * Puts a new value into the properties provided not other value is already
+ * there.
+ *
+ * @param key
+ * The property key, not empty and not null.
+ * @param value
+ * The property value, may be empty, not null.
+ * @param lineNumber
+ * The line number, a positive integer or 0 if the line number is
+ * undefined.
+ * @since 1.6.1
+ */
+ public void put(String key, String value, int lineNumber) {
+ if (key == null) {
+ throw new IllegalArgumentException("Parameter 'key' must not be null.");
+ }
+ if (StringUtility.isEmpty(key)) {
+ throw new IllegalArgumentException("Parameter 'key' must not be empty.");
+ }
+ if (value == null) {
+ throw new IllegalArgumentException("Parameter 'value' must not be null.");
+ }
+ if (lineNumber < 0l) {
+ throw new IllegalArgumentException("Parameter 'lineNumber' must not be negative. Specified value is "
+ + lineNumber + ".");
+ }
+ if (!properties.containsKey(key)) {
+ AssemblerProperty property = new AssemblerProperty(key, value, lineNumber);
+ properties.put(key, property);
+ }
+ }
+
+ /**
+ * Gets a property from the properties map.
+ *
+ * @param key
+ * The property key, not empty and not null.
+ * @return The property or null if the property is not defined.
+ *
+ * @since 1.6.1
+ */
+ public AssemblerProperty get(String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("Parameter 'key' must not be null.");
+ }
+ if (StringUtility.isEmpty(key)) {
+ throw new IllegalArgumentException("Parameter 'key' must not be empty.");
+ }
+ return properties.get(key);
+ }
+
+ @Override
+ public String toString() {
+ return properties.toString();
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/CPU.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/CPU.java
new file mode 100644
index 00000000..2c0b38d5
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/CPU.java
@@ -0,0 +1,31 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm;
+
+/**
+ * Enum for the supported CPUs. Used for restricting the visible instructions.
+ *
+ * @author Peter Dell
+ *
+ * @sinbce 1.6.1
+ */
+public enum CPU {
+
+ MOS6502, MOS6502_ILLEGAL, MOS65C02, MOS6502_DTV, MOS65816
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Hardware.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Hardware.java
new file mode 100644
index 00000000..7478f01a
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Hardware.java
@@ -0,0 +1,31 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm;
+
+/**
+ * Enum for the supported hardware platforms. Used for classifying compilers,
+ * emulators and converters.
+ *
+ * @author Peter Dell
+ *
+ */
+public enum Hardware {
+
+ GENERIC, APPLE2, ATARI2600, ATARI7800, ATARI8BIT, C64, NES, TEST
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/HardwareUtility.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/HardwareUtility.java
new file mode 100644
index 00000000..73b76cff
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/HardwareUtility.java
@@ -0,0 +1,170 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import com.wudsn.ide.asm.compiler.CompilerFileWriter;
+import com.wudsn.ide.asm.compiler.writer.AppleFileWriter;
+
+/**
+ * Map value of {@link Hardware} to icon paths and descriptors.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class HardwareUtility {
+
+ /**
+ * Creation is private.
+ */
+ private HardwareUtility() {
+ }
+
+ /**
+ * Gets the default file extension for executable files on a hardware.
+ *
+ * @param hardware
+ * The hardware, not null.
+ * @return The default file extension, may be empty, not null.
+ *
+ * @since 1.6.1
+ */
+ public static String getDefaultFileExtension(Hardware hardware) {
+ if (hardware == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'hardware' must not be null.");
+ }
+ switch (hardware) {
+ case APPLE2:
+ // AppleDos 3.3 binary file
+ // start-lo,start-hi,length-lo,length-hi,data
+ return ".b";
+ case ATARI2600:
+ // Atari VCS ROM cartridge
+ return ".bin";
+ case ATARI7800:
+ // Atari 7800 ROM cartridge
+ return ".bin";
+ case ATARI8BIT:
+ // AtariDOS 2.5 compound file,
+ // $ff,$ff,start-lo,start-hi,end-lo,end-hi,data
+ return ".xex";
+ case C64:
+ // C64 program file
+ // start-lo,start-hi,data
+ return ".prg";
+ case NES:
+ // NES ROM file
+ return ".nes";
+ case TEST:
+ return ".tst";
+ default:
+ return "";
+ }
+ }
+
+ /**
+ * Gets the image path for a hardware image.
+ *
+ * @param hardware
+ * The hardware, not null.
+ * @return The image path for the hardware image, not empty and not
+ * null.
+ */
+ public static String getImagePath(Hardware hardware) {
+ if (hardware == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'hardware' must not be null.");
+ }
+ String path;
+ switch (hardware) {
+ case GENERIC:
+ path = "hardware-generic-16x16.gif";
+ break;
+ case APPLE2:
+ path = "hardware-apple2-16x16.gif";
+ break;
+ case ATARI2600:
+ path = "hardware-atari2600-16x16.gif";
+ break;
+ case ATARI7800:
+ path = "hardware-atari7800-16x16.gif";
+ break;
+ case ATARI8BIT:
+ path = "hardware-atari8bit-16x16.gif";
+ break;
+ case C64:
+ path = "hardware-c64-16x16.gif";
+ break;
+ case NES:
+ path = "hardware-nes-16x16.gif";
+ break;
+ case TEST:
+ path = "hardware-test-16x16.gif";
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown hardware " + hardware
+ + ".");
+ }
+ return path;
+ }
+
+ /**
+ * Gets the image descriptor for a hardware image.
+ *
+ * @param hardware
+ * The hardware, not null.
+ * @return The image descriptor for the hardware image, not
+ * null.
+ */
+ public static ImageDescriptor getImageDescriptor(Hardware hardware) {
+ if (hardware == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'hardware' must not be null.");
+ }
+ ImageDescriptor result;
+ result = AssemblerPlugin.getInstance().getImageDescriptor(
+ getImagePath(hardware));
+ return result;
+ }
+
+ /**
+ * Gets the compiler file writer a hardware.
+ *
+ * @param hardware
+ * The hardware, not null.
+ * @return The image descriptor for the hardware image, not
+ * null.
+ * @since 1.6.4
+ */
+ public static CompilerFileWriter getCompilerFileWriter(Hardware hardware) {
+ if (hardware == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'hardware' must not be null.");
+ }
+ CompilerFileWriter compilerFileWriter;
+ if (hardware.equals(Hardware.APPLE2)) {
+ compilerFileWriter = new AppleFileWriter();
+ } else {
+ compilerFileWriter = new CompilerFileWriter();
+ }
+ return compilerFileWriter;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts.java
new file mode 100644
index 00000000..931ac98b
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts.java
@@ -0,0 +1,288 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Class which holds the localized text constants.
+ *
+ * @author Peter Dell
+ */
+public final class Texts extends NLS {
+
+ public static String TOC_ASSEMBLER_SYNTAX_YES;
+ public static String TOC_ASSEMBLER_SYNTAX_NO;
+ public static String TOC_ASSEMBLER_SYNTAX_BLOCK_DEFINITION_CHARACTERS;
+ public static String TOC_ASSEMBLER_SYNTAX_COMPLETION_PROPOSAL_AUTO_ACTIVATION_CHARACTERS;
+ public static String TOC_ASSEMBLER_SYNTAX_IDENTIFIER_PART_CHARACTERS;
+ public static String TOC_ASSEMBLER_SYNTAX_IDENTIFIER_SEPARATOR_CHARACTER;
+ public static String TOC_ASSEMBLER_SYNTAX_IDENTIFIER_START_CHARACTERS;
+ public static String TOC_ASSEMBLER_SYNTAX_IDENTIFIERS_CASE_SENSITIVE;
+ public static String TOC_ASSEMBLER_SYNTAX_INSTRUCTIONS_CASE_SENSITIVE;
+ public static String TOC_ASSEMBLER_SYNTAX_LABEL_DEFINITION_SUFFIX_CHARACTER;
+ public static String TOC_ASSEMBLER_SYNTAX_MACRO_USAGE_PREFIX_CHARACTER;
+ public static String TOC_ASSEMBLER_SYNTAX_MULTIPLE_LINES_COMMENT_DELIMITERS;
+ public static String TOC_ASSEMBLER_SYNTAX_SINGLE_LINE_COMMENT_DELIMITERS;
+ public static String TOC_ASSEMBLER_SYNTAX_SOURCE_INCLUDE_DEFAULT_EXTENSION;
+ public static String TOC_ASSEMBLER_SYNTAX_STRING_DELIMITERS;
+
+ /**
+ * Compiler console.
+ */
+ public static String COMPILER_CONSOLE_TITLE;
+
+ /**
+ * Compiler source parser tree.
+ */
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFAULT;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFINITION_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_IMPLEMENTATION_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_EQUATE_DEFINITION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LABEL_DEFINITION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_ENUM_DEFINITION_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_STRUCTURE_DEFINITION_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LOCAL_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_MACRO_DEFINITION_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PAGES_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PROCEDURE_DEFINITION_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_REPEAT_SECTION;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_SOURCE_INCLUDE;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_INCLUDE;
+ public static String COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_OUTPUT;
+
+ /**
+ * Compiler syntax.
+ */
+ public static String COMPILER_SYNTAX_INSTRUCTION_DIRECTIVE;
+ public static String COMPILER_SYNTAX_LEGAL_OPCODE;
+ public static String COMPILER_SYNTAX_ILLEGAL_OPCODE;
+ public static String COMPILER_SYNTAX_PSEUDO_OPCODE;
+ public static String COMPILER_SYNTAX_W65816_ONLY;
+
+ /**
+ * Assembler toolbar and menu.
+ *
+ */
+ public static String ASSEMBLER_TOOLBAR_RUN_WITH_DEFAULT_LABEL;
+
+ /**
+ * Assembler content outline.
+ */
+ public static String ASSEMBLER_CONTENT_OUTLINE_SORT_BUTTON_TOOL_TIP;
+ public static String ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_DEFAULT;
+ public static String ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_DEFINITION_SECTION;
+ public static String ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_IMPLEMENTATION_SECTION;
+
+ /**
+ * Assembler hyperlink detector.
+ */
+ public static String ASSEMBLER_HYPERLINK_DETECTOR_OPEN_SOURCE_WITH_ASSEMBLER_EDITOR;
+ public static String ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_HEX_EDITOR;
+ public static String ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_GRAPHICS_EDITOR;
+ public static String ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_DEFAULT_EDITOR;
+ public static String ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_SYSTEM_EDITOR;
+ public static String ASSEMBLER_HYPERLINK_DETECTOR_OPEN_IDENTIFIER;
+ public static String ASSEMBLER_HYPERLINK_DETECTOR_OPEN_IDENTIFIER_IN_INCLUDE;
+ public static String ASSEMBLER_HYPERLINK_FILE_NOT_EXISTS;
+
+ /**
+ * Assembler breakpoints.
+ */
+ public static String ASSEMBLER_BREAKPOINT_MARKER_MESSAGE;
+ public static String ASSEMBLER_BREAKPOINT_TOGGLE_TYPE_MENU_TEXT;
+
+ /**
+ * Compiler symbols
+ */
+ public static String COMPILER_SYMBOLS_VIEW_FILTER_TOOLTIP;
+ public static String COMPILER_SYMBOLS_VIEW_SOURCE_LABEL;
+ public static String COMPILER_SYMBOLS_VIEW_SOURCE_NONE;
+ public static String COMPILER_SYMBOLS_VIEW_SOURCE_TOTAL_COUNT;
+ public static String COMPILER_SYMBOLS_VIEW_SOURCE_FILTERED_COUNT;
+ public static String COMPILER_SYMBOLS_VIEW_TYPE_COLUMN_LABEL;
+ public static String COMPILER_SYMBOLS_VIEW_BANK_COLUMN_LABEL;
+ public static String COMPILER_SYMBOLS_VIEW_NAME_COLUMN_LABEL;
+ public static String COMPILER_SYMBOLS_VIEW_HEX_VALUE_COLUMN_LABEL;
+ public static String COMPILER_SYMBOLS_VIEW_DECIMAL_VALUE_COLUMN_LABEL;
+ public static String COMPILER_SYMBOLS_VIEW_STRING_VALUE_COLUMN_LABEL;
+
+ /**
+ * Preferences: syntax highlighting.
+ */
+ public static String PREFERENCES_SYNTAX_HIGHLIGHTING_GROUP_TITLE;
+
+ public static String PREFERENCES_TEXT_ATTRIBUTE_COMMENT_NAME;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_STRING_NAME;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_NUMBER_NAME;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_DIRECTIVE;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_OPCODE_LEGAL_NAME;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_OPCODE_ILLEGAL_NAME;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_OPCODE_PSEUDO_NAME;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_EQUATE;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_LABEL;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_ENUM_DEFINITION_SECTION;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_STRUCTURE_DEFINITION_SECTION;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_LOCAL_SECTION;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_MACRO_DEFINITION_SECTION;
+ public static String PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_PROCEDURE_DEFINITION_SECTION;
+
+ public static String PREFERENCES_FOREGROUND_COLOR_LABEL;
+ public static String PREFERENCES_BOLD_LABEL;
+ public static String PREFERENCES_ITALIC_LABEL;
+
+ /**
+ * Preferences: editor content assist and parsing.
+ */
+ public static String PREFERENCES_EDITOR_GROUP_TITLE;
+
+ public static String PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_LABEL;
+ public static String PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_UPPER_CASE_TEXT;
+ public static String PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_LOWER_CASE_TEXT;
+
+ public static String PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_LABEL;
+ public static String PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_FIRST_ERROR_OR_WARNING_TEXT;
+ public static String PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_FIRST_ERROR_TEXT;
+
+ /**
+ * Preferences: compiler and runner
+ */
+ public static String PREFERENCES_DOWNLOAD_LINK;
+ public static String PREFERENCES_DOWNLOAD_LINK_TOOL_TIP;
+
+ /**
+ * Preferences: compiler.
+ */
+ public static String PREFERENCES_COMPILER_CPU_LABEL;
+
+ public static String PREFERENCES_COMPILER_EXECUTABLE_PATH_LABEL;
+ public static String PREFERENCES_COMPILER_HARDWARE_ACTIVE_LABEL;
+ public static String PREFERENCES_COMPILER_DEFAULT_PARAMETERS_LABEL;
+ public static String PREFERENCES_COMPILER_PARAMETERS_LABEL;
+ public static String PREFERENCES_COMPILER_PARAMETERS_HELP;
+ public static String PREFERENCES_COMPILER_PARAMETERS_VARIABLES;
+
+ public static String PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_LABEL;
+ public static String PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_SOURCE_FOLDER_TEXT;
+ public static String PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_TEMP_FOLDER_TEXT;
+ public static String PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_FIXED_FOLDER_TEXT;
+ public static String PREFERENCES_COMPILER_OUTPUT_FOLDER_PATH_LABEL;
+ public static String PREFERENCES_COMPILER_OUTPUT_FILE_EXTENSION_LABEL;
+
+ public static String PREFERENCES_COMPILER_RUNNER_ID_LABEL;
+ public static String PREFERENCES_COMPILER_RUNNER_EXECUTABLE_PATH_LABEL;
+ public static String PREFERENCES_COMPILER_RUNNER_DEFAULT_COMMAND_LINE_LABEL;
+ public static String PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_LABEL;
+ public static String PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_HELP;
+ public static String PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_VARIABLES;
+ public static String PREFERENCES_COMPILER_RUNNER_WAIT_FOR_COMPLETION_LABEL;
+
+ /**
+ * Help table of contents
+ */
+ public static String TOC_WUDSN_IDE_LABEL;
+
+ public static String TOC_IDE_TOPIC_LABEL;
+
+ public static String TOC_ASSEMBLERS_TOPIC_LABEL;
+ public static String TOC_ASSEMBLER_GENERAL_TOPIC_LABEL;
+ public static String TOC_ASSEMBLER_NAME_LABEL;
+ public static String TOC_ASSEMBLER_HOME_PAGE_LABEL;
+ public static String TOC_ASSEMBLER_DEFAULT_HARDWARE_LABEL;
+ public static String TOC_ASSEMBLER_SUPPORTED_CPUS_LABEL;
+ public static String TOC_ASSEMBLER_DEFAULT_PARAMETERS_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTIONS_TOPIC_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_TYPE_DIRECTIVES_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_TYPE_LEGAL_OPCODES_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_TYPE_PSEUDO_OPCODES_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_TYPE_ILLEGAL_OPCODES_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_TYPE_W65816_OPCODES_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_TYPE_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_NAME_LABEL;
+ public static String TOC_ASSEMBLER_INSTRUCTION_DESCRIPTION_LABEL;
+ public static String TOC_ASSEMBLER_MANUAL_TOPIC_LABEL;
+
+ public static String TOC_HARDWARES_TOPIC_LABEL;
+ public static String TOC_HARDWARE_NAME_LABEL;
+ public static String TOC_HARDWARE_ID_LABEL;
+ public static String TOC_HARDWARE_ICON_LABEL;
+ public static String TOC_HARDWARE_DEFAULT_FILE_EXTENSION_LABEL;
+ public static String TOC_HARDWARE_EMULATOR_LABEL;
+ public static String TOC_HARDWARE_HOME_PAGE_LABEL;
+ public static String TOC_HARDWARE_DEFAULT_PARAMETERS_LABEL;
+
+ public static String TOC_CPUS_TOPIC_LABEL;
+ public static String TOC_CPU_NAME_LABEL;
+ public static String TOC_CPU_OPCODE_LABEL;
+
+ /**
+ * Messages for the Assembler plugin.
+ */
+ public static String MESSAGE_E100;
+ public static String MESSAGE_E101;
+ public static String MESSAGE_E102;
+ public static String MESSAGE_E103;
+ public static String MESSAGE_E104;
+ public static String MESSAGE_E105;
+ public static String MESSAGE_E106;
+ public static String MESSAGE_E107;
+ public static String MESSAGE_E108;
+ public static String MESSAGE_I109;
+ public static String MESSAGE_I110;
+ public static String MESSAGE_E111;
+ public static String MESSAGE_E112;
+ public static String MESSAGE_E113;
+ public static String MESSAGE_E114;
+ public static String MESSAGE_E115;
+ public static String MESSAGE_E116;
+ public static String MESSAGE_E117;
+ public static String MESSAGE_I118;
+ public static String MESSAGE_E119;
+ public static String MESSAGE_W120;
+ public static String MESSAGE_I121;
+ public static String MESSAGE_E122;
+ public static String MESSAGE_E123;
+ public static String MESSAGE_E124;
+ public static String MESSAGE_E125;
+ public static String MESSAGE_E126;
+ public static String MESSAGE_E127;
+ public static String MESSAGE_E128;
+ public static String MESSAGE_E129;
+ public static String MESSAGE_E130;
+ public static String MESSAGE_E131;
+ public static String MESSAGE_E132;
+ public static String MESSAGE_E133;
+ public static String MESSAGE_E134;
+ public static String MESSAGE_E135;
+ public static String MESSAGE_E136;
+ public static String MESSAGE_E137;
+ public static String MESSAGE_E138;
+ public static String MESSAGE_E139;
+ public static String MESSAGE_E140;
+ public static String MESSAGE_E141;
+ public static String MESSAGE_E142;
+ public static String MESSAGE_S143;
+ /**
+ * Initializes the constants.
+ */
+ static {
+ NLS.initializeMessages(Texts.class.getName(), Texts.class);
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts.properties b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts.properties
new file mode 100644
index 00000000..6dd13a77
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts.properties
@@ -0,0 +1,206 @@
+COMPILER_CONSOLE_TITLE=Compiler Console
+
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFAULT=Default
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFINITION_SECTION=Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_IMPLEMENTATION_SECTION=Implementation Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_EQUATE_DEFINITION=Equate Definition
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LABEL_DEFINITION=Label Definition
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_ENUM_DEFINITION_SECTION=Enum Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_STRUCTURE_DEFINITION_SECTION=Structure Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LOCAL_SECTION=Local Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_MACRO_DEFINITION_SECTION=Macro Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PAGES_SECTION=Pages Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PROCEDURE_DEFINITION_SECTION=Procedure Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_REPEAT_SECTION=Repeat Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_SOURCE_INCLUDE=Source Include
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_INCLUDE=Binary Include
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_OUTPUT=Binary Output
+
+COMPILER_SYNTAX_INSTRUCTION_DIRECTIVE=Directive
+COMPILER_SYNTAX_LEGAL_OPCODE=Legal Opcode
+COMPILER_SYNTAX_ILLEGAL_OPCODE=Illegal Opcode
+COMPILER_SYNTAX_PSEUDO_OPCODE=Pseudo Opcode
+COMPILER_SYNTAX_W65816_ONLY=W65816 only
+
+ASSEMBLER_TOOLBAR_RUN_WITH_DEFAULT_LABEL=(default)
+
+ASSEMBLER_CONTENT_OUTLINE_SORT_BUTTON_TOOL_TIP=Sort
+ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_DEFAULT=Default
+ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_DEFINITION_SECTION=Definition Section
+ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_IMPLEMENTATION_SECTION=Implementation Section
+
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_SOURCE_WITH_ASSEMBLER_EDITOR=Open with Assembler Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_HEX_EDITOR=Open with Hex Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_GRAPHICS_EDITOR=Open with Graphics Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_DEFAULT_EDITOR=Open with Default Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_SYSTEM_EDITOR=Open with System Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_IDENTIFIER={0} {1} in line {2}
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_IDENTIFIER_IN_INCLUDE={0} {1} in line {2} of {3}
+ASSEMBLER_HYPERLINK_FILE_NOT_EXISTS=Target file '{0}' not exists. Do you want to create the file now?
+
+ASSEMBLER_BREAKPOINT_MARKER_MESSAGE={0} [line: {1}] - {2}
+ASSEMBLER_BREAKPOINT_TOGGLE_TYPE_MENU_TEXT=Assembler Breakpoints
+
+COMPILER_SYMBOLS_VIEW_FILTER_TOOLTIP=Type one or more substrings separated by spaces to filter the result list
+COMPILER_SYMBOLS_VIEW_SOURCE_LABEL=Source:
+COMPILER_SYMBOLS_VIEW_SOURCE_NONE=None
+COMPILER_SYMBOLS_VIEW_SOURCE_TOTAL_COUNT={0} symbols
+COMPILER_SYMBOLS_VIEW_SOURCE_FILTERED_COUNT={0} of {1} symbols
+COMPILER_SYMBOLS_VIEW_SOURCE_NONE=Symbols
+COMPILER_SYMBOLS_VIEW_TYPE_COLUMN_LABEL=Type
+COMPILER_SYMBOLS_VIEW_BANK_COLUMN_LABEL=Bank
+COMPILER_SYMBOLS_VIEW_NAME_COLUMN_LABEL=Name
+COMPILER_SYMBOLS_VIEW_HEX_VALUE_COLUMN_LABEL=Hex Value
+COMPILER_SYMBOLS_VIEW_DECIMAL_VALUE_COLUMN_LABEL=Decimal Value
+COMPILER_SYMBOLS_VIEW_STRING_VALUE_COLUMN_LABEL=String Value
+
+PREFERENCES_SYNTAX_HIGHLIGHTING_GROUP_TITLE=Syntax Highlighting
+
+PREFERENCES_TEXT_ATTRIBUTE_COMMENT_NAME=Comments
+PREFERENCES_TEXT_ATTRIBUTE_STRING_NAME=Strings
+PREFERENCES_TEXT_ATTRIBUTE_NUMBER_NAME=Numbers
+PREFERENCES_TEXT_ATTRIBUTE_DIRECTIVE=Directives
+PREFERENCES_TEXT_ATTRIBUTE_OPCODE_LEGAL_NAME=Opcodes
+PREFERENCES_TEXT_ATTRIBUTE_OPCODE_ILLEGAL_NAME=Illegal Opcodes
+PREFERENCES_TEXT_ATTRIBUTE_OPCODE_PSEUDO_NAME=Pseudo Opcodes
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_EQUATE=Identifiers of Equates
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_LABEL=Identifiers of Labels
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_ENUM_DEFINITION_SECTION=Identifiers of Enums
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_STRUCTURE_DEFINITION_SECTION=Identifiers of Structures
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_LOCAL_SECTION=Identifiers of Local Sections
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_MACRO_DEFINITION_SECTION=Identifiers of Macros
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_PROCEDURE_DEFINITION_SECTION=Identifiers of Procedures
+
+PREFERENCES_EDITOR_GROUP_TITLE=Editor
+
+PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_LABEL=Default Case for Content Assist
+PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_LOWER_CASE_TEXT=Lower Case Instructions
+PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_UPPER_CASE_TEXT=Upper Case Instructions
+
+PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_LABEL=Position after compiling
+PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_FIRST_ERROR_OR_WARNING_TEXT=To first error or warning
+PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_FIRST_ERROR_TEXT=To first error
+
+
+PREFERENCES_FOREGROUND_COLOR_LABEL=&Color:
+PREFERENCES_BOLD_LABEL=&Bold
+PREFERENCES_ITALIC_LABEL=&Italic
+
+PREFERENCES_DOWNLOAD_LINK=Download
+PREFERENCES_DOWNLOAD_LINK_TOOL_TIP=Open download page {0}
+
+PREFERENCES_COMPILER_CPU_LABEL=CP&U
+PREFERENCES_COMPILER_EXECUTABLE_PATH_LABEL=Path to &Compiler
+PREFERENCES_COMPILER_HARDWARE_ACTIVE_LABEL=Use for {0}
+PREFERENCES_COMPILER_DEFAULT_PARAMETERS_LABEL=&Default Parameters
+PREFERENCES_COMPILER_PARAMETERS_LABEL=&Parameters
+PREFERENCES_COMPILER_PARAMETERS_HELP=Available variables are:
+PREFERENCES_COMPILER_PARAMETERS_VARIABLES=${sourceFolderPath} The absolute path to the source folder\n${sourceFilePath} The absolute path to the source file\n${outputFolderPath} The absolute path to the output folder\n${outputFilePath} The absolute path to the output file\n${outputFilePathWithoutExtension} The absolute path to the output file without extension\n${outputFileName} The name of the output file including its extension\n${outputFileNameWithoutExtension} The name of the output file without extension\n${outputFileNameShortWithoutExtension} The name of the output file without extension shortened to 8 alphanumeric characters
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_LABEL=&Output Folder
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_SOURCE_FOLDER_TEXT=&Source Folder
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_TEMP_FOLDER_TEXT=&Temporary Folder
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_FIXED_FOLDER_TEXT=&Fixed Folder
+PREFERENCES_COMPILER_OUTPUT_FOLDER_PATH_LABEL=&Output Folder
+PREFERENCES_COMPILER_OUTPUT_FILE_EXTENSION_LABEL=Output File E&xtension
+PREFERENCES_COMPILER_RUNNER_ID_LABEL=Default &Application to open Output File
+PREFERENCES_COMPILER_RUNNER_EXECUTABLE_PATH_LABEL=Path to A&pplication
+PREFERENCES_COMPILER_RUNNER_DEFAULT_COMMAND_LINE_LABEL=&Default Command Line
+PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_LABEL=Command &Line
+PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_HELP=Available variables are:
+PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_VARIABLES=${runnerExecutablePath} The absolute path to the application\n${sourceFolderPath} The absolute path to the source folder\n${sourceFilePath} The absolute path to the source file\n${outputFolderPath} The absolute path to the output folder\n${outputFilePath} The absolute path to the output file\n${outputFilePathWithoutExtension} The absolute path to the output file without extension\n${outputFileName} The name of the output file including its extension\n${outputFileNameWithoutExtension} The name of the output file without extension\n${outputFileNameShortWithoutExtension} The name of the output file without extension shortened to 8 alphanumeric characters
+PREFERENCES_COMPILER_RUNNER_WAIT_FOR_COMPLETION_LABEL=Wait for end of application
+
+TOC_WUDSN_IDE_LABEL=WUDSN IDE Guide
+
+TOC_IDE_TOPIC_LABEL=WUDSN IDE
+
+TOC_ASSEMBLERS_TOPIC_LABEL=Assemblers
+TOC_ASSEMBLER_GENERAL_TOPIC_LABEL=General
+TOC_ASSEMBLER_NAME_LABEL=Name
+TOC_ASSEMBLER_HOME_PAGE_LABEL=Home Page
+TOC_ASSEMBLER_DEFAULT_HARDWARE_LABEL=Default Hardware
+TOC_ASSEMBLER_SUPPORTED_CPUS_LABEL=Supported CPUs
+TOC_ASSEMBLER_DEFAULT_PARAMETERS_LABEL=Default Parameters
+TOC_ASSEMBLER_INSTRUCTIONS_TOPIC_LABEL=Instructions
+TOC_ASSEMBLER_INSTRUCTION_TYPE_DIRECTIVES_LABEL=Directives
+TOC_ASSEMBLER_INSTRUCTION_TYPE_LEGAL_OPCODES_LABEL=Legal Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_PSEUDO_OPCODES_LABEL=Pseudo Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_ILLEGAL_OPCODES_LABEL=Illegal Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_W65816_OPCODES_LABEL=W65816 Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_LABEL=Type
+TOC_ASSEMBLER_INSTRUCTION_NAME_LABEL=Name
+TOC_ASSEMBLER_INSTRUCTION_DESCRIPTION_LABEL=Description
+TOC_ASSEMBLER_SYNTAX_YES=Yes
+TOC_ASSEMBLER_SYNTAX_NO=No
+TOC_ASSEMBLER_SYNTAX_BLOCK_DEFINITION_CHARACTERS=Block Definition Characters
+TOC_ASSEMBLER_SYNTAX_COMPLETION_PROPOSAL_AUTO_ACTIVATION_CHARACTERS=Completion Proposal Characters
+TOC_ASSEMBLER_SYNTAX_IDENTIFIER_PART_CHARACTERS=Identifier Part Characters
+TOC_ASSEMBLER_SYNTAX_IDENTIFIER_SEPARATOR_CHARACTER=Identifier Separator Character
+TOC_ASSEMBLER_SYNTAX_IDENTIFIER_START_CHARACTERS=Identifier Start Characters
+TOC_ASSEMBLER_SYNTAX_IDENTIFIERS_CASE_SENSITIVE=Identifiers Case Sensitive
+TOC_ASSEMBLER_SYNTAX_INSTRUCTIONS_CASE_SENSITIVE=Instructions Case Sensitive
+TOC_ASSEMBLER_SYNTAX_LABEL_DEFINITION_SUFFIX_CHARACTER=Label Definition Suffix Character
+TOC_ASSEMBLER_SYNTAX_MACRO_USAGE_PREFIX_CHARACTER=Macro Usage Prefix Character
+TOC_ASSEMBLER_SYNTAX_MULTIPLE_LINES_COMMENT_DELIMITERS=Multiple Lines Comment Delimiters
+TOC_ASSEMBLER_SYNTAX_SINGLE_LINE_COMMENT_DELIMITERS=Single Line Comment Delimiters
+TOC_ASSEMBLER_SYNTAX_SOURCE_INCLUDE_DEFAULT_EXTENSION=Source Include Default Extension
+TOC_ASSEMBLER_SYNTAX_STRING_DELIMITERS=String Delimiters
+TOC_ASSEMBLER_MANUAL_TOPIC_LABEL=Manual
+
+TOC_HARDWARES_TOPIC_LABEL=Hardwares
+TOC_HARDWARE_NAME_LABEL=Hardware
+TOC_HARDWARE_ID_LABEL=Identifier
+TOC_HARDWARE_ICON_LABEL=Icon
+TOC_HARDWARE_DEFAULT_FILE_EXTENSION_LABEL=Default File Extension
+TOC_HARDWARE_EMULATOR_LABEL=Emulator
+TOC_HARDWARE_HOME_PAGE_LABEL=Home Page
+TOC_HARDWARE_DEFAULT_PARAMETERS_LABEL=Default Parameters
+
+TOC_CPUS_TOPIC_LABEL=CPUs
+TOC_CPU_NAME_LABEL=CPU
+TOC_CPU_OPCODE_LABEL=Opcode
+
+MESSAGE_E100=Path to '{0}' compiler executable is not set in the 'Assembler' preferences.
+MESSAGE_E101=The compiler '{0}' does not specify default parameters.
+MESSAGE_E102=The compiler '{0}' does not specify a help file path.
+MESSAGE_E103=Path to '{0}' compiler executable in the preferences points to non-existing file '{1}'.
+MESSAGE_E104=Output file extension must be set in the preferences of compiler '{0}' or via the annotation '{1}'.
+MESSAGE_E105=Cannot execute compiler process '{0}' in working directory '{1}'. System error: {2}
+MESSAGE_E106=Output file '{0}' cannot be opened for writing. End all applications which may keep the file open.
+MESSAGE_E107=Output file not created. Check the error messages and the console log.
+MESSAGE_E108=Output file not updated. Check the error messages and the console log.
+MESSAGE_I109=Output file '{0}' created or updated with {1} (${2}) bytes.
+MESSAGE_I110=Symbols file '{0}' created with {1} symbols.
+MESSAGE_E111=Cannot open symbols file '{0}' for output. System error: {1}
+MESSAGE_E112=Path to application executable is not set in the preferences of application '{0}'.
+MESSAGE_E113=Cannot execute application '{0}' process '{1}' in working directory '{2}'. System error: {3}
+MESSAGE_E114=Path to '{0}' application executable in the preferences points to non-existing file '{1}'.
+MESSAGE_E115=Cannot open output file '{0}' with the standard application since no application is registered for the file extension '{1}'.
+MESSAGE_E116=Definition for application '{0}' from the preferences of hardware '{1}' is not registered.
+MESSAGE_E117=Cannot delete empty symbols file '{0}'.
+MESSAGE_I118=Opening output file '{0}' with application '{1}'.
+MESSAGE_E119=Cannot open output file '{0}' with application '{1}'.
+MESSAGE_W120=Breakpoints will be ignored because the application '{0}' does not support passing source level breakpoints.
+MESSAGE_I121=Breakpoints file '{0}' created with {1} active breakpoints.
+MESSAGE_E122=Cannot open breakpoints file '{0}' for output. System error: {1}
+MESSAGE_E123=Cannot delete empty breakpoints file '{0}'.
+MESSAGE_E124=Unknown hardware '{0}'. Specify one of the following valid values '{1}'.
+MESSAGE_E125=Main source file '{0}' does not exist.
+MESSAGE_E126=Output file created but empty. Check the error messages and the console log.
+MESSAGE_E127=Compiler process ended with return code {0}. Check the error messages and the console log.
+MESSAGE_E128=Hardware not specified. Specify one of the following valid values '{0}'.
+MESSAGE_E129=Main source file specifies or defaults to hardware '{0}' while include file specifies or defaults to hardware '{1}'.
+MESSAGE_E130=Help for the '{0}' compiler cannot be displayed because the path to the compiler executable is not set in the preferences.
+MESSAGE_E131=Help for the '{0}' compiler cannot be displayed because no help file was found in the paths '{1}' relative to the compiler executable path '{0}'.
+MESSAGE_E132=Disk image file '{0}' does not exist. Create a bootable disk image where the output file '{1}' can be stored.
+MESSAGE_E133=Disk image file '{0}' is not writeable. Make the disk image file is writeable, so the output file '{1}' can be stored.
+MESSAGE_E134=Disk image file '{0}' cannot be opened for reading. System error: {1}
+MESSAGE_E135=Disk image file '{0}' does not contain a valid file system. Make sure the disk image is properly formatted, so the output file '{1}' can be stored.
+MESSAGE_E136=Disk image file '{0}' is full. System error: {1}
+MESSAGE_E137=Disk image file '{0}' cannot be opened for writing. System error: {1}
+MESSAGE_E138=Output file {0} has an unsupported file extension or invalid content. Supported file extensions are ".b" (Apple II binary file with format [start, length, code]), ".prg" (C64 program file with format [start, code]) and ".xex" (Atari compound file with format [$ffff, start,end,code]).
+MESSAGE_E139=Output file extension '{0}' must start with ".".
+MESSAGE_E140=Output folder mode be set in the preferences of compiler '{0}' or via the annotation '{1}'.
+MESSAGE_E141=Unknown output folder mode '{0}'. Specify one of the following valid values '{1}'.
+MESSAGE_E142=Include statement for file '{0}' uses a file name that has a different case different from real file system name '{1}'. Correct the file name in the include statement.
+MESSAGE_S143=In include file '{0}', line {1}.
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts_de_DE.properties b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts_de_DE.properties
new file mode 100644
index 00000000..ad857909
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/Texts_de_DE.properties
@@ -0,0 +1,204 @@
+COMPILER_CONSOLE_TITLE=Kompiler Konsole
+
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFAULT=Default
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFINITION_SECTION=Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_IMPLEMENTATION_SECTION=Implementation Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_EQUATE_DEFINITION=Equate Definition
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LABEL_DEFINITION=Label Definition
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_ENUM_DEFINITION_SECTION=Enum Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_STRUCTURE_DEFINITION_SECTION=Structure Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LOCAL_SECTION=Local Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_MACRO_DEFINITION_SECTION=Macro Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PAGES_SECTION=Pages Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PROCEDURE_DEFINITION_SECTION=Procedure Definition Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_REPEAT_SECTION=Repeat Section
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_SOURCE_INCLUDE=Source Include
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_INCLUDE=Binary Include
+COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_OUTPUT=Binary Output
+
+COMPILER_SYNTAX_INSTRUCTION_DIRECTIVE=Direktive
+COMPILER_SYNTAX_LEGAL_OPCODE=Legaler Opcode
+COMPILER_SYNTAX_ILLEGAL_OPCODE=Illegaler Opcode
+COMPILER_SYNTAX_PSEUDO_OPCODE=Pseudo Opcode
+COMPILER_SYNTAX_W65816_ONLY=nur W65816
+
+ASSEMBLER_TOOLBAR_RUN_WITH_DEFAULT_LABEL=(Standard)
+
+ASSEMBLER_CONTENT_OUTLINE_SORT_BUTTON_TOOL_TIP=Sortieren
+ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_DEFAULT=Standard
+ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_DEFINITION_SECTION=Definitionsabschnitt
+ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_IMPLEMENTATION_SECTION=Implementierungsabschnitt
+
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_SOURCE_WITH_ASSEMBLER_EDITOR=Öffnen mit Assembler Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_HEX_EDITOR=Öffnen mit Hex Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_GRAPHICS_EDITOR=Öffnen mit Grafik Editor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_DEFAULT_EDITOR=Öffnen mit Standardeditor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_BINARY_WITH_SYSTEM_EDITOR=Öffnen mit Systemeditor
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_IDENTIFIER={0} {1} in Zeile {2}
+ASSEMBLER_HYPERLINK_DETECTOR_OPEN_IDENTIFIER_IN_INCLUDE={0} {1} in Zeile {2} von {3}
+ASSEMBLER_HYPERLINK_FILE_NOT_EXISTS=Ziel-Datei '{0}' existiert nicht. Möchten Sie die Ziel-Datei nun anlegen?
+
+ASSEMBLER_BREAKPOINT_MARKER_MESSAGE={0} [Zeile: {1}] - {2}
+ASSEMBLER_BREAKPOINT_TOGGLE_TYPE_MENU_TEXT=Assembler Breakpoints
+
+COMPILER_SYMBOLS_VIEW_FILTER_TOOLTIP=Geben sie eine oder mehrere Teilzeichenfolgen durch Leerzeichen getrennt an
+COMPILER_SYMBOLS_VIEW_SOURCE_LABEL=Quelle:
+COMPILER_SYMBOLS_VIEW_SOURCE_NONE=Keine
+COMPILER_SYMBOLS_VIEW_SOURCE_TOTAL_COUNT={0} Symbole
+COMPILER_SYMBOLS_VIEW_SOURCE_FILTERED_COUNT={0} von {1} Symbolen
+COMPILER_SYMBOLS_VIEW_TYPE_COLUMN_LABEL=Typ
+COMPILER_SYMBOLS_VIEW_BANK_COLUMN_LABEL=Bank
+COMPILER_SYMBOLS_VIEW_NAME_COLUMN_LABEL=Name
+COMPILER_SYMBOLS_VIEW_HEX_VALUE_COLUMN_LABEL=Hexadezimalwert
+COMPILER_SYMBOLS_VIEW_DECIMAL_VALUE_COLUMN_LABEL=Dezimalwert
+COMPILER_SYMBOLS_VIEW_STRING_VALUE_COLUMN_LABEL=Textwert
+
+PREFERENCES_SYNTAX_HIGHLIGHTING_GROUP_TITLE=Syntax Hervorhebung
+
+PREFERENCES_TEXT_ATTRIBUTE_COMMENT_NAME=Kommentare
+PREFERENCES_TEXT_ATTRIBUTE_STRING_NAME=Textkonstanten
+PREFERENCES_TEXT_ATTRIBUTE_NUMBER_NAME=Zahlen
+PREFERENCES_TEXT_ATTRIBUTE_DIRECTIVE=Direktive
+PREFERENCES_TEXT_ATTRIBUTE_OPCODE_LEGAL_NAME=Opcodes
+PREFERENCES_TEXT_ATTRIBUTE_OPCODE_ILLEGAL_NAME=Illegale Opcodes
+PREFERENCES_TEXT_ATTRIBUTE_OPCODE_PSEUDO_NAME=Pseudo Opcodes
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_EQUATE=Namen von Equates
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_LABEL=Namen von Labels
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_ENUM_DEFINITION_SECTION=Namen von Enums
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_STRUCTURE_DEFINITION_SECTION=Namen von von Strukturen
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_LOCAL_SECTION=Namen von Lokalen Bereichen
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_MACRO_DEFINITION_SECTION=Namen von Macros
+PREFERENCES_TEXT_ATTRIBUTE_IDENTIFIER_PROCEDURE_DEFINITION_SECTION=Namen von Prozeduren
+
+PREFERENCES_EDITOR_GROUP_TITLE=Editor
+
+PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_LABEL=Standard Schreibweise für Befehlsvorschläge
+PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_LOWER_CASE_TEXT=Kleingeschriebene Befehle
+PREFERENCES_CONTENT_ASSIST_PROCESSOR_DEFAULT_CASE_UPPER_CASE_TEXT=Großgeschriebene Befehle
+
+PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_LABEL=Positionieren nach Kompilieren
+PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_FIRST_ERROR_OR_WARNING_TEXT=Auf ersten Fehler oder erste Warnung
+PREFERENCES_COMPILE_COMMAND_POSITIONING_MODE_FIRST_ERROR_TEXT=Auf ersten Fehler
+
+PREFERENCES_FOREGROUND_COLOR_LABEL=&Farbe:
+PREFERENCES_BOLD_LABEL=F&ett
+PREFERENCES_ITALIC_LABEL=&Kursiv
+
+PREFERENCES_DOWNLOAD_LINK=Download
+PREFERENCES_DOWNLOAD_LINK_TOOL_TIP=Webseite {0} für Download öffnen
+
+PREFERENCES_COMPILER_CPU_LABEL=CP&U
+PREFERENCES_COMPILER_EXECUTABLE_PATH_LABEL=Pfad zum &Kompiler
+PREFERENCES_COMPILER_HARDWARE_ACTIVE_LABEL=Verwenden für {0}
+PREFERENCES_COMPILER_DEFAULT_PARAMETERS_LABEL=&Standardparameter
+PREFERENCES_COMPILER_PARAMETERS_LABEL=&Parameter
+PREFERENCES_COMPILER_PARAMETERS_HELP=Verfügbare Variablen sind:
+PREFERENCES_COMPILER_PARAMETERS_VARIABLES=${sourceFolderPath} Absoluter Pfad zum Quell-Ordner\n${sourceFilePath} Absoluter Pfad zur Quell-Datei\n${outputFolderPath} Absoluter Pfad zum Ausgabe-Ordner\n${outputFilePath} Absoluter Pfad der Ausgabe-Datei\n${outputFilePathWithoutExtension} Absoluter Pfad der Ausgabe-Datei ohne ihre Dateierweiterung\n${outputFileName} Name der Ausgabe-Datei inklusive ihrer Dateierweiterung\n${outputFileNameWithoutExtension} Name der Ausgabe-Datei ohne ihre Dateierweiterung\n${outputFileNameShortWithoutExtension} Name der Ausgabe-Datei ohne ihre Dateierweiterung, gekürzt auf 8 alpha-numerische Zeichen
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_LABEL=&Ausgabe-Ordner
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_SOURCE_FOLDER_TEXT=&Quell-Ordner
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_TEMP_FOLDER_TEXT=&Temporärer Ordner
+PREFERENCES_COMPILER_OUTPUT_FOLDER_MODE_FIXED_FOLDER_TEXT=&Fester Ordner
+PREFERENCES_COMPILER_OUTPUT_FOLDER_PATH_LABEL=Ausgabe-O&rdner
+PREFERENCES_COMPILER_OUTPUT_FILE_EXTENSION_LABEL=Ausgabe-&Dateierweiterung
+PREFERENCES_COMPILER_RUNNER_ID_LABEL=Standardan&wendung zum Öffnen der Ausgabe-Datei
+PREFERENCES_COMPILER_RUNNER_EXECUTABLE_PATH_LABEL=P&fad zur Anwendung
+PREFERENCES_COMPILER_RUNNER_DEFAULT_COMMAND_LINE_LABEL=S&tandard-Kommandozeile
+PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_LABEL=Kommando&zeile
+PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_HELP=Verfügbare Variablen sind:
+PREFERENCES_COMPILER_RUNNER_COMMAND_LINE_VARIABLES=${runnerExecutablePath} Absoluter Pfad zur Anwendung\n${sourceFolderPath} Absoluter Pfad zum Quell-Ordner\n${sourceFilePath} Absoluter Pfad zur Quell-Datei\n${outputFolderPath} Absoluter Pfad zum Ausgabe-Ordner\n${outputFilePath} Absoluter Pfad der Ausgabe-Datei\n${outputFilePathWithoutExtension} Absoluter Pfad der Ausgabe-Datei ohne ihre Dateierweiterung\n${outputFileName} Name der Ausgabe-Datei inklusive ihrer Dateierweiterung\n${outputFileNameWithoutExtension} Name der Ausgabe-Datei ohne ihre Dateierweiterung\n${outputFileNameShortWithoutExtension} Name der Ausgabe-Datei ohne ihre Dateierweiterung, gekürzt auf 8 alpha-numerische Zeichen
+PREFERENCES_COMPILER_RUNNER_WAIT_FOR_COMPLETION_LABEL=Auf Ende der Anwendung warten
+
+TOC_WUDSN_IDE_LABEL=WUDSN IDE Handbuch
+
+TOC_IDE_TOPIC_LABEL=WUDSN IDE
+
+TOC_ASSEMBLERS_TOPIC_LABEL=Assembler
+TOC_ASSEMBLER_GENERAL_TOPIC_LABEL=Allgemein
+TOC_ASSEMBLER_NAME_LABEL=Name
+TOC_ASSEMBLER_HOME_PAGE_LABEL=Home Page
+TOC_ASSEMBLER_DEFAULT_HARDWARE_LABEL=Standardhardware
+TOC_ASSEMBLER_SUPPORTED_CPUS_LABEL=Unterstütze CPUs
+TOC_ASSEMBLER_DEFAULT_PARAMETERS_LABEL=Standardparameter
+TOC_ASSEMBLER_INSTRUCTIONS_TOPIC_LABEL=Befehle
+TOC_ASSEMBLER_INSTRUCTION_TYPE_DIRECTIVES_LABEL=Direktiven
+TOC_ASSEMBLER_INSTRUCTION_TYPE_LEGAL_OPCODES_LABEL=Legale Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_PSEUDO_OPCODES_LABEL=Pseudo Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_ILLEGAL_OPCODES_LABEL=Illegale Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_W65816_OPCODES_LABEL=W65816 Opcodes
+TOC_ASSEMBLER_INSTRUCTION_TYPE_LABEL=Typ
+TOC_ASSEMBLER_INSTRUCTION_NAME_LABEL=Name
+TOC_ASSEMBLER_INSTRUCTION_DESCRIPTION_LABEL=Beschreibung
+TOC_ASSEMBLER_SYNTAX_YES=Ja
+TOC_ASSEMBLER_SYNTAX_NO=Nein
+TOC_ASSEMBLER_SYNTAX_BLOCK_DEFINITION_CHARACTERS=Zeichen für Block Definitionen
+TOC_ASSEMBLER_SYNTAX_COMPLETION_PROPOSAL_AUTO_ACTIVATION_CHARACTERS=Zeichen für Vervollständigungsvorschlag
+TOC_ASSEMBLER_SYNTAX_IDENTIFIER_PART_CHARACTERS=Zeichen für Namen
+TOC_ASSEMBLER_SYNTAX_IDENTIFIER_SEPARATOR_CHARACTER=Trennzeichen für Namen
+TOC_ASSEMBLER_SYNTAX_IDENTIFIER_START_CHARACTERS=Anfangszeichen für Namen
+TOC_ASSEMBLER_SYNTAX_IDENTIFIERS_CASE_SENSITIVE=Namen unterscheiden Groß-/Kleinschreibung
+TOC_ASSEMBLER_SYNTAX_INSTRUCTIONS_CASE_SENSITIVE=Instruktionen unterscheiden Groß-/Kleinschreibung
+TOC_ASSEMBLER_SYNTAX_LABEL_DEFINITION_SUFFIX_CHARACTER=Suffixzeichen für Label Definitionen
+TOC_ASSEMBLER_SYNTAX_MACRO_USAGE_PREFIX_CHARACTER=Zeichen für Verwendung von Makros
+TOC_ASSEMBLER_SYNTAX_MULTIPLE_LINES_COMMENT_DELIMITERS=Trennzeichen für mehrzeilige Kommentare
+TOC_ASSEMBLER_SYNTAX_SINGLE_LINE_COMMENT_DELIMITERS=Trennzeichen für einzeilige Kommentare
+TOC_ASSEMBLER_SYNTAX_SOURCE_INCLUDE_DEFAULT_EXTENSION=Standard Datei-Erweiterung für Quell-Dateien
+TOC_ASSEMBLER_SYNTAX_STRING_DELIMITERS=Trennzeichen für Textkonstanten
+TOC_ASSEMBLER_MANUAL_TOPIC_LABEL=Handbuch
+
+TOC_HARDWARES_TOPIC_LABEL=Hardware Platformen
+TOC_HARDWARE_NAME_LABEL=Hardware
+TOC_HARDWARE_ID_LABEL=Identifikation
+TOC_HARDWARE_ICON_LABEL=Ikone
+TOC_HARDWARE_DEFAULT_FILE_EXTENSION_LABEL=Standard-Dateierweiterung
+TOC_HARDWARE_EMULATOR_LABEL=Emulator
+TOC_HARDWARE_HOME_PAGE_LABEL=Home Page
+TOC_HARDWARE_DEFAULT_PARAMETERS_LABEL=Standardparameter
+
+TOC_CPUS_TOPIC_LABEL=CPUs
+TOC_CPU_NAME_LABEL=CPU
+TOC_CPU_OPCODE_LABEL=Opcode
+
+MESSAGE_E100=Pfad zur ausführbaren Datei des Kompilers '{0}' ist in den 'Assembler' Voreinstellungen nicht angegeben.
+MESSAGE_E101=Der Kompiler '{0}' definiert keine Standardparameter.
+MESSAGE_E102=Der Kompiler '{0}' getHelpFile keine Pfade zu Hilfe-Dateien.
+MESSAGE_E103=Pfad zur ausführbaren Datei des Kompilers '{0}' in den Voreinstellungen verweist auf die nicht existierende Datei '{1}'.
+MESSAGE_E104=Ausgabe-Dateierweiterung muss in den Voreinstellungen des Kompilers '{0}' oder mit der Annotation '{1}' angegeben werden.
+MESSAGE_E105=Kompilerprozess '{0}' kann im Arbeitsverzeichnis '{1}' nicht ausgeführt werden. Systemfehler: {2}
+MESSAGE_E106=Ausgabe-Datei '{0}' kann nicht zum Schreiben geöffnet werden. Beenden Sie alle Anwendungen welche die Datei geöffnet haben könnten.
+MESSAGE_E107=Ausgabe-Datei wurde nicht erzeugt. Prüfen Sie die Fehlermeldungen und die Konsolenausgabe.
+MESSAGE_E108=Ausgabe-Datei wurde nicht aktualisiert. Prüfen Sie die Fehlermeldungen und die Konsolenausgabe.
+MESSAGE_I109=Ausgabe-Datei '{0}' mit einer Größe von {1} (${2}) Bytes erzeugt.
+MESSAGE_I110=Symbol-Datei '{0}' mit {1} Symbolen erzeugt.
+MESSAGE_E111=Symbol-Datei '{0}' kann nicht zum Schreiben geöffnet werden. Systemfehler: {1}
+MESSAGE_E112=Pfad zur ausführbaren Datei des Emulators ist in den Voreinstellungen des Emulators '{0}' nicht angegeben.
+MESSAGE_E113=Prozess '{1}' for den Emulator '{0}' kann im Arbeitsverzeichnis '{1}' nicht ausgeführt werden. Systemfehler: {2}
+MESSAGE_E114=Pfad zur ausführbaren Datei des Anwendung '{0}' in der Voreinstellungen verweist auf die nicht existierende Datei '{1}'.
+MESSAGE_E115=Ausgabe-Datei '{0}' kann nicht geöffnet werden, da keine Standardanwendung für die Dateierweiterung '{1}' registiert ist.
+MESSAGE_E116=Definition für die Anwendung '{0}' aus den Voreinstellungen für die Hardware '{1}' ist nicht registriert.
+MESSAGE_E117=Symbol-Datei '{0}' ist leer, aber kann nicht gelöscht werden.
+MESSAGE_I118=Ausgabe-Datei '{0}' wird mit Anwendung '{1}' geöffnet.
+MESSAGE_E119=Ausgabe-Datei '{0}' kann nicht mit Anwendung '{1}' geöffnet werden.
+MESSAGE_W120=Unterbrechungspunkte werden ignoriert, da die Anwendung '{0}' die Übergabe von Quelltext-Unterbrechungspunkte nicht unterstützt.
+MESSAGE_I121=Unterbrechungspunkte-Datei '{0}' mit {1} aktiven Unterbrechungspunkten erzeugt.
+MESSAGE_E122=Unterbrechungspunkte-Datei '{0}' kann nicht zum Schreiben geöffnet werden. Systemfehler: {1}
+MESSAGE_E123=Unterbrechungspunkte-Datei '{0}' ist leer, aber kann nicht gelöscht werden.
+MESSAGE_E124=Unbekannte Hardware '{0}'. Geben Sie einen der folgenden gültigen Werte an '{1}'.
+MESSAGE_E125=Haupt-Quell-Datei '{0}' existiert nicht.
+MESSAGE_E126=Ausgabe-Datei erzeugt is aber leer. Prüfen Sie die Fehlermeldungen und die Konsolenausgabe.
+MESSAGE_E127=Kompilerprozess endete mit dem Rückgabewert {0}. Prüfen Sie die Fehlermeldungen und die Konsolenausgabe.
+MESSAGE_E128=Hardware nicht angegeben. Gültige Werte sind '{0}'.
+MESSAGE_E129=Haupt-Quell-Datei spezifiziert oder verwendet die Hardware '{0}' während die Include-Quell-Datei die Hardware '{1}' spezifiziert oder verwendet.
+MESSAGE_E130=Handbuch zum Kompiler '{0}' kann nicht angezeigt werden, da der Pfad zur ausführbaren Datei des Kompilers in den Voreinstellungen nicht angegeben ist.
+MESSAGE_E131=Handbuch zum Kompiler '{0}' kann nicht angezeigt werden, da keine Hilfe-Datei in den Pfaden '{1}' relativ zur ausführbaren Datei '{2}' des Kompilers gefunden wurde.
+MESSAGE_E132=Disketten-Image-Datei '{0}' existiert nicht. Lege ein bootfähiges Disketten-Image an, auf dem die Ausgabe-Datei '{1}' gespeichert werden kann.
+MESSAGE_E133=Disketten-Image-Datei '{0}' ist nicht schreibbar. Mache das Diskettenimage schreibbbar, damit die Ausgabe-Datei '{1}' gespeichert werden kann.
+MESSAGE_E134=Disketten-Image-Datei '{0}' kann not nicht zum Lesen geöffnet werden. Systemfehler: {1}
+MESSAGE_E135=Disketten-Image-Datei '{0}' enthält kein gültiges Dateisystem. Stelle sicher, dass das Diskettenimage korrekt formatiert ist, damit die Ausgabe-Datei '{1}' gespeichert werden kann.
+MESSAGE_E136=Disketten-Image-Datei '{0}' ist voll. Systemfehler: {1}
+MESSAGE_E137=Disketten-Image-Datei '{0}' kann nicht zum Schreiben geöffnet werden. Systemfehler: {1}
+MESSAGE_E138=Ausgabe-Datei '{0}' has eine nicht unterstütze Dateierweiterunge oder ungültigen Inhalt. Unterstützte Dateierweiterungen sind ".b" (Apple II Binär-Datei im Format [start, length, code]), ".prg" (C64 Programm-Datei im Format [start, code]) und ".xex" (Atari Compound-Datei im Format [$ffff, start,end,code]).
+MESSAGE_E139=Ausgabe-Dateierweiterung '{0}' muss mit "." beginnen.
+MESSAGE_E140=Ausgabe-Ordnermodus muss in den Voreinstellungen des Kompilers '{0}' oder mit der Annotation '{1}' angegeben werden.
+MESSAGE_E141=Unbekannter Ausgabe-Ordnermodus '{0}'. Geben Sie einen der folgenden gültigen Werte an '{1}'.
+MESSAGE_E142=Include Anweisung für die Datei '{0}' verwendet im Dateinamen eine andere Groß-Kleinschreibung als der echte Dateiname {1} auf dem Dateisystem. Korrigieren Sie den Dateinamen in der Include Anweisung.
+MESSAGE_S143=In Include-Datei '{0}', Zeile {1}.
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/Compiler.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/Compiler.java
new file mode 100644
index 00000000..671ef52f
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/Compiler.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+
+/**
+ * Base class for compiler implementations. Sub classes have to be stateless.
+ *
+ * @author Peter Dell
+ */
+public abstract class Compiler {
+
+ // See {@link CompilerId} for predefined ids.
+ private CompilerDefinition definition;
+
+ /**
+ * Creation is protected.
+ */
+ protected Compiler() {
+
+ }
+
+ /**
+ * Sets the definition of the compiler. Called by {@link CompilerRegistry}
+ * only.
+ *
+ * @param definition
+ * The definition if the compiler, not null.
+ */
+ final void setDefinition(CompilerDefinition definition) {
+ if (definition == null) {
+ throw new IllegalArgumentException("Parameter 'type' must not be null.");
+ }
+ this.definition = definition;
+ }
+
+ /**
+ * Gets the definition of the compiler.
+ *
+ * @return The definition of the compiler, not null.
+ */
+ public final CompilerDefinition getDefinition() {
+ if (definition == null) {
+ throw new IllegalStateException("Field 'definition' must not be null.");
+ }
+ return definition;
+ }
+
+ /**
+ * Creates a compiler source parser.
+ *
+ * @return The compiler source parser, not null.
+ */
+ public abstract CompilerSourceParser createSourceParser();
+
+ /**
+ * Checks if the exit code of the compiler process represents success. By
+ * default 0 is interpreted as success, but a compiler may
+ * override this.
+ *
+ * @param exitValue
+ * The exit code of the compiler process.
+ * @return true if the exit code represents success (only
+ * information and warning messages) or a failure (at least one error
+ * message).
+ *
+ * @since 1.7.0
+ */
+ public boolean isSuccessExitValue(int exitValue) {
+ return exitValue == 0;
+ }
+
+ /**
+ * Creates the parser to for the compiler output.
+ *
+ * @return The parser to for the compiler output, not null.
+ */
+ public abstract CompilerProcessLogParser createLogParser();
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/Compiler.xml b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/Compiler.xml
new file mode 100644
index 00000000..9ca3c1ab
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/Compiler.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerConsole.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerConsole.java
new file mode 100644
index 00000000..adcfa0da
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerConsole.java
@@ -0,0 +1,102 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import java.io.PrintStream;
+
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.IConsoleView;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+import com.wudsn.ide.asm.Texts;
+
+/**
+ * The console to show the user the output from the compiler.
+ *
+ * @author Peter Dell
+ * @author Daniel Mitte
+ */
+public final class CompilerConsole {
+
+ private IConsoleManager consoleManager;
+ public MessageConsole console;
+
+ private MessageConsoleStream messageStream;
+ private PrintStream printStream;
+
+ /**
+ * Create a new console-window.
+ *
+ */
+ public CompilerConsole() {
+ consoleManager = ConsolePlugin.getDefault().getConsoleManager();
+ console = new MessageConsole(Texts.COMPILER_CONSOLE_TITLE, null);
+ consoleManager.addConsoles(new IConsole[] { console });
+
+ messageStream = console.newMessageStream();
+ messageStream.setActivateOnWrite(false);
+ messageStream.print("");
+ printStream = new PrintStream(messageStream);
+ }
+
+ /**
+ * Brings this console view instance to front in the console view editor
+ * part.
+ *
+ * @param consoleView
+ * The console view editor part, not null.
+ */
+
+ public void display(IConsoleView consoleView) {
+ if (consoleView == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'consoleView' must not be null.");
+ }
+ consoleView.display(console);
+
+ }
+
+ /**
+ * Add a line to console.
+ *
+ * @param message
+ * The message to print, not null.
+ */
+ public void println(String message) {
+ if (message == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'message' must not be null.");
+ }
+ messageStream.println(message);
+ }
+
+ /**
+ * Gets a print messageStream to write to this console.
+ *
+ * @return The print messageStream, not null.
+ */
+ public PrintStream getPrintStream() {
+ return printStream;
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerDefinition.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerDefinition.java
new file mode 100644
index 00000000..ec6cb7e3
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerDefinition.java
@@ -0,0 +1,436 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import java.io.File;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+import com.wudsn.ide.asm.CPU;
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.Texts;
+import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
+import com.wudsn.ide.base.common.FileUtility;
+import com.wudsn.ide.base.common.StringUtility;
+import com.wudsn.ide.base.common.TextUtility;
+
+/**
+ * Definition of a compiler. The definition contains all static meta information
+ * about the compiler. It is normally defined via an extension. The id of a
+ * compiler must be unique across all compilers.
+ *
+ * @author Peter Dell
+ */
+public final class CompilerDefinition implements Comparable {
+
+ // Id
+ private String id;
+ private String name;
+ private String className;
+
+ // Installation and use.
+ private String helpFilePaths;
+ private String homePageURL;
+
+ // Editing and source parsing.
+ private List supportedCPUs;
+ private CompilerSyntax syntax;
+
+ // Compiling.
+ private String defaultParameters;
+
+ // Assignment to default hardware type.
+ private Hardware defaultHardware;
+
+ /**
+ * Creation is package local. Called by {@link CompilerRegistry} only.
+ */
+ CompilerDefinition() {
+
+ }
+
+ /**
+ * Sets the id of the compiler. Called by {@link CompilerRegistry} only.
+ *
+ * @param id
+ * The id of the compiler, not empty and not null.
+ */
+ final void setId(String id) {
+ if (id == null) {
+ throw new IllegalArgumentException("Parameter 'id' must not be null.");
+ }
+ if (StringUtility.isEmpty(id)) {
+ throw new IllegalArgumentException("Parameter 'id' must not be empty.");
+ }
+ this.id = id;
+ }
+
+ /**
+ * Gets the id of the compiler.
+ *
+ * @return The id of the compiler, not empty and not null.
+ */
+ public final String getId() {
+ if (id == null) {
+ throw new IllegalStateException("Field 'id' must not be null.");
+ }
+ return id;
+ }
+
+ /**
+ * Sets the localized name of the compiler. Called by
+ * {@link CompilerRegistry} only.
+ *
+ * @param name
+ * The localized name of the compiler, not empty and not
+ * null.
+ */
+ final void setName(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Parameter 'name' must not be null.");
+ }
+ if (StringUtility.isEmpty(id)) {
+ throw new IllegalArgumentException("Parameter 'name' must not be empty.");
+ }
+ this.name = name;
+ }
+
+ /**
+ * Gets the localized name of the compiler.
+ *
+ * @return The localized name of the compiler, not empty and not
+ * null.
+ */
+ public final String getName() {
+ if (name == null) {
+ throw new IllegalStateException("Field 'name' must not be null.");
+ }
+ return name;
+ }
+
+ /**
+ * Sets the class name of the compiler. Called by {@link CompilerRegistry}
+ * only.
+ *
+ * @param className
+ * The class name of the compiler, not empty and not
+ * null.
+ */
+ final void setClassName(String className) {
+ if (className == null) {
+ throw new IllegalArgumentException("Parameter 'className' must not be null.");
+ }
+ this.className = className;
+ }
+
+ /**
+ * Gets the class name of the compiler.
+ *
+ * @return The class name of the compiler, not empty and not
+ * null.
+ */
+ public final String getClassName() {
+ if (className == null) {
+ throw new IllegalStateException("Field 'className' must not be null.");
+ }
+ return className;
+ }
+
+ /**
+ * Sets the absolute URL of the home page where the compiler can be
+ * downloaded. Called by {@link CompilerRegistry} only.
+ *
+ * @param homePageURL
+ * The absolute URL of the home page where the compiler can be
+ * downloaded. May be empty or null.
+ */
+ final void setHomePageURL(String homePageURL) {
+ if (homePageURL == null) {
+ homePageURL = "";
+ }
+ this.homePageURL = homePageURL;
+ }
+
+ /**
+ * Gets the absolute URL of the home page where the compiler can be
+ * downloaded.
+ *
+ * @return The absolute URL of the home page where the compiler can be
+ * downloaded. The result may be empty or null.
+ */
+ public final String getHomePageURL() {
+ if (homePageURL == null) {
+ homePageURL = "";
+ }
+ return homePageURL;
+ }
+
+ /**
+ * Sets the help file paths to locate the help file for the compiler. Called
+ * by {@link CompilerRegistry} only.
+ *
+ * @param helpFilePaths
+ * The relative file path to locate the help file for the
+ * compiler based on the folder of the executable. ".", ".." and
+ * "/" may be used to specify the path. A path may end with a
+ * language in the form "(en)". Multiple paths are separated by
+ * ",". May be empty or null.
+ */
+ final void setHelpFilePaths(String helpFilePaths) {
+ if (helpFilePaths == null) {
+ helpFilePaths = "";
+ }
+ this.helpFilePaths = helpFilePaths;
+ }
+
+ /**
+ * Gets the help file paths to locate the help file for the compiler.
+ *
+ * @return The relative file path to locate the help file for the compiler
+ * based on the folder of the executable. ".", ".." and "/" may be
+ * used to specify the path. A path may end with a language in the
+ * form "(en)".Multiple paths are separated by ",". The result may
+ * be empty, not null.
+ */
+ public final String getHelpFilePaths() {
+ if (helpFilePaths == null) {
+ throw new IllegalStateException("Field 'helpFilePaths' must not be null.");
+ }
+ return helpFilePaths;
+ }
+
+ /**
+ * Determines if this compiler offers a help file at all.
+ *
+ * @return true if this compiler offers a help file,
+ * false otherwise.
+ */
+ public final boolean hasHelpFile() {
+ return StringUtility.isSpecified(helpFilePaths);
+ }
+
+ /**
+ * Gets the help file for the compiler. This includes locating the most
+ * appropriate file in the file system based on the current locale.
+ *
+ * @param compilerExecutablePath
+ * the compiler executable path, may be empty, not
+ * null.
+ * @return The help file, or null not help file could be found.
+ *
+ * @throws CoreException
+ * if the compilerExecutablePath is empty, the compiler does not
+ * specify a help path or no help file can be found.
+ */
+ public final File getHelpFile(String compilerExecutablePath) throws CoreException {
+ if (compilerExecutablePath == null) {
+ throw new IllegalArgumentException("Parameter 'compilerExecutablePath' must not be null.");
+ }
+ if (StringUtility.isEmpty(compilerExecutablePath)) {
+ // ERROR: Help for the '{0}' compiler cannot be
+ // displayed because the path to the compiler executable
+ // is not set in the preferences.
+ throw new CoreException(new Status(IStatus.ERROR, AssemblerPlugin.ID, TextUtility.format(
+ Texts.MESSAGE_E130, name)));
+ }
+ if (!hasHelpFile()) {
+ // ERROR: The compiler '{0}' does not specify a help file path.
+ throw new CoreException(new Status(IStatus.ERROR, AssemblerPlugin.ID, TextUtility.format(
+ Texts.MESSAGE_E102, name)));
+ }
+
+ String localeLanguage = Locale.getDefault().getLanguage();
+ File firstFile = null;
+ File firstLanguageFile = null;
+ StringTokenizer tokenizer = new StringTokenizer(helpFilePaths, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String helpFilePath = tokenizer.nextToken().trim();
+ String helpFileLanguage = "";
+ int index = helpFilePath.lastIndexOf("(");
+ if (index > 0) {
+ helpFileLanguage = helpFilePath.substring(index + 1, index + 3);
+ helpFilePath = helpFilePath.substring(0, index - 1).trim();
+ }
+ File file = FileUtility.getCanonicalFile(new File(new File(compilerExecutablePath).getParent(),
+ helpFilePath));
+ if (file.exists()) {
+ if (firstFile == null) {
+ firstFile = file;
+ }
+ if (firstLanguageFile == null && helpFileLanguage.equals(localeLanguage)) {
+ firstLanguageFile = file;
+ }
+ }
+ }
+ // Use language specific file if present, use first file otherwise.
+ File result = firstLanguageFile;
+ if (result == null) {
+ result = firstFile;
+ }
+ if (result == null) {
+ // ERROR: Help for the '{0}' compiler cannot be displayed because no
+ // help file was found in the paths '{1}' for the compiler
+ // executable path '{0}'.
+ throw new CoreException(new Status(IStatus.ERROR, AssemblerPlugin.ID, TextUtility.format(
+ Texts.MESSAGE_E131, name, helpFilePaths, compilerExecutablePath)));
+ }
+ return result;
+
+ }
+
+ /**
+ * Sets the list of supported CPUs Called by {@link CompilerRegistry} only.
+ *
+ * @param supportedCPUs
+ * The unmodifiable list of supported CPUs, not empty and not
+ * null.
+ * @since 1.6.1
+ */
+ final void setSupportedCPUs(List supportedCPUs) {
+ if (supportedCPUs == null) {
+ throw new IllegalArgumentException("Parameter 'supportedCPUs' must not be null.");
+ }
+ if (supportedCPUs.isEmpty()) {
+ throw new IllegalArgumentException("Parameter 'supportedCPUs' must not be empty.");
+ }
+ this.supportedCPUs = supportedCPUs;
+ }
+
+ /**
+ * Gets the unmodifiable list of CPUs supported by this compiler. The first
+ * entry defines the default CPU.
+ *
+ * @return The unmodifiable list of CPUs supported by this compiler, not
+ * empty and, not null.
+ *
+ * @since 1.6.1
+ */
+ public final List getSupportedCPUs() {
+ if (supportedCPUs == null) {
+ throw new IllegalStateException("Field 'supportedCPUs' must not be null.");
+ }
+ return supportedCPUs;
+ }
+
+ /**
+ * Sets the compiler syntax. Called by {@link CompilerRegistry} only.
+ *
+ * @param syntax
+ * The compiler syntax, not null.
+ */
+ final void setSyntax(CompilerSyntax syntax) {
+ if (syntax == null) {
+ throw new IllegalArgumentException("Parameter 'syntax' must not be null.");
+ }
+ this.syntax = syntax;
+ }
+
+ /**
+ * Gets the compiler syntax.
+ *
+ * @return The compiler syntax, not null.
+ */
+ public final CompilerSyntax getSyntax() {
+ if (syntax == null) {
+ throw new IllegalStateException("Field 'syntax' must not be null.");
+ }
+ return syntax;
+ }
+
+ /**
+ * Sets the compiler default parameters. Called by {@link CompilerRegistry}
+ * only.
+ *
+ * @param defaultParameters
+ * The compiler default parameters, not null.
+ */
+ final void setDefaultParameters(String defaultParameters) {
+ if (defaultParameters == null) {
+ throw new IllegalArgumentException("Parameter 'defaultParameters' must not be null.");
+ }
+ this.defaultParameters = defaultParameters;
+ }
+
+ /**
+ * Gets the compiler default parameters.
+ *
+ * @return The compiler default parameters, not null.
+ */
+ public final String getDefaultParameters() {
+ if (defaultParameters == null) {
+ throw new IllegalStateException("Field 'defaultParameters' must not be null.");
+ }
+ return defaultParameters;
+ }
+
+ /**
+ * Sets the default hardware to be assumed for this compiler. Called by
+ * {@link CompilerRegistry} only.
+ *
+ * @param hardware
+ * The default hardware, not null.
+ */
+ final void setDefaultHardware(Hardware hardware) {
+ if (hardware == null) {
+ throw new IllegalArgumentException("Parameter 'hardware' must not be null.");
+ }
+ this.defaultHardware = hardware;
+ }
+
+ /**
+ * Gets the default hardware for this compiler.
+ *
+ * @return The default hardwares, not null.
+ */
+ public final Hardware getDefaultHardware() {
+ if (defaultHardware == null) {
+ throw new IllegalStateException("Field 'defaultHardware' must not be null.");
+ }
+ return defaultHardware;
+ }
+
+ /**
+ * See {@link Comparable}.
+ */
+ @Override
+ public int compareTo(CompilerDefinition o) {
+ if (o == null) {
+ throw new IllegalArgumentException("Parameter 'o' must not be null.");
+ }
+ if (id == null || o.id == null) {
+ if (id == null) {
+ throw new IllegalStateException("Field 'id' must not be null for this or for argument.");
+ }
+ }
+ return id.compareTo(o.id);
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerFileWriter.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerFileWriter.java
new file mode 100644
index 00000000..2ed2727a
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerFileWriter.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+public class CompilerFileWriter {
+ /**
+ * Creates or updates a disk image file with the output file.
+ *
+ * @param files The compiler files, not null.
+ *
+ * @return true if no disk image is required or it is required and has been updated.
+ *
+ * @since 1.6.3
+ */
+ public boolean createOrUpdateDiskImage(CompilerFiles files) {
+ if (files == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'outputFile' must not be null.");
+ }
+ return true;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerFiles.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerFiles.java
new file mode 100644
index 00000000..cde61fe2
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerFiles.java
@@ -0,0 +1,256 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IFile;
+
+import com.wudsn.ide.asm.AssemblerProperties;
+import com.wudsn.ide.asm.AssemblerProperties.AssemblerProperty;
+import com.wudsn.ide.asm.preferences.CompilerPreferences;
+import com.wudsn.ide.base.common.FileUtility;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Container class for the folder, file names and paths of the source file, the
+ * output file and the symbols file.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class CompilerFiles {
+
+ public final class SourceFile {
+
+ public final IFile iFile;
+
+ public final File folder;
+ public final String folderPath;
+
+ public final File file;
+ public final String filePath;
+ public final String fileName;
+ public final String fileNameWithoutExtension;
+
+ public final AssemblerProperties assemblerProperties;
+
+ SourceFile(IFile iFile, AssemblerProperties assemblerProperties) {
+
+ if (iFile == null) {
+ throw new IllegalArgumentException("Parameter 'iFile' must not be null.");
+ }
+ if (assemblerProperties == null) {
+ throw new IllegalArgumentException("Parameter 'assemblerProperties' must not be null.");
+ }
+
+ this.iFile = iFile;
+ this.assemblerProperties = assemblerProperties;
+
+ // Source file.
+ filePath = iFile.getLocation().toOSString();
+ file = FileUtility.getCanonicalFile(new File(filePath));
+ fileName = file.getName();
+
+ String extension = iFile.getFileExtension();
+ if (extension == null) {
+ extension = "";
+ }
+ fileNameWithoutExtension = fileName.substring(0, fileName.length() - extension.length() - 1);
+
+ // Source folder.
+ folder = file.getParentFile();
+ folderPath = folder.getPath();
+ }
+ }
+
+ /**
+ * The actual source file which is currently open.
+ */
+ public final SourceFile sourceFile;
+
+ /**
+ * The main source file which is either the current file or the file
+ * indicated by the property "@com.wudsn.ide.asm.editor.MainSourceFile".
+ */
+ public final SourceFile mainSourceFile;
+
+ public final AssemblerProperty outputFolderModeProperty;
+ public final String outputFolderMode;
+
+ public final AssemblerProperty outputFolderProperty;
+ public final File outputFolder;
+ public final String outputFolderPath;
+
+ public final File outputFile;
+ public final String outputFilePath;
+ public final String outputFilePathWithoutExtension;
+
+ public final AssemblerProperty outputFileProperty;
+ public final String outputFileName;
+ public final String outputFileNameWithoutExtension;
+ public final AssemblerProperty outputFileExtensionProperty;
+ public final String outputFileExtension;
+ public final String outputFileNameShortWithoutExtension;
+
+ public final File symbolsFile;
+ public final String symbolsFilePath;
+ public final String symbolsFileName;
+
+ public CompilerFiles(IFile mainSourceIFile, AssemblerProperties mainSourceFileAssemblerProperties,
+ IFile sourceIFile, AssemblerProperties sourceFileAssemblerProperties,
+ CompilerPreferences compilerPreferences) {
+
+ if (mainSourceIFile == null) {
+ throw new IllegalArgumentException("Parameter 'mainSourceIFile' must not be null.");
+ }
+ if (sourceIFile == null) {
+ throw new IllegalArgumentException("Parameter 'sourceIFile' must not be null.");
+ }
+ if (compilerPreferences == null) {
+ throw new IllegalArgumentException("Parameter 'compilerPreferences' must not be null.");
+ }
+ this.mainSourceFile = new SourceFile(mainSourceIFile, mainSourceFileAssemblerProperties);
+ this.sourceFile = new SourceFile(sourceIFile, sourceFileAssemblerProperties);
+
+ // Output folder mode
+ // Can be overridden via annotation property in main source file
+ String localOutputFolderPath = compilerPreferences.getOutputFolderPath();
+ String localOutputFolderMode = compilerPreferences.getOutputFolderMode();
+ String localOutputFileExtension = compilerPreferences.getOutputFileExtension();
+
+ // Properties which override the preferences
+ outputFolderModeProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FOLDER_MODE);
+ outputFolderProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FOLDER);
+ outputFileExtensionProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FILE_EXTENSION);
+ outputFileProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FILE);
+
+ // The following sequence sets the instance fields "outputFolder" and
+ // "outputFileNameWithoutExtension" as well as the
+ // "outputFileNameWithoutExtension".
+ // If the output file is specified explicitly, it overrides all output
+ // properties.
+ if (outputFileProperty != null) {
+
+ // Make the file an absolute file.
+ File file = new File(outputFileProperty.value);
+ if (!file.isAbsolute()) {
+ file = new File(mainSourceFile.file.getParentFile(), file.getPath());
+ }
+ file = FileUtility.getCanonicalFile(file);
+
+ outputFolderMode = CompilerOutputFolderMode.FIXED_FOLDER;
+ outputFolder = file.getParentFile();
+
+ // Split the file name and file extension.
+ String fileName = file.getName();
+ int index = fileName.lastIndexOf('.');
+ if (index > 0) {
+ outputFileNameWithoutExtension = fileName.substring(0, index);
+ localOutputFileExtension = fileName.substring(index);
+ } else {
+ outputFileNameWithoutExtension = fileName;
+ localOutputFileExtension = "";
+ }
+ } else {
+ // The output file extension is independent of the rest.
+ if (outputFileExtensionProperty != null) {
+ localOutputFileExtension = outputFileExtensionProperty.value;
+ }
+ // If the output folder mode is specified explicitly, it overrides
+ // the output
+ // folder mode preferences.
+ if (outputFolderModeProperty != null) {
+ localOutputFolderMode = outputFolderModeProperty.value;
+ }
+
+ // If the output folder is specified explicitly, it overrides the
+ // output folder mode and folder preferences.
+ if (outputFolderProperty != null) {
+ localOutputFolderMode = CompilerOutputFolderMode.FIXED_FOLDER;
+ localOutputFolderPath = outputFolderProperty.value;
+ }
+
+ if (localOutputFolderMode.equals(CompilerOutputFolderMode.SOURCE_FOLDER)) {
+ localOutputFolderPath = mainSourceFile.folderPath;
+ } else if (localOutputFolderMode.equals(CompilerOutputFolderMode.FIXED_FOLDER)) {
+ // Fallback
+ if (StringUtility.isEmpty(localOutputFolderPath)) {
+ localOutputFolderPath = System.getProperty("java.io.tmpdir");
+ }
+ } else {
+ localOutputFolderPath = System.getProperty("java.io.tmpdir");
+ }
+
+ File file = new File(localOutputFolderPath);
+ if (!file.isAbsolute()) {
+ file = new File(sourceFile.file, file.getPath());
+ }
+ file = FileUtility.getCanonicalFile(file);
+
+ outputFolderMode = localOutputFolderMode;
+ outputFolder = file;
+
+ // Output file.
+ outputFileNameWithoutExtension = mainSourceFile.fileNameWithoutExtension;
+ }
+
+ // Common output parts.
+ outputFolderPath = outputFolder.getPath();
+ outputFileNameShortWithoutExtension = getFileNameShort(outputFileNameWithoutExtension);
+ outputFileName = outputFileNameWithoutExtension + localOutputFileExtension;
+ outputFileExtension = localOutputFileExtension;
+ outputFile = new File(outputFolder, outputFileName);
+ outputFilePath = outputFile.getPath();
+ outputFilePathWithoutExtension = new File(outputFolder, outputFileNameWithoutExtension).getPath();
+
+ // Symbols file.
+ symbolsFileName = mainSourceFile.fileNameWithoutExtension + ".lbl";
+ symbolsFile = new File(outputFolder, symbolsFileName);
+ symbolsFilePath = symbolsFile.getPath();
+
+ }
+
+ /**
+ * Computes a short file consisting of at most 8 ASCII letters and digits
+ * which starts with a letter.
+ *
+ * @param fileName
+ * The file name, may be empty, not null.
+ * @return The short file, name, not empty and not null.
+ */
+ private String getFileNameShort(String fileName) {
+ if (fileName == null) {
+ throw new IllegalArgumentException("Parameter 'fileName' must not be null.");
+ }
+ StringBuilder builder = new StringBuilder(fileName);
+ for (int i = 0; i < fileName.length() && builder.length() < 8; i++) {
+ char c = fileName.charAt(i);
+ c = Character.toUpperCase(c);
+ if (c >= 'A' && c <= 'Z' && (builder.length() > 0) || c >= '0' && c <= '9') {
+ builder.append(c);
+ }
+ }
+ if (builder.length() == 0) {
+ return "UNKNOWN";
+ }
+ return builder.toString();
+ }
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerOutputFolderMode.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerOutputFolderMode.java
new file mode 100644
index 00000000..7991b23e
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerOutputFolderMode.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * The target directory mode controls which folder is use to create the binary
+ * file in.
+ *
+ * @author Peter Dell
+ */
+public final class CompilerOutputFolderMode {
+
+ /**
+ * Creation is private.
+ */
+ private CompilerOutputFolderMode() {
+ }
+
+ public final static String SOURCE_FOLDER = "SOURCE_FOLDER";
+ public final static String TEMP_FOLDER = "TEMP_FOLDER";
+ public final static String FIXED_FOLDER = "FIXED_FOLDER";
+
+ /**
+ * Determines if the output folder mode is defined.
+ *
+ * @param outputFolderMode
+ * The output folder mode, not null.
+ * @return true if the output folder mode is not specified or
+ * defined.
+ */
+ public static boolean isDefined(String outputFolderMode) {
+ if (outputFolderMode == null) {
+ throw new IllegalArgumentException("Parameter 'outputFolderMode' must not be null.");
+ }
+ if (StringUtility.isEmpty(outputFolderMode)) {
+ return true;
+ }
+ if (outputFolderMode.equals(SOURCE_FOLDER) || outputFolderMode.equals(TEMP_FOLDER)
+ || outputFolderMode.equals(FIXED_FOLDER)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Gets the comma separated list of allowed values.
+ *
+ * @return The comma separated list of allowed values, not null
+ * .
+ */
+ public static String getAllowedValues() {
+ return SOURCE_FOLDER + ", " + TEMP_FOLDER + ", " + FIXED_FOLDER;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerProcessLogParser.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerProcessLogParser.java
new file mode 100644
index 00000000..69dbc158
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerProcessLogParser.java
@@ -0,0 +1,286 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import java.io.File;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+import com.wudsn.ide.asm.Texts;
+import com.wudsn.ide.base.common.NumberUtility;
+import com.wudsn.ide.base.common.TextUtility;
+
+/**
+ * Base class for compiler process log parsing.
+ *
+ * @author Peter Dell
+ */
+public abstract class CompilerProcessLogParser {
+
+ /**
+ * Proxy class for creating instances of {@link IMarker}.
+ *
+ * @since 1.6.1
+ */
+ public static final class Marker {
+ private IFile iFile;
+ private int lineNumber;
+ private int severity;
+ private String message;
+ private Marker detailMarker;
+
+ Marker(IFile iFile, int lineNumber, int severity, String message, Marker detailMarker) {
+ if (iFile == null) {
+ throw new IllegalArgumentException("Parameter 'iFile' must not be null.");
+ }
+ if (message == null) {
+ throw new IllegalArgumentException("Parameter 'message' must not be null.");
+ }
+ this.iFile = iFile;
+ this.lineNumber = lineNumber;
+ this.severity = severity;
+ this.message = message;
+ this.detailMarker = detailMarker;
+ }
+
+ /**
+ * Gets the iFile the marker refers to.
+ *
+ * @return The iFile, not null.
+ */
+ public IFile getIFile() {
+ return iFile;
+ }
+
+ /**
+ * Gets the line number.
+ *
+ * @return The liner number or 0, if there is no known line number.
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ /**
+ * Gets the severity.
+ *
+ * @return The severity, see {@link IMarker#SEVERITY}.
+ */
+ public int getSeverity() {
+ return severity;
+ }
+
+ /**
+ * Gets the message.
+ *
+ * @return The message, may be empty, not null.
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Gets the detail marker, describing this marker in more detail.
+ *
+ * @return The detail marker or null.
+ */
+ public Marker getDetailMarker() {
+ return detailMarker;
+ }
+
+ @Override
+ public String toString() {
+ return iFile.getFullPath() + ":" + lineNumber + ":" + severity + ":" + message;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof Marker)) {
+ return false;
+ }
+ Marker other = (Marker) o;
+ return iFile.getFullPath().equals(other.iFile.getFullPath())
+ && lineNumber == other.lineNumber
+ && severity == other.severity
+ && message.equals(other.message)
+ && ((detailMarker == null && other.detailMarker == null) || detailMarker.equals(other.detailMarker));
+
+ }
+
+ @Override
+ public int hashCode() {
+ return lineNumber;
+
+ }
+ }
+
+ private boolean initialized;
+ protected CompilerFiles files;
+ protected String mainSourceFilePath;
+ protected String outputLog;
+ protected String errorLog;
+ protected boolean markerAvailable;
+ protected String filePath;
+ protected int lineNumber;
+ protected int severity;
+ protected String message;
+
+ protected CompilerProcessLogParser() {
+ }
+
+ public final void setLogs(CompilerFiles files, String outputLog, String errorLog) {
+ if (files == null) {
+ throw new IllegalArgumentException("Parameter 'files' must not be null.");
+ }
+ if (outputLog == null) {
+ throw new IllegalArgumentException("Parameter 'outputLog' must not be null.");
+ }
+ if (errorLog == null) {
+ throw new IllegalArgumentException("Parameter 'errorLog' must not be null.");
+ }
+ this.files = files;
+ this.mainSourceFilePath = files.mainSourceFile.filePath;
+ this.outputLog = outputLog;
+ this.errorLog = errorLog;
+ initialize();
+ initialized = true;
+ markerAvailable = false;
+ return;
+ }
+
+ protected void initialize() {
+ }
+
+ public final boolean nextMarker() {
+ filePath = "";
+ lineNumber = 0;
+ severity = 0;
+ message = "";
+ markerAvailable = false;
+ findNextMarker();
+ return markerAvailable;
+ }
+
+ protected abstract void findNextMarker();
+
+ /**
+ * Adds the compiler symbols from the process output to the specified list.
+ *
+ * @param list
+ * The modifiable list to which the compiler symbols shall be
+ * added, not null.
+ *
+ * @throws CoreException
+ * if the symbols information is present, but cannot be read or
+ * parsed.
+ */
+ public void addCompilerSymbols(List list) throws CoreException {
+ }
+
+ /**
+ * Creates a new marker proxy for a file.
+ *
+ * @return The marker proxy, not null.
+ *
+ * @since 1.6.1
+ */
+ public final Marker getMarker() {
+
+ if (!initialized) {
+ throw new IllegalStateException("No log set.");
+ }
+ if (!markerAvailable) {
+ throw new IllegalStateException("No marker available.");
+ }
+ IFile mainSourceIFile = files.mainSourceFile.iFile;
+ IFile iFile = mainSourceIFile;
+ String normalizedFilePath = filePath.replace(File.separatorChar, '/');
+ String normalizedMainSourceFilePath = mainSourceFilePath.replace(File.separatorChar, '/');
+ Marker detailMarker = null;
+ if (normalizedFilePath.length() > 0 && !normalizedFilePath.equals(normalizedMainSourceFilePath)) {
+ String folderPath = mainSourceIFile.getParent().getLocation().toOSString();
+ String normalizedFolderPath = folderPath.replace(File.separatorChar, '/');
+
+ String relativePath;
+
+ // Absolute include path, may even be a brother or parent path?
+ if (normalizedFilePath.startsWith(normalizedFolderPath)) {
+ relativePath = normalizedFilePath.substring(folderPath.length() + 1);
+ } else {
+ // Simple relative path.
+ relativePath = normalizedFilePath;
+ }
+
+ // Create absolute iFile.
+ iFile = mainSourceIFile.getParent().getFile(new Path(relativePath));
+
+ // Check if it exists. This requires the file path to be in exactly
+ // the right case, even if the file system is case insensitive.
+ if (iFile == null || !iFile.exists()) {
+
+ // If the file exists, but the include was specified with a
+ // different case, an additional detail error message is issued.
+ IFile caseInsenstiveIFile = null;
+ if (iFile != null) {
+ try {
+ IResource[] members = iFile.getParent().members();
+ for (int i = 0; i < members.length && caseInsenstiveIFile == null; i++) {
+ if (members[i] instanceof IFile && members[i].getName().equalsIgnoreCase(iFile.getName())) {
+ caseInsenstiveIFile = (IFile) members[i];
+ }
+ }
+ } catch (CoreException ex) {
+ AssemblerPlugin.getInstance().logError("Could not retrieve members of {0}",
+ new Object[] { iFile }, ex);
+ }
+ }
+
+ // Use the case insensitive file if found and the main file
+ // otherwise.
+ if (iFile != null && caseInsenstiveIFile != null) {
+ // ERROR: Include statement for file '{0}' uses a file name
+ // that has a different case different from file system name
+ // {1}. Correct the file name in the include statement.
+ String caseMessage = TextUtility.format(Texts.MESSAGE_E142, iFile.getName(),
+ caseInsenstiveIFile.getName());
+ detailMarker = new Marker(mainSourceIFile, 0, IMarker.SEVERITY_ERROR, caseMessage, null);
+
+ iFile = caseInsenstiveIFile;
+ } else {
+ iFile = mainSourceIFile;
+ // INFO: In include file '{0}', line {1}.
+ message += " "
+ + TextUtility.format(Texts.MESSAGE_S143, filePath,
+ NumberUtility.getLongValueDecimalString(lineNumber));
+ lineNumber = 0;
+ }
+ }
+
+ }
+
+ return new Marker(iFile, lineNumber, severity, message.trim(), detailMarker);
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerRegistry.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerRegistry.java
new file mode 100644
index 00000000..6ff56bcc
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerRegistry.java
@@ -0,0 +1,244 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+
+import com.wudsn.ide.asm.CPU;
+import com.wudsn.ide.asm.Hardware;
+import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
+
+/**
+ * Registry for compilers, based on the extension points
+ * {@value CompilerRegistry#COMPILERS}.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class CompilerRegistry {
+
+ /**
+ * The id of the extension point which provides the compilers.
+ */
+ private static final String COMPILERS = "com.wudsn.ide.asm.compilers";
+
+ /**
+ * The registered compiler definition.
+ */
+ private List compilerDefinitionList;
+
+ /**
+ * The cached map of compiler instances.
+ */
+ private Map compilerMap;
+
+ /**
+ * Creation is public.
+ */
+ public CompilerRegistry() {
+ compilerDefinitionList = Collections.emptyList();
+ compilerMap = Collections.emptyMap();
+
+ }
+
+ /**
+ * Initializes the list of available compilers.
+ */
+ public void init() {
+
+ compilerDefinitionList = new ArrayList();
+ compilerMap = new TreeMap();
+
+ IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+ IExtensionPoint extensionPoint = extensionRegistry
+ .getExtensionPoint(COMPILERS);
+ if (extensionPoint == null) {
+ throw new IllegalStateException("Extension point '" + COMPILERS
+ + "' is not defined.");
+ }
+
+ IExtension[] extensions = extensionPoint.getExtensions();
+
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] configurationElements = extension
+ .getConfigurationElements();
+ for (IConfigurationElement configurationElement : configurationElements) {
+
+ try {
+ CompilerDefinition compilerDefinition;
+ compilerDefinition = new CompilerDefinition();
+ compilerDefinition.setId(configurationElement
+ .getAttribute("id"));
+ compilerDefinition.setName(configurationElement
+ .getAttribute("name"));
+ compilerDefinition.setClassName(configurationElement
+ .getAttribute("class"));
+ compilerDefinition.setHelpFilePaths(configurationElement
+ .getAttribute("helpFilePaths"));
+ compilerDefinition.setHomePageURL(configurationElement
+ .getAttribute("homePageURL"));
+ compilerDefinition
+ .setDefaultParameters(configurationElement
+ .getAttribute("defaultParameters"));
+
+ configurationElement.getChildren("supportedCPU");
+ IConfigurationElement[] supportedCPUArray;
+ supportedCPUArray = configurationElement
+ .getChildren("supportedCPU");
+ List supportedCPUs = new ArrayList(
+ supportedCPUArray.length);
+ for (IConfigurationElement supportedCPU : supportedCPUArray) {
+ supportedCPUs.add(CPU.valueOf(supportedCPU
+ .getAttribute("cpu")));
+ }
+ supportedCPUs = Collections.unmodifiableList(supportedCPUs);
+ compilerDefinition.setSupportedCPUs(supportedCPUs);
+ compilerDefinition.setDefaultHardware(Hardware
+ .valueOf(configurationElement
+ .getAttribute("defaultHardware")));
+
+ compilerDefinitionList.add(compilerDefinition);
+
+ addCompiler(configurationElement, compilerDefinition);
+ } catch (RuntimeException ex) {
+ throw new RuntimeException(
+ "Error during registration of compiler '"
+ + configurationElement.getAttribute("id")
+ + "'.", ex);
+ }
+ }
+ }
+
+ compilerDefinitionList = new ArrayList(
+ compilerDefinitionList);
+ Collections.sort(compilerDefinitionList);
+ compilerDefinitionList = Collections
+ .unmodifiableList(compilerDefinitionList);
+ compilerMap = Collections.unmodifiableMap(compilerMap);
+ }
+
+ /**
+ * Adds a new compiler.
+ *
+ * @param configurationElement
+ * The configuration element used as class instance factory, not
+ * null.
+ *
+ * @param compilerDefinition
+ * The compiler definition, not null.
+ */
+ private void addCompiler(IConfigurationElement configurationElement,
+ CompilerDefinition compilerDefinition) {
+ if (configurationElement == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'configurationElement' must not be null.");
+ }
+ if (compilerDefinition == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerDefinition' must not be null.");
+ }
+
+ String id = compilerDefinition.getId();
+ Compiler compiler;
+ try {
+ // The class loading must be delegated to the framework.
+ compiler = (Compiler) configurationElement
+ .createExecutableExtension("class");
+ } catch (CoreException ex) {
+ throw new RuntimeException(
+ "Cannot create compiler instance for id '" + id + "'.", ex);
+ }
+
+ // Build the list of common and specific syntax definition files.
+ List> compilerClasses = new ArrayList>(2);
+ compilerClasses.add(compiler.getClass());
+ compilerClasses.add(Compiler.class);
+
+ CompilerSyntax syntax;
+ syntax = new CompilerSyntax(id);
+
+ syntax.loadXMLData(compilerClasses);
+
+ compilerDefinition.setSyntax(syntax);
+
+ compiler.setDefinition(compilerDefinition);
+
+ compiler = compilerMap.put(id, compiler);
+ if (compiler != null) {
+ throw new RuntimeException("Compiler id '" + id
+ + "' is already registered to class '"
+ + compiler.getClass().getName() + "'.");
+ }
+
+ }
+
+ /**
+ * Gets the unmodifiable list of compiler definitions, sorted by their id.
+ *
+ *
+ * @return The unmodifiable list of compiler definitions, sorted by their
+ * id, may be empty, not null
+ *
+ * @since 1.6.1
+ */
+ public List getCompilerDefinitions() {
+ return compilerDefinitionList;
+ }
+
+ /**
+ * Gets the compiler for a given id. Instances of compiler are stateless
+ * singletons within the plugin.
+ *
+ * @param compilerId
+ * The compiler id, not null.
+ *
+ * @return The compiler, not null.
+ */
+ public Compiler getCompiler(String compilerId) {
+ if (compilerId == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerId' must not be null.");
+ }
+ Compiler result;
+ synchronized (compilerMap) {
+
+ result = compilerMap.get(compilerId);
+ }
+ if (result == null) {
+
+ throw new IllegalArgumentException("Unknown compiler id '"
+ + compilerId + "'.");
+ }
+
+ return result;
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerSymbol.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerSymbol.java
new file mode 100644
index 00000000..63771105
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerSymbol.java
@@ -0,0 +1,156 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+import com.wudsn.ide.base.common.HexUtility;
+import com.wudsn.ide.base.common.NumberUtility;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * A symbols in the symbol table. A symbol may be an equate or a label and it
+ * may represent a numeric numericValue or an address.
+ *
+ * @author Peter Dell
+ */
+public final class CompilerSymbol {
+
+ public static final int NUMBER = 1;
+ public static final int STRING = 2;
+
+ private final int type;
+ private final String name;
+ private final String nameUpperCase;
+ private final String bankString;
+ private final int valueType;
+ private final String numberValueHexString;
+ private final String numberValueHexStringUpperCase;
+ private final String numberValueDecimalString;
+ private final String stringValue;
+ private final String stringValueUpperCase;
+
+ public static final int UNDEFINED_BANK = -1;
+
+ private CompilerSymbol(int type, String name, int bank, int valueType, long numberValue, String stringValue) {
+ if (name == null)
+ throw new IllegalArgumentException("Parameter 'name' must not be null.");
+ if (StringUtility.isEmpty(name)) {
+ throw new IllegalArgumentException("Parameter 'name' must not be empty.");
+ }
+ if (stringValue == null) {
+ throw new IllegalArgumentException("Parameter 'stringValue' must not be null.");
+ }
+ this.type = type;
+ this.name = name.trim();
+ this.nameUpperCase = name.toUpperCase();
+ this.bankString = bank != UNDEFINED_BANK ? NumberUtility.getLongValueDecimalString(bank) : "";
+ this.valueType = valueType;
+ switch (valueType) {
+ case NUMBER:
+ numberValue = numberValue & 0xfffffff;
+ int length = (HexUtility.getLongValueHexLength(numberValue) + 1) & 0xffffffe;
+ this.numberValueHexString = HexUtility.getLongValueHexString(numberValue, length);
+ this.numberValueHexStringUpperCase = numberValueHexString.toUpperCase();
+ this.numberValueDecimalString = NumberUtility.getLongValueDecimalString(numberValue);
+ this.stringValue = "";
+ this.stringValueUpperCase = stringValue;
+ break;
+ case STRING:
+ this.numberValueHexString = "";
+ this.numberValueHexStringUpperCase = "";
+ this.numberValueDecimalString = "";
+ this.stringValue = stringValue;
+ this.stringValueUpperCase = stringValue.toUpperCase();
+ break;
+ default:
+ throw new IllegalArgumentException("Value type '" + valueType + "' is not supported.");
+ }
+ }
+
+ public static CompilerSymbol createNumberSymbol(int type, String name, int bank, long numberValue) {
+ return new CompilerSymbol(type, name, bank, NUMBER, numberValue, "");
+ }
+
+ public static CompilerSymbol createNumberHexSymbol(String name, String hexValue) throws NumberFormatException {
+ return new CompilerSymbol(CompilerSymbolType.DEFAULT, name, UNDEFINED_BANK, NUMBER,
+ Long.parseLong(hexValue, 16), "");
+ }
+
+ public static CompilerSymbol createStringSymbol(String name, String stringValue) {
+ return new CompilerSymbol(CompilerSymbolType.DEFAULT, name, UNDEFINED_BANK, STRING, 0, stringValue);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getNameUpperCase() {
+ return nameUpperCase;
+ }
+
+ public String getBankString() {
+ return bankString;
+ }
+
+ public String getValueAsHexString() {
+ return numberValueHexString;
+ }
+
+ /**
+ * Upper case version of the hex string for fuzzy search.
+ *
+ * @return The upper case version of the hex string.
+ */
+ public String getValueAsHexStringUpperCase() {
+ return numberValueHexStringUpperCase;
+ }
+
+ public String getValueAsDecimalString() {
+ return numberValueDecimalString;
+ }
+
+ public String getValueAsString() {
+ return stringValue;
+ }
+
+ /**
+ * Upper case version of the hex string for fuzzy search.
+ *
+ * @return The upper case version of the hex string.
+ */
+ public String getValueAsStringUpperCase() {
+ return stringValueUpperCase;
+ }
+
+ @Override
+ public String toString() {
+ switch (valueType) {
+ case NUMBER:
+ return name + "=" + getValueAsHexString();
+ case STRING:
+ return name + "=" + getValueAsString();
+ }
+ throw new IllegalStateException();
+
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerSymbolType.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerSymbolType.java
new file mode 100644
index 00000000..5c4c0493
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerSymbolType.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.compiler;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParserTreeObjectType;
+
+/**
+ * Constant values for symbol types. Symbol types are a subset of the source
+ * tree object types.
+ *
+ * @author Peter Dell
+ */
+public final class CompilerSymbolType {
+
+ /**
+ * Creation is private.
+ */
+ private CompilerSymbolType() {
+ }
+
+ /**
+ * Default-type
+ */
+ public static final int DEFAULT = CompilerSourceParserTreeObjectType.DEFAULT;
+
+ public static final int EQUATE_DEFINITION = CompilerSourceParserTreeObjectType.EQUATE_DEFINITION;
+ public static final int LABEL_DEFINITION = CompilerSourceParserTreeObjectType.LABEL_DEFINITION;
+
+ public static final int ENUM_DEFINITION_SECTION = CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION;
+ public static final int STRUCTURE_DEFINITION_SECTION = CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION;
+ public static final int MACRO_DEFINITION_SECTION = CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION;
+ public static final int LOCAL_SECTION = CompilerSourceParserTreeObjectType.LOCAL_SECTION;
+ public static final int PROCEDURE_DEFINITION_SECTION = CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION;
+
+ /**
+ * Gets the localized text for a compiler symbol type.
+ *
+ * @param type
+ * The type, see constants of this class.
+ * @return The localized text, may be empty but not null.
+ */
+ public static String getText(int type) {
+ String result;
+ switch (type) {
+ case DEFAULT:
+ case EQUATE_DEFINITION:
+ case LABEL_DEFINITION:
+ case ENUM_DEFINITION_SECTION:
+ case STRUCTURE_DEFINITION_SECTION:
+ case MACRO_DEFINITION_SECTION:
+ case LOCAL_SECTION:
+ case PROCEDURE_DEFINITION_SECTION:
+ result = CompilerSourceParserTreeObjectType.getText(type);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown type " + type + ".");
+ }
+ return result;
+
+ }
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerVariables.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerVariables.java
new file mode 100644
index 00000000..bc0ac64e
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerVariables.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler;
+
+/**
+ * Utility class to handle dynamic variables.
+ *
+ * @author Peter Dell
+ */
+public final class CompilerVariables {
+
+ /**
+ * Creation is private.
+ */
+ private CompilerVariables() {
+ }
+
+ public static final String SOURCE_FOLDER_PATH = "${sourceFolderPath}";
+ public static final String SOURCE_FILE_PATH = "${sourceFilePath}";
+ public static final String OUTPUT_FOLDER_PATH = "${outputFolderPath}";
+ public static final String OUTPUT_FILE_PATH = "${outputFilePath}";
+ public static final String OUTPUT_FILE_PATH_WITHOUT_EXTENSION = "${outputFilePathWithoutExtension}";
+ public static final String OUTPUT_FILE_NAME = "${outputFileName}";
+ public static final String OUTPUT_FILE_NAME_WITHOUT_EXTENSION = "${outputFileNameWithoutExtension}";
+ public static final String OUTPUT_FILE_NAME_SHORT_WITHOUT_EXTENSION = "${outputFileNameShortWithoutExtension}";
+
+ public static String replaceVariables(String parameter,
+ CompilerFiles files) {
+ if (parameter == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'parameter' must not be null.");
+ }
+ if (files == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'files' must not be null.");
+ }
+
+ // When referring to the source file and folder at compiler time,
+ // this always means the main source file.
+ parameter = parameter.replace(SOURCE_FOLDER_PATH,
+ files.mainSourceFile.folderPath);
+ parameter = parameter.replace(SOURCE_FILE_PATH,
+ files.mainSourceFile.filePath);
+ parameter = parameter.replace(OUTPUT_FOLDER_PATH,
+ files.outputFolderPath);
+ parameter = parameter.replace(OUTPUT_FILE_PATH, files.outputFilePath);
+ parameter = parameter.replace(OUTPUT_FILE_PATH_WITHOUT_EXTENSION,
+ files.outputFilePathWithoutExtension);
+ parameter = parameter.replace(OUTPUT_FILE_NAME, files.outputFileName);
+ parameter = parameter.replace(OUTPUT_FILE_NAME_WITHOUT_EXTENSION,
+ files.outputFileNameWithoutExtension);
+ parameter = parameter.replace(OUTPUT_FILE_NAME_SHORT_WITHOUT_EXTENSION,
+ files.outputFileNameShortWithoutExtension);
+
+ return parameter;
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceFile.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceFile.java
new file mode 100644
index 00000000..89b28816
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceFile.java
@@ -0,0 +1,460 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.parser;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+
+import com.wudsn.ide.asm.Texts;
+import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
+import com.wudsn.ide.base.common.FileUtility;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Container for recursive parsing of source files using
+ * {@link CompilerSourceParser#parse(CompilerSourceFile, CompilerSourceParserLineCallback)}
+ * .
+ *
+ * @author Peter Dell
+ */
+public final class CompilerSourceFile {
+
+ private final static class FoldingStackEntry {
+ public final int startOffset;
+ public final boolean forSection;
+
+ public FoldingStackEntry(int startOffset, boolean forSection) {
+ this.startOffset = startOffset;
+ this.forSection = forSection;
+ }
+
+ @Override
+ public String toString() {
+ return "startOffset=" + startOffset + ", forSection=" + forSection;
+ }
+ }
+
+ private CompilerSyntax compilerSyntax;
+ private File documentFile;
+ private File documentDirectory;
+ private IDocument document;
+
+ private List foldingPositions;
+
+ /**
+ * Temporary data during the parse process.
+ */
+ private List foldingStack;
+
+ /**
+ * The result of the last parse process.
+ */
+ private CompilerSourceParserTreeObject definitionSection;
+ private List implementationSections;
+ private List sectionStack;
+
+ /**
+ * Creates a new compiler source file. Instances are only created by
+ * {@link CompilerSourceParser#createCompilerSourceFile(File, IDocument)}.
+ *
+ * @param compilerSyntax
+ * The compiler syntax used to parse this file, not
+ * null.
+ * @param documentFile
+ * The file in the file system. Its directory is used to resolve
+ * relative file paths, or null if the document is
+ * not yet persistent.
+ * @param document
+ * The document, not null.
+ */
+ CompilerSourceFile(CompilerSyntax compilerSyntax, File documentFile, IDocument document) {
+ if (compilerSyntax == null) {
+ throw new IllegalArgumentException("Parameter 'compilerSyntax' must not be null.");
+ }
+ if (document == null) {
+ throw new IllegalArgumentException("Parameter 'document' must not be null.");
+ }
+ this.compilerSyntax = compilerSyntax;
+ if (documentFile != null) {
+ documentFile = FileUtility.getCanonicalFile(documentFile);
+ this.documentFile = documentFile;
+ this.documentDirectory = documentFile.getParentFile();
+ }
+
+ this.document = document;
+
+ // Folding.
+ foldingPositions = new ArrayList();
+ foldingStack = new ArrayList();
+
+ // Sections.
+ definitionSection = new CompilerSourceParserTreeObject(this, 0,
+ CompilerSourceParserTreeObjectType.DEFINITION_SECTION, "DefinitionSection",
+ Texts.ASSEMBLER_CONTENT_OUTLINE_TREE_TYPE_DEFINITION_SECTION, "");
+ implementationSections = new ArrayList();
+ sectionStack = new ArrayList();
+ }
+
+ /**
+ * Gets the compiler syntax user to parse this file.
+ *
+ * @return The compiler syntax, not null.
+ *
+ * @since 1.6.1
+ */
+ public CompilerSyntax getCompilerSyntax() {
+ return compilerSyntax;
+ }
+
+ /**
+ * Gets the canonical document file.
+ *
+ * @return The file where the document is located, or null if
+ * the document is not yet persistent.
+ */
+ public File getDocumentFile() {
+ return documentFile;
+ }
+
+ /**
+ * Gets the document directory.
+ *
+ * @return The directory which is used to resolved relative file paths, or
+ * null if the document is not yet persistent.
+ */
+ public File getDocumentDirectory() {
+ return documentDirectory;
+ }
+
+ /**
+ * Gets the document.
+ *
+ * @return The document, not null.
+ */
+ public IDocument getDocument() {
+ return document;
+ }
+
+ /**
+ * Gets the sections of this file.
+ *
+ * @return The unmodifiable list of section, may be empty, not
+ * null.
+ */
+ public List getSections() {
+ List result;
+ result = new ArrayList();
+ if (definitionSection != null && definitionSection.hasChildren()) {
+ result.add(definitionSection);
+ }
+
+ result.addAll(implementationSections);
+ result = Collections.unmodifiableList(result);
+ return result;
+ }
+
+ final CompilerSourceParserTreeObject getDefinitionSection() {
+ return definitionSection;
+ }
+
+ final List getImplementationSections() {
+ return implementationSections;
+ }
+
+ /**
+ * Gets the list of foldingPositions for folding after parsed has completed.
+ *
+ * @return The non-modifiable sorted list of foldingPositions, may be empty,
+ * not null.
+ */
+ public List getFoldingPositions() {
+ return Collections.unmodifiableList(foldingPositions);
+ }
+
+ /**
+ * Determines if the currently active folding was started for a section.
+ *
+ * @return true if the folding was started for a section,
+ * false if not.
+ */
+ final boolean isFoldingForSection() {
+ if (foldingStack.isEmpty()) {
+ return false; // Ignore wrong nesting.
+ }
+ FoldingStackEntry entry = foldingStack.get(foldingStack.size() - 1);
+ return entry.forSection;
+ }
+
+ /**
+ * Starts a new active folding level.
+ *
+ * @param startOffset
+ * The start offset, a non-negative integer.
+ * @param forSection
+ * true if the folding is started for a section,
+ * false if not.
+ */
+ final void beginFolding(int startOffset, boolean forSection) {
+ if (startOffset < 0) {
+ throw new IllegalArgumentException("Parameter 'startOffset' must not be negative. Specified value is "
+ + startOffset + ".");
+ }
+ foldingStack.add(new FoldingStackEntry(startOffset, forSection));
+ }
+
+ /**
+ * Ends the currently active folding level.
+ *
+ * @param endOffset
+ * The end offset, a non-negative integer. This must be the
+ * actual offset of the last character in the line, including the
+ * line end delimiter, if present.
+ */
+ final void endFolding(int endOffset) {
+ if (endOffset < 0) {
+ throw new IllegalArgumentException("Parameter 'endOffset' must not be negative. Specified value is "
+ + endOffset + ".");
+ }
+
+ if (foldingStack.isEmpty()) {
+ return; // Ignore wrong nesting.
+ }
+ FoldingStackEntry entry = foldingStack.remove(foldingStack.size() - 1);
+ int length = endOffset - entry.startOffset;
+ if (length < 0) {
+ throw new IllegalArgumentException("End offset " + endOffset + " is less than the start offset "
+ + entry.startOffset + ".");
+ }
+ // Add only non-empty positions.
+ if (length > 0) {
+ foldingPositions.add(new Position(entry.startOffset, length));
+ }
+ }
+
+ /**
+ * Ends all currently active folding levels.
+ *
+ */
+ final void endAllFoldings() {
+
+ while (!foldingStack.isEmpty()) {
+ endFolding(document.getLength() > 0 ? document.getLength() - 1 : 0);
+
+ }
+ }
+
+ /**
+ * Ends all currently active sections.
+ *
+ */
+ public void endAllSections() {
+ while (!sectionStack.isEmpty()) {
+ endSection(document.getLength() > 0 ? document.getLength() - 1 : 0);
+ }
+ }
+
+ /**
+ * Starts a new active section.
+ *
+ * @param startOffset
+ * The start offset, a non-negative integer.
+ * @param section
+ * The new section, not null.
+ * @param withFolding
+ * true if the section is also a folding section,
+ * false otherwise.
+ */
+ final void beginSection(int startOffset, CompilerSourceParserTreeObject section, boolean withFolding) {
+ if (startOffset < 0) {
+ throw new IllegalArgumentException("Parameter 'startOffset' must not be negative. Specified value is "
+ + startOffset + ".");
+ }
+ if (section == null) {
+ throw new IllegalArgumentException("Parameter 'section' must not be null.");
+ }
+
+ if (!sectionStack.isEmpty()) {
+ CompilerSourceParserTreeObject parent = sectionStack.get(sectionStack.size() - 1);
+ parent.addChild(section);
+ }
+ sectionStack.add(section);
+ if (withFolding) {
+ beginFolding(startOffset, true);
+ }
+
+ }
+
+ /**
+ * Ends the currently active section.
+ *
+ * @param endOffset
+ * The end offset, a non-negative integer. This must be the
+ * actual offset of the last character in the line, including the
+ * line end delimiter, if present.
+ *
+ * @return The new top of the section stack, may be null.
+ */
+ final CompilerSourceParserTreeObject endSection(int endOffset) {
+ if (endOffset < 0) {
+ throw new IllegalArgumentException("Parameter 'endOffset' must not be negative. Specified value is "
+ + endOffset + ".");
+ }
+
+ CompilerSourceParserTreeObject result;
+ result = null;
+
+ // Remove top of stack.
+ if (!sectionStack.isEmpty()) {
+ sectionStack.remove(sectionStack.size() - 1);
+
+ // Make top of stack the new active section, accepting illegal pops.
+ if (!sectionStack.isEmpty()) {
+ result = sectionStack.get(sectionStack.size() - 1);
+ }
+ endFolding(endOffset);
+ }
+ return result;
+ }
+
+ public List getIdentifiers() {
+ List foundElements;
+ foundElements = new ArrayList();
+ getIdentifiers(getSections(), foundElements);
+ foundElements = Collections.unmodifiableList(foundElements);
+ return foundElements;
+ }
+
+ private void getIdentifiers(List allElements,
+ List foundElements) {
+ if (allElements == null) {
+ throw new IllegalArgumentException("Parameter 'allElements' must not be null.");
+ }
+ if (foundElements == null) {
+ throw new IllegalArgumentException("Parameter 'foundElements' must not be null.");
+ }
+ CompilerSourceParserTreeObject element = null;
+ for (int i = 0; i < allElements.size(); i++) {
+ element = allElements.get(i);
+ switch (element.getType()) {
+ case CompilerSourceParserTreeObjectType.EQUATE_DEFINITION:
+ case CompilerSourceParserTreeObjectType.LABEL_DEFINITION:
+ case CompilerSourceParserTreeObjectType.LOCAL_SECTION:
+ case CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION:
+
+ foundElements.add(element);
+ break;
+ }
+ if (element.hasChildren()) {
+ getIdentifiers(element.getChildren(), foundElements);
+ }
+
+ }
+ }
+
+ /**
+ * Find the definition elements for a given identifier.
+ *
+ * @param identifier
+ * The identifier to search for, not empty and not
+ * null.
+ * @return The unmodifiable list of compiler source tree object with the
+ * label, may be empty, not null. The result may
+ * contain entries from source include files.
+ */
+ public List getIdentifierDefinitionElements(String identifier) {
+
+ if (identifier == null) {
+ throw new IllegalArgumentException("Parameter 'identifier' must not be null.");
+ }
+ if (StringUtility.isEmpty(identifier)) {
+ throw new IllegalArgumentException("Parameter 'identifier' must not be empty.");
+ }
+ List foundElements;
+ foundElements = new ArrayList();
+ getIdentifierDefinitionElements(getSections(), identifier, foundElements);
+ foundElements = Collections.unmodifiableList(foundElements);
+ return foundElements;
+
+ }
+
+ private void getIdentifierDefinitionElements(List allElements, String identifier,
+ List foundElements) {
+ if (allElements == null) {
+ throw new IllegalArgumentException("Parameter 'allElements' must not be null.");
+ }
+ if (identifier == null) {
+ throw new IllegalArgumentException("Parameter 'identifier' must not be null.");
+ }
+ if (foundElements == null) {
+ throw new IllegalArgumentException("Parameter 'foundElements' must not be null.");
+ }
+ String compoundIdentifierSuffix = null;
+ char c = compilerSyntax.getIdentifierSeparatorCharacter();
+ if (c != CompilerSyntax.NO_CHARACTER) {
+ compoundIdentifierSuffix = c + identifier;
+ }
+
+ boolean identifiersCaseSensitive = compilerSyntax.areIdentifiersCaseSensitive();
+ CompilerSourceParserTreeObject element = null;
+ for (int i = 0; i < allElements.size(); i++) {
+ element = allElements.get(i);
+ switch (element.getType()) {
+ case CompilerSourceParserTreeObjectType.EQUATE_DEFINITION:
+ case CompilerSourceParserTreeObjectType.LABEL_DEFINITION:
+ case CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.LOCAL_SECTION:
+ case CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION:
+ // Check if name equals the identifier, compound name equals the
+ // identifier or compound name ends with
+ // compoundIdentifierSuffix.
+ if (identifiersCaseSensitive) {
+ if (element.getName().equals(identifier)
+ || element.getCompoundName().equals(identifier)
+ || (compoundIdentifierSuffix != null && element.getCompoundName().endsWith(
+ compoundIdentifierSuffix))) {
+ foundElements.add(element);
+ }
+ } else {
+ if (element.getName().equalsIgnoreCase(identifier)
+ || element.getCompoundName().equals(identifier)
+ || (compoundIdentifierSuffix != null && element.getCompoundName().regionMatches(true,
+ element.getCompoundName().length() - compoundIdentifierSuffix.length(),
+ compoundIdentifierSuffix, 0, compoundIdentifierSuffix.length()))) {
+ foundElements.add(element);
+ }
+ }
+ break;
+ }
+
+ if (element.hasChildren()) {
+ getIdentifierDefinitionElements(element.getChildren(), identifier, foundElements);
+ }
+
+ }
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParser.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParser.java
new file mode 100644
index 00000000..fb06d661
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParser.java
@@ -0,0 +1,1214 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.parser;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+import com.wudsn.ide.asm.AssemblerProperties;
+import com.wudsn.ide.asm.compiler.Compiler;
+import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
+import com.wudsn.ide.asm.compiler.syntax.Instruction;
+import com.wudsn.ide.asm.compiler.syntax.InstructionSet;
+import com.wudsn.ide.asm.compiler.syntax.InstructionType;
+import com.wudsn.ide.base.BasePlugin;
+import com.wudsn.ide.base.common.FileUtility;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Source parser for creating {@link CompilerSourceParserTreeObject} instances.
+ * The performance is so good, that no caching for the results of source include
+ * parsing is required.
+ *
+ * @author Peter Dell
+ *
+ */
+public abstract class CompilerSourceParser {
+
+ // The sections of a single line
+ private static final class LineSection {
+ public static final int NONE = 0;
+ public static final int SYMBOL = 1;
+ public static final int INSTRUCTION = 2;
+ public static final int OPERAND = 3;
+ }
+
+ // The compiler syntax and instruction set.
+ private CompilerSyntax compilerSyntax;
+ private InstructionSet instructionSet;
+
+ // Fields set once for parsing a file.
+ private CompilerSourceFile compilerSourceFile;
+
+ // Fields modified during parsing.
+ private CompilerSourceParserTreeObject section;
+
+ // Fields modified per line. Preserved to and restored from local variables
+ // during recursive parsing of SOURCE_INCLUDE_DIRECTIVE instructions.
+ private CompilerSourceParserTreeObject child;
+ private CompilerSourceParserTreeObject labelChild;
+ private boolean blockStarting;
+ private boolean blockEnding;
+
+ // For debugging.
+ private boolean logEnabled = false;
+
+ /**
+ * Extract all {@link AssemblerProperties} properties from a document.
+ *
+ * @param document
+ * The document, not null.
+ * @return The properties, may be empty, not null.
+ */
+ public static AssemblerProperties getDocumentProperties(IDocument document) {
+ if (document == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'document' must not be null.");
+ }
+ String content = document.get();
+ AssemblerProperties properties = new AssemblerProperties();
+
+ int index1 = content.indexOf(AssemblerProperties.PREFIX);
+ while (index1 >= 0) {
+
+ int indexEqualSign = content.indexOf('=', index1);
+ int indexNewLine = content.indexOf('\n', index1);
+ if (indexNewLine < 0) {
+ indexNewLine = content.indexOf('\r', index1);
+ }
+ if (indexNewLine < 0) {
+ indexNewLine = content.length();
+ }
+
+ if (indexEqualSign >= 0 && indexEqualSign < indexNewLine) {
+ String key = content.substring(index1, indexEqualSign).trim();
+ String value = content.substring(indexEqualSign + 1,
+ indexNewLine).trim();
+ int lineNumber;
+ try {
+ lineNumber = document.getLineOfOffset(index1) + 1;
+ } catch (BadLocationException ex) {
+ lineNumber = 0;
+ }
+ properties.put(key, value, lineNumber);
+ }
+ index1 = content.indexOf(AssemblerProperties.PREFIX, indexNewLine);
+ }
+ return properties;
+ }
+
+ /**
+ * Creation is protected.
+ */
+ protected CompilerSourceParser() {
+
+ }
+
+ /**
+ * Gets the compiler syntax for this parser.
+ *
+ * @return The compiler syntax, not null.
+ */
+ public final CompilerSyntax getCompilerSyntax() {
+ if (compilerSyntax == null) {
+ throw new IllegalStateException(
+ "Field 'compilerSyntax' must not be null.");
+ }
+ return compilerSyntax;
+ }
+
+ /**
+ * Gets the instruction for the currently active CPU.
+ *
+ * @return The instruction set, not null.
+ *
+ * @since 1.6.1
+ */
+ public final InstructionSet getInstructionSet() {
+ if (instructionSet == null) {
+ throw new IllegalStateException(
+ "Field 'instructionSet' must not be null.");
+ }
+ return instructionSet;
+ }
+
+ /**
+ * Logs a message to the error log in case logging is enabled.
+ *
+ * @param message
+ * The message with place holders, may be empty, not
+ * null.
+ * @param parameters
+ * The parameters for the place holders, may be empty or
+ * null.
+ */
+ private void log(String message, Object... parameters) {
+ if (logEnabled) {
+ BasePlugin.getInstance().log(message, parameters);
+ }
+
+ }
+
+ /**
+ * Called by {@link Compiler} to link the parser to the compile syntax.
+ *
+ * @param instructionSet
+ * The instruction set, not null.
+ */
+ public final void init(InstructionSet instructionSet) {
+ if (instructionSet == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'instructionSet' must not be null.");
+ }
+ this.instructionSet = instructionSet;
+ this.compilerSyntax = instructionSet.getCompilerSyntax();
+
+ }
+
+ /**
+ * Detects a file references in the given source line. This method is
+ * stateless.
+ *
+ * @param line
+ * The source line, may be empty, not null.
+ * @param include
+ * The modifiable include statement description, not
+ * null.
+ */
+ public final void detectFileReference(String line,
+ CompilerSourceParserFileReference include) {
+ if (line == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'line' must not be null.");
+ }
+ if (include == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'include' must not be null.");
+ }
+
+ boolean caseSenstive = instructionSet.areInstructionsCaseSensitive();
+ if (!caseSenstive) {
+ line = line.toUpperCase();
+ }
+
+ // Find next (possible) quote.
+ int quoteOffset = -1;
+ Iterator i = compilerSyntax.getStringDelimiters().iterator();
+ while (i.hasNext() && quoteOffset == -1) {
+ String quote = i.next();
+ quoteOffset = line.indexOf(quote);
+ }
+
+ for (Instruction instruction : instructionSet
+ .getFileReferenceInstructions()) {
+ int instructionOffset;
+ String instructionName;
+
+ if (caseSenstive) {
+ instructionName = instruction.getName();
+ } else {
+ instructionName = instruction.getUpperCaseName();
+ }
+ instructionOffset = line.indexOf(instructionName);
+
+ // Key word found before the quote?
+ if (quoteOffset > -1 && instructionOffset > -1
+ && instructionOffset < quoteOffset) {
+ if (instruction.getType() == InstructionType.SOURCE_INCLUDE_DIRECTIVE) {
+ include.setType(CompilerSourceParserFileReferenceType.SOURCE);
+ } else if (instruction.getType() == InstructionType.BINARY_INCLUDE_DIRECTIVE
+ || instruction.getType() == InstructionType.BINARY_OUTPUT_DIRECTIVE) {
+ include.setType(CompilerSourceParserFileReferenceType.BINARY);
+ } else {
+ throw new IllegalStateException("Include instruction '"
+ + instructionName + "' has the unsupported type '"
+ + instruction.getType() + "'");
+ }
+
+ include.setDirectiveEndOffset(instructionOffset
+ + instructionName.length());
+ return;
+ }
+
+ }
+ }
+
+ /**
+ * Enhances the file path of an include, for example add a default extension
+ * for source includes.
+ *
+ * @param type
+ * The type of include, see
+ * {@link CompilerSourceParserFileReferenceType}.
+ *
+ * @param documentDirectory
+ * The current directory which act as the basis for relative
+ * paths or not null if it is not known.
+ *
+ * @param filePath
+ * The possibly relative file path of the include file in OS
+ * specific notation, not empty and not null.
+ * @return The enhanced absolute file path of the include file in OS
+ * specific notation, not empty and not null.
+ */
+ public final String getIncludeAbsoluteFilePath(int type,
+ File documentDirectory, String filePath) {
+
+ if (filePath == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'filePath' must not be null.");
+ }
+
+ String relativeCurrentPrefix;
+ String relativeParentPrefix;
+ File absoluteFile;
+ relativeCurrentPrefix = ".";
+ relativeParentPrefix = "..";
+
+ // Ensure documentDirectory is a canonical file.
+ if (documentDirectory != null) {
+ documentDirectory = FileUtility.getCanonicalFile(documentDirectory);
+ }
+
+ // Check double or single dots followed by path delimiter first.
+ int relativeParentPrefixLength = relativeParentPrefix.length() + 1;
+ int relativeCurrentPrefixLength = relativeCurrentPrefix.length() + 1;
+ if (filePath.startsWith(relativeParentPrefix)
+ && filePath.length() >= relativeParentPrefixLength) {
+ if (documentDirectory == null) {
+ return null;
+ }
+ absoluteFile = new File(documentDirectory.getParentFile(),
+ filePath.substring(relativeParentPrefixLength));
+
+ } else if (filePath.startsWith(relativeCurrentPrefix)
+ && filePath.length() >= relativeCurrentPrefixLength) {
+ if (documentDirectory == null) {
+ return null;
+ }
+ absoluteFile = new File(documentDirectory,
+ filePath.substring(relativeCurrentPrefixLength));
+ } else {
+
+ // If there is no file separator in the file name, we can assume a
+ // relative path based on the current directory.
+ File file = new File(filePath);
+ if (file.exists()) {
+ absoluteFile = file;
+ } else {
+ absoluteFile = new File(documentDirectory, filePath);
+ }
+ }
+
+ // Ensure the complete file path is in OS notation.
+ absoluteFile = FileUtility.getCanonicalFile(absoluteFile);
+ String absoluteFilePath = absoluteFile.getPath();
+ if (type == CompilerSourceParserFileReferenceType.SOURCE) {
+ int index = absoluteFilePath.lastIndexOf(File.separator);
+ if (index < 1) {
+ index = 0;
+ }
+ String fileName = absoluteFilePath.substring(index);
+ index = fileName.lastIndexOf('.');
+ if (index == -1) {
+ String extension = compilerSyntax
+ .getSourceIncludeDefaultExtension();
+ if (extension.length() > 0) {
+ absoluteFilePath = absoluteFilePath + "." + extension;
+ }
+ }
+ }
+ return absoluteFilePath;
+ }
+
+ /**
+ * Creates a new, yet empty compiler source file.
+ *
+ * @param file
+ * The file, not null.
+ * @param document
+ * The document, not null.
+ * @return The compiler source file for use in
+ * {@link #parse(CompilerSourceFile, CompilerSourceParserLineCallback)}
+ * , not null.
+ * @since 1.6.1
+ */
+ public final CompilerSourceFile createCompilerSourceFile(File file,
+ IDocument document) {
+ if (compilerSyntax == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerSyntax' must not be null.");
+ }
+ if (document == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'document' must not be null.");
+ }
+ return new CompilerSourceFile(compilerSyntax, file, document);
+ }
+
+ /**
+ * Creates a new compiler source file for persistent file.
+ *
+ * @param filePath
+ * The absolute file path, not empty and not null.
+ * @return The compiler source file, not null.
+ *
+ * @since 1.6.3
+ */
+ private CompilerSourceFile createCompilerSourceFile(String filePath) {
+ if (filePath == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'filePath' must not be null.");
+ }
+ if (StringUtility.isEmpty(filePath)) {
+ throw new IllegalArgumentException(
+ "Parameter 'filePath' must not be empty.");
+ }
+ File newDocumentFile = new File(filePath);
+ String newDocumentContent;
+ try {
+ newDocumentContent = FileUtility.readString(newDocumentFile,
+ FileUtility.MAX_SIZE_UNLIMITED);
+ } catch (CoreException ex) {
+ newDocumentContent = compilerSyntax
+ .getSingleLineCommentDelimiters().get(0)
+ + " "
+ + ex.getMessage();
+ }
+ IDocument newDocument = new Document(newDocumentContent);
+ CompilerSourceFile newSourceFile = createCompilerSourceFile(
+ newDocumentFile, newDocument);
+ return newSourceFile;
+ }
+
+ /**
+ * Parse the new input and builds up the parse tree.
+ *
+ * @param compilerSourceFile
+ * The file to be parsed, not null.
+ * @param compilerSourceParserLineCallback
+ * The callback to be notified when a certain line is encountered
+ * or null.
+ */
+ public final void parse(CompilerSourceFile compilerSourceFile,
+ CompilerSourceParserLineCallback compilerSourceParserLineCallback) {
+ if (compilerSourceFile == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerSourceFile' must not be null.");
+ }
+ Map parsedFiles;
+ parsedFiles = new HashMap();
+ parseInternal(compilerSourceFile, parsedFiles,
+ compilerSourceParserLineCallback);
+ return;
+ }
+
+ /**
+ * Parse the new input and builds up the parse tree recursively with
+ * collecting already parsed includes.
+ *
+ * @param compilerSourceFile
+ * The file to be parsed, not null.
+ * @param parsedFiles
+ * The list of already parsed file names to prevent recursion,
+ * not null.
+ * @param compilerSourceParserLineCallback
+ * The callback to be notified when a certain line is encountered
+ * or null.
+ * @return true if the file was parsed now, false
+ * if the file is already in the list of parsed files.
+ */
+ private boolean parseInternal(CompilerSourceFile compilerSourceFile,
+ Map parsedFiles,
+ CompilerSourceParserLineCallback compilerSourceParserLineCallback) {
+ if (compilerSourceFile == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerSourceFile' must not be null.");
+ }
+ if (parsedFiles == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'parsedFiles' must not be null.");
+ }
+
+ // Ensure every persistent file is parsed only once to prevent infinite
+ // recursions cause by circular includes. Non-persistent files cannot
+ // cause recursions since they cannot be included yet.
+ if (compilerSourceFile.getDocumentFile() != null) {
+ String key = compilerSourceFile.getDocumentFile().getPath();
+ if (parsedFiles.containsKey(key)) {
+ return false;
+ }
+ parsedFiles.put(key, compilerSourceFile);
+ }
+
+ this.compilerSourceFile = compilerSourceFile;
+
+ // To allow folding for introduction comment at the begin of the source,
+ // the definition section is always open already, even if it does not
+ // contain any definitions.
+ child = compilerSourceFile.getDefinitionSection();
+ beginSection(0, true);
+
+ IDocument document = compilerSourceFile.getDocument();
+ int lines = document.getNumberOfLines();
+ int lineOffset, lineLength, startOffset, endOffset;
+ String stringLine = "";
+
+ // Prepare line and document offsets.
+ lineOffset = 0;
+ lineLength = 0;
+ startOffset = 0;
+ endOffset = 0;
+
+ // Prepare line section buffers.
+ StringBuilder symbolBuffer;
+ StringBuilder instructionBuffer;
+ StringBuilder operandBuffer;
+ StringBuilder commentBuffer;
+ char blockDefinitonStartCharacter;
+ char blockDefinitonEndCharacter;
+
+ symbolBuffer = new StringBuilder(100);
+ instructionBuffer = new StringBuilder(100);
+ operandBuffer = new StringBuilder(100);
+ commentBuffer = new StringBuilder(100);
+ blockDefinitonStartCharacter = compilerSyntax
+ .getBlockDefinitionStartCharacter();
+ blockDefinitonEndCharacter = compilerSyntax
+ .getBlockDefinitionEndCharacter();
+
+ for (int lineNumber = 0; lineNumber < lines; lineNumber++) {
+
+ /**
+ * Part 1: Parse line segments from line strin.
+ */
+
+ int symbolOffset = 0;
+ boolean symbolOffsetFound = false;
+ symbolBuffer.setLength(0);
+ int instructionOffset = 0;
+ boolean instructionOffsetFound = false;
+ instructionBuffer.setLength(0);
+ int operandOffset = 0;
+ boolean operandOffsetFound = false;
+ operandBuffer.setLength(0);
+ int commentOffset = 0;
+ boolean commentOffsetFound = false;
+ commentBuffer.setLength(0);
+
+ try {
+ IRegion region = document.getLineInformation(lineNumber);
+ lineOffset = region.getOffset();
+ lineLength = region.getLength();
+ stringLine = document.get(lineOffset, lineLength);
+
+ int pos = 0;
+ char lastChar = 0;
+ int lineSection = LineSection.NONE;
+ while (pos < lineLength) {
+ char ch = stringLine.charAt(pos);
+ boolean whiteSpace = Character.isWhitespace(ch);
+ // Find the next word.
+ if (pos == 0
+ || (!whiteSpace && Character.isWhitespace(lastChar))) {
+
+ // Does the current section allow instructions?
+ if (CompilerSourceParserTreeObjectType
+ .areInstructionsAllowed(section.getType())) {
+ if (lineSection == LineSection.NONE) {
+ lineSection = LineSection.SYMBOL;
+ } else if (lineSection == LineSection.SYMBOL) {
+ lineSection = LineSection.INSTRUCTION;
+ if (symbolBuffer.length() > 0) {
+ String possibleInstruction = symbolBuffer
+ .toString().toUpperCase();
+ if (isInstruction(possibleInstruction)) {
+
+ instructionOffset = symbolOffset;
+ instructionOffsetFound = true;
+ instructionBuffer.append(symbolBuffer);
+ symbolOffset = 0;
+ symbolBuffer.setLength(0);
+ lineSection = LineSection.OPERAND;
+ }
+ }
+ } else if (lineSection == LineSection.INSTRUCTION) {
+ lineSection = LineSection.OPERAND;
+ }
+ } else {
+ // No instructions allowed.
+ if (!symbolOffsetFound) {
+ if (!whiteSpace
+ && lineSection == LineSection.NONE) {
+ lineSection = LineSection.SYMBOL;
+ }
+ } else {
+ lineSection = LineSection.OPERAND;
+ }
+ }
+
+ }
+ String type = document.getPartition(lineOffset + pos)
+ .getType();
+ if (type.equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+ if (lineSection == LineSection.SYMBOL) {
+
+ // TODO: Does not work with kernel equates
+ // if (symbolBuffer.length() == 0 &&
+ // compilerSyntax.isIdentifierStartCharacter(ch)
+ // || symbolBuffer.length() > 0 &&
+ // compilerSyntax.isIdentifierPartCharacter(ch))
+ if (compilerSyntax.isIdentifierCharacter(ch)) {
+ if (!symbolOffsetFound) {
+ symbolOffsetFound = true;
+ symbolOffset = pos;
+ }
+ symbolBuffer.append(ch);
+
+ }
+ } else if (lineSection == LineSection.INSTRUCTION) {
+ if (!whiteSpace) {
+ if (!instructionOffsetFound) {
+ instructionOffsetFound = true;
+ instructionOffset = pos;
+ }
+ instructionBuffer.append(ch);
+ }
+ } else {
+ if (!operandOffsetFound) {
+ operandOffsetFound = true;
+ operandOffset = pos;
+ }
+ operandBuffer.append(ch);
+ }
+ } else if (type
+ .equals(CompilerSourcePartitionScanner.PARTITION_COMMENT_SINGLE)) {
+ if (!commentOffsetFound) {
+ commentOffsetFound = true;
+ commentOffset = pos;
+ }
+ // Keep spaces within comments and convert tabs to
+ // spaces.
+ if (ch == 0x9) {
+ ch = ' ';
+ }
+ if (ch != 0xa && ch != 0xd) {
+ commentBuffer.append(ch);
+ }
+ } else if (type
+ .equals(CompilerSourcePartitionScanner.PARTITION_STRING)) {
+ operandBuffer.append(ch);
+ }
+
+ lastChar = ch;
+ pos++;
+ }
+
+ } catch (BadLocationException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ /**
+ * Part 2: Post processing of line segments
+ */
+ startOffset = lineOffset;
+ try {
+ endOffset = startOffset + document.getLineLength(lineNumber);
+ } catch (BadLocationException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ // Check if the single symbol in the line is actually an
+ // instruction.
+ String possibleInstruction = symbolBuffer.toString().toUpperCase();
+ if (isInstruction(possibleInstruction)) {
+
+ instructionOffset = symbolOffset;
+ instructionBuffer.append(symbolBuffer);
+ symbolOffset = 0;
+ symbolBuffer.setLength(0);
+ }
+
+ String symbol = symbolBuffer.toString();
+ String instruction = instructionBuffer.toString();
+ if (!instructionSet.areInstructionsCaseSensitive()) {
+ instruction = instruction.toUpperCase();
+ }
+
+ // Refine operand and detect block start and end.
+ String operand = operandBuffer.toString().trim();
+ blockStarting = false;
+ if (operandOffsetFound) {
+ int blockStartOffset = operand
+ .indexOf(blockDefinitonStartCharacter);
+ if (blockStartOffset > -1) {
+ operand = operand.substring(0, blockStartOffset);
+ blockStarting = true;
+ }
+ }
+ blockEnding = false;
+ int blockEndOffset = stringLine.indexOf(blockDefinitonEndCharacter);
+ if (blockEndOffset > -1) {
+ if (!commentOffsetFound || blockEndOffset < commentOffset) {
+ blockEnding = true;
+ }
+ }
+
+ // Refine comment. Strip leading single comment sign.
+ String comment = commentBuffer.toString();
+ if (comment.length() > 0) {
+ for (String singleLineCommentDelimiter : compilerSyntax
+ .getSingleLineCommentDelimiters()) {
+ if (comment.startsWith(singleLineCommentDelimiter)) {
+ comment = comment.substring(singleLineCommentDelimiter
+ .length());
+ }
+ }
+ comment = comment.trim();
+ }
+
+ /**
+ * Part 3: Parse labels or equates, either directly or via
+ * delegation.
+ */
+ // This is an instance variable modified per line.
+ labelChild = null;
+
+ // Depending on the current context parsing is delegated or not.
+ switch (section.getType()) {
+ case CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION:
+ if (symbol.length() > 0) {
+ String value = operand.trim();
+
+ if (value.startsWith("=")) {
+ value = value.substring(1).trim();
+ }
+ if (value.length() == 0) {
+ value = "(auto)";
+ }
+ createEquateDefinitionChild(startOffset, startOffset
+ + symbolOffset, symbol, value, comment);
+ }
+ break;
+ case CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION:
+ if (symbol.length() > 0) {
+ createLabelDefinitionChild(startOffset, startOffset
+ + symbolOffset, symbol, comment);
+ }
+ break;
+ default:
+ parseLine(startOffset, symbol, symbolOffset, instruction,
+ instructionOffset, operand, comment);
+ break;
+ }
+
+ /**
+ * Part 4: Instruction based parsing
+ */
+ int positionStartOffset = startOffset + instructionOffset;
+ parseInstruction(startOffset, endOffset, positionStartOffset,
+ symbol, instruction, operand, comment, parsedFiles,
+ compilerSourceParserLineCallback);
+ // Label not yet consumed by instruction, so it is a single label.
+ if (labelChild != null) {
+ section.addChild(labelChild);
+ }
+
+ /**
+ * Part 6: Handle generic block starts and ends.
+ */
+ if (blockStarting && child == null) {
+ // Block started but not yet converted into a child like a macro
+ // or procedure.
+ beginFolding(startOffset);
+ }
+ if (blockEnding) {
+ // Arbitrary block end, can be section or folding.
+ if (compilerSourceFile.isFoldingForSection()) {
+ endSection(startOffset + blockEndOffset);
+ } else {
+ endFolding(startOffset + blockEndOffset);
+ }
+ }
+
+ /**
+ * Part 7: Callback for dedicated source file lines.
+ */
+ // Was the current file and line relevant for the callback?
+ if (compilerSourceParserLineCallback != null
+ && compilerSourceParserLineCallback.getSourceFilePath()
+ .equals(compilerSourceFile.getDocumentFile()
+ .getPath())
+ && lineNumber == compilerSourceParserLineCallback
+ .getLineNumber()) {
+ compilerSourceParserLineCallback.processLine(this,
+ compilerSourceFile, lineNumber, startOffset,
+ symbolOffset, isInstruction(instruction),
+ instructionOffset, instruction, operandOffset, section);
+ }
+ }
+
+ // End last section.
+ endSection(document.getLength() > 0 ? document.getLength() - 1 : 0);
+
+ // End incomplete sections.
+ compilerSourceFile.endAllSections();
+
+ // End incomplete sections.
+ compilerSourceFile.endAllFoldings();
+
+ return true;
+ }
+
+ private boolean isInstruction(String instructionName) {
+ if (instructionName == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'instructionName' must not be null.");
+ }
+ boolean result;
+ result = instructionSet.getInstruction(instructionName) != null;
+ return result;
+ }
+
+ protected void parseLine(int startOffset, String symbol, int symbolOffset,
+ String instruction, int instructionOffset, String operand,
+ String comment) {
+ return;
+ }
+
+ protected final void createEquateDefinitionChild(int startOffset,
+ int positionStartOffset, String symbol, String operand,
+ String comment) {
+ ensureDefinitionSection(startOffset, positionStartOffset);
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.EQUATE_DEFINITION, symbol,
+ symbol + " = " + operand, comment);
+ section.addChild(child);
+
+ }
+
+ protected final void createLabelDefinitionChild(int startOffset,
+ int positionStartOffset, String symbol, String comment) {
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.LABEL_DEFINITION, symbol,
+ symbol, comment);
+ // Remember the label child. It will be added only if the label is not
+ // consumed by some other instruction.
+ labelChild = child;
+ }
+
+ protected final void beginImplementationSection(int startOffset,
+ int positionStartOffset, String operand, String comment) {
+
+ if (section.getParent() != null) {
+ return;
+ }
+ int endOffset = startOffset - 1;
+ if (endOffset < 0) {
+ endOffset = 0;
+ }
+ endSection(endOffset);
+
+ // Folding for an implementation section should only bebe active if
+ // there is´a name section in the code.
+ boolean withFolding = (StringUtility.isSpecified(operand));
+ if (StringUtility.isEmpty(operand)) {
+ operand = "Implementation Section";
+ }
+
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION,
+ operand, operand, comment);
+
+ // This will always be a top level section.
+ beginSection(startOffset, withFolding);
+ compilerSourceFile.getImplementationSections().add(section);
+ labelChild = null;
+ }
+
+ /**
+ * Parse the instruction in a single line.
+ *
+ * @param startOffset
+ * The start offset of the line.
+ * @param endOffset
+ * The end offset of the line, including its last character and
+ * the line delimiter is available.
+ * @param positionStartOffset
+ * The start offset for positioning the cursor.
+ * @param symbol
+ * The symbol name, may be empty, not null.
+ * @param instructionName
+ * The instruction name, may be empty, not null.
+ * @param operand
+ * The operand, may be empty, not null.
+ * @param comment
+ * The comment, may be empty, not null.
+ * @param parsedFiles
+ * The parsed files, not null.
+ * @param compilerSourceParserLineCallback
+ * The callback to be notified when a certain line is encountered
+ * or null.
+ */
+ private void parseInstruction(int startOffset, int endOffset,
+ int positionStartOffset, String symbol, String instructionName,
+ String operand, String comment,
+ Map parsedFiles,
+ CompilerSourceParserLineCallback compilerSourceParserLineCallback) {
+
+ if (StringUtility.isEmpty(instructionName)) {
+ return;
+ }
+ Instruction instruction = instructionSet
+ .getInstruction(instructionName);
+
+ if (instruction == null) {
+ return;
+ }
+
+ if (logEnabled) {
+ log("parseInstruction: startOffset={0} endOffset={1} positionStartOffset={2}, symbol={3} instructionName={4} symbol={5} instructionType={6} labelChild={7}",
+ Integer.toString(startOffset), Integer.toString(endOffset),
+ Integer.toString(positionStartOffset), symbol,
+ instructionName, operand,
+ Integer.toString(instruction.getType()), labelChild);
+ }
+
+ String symbolOrOperand;
+ String symbolOrOperandFirstWord;
+ symbolOrOperand = symbol;
+ if (StringUtility.isEmpty(symbolOrOperand)) {
+ symbolOrOperand = operand;
+ }
+ symbolOrOperandFirstWord = symbolOrOperand;
+ int i = 0;
+ for (; i < symbolOrOperandFirstWord.length(); i++) {
+ if (Character.isWhitespace(symbolOrOperandFirstWord.charAt(i))) {
+ break;
+ }
+ }
+ symbolOrOperandFirstWord = symbolOrOperandFirstWord.substring(0, i);
+
+ switch (instruction.getType()) {
+ case InstructionType.BEGIN_IMPLEMENTATION_SECTION_DIRECTIVE:
+ beginImplementationSection(startOffset, positionStartOffset,
+ operand, comment);
+ break;
+ case InstructionType.DIRECTIVE:
+ if (blockStarting) {
+ beginFolding(startOffset);
+ }
+ break;
+ case InstructionType.BEGIN_FOLDING_BLOCK_DIRECTIVE:
+ beginFolding(startOffset);
+ break;
+ case InstructionType.END_FOLDING_BLOCK_DIRECTIVE:
+ endFolding(endOffset);
+ break;
+ case InstructionType.END_SECTION_DIRECTIVE:
+ endSection(endOffset);
+ break;
+
+ case InstructionType.BEGIN_ENUM_DEFINITION_SECTION_DIRECTIVE:
+ ensureDefinitionSection(startOffset, positionStartOffset);
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION,
+ symbolOrOperandFirstWord, symbolOrOperand, comment);
+ beginSection(startOffset, true);
+ break;
+
+ case InstructionType.BEGIN_STRUCTURE_DEFINITION_SECTION_DIRECTIVE:
+ ensureDefinitionSection(startOffset, positionStartOffset);
+ createChild(
+ positionStartOffset,
+ CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION,
+ symbolOrOperandFirstWord, symbolOrOperand, comment);
+ beginSection(startOffset, true);
+ break;
+
+ case InstructionType.BEGIN_LOCAL_SECTION_DIRECTIVE:
+ ensureImplementationSection(startOffset, positionStartOffset);
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.LOCAL_SECTION,
+ symbolOrOperandFirstWord, symbolOrOperand, comment);
+ beginSection(startOffset, true);
+
+ break;
+ case InstructionType.BEGIN_MACRO_DEFINITION_SECTION_DIRECTIVE:
+ ensureDefinitionSection(startOffset, positionStartOffset);
+ createChild(
+ positionStartOffset,
+ CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION,
+ symbolOrOperandFirstWord, symbolOrOperand, comment);
+ beginSection(startOffset, true);
+ break;
+ case InstructionType.BEGIN_PROCEDURE_DEFINITION_SECTION_DIRECTIVE:
+ ensureImplementationSection(startOffset, positionStartOffset);
+ createChild(
+ positionStartOffset,
+ CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION,
+ symbolOrOperandFirstWord, symbolOrOperand, comment);
+ beginSection(startOffset, true);
+ break;
+ case InstructionType.BEGIN_PAGES_SECTION_DIRECTIVE:
+ ensureImplementationSection(startOffset, positionStartOffset);
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.PAGES_SECTION, "",
+ symbolOrOperand, comment);
+ beginSection(startOffset, true);
+ break;
+ case InstructionType.BEGIN_REPEAT_SECTION_DIRECTIVE:
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.REPEAT_SECTION, "",
+ symbolOrOperand, comment);
+ beginSection(startOffset, true);
+ break;
+
+ case InstructionType.SOURCE_INCLUDE_DIRECTIVE:
+ // Remove leading and trailing string delimiters.
+ String filePath = operand;
+ for (String stringDelimiter : compilerSyntax.getStringDelimiters()) {
+ if (filePath.startsWith(stringDelimiter)) {
+ filePath = filePath.substring(stringDelimiter.length());
+ break;
+ }
+ }
+ for (String stringDelimiter : compilerSyntax.getStringDelimiters()) {
+ if (filePath.endsWith(stringDelimiter)) {
+ filePath = filePath.substring(0, filePath.length()
+ - stringDelimiter.length());
+ break;
+ }
+ }
+ filePath = getIncludeAbsoluteFilePath(
+ CompilerSourceParserFileReferenceType.SOURCE,
+ compilerSourceFile.getDocumentDirectory(), filePath);
+
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.SOURCE_INCLUDE, "",
+ operand, comment);
+
+ // If there is no file, the include is a normal child.
+ if (filePath == null) {
+ if (labelChild == null) {
+ section.addChild(child);
+ } else {
+ labelChild.addChild(child);
+ }
+ } else {
+ // If there is a file, the include is a section.
+ beginSection(startOffset, true);
+
+ // Preserve current line specific state into local variables.
+ CompilerSourceFile oldSourceFile = compilerSourceFile;
+ CompilerSourceParserTreeObject oldSection = section;
+ CompilerSourceParserTreeObject oldChild = child;
+ CompilerSourceParserTreeObject oldLabelChild = labelChild;
+ boolean oldBlockStarting = blockStarting;
+ boolean oldBlockEnding = blockEnding;
+
+ CompilerSourceFile newSourceFile = createCompilerSourceFile(filePath);
+
+ // This might be moved to the createCompilerSourceFile() method.
+ CompilerSourcePartitionScanner partitionScanner = new CompilerSourcePartitionScanner(
+ compilerSyntax);
+ partitionScanner.createDocumentPartitioner(newSourceFile
+ .getDocument());
+ boolean parsed = parseInternal(newSourceFile, parsedFiles,
+ compilerSourceParserLineCallback);
+
+ if (parsed) {
+ // Restore old line specific state from local variables.
+ section = oldSection;
+ compilerSourceFile = oldSourceFile;
+ child = oldChild;
+ labelChild = oldLabelChild;
+ blockStarting = oldBlockStarting;
+ blockEnding = oldBlockEnding;
+
+ section.setIncludedCompilerSourceFile(newSourceFile);
+ List newSourceFileSections = newSourceFile
+ .getSections();
+ if (newSourceFileSections.size() == 1
+ && newSourceFileSections.get(0).getType() == CompilerSourceParserTreeObjectType.SOURCE_INCLUDE) {
+ newSourceFileSections = newSourceFileSections.get(0)
+ .getChildren();
+ }
+ for (CompilerSourceParserTreeObject newChild : newSourceFileSections) {
+ section.addChild(newChild);
+ }
+ } else {
+ AssemblerPlugin
+ .getInstance()
+ .log("Include file '{0}' was already parsed. Stopping recursion.",
+ new Object[] { newSourceFile
+ .getDocumentFile().getPath() });
+ }
+ endSection(endOffset);
+ }
+ break;
+ case InstructionType.BINARY_INCLUDE_DIRECTIVE:
+ ensureImplementationSection(startOffset, positionStartOffset);
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.BINARY_INCLUDE, "",
+ operand, comment);
+ if (labelChild == null) {
+ section.addChild(child);
+ } else {
+ labelChild.addChild(child);
+ }
+
+ break;
+ case InstructionType.BINARY_OUTPUT_DIRECTIVE:
+
+ createChild(positionStartOffset,
+ CompilerSourceParserTreeObjectType.BINARY_OUTPUT, "",
+ operand, comment);
+ if (labelChild == null) {
+ section.addChild(child);
+ } else {
+ labelChild.addChild(child);
+ }
+
+ break;
+ }
+
+ }
+
+ private void ensureDefinitionSection(int startOffset,
+ int positionStartOffset) {
+ // To allow folding for introduction comment at the begin of the source,
+ // the definition section is always open already.
+ }
+
+ private void ensureImplementationSection(int startOffset,
+ int positionStartOffset) {
+ if (section.getType() == CompilerSourceParserTreeObjectType.DEFINITION_SECTION) {
+ beginImplementationSection(startOffset, positionStartOffset, "", "");
+ }
+ }
+
+ private void createChild(int startOffset, int type, String name,
+ String displayName, String comment) {
+ if (startOffset < 0) {
+ throw new IllegalArgumentException(
+ "Parameter 'startOffset' must not be negative. Specified value is "
+ + startOffset + ".");
+ }
+ if (name == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'name' must not be null.");
+ }
+ if (displayName == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'displayName' must not be null.");
+ }
+ if (comment == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'comment' must not be null.");
+ }
+
+ child = new CompilerSourceParserTreeObject(compilerSourceFile,
+ startOffset, type, name, displayName, comment);
+ }
+
+ /**
+ * Starts a new active section.
+ *
+ * @param startOffset
+ * The start offset, a non-negative integer.
+ * @param withFolding
+ * true if the section is also a folding section,
+ * false otherwise.
+ */
+ private void beginSection(int startOffset, boolean withFolding) {
+ if (startOffset < 0) {
+ throw new IllegalArgumentException(
+ "Parameter 'startOffset' must not be negative. Specified value is "
+ + startOffset + ".");
+ }
+ if (child == null) {
+ throw new IllegalStateException("Field 'child' must not be null.");
+ }
+ section = child;
+ compilerSourceFile.beginSection(startOffset, section, withFolding);
+ labelChild = null;
+ blockStarting = false;
+ }
+
+ /**
+ * Ends the currently active section.
+ *
+ * @param endOffset
+ * The end offset, a non-negative integer.
+ */
+ private void endSection(int endOffset) {
+ if (section == null) {
+ throw new IllegalStateException(
+ "Variable 'section' must not be null.");
+ }
+ if (endOffset < 0) {
+ throw new IllegalArgumentException(
+ "Parameter 'endOffset' must not be negative. Specified value is "
+ + endOffset + ".");
+ }
+ CompilerSourceParserTreeObject section;
+ section = compilerSourceFile.endSection(endOffset);
+ if (section != null) {
+ this.section = section;
+ }
+ labelChild = null;
+ blockEnding = false;
+ }
+
+ /**
+ * Starts a new active folding which does not belong to a section.
+ *
+ * @param startOffset
+ * The start offset, a non-negative integer.
+ */
+ private void beginFolding(int startOffset) {
+ compilerSourceFile.beginFolding(startOffset, false);
+ blockStarting = false;
+ }
+
+ /**
+ * Ends the currently active folding which does not belong to a section.
+ *
+ * @param endOffset
+ * The end offset, a non-negative integer. This must be the
+ * actual offset of the last character in the line, including the
+ * line end delimiter, if present.
+ */
+ private void endFolding(int endOffset) {
+ compilerSourceFile.endFolding(endOffset);
+ blockEnding = false;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserFileReference.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserFileReference.java
new file mode 100644
index 00000000..a3c191c6
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserFileReference.java
@@ -0,0 +1,72 @@
+package com.wudsn.ide.asm.compiler.parser;
+
+public final class CompilerSourceParserFileReference {
+
+ private int type;
+ private int directiveEndOffset;
+
+ /**
+ * Creation is public.
+ */
+ public CompilerSourceParserFileReference() {
+ type = CompilerSourceParserFileReferenceType.NONE;
+ directiveEndOffset = 0;
+
+ }
+
+ /**
+ * Sets the type of the include.
+ *
+ * @param type
+ * The type of the include, see
+ * {@link CompilerSourceParserFileReferenceType}.
+ */
+ public void setType(int type) {
+ switch (type) {
+ case CompilerSourceParserFileReferenceType.SOURCE:
+ case CompilerSourceParserFileReferenceType.BINARY:
+ break;
+
+ default:
+ throw new IllegalArgumentException("Illegal include type " + type
+ + ".");
+ }
+ this.type = type;
+ }
+
+ /**
+ * Get the type of the include.
+ *
+ * @return The type of the include, see
+ * {@link CompilerSourceParserFileReferenceType}.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Sets the include directive end offset. The value must be the offset of
+ * first character after the directive.
+ *
+ * @param directiveEndOffset
+ * The include directive end offset, a non-negative integer.
+ */
+ public void setDirectiveEndOffset(int directiveEndOffset) {
+ if (directiveEndOffset < 0) {
+ throw new IllegalArgumentException(
+ "Parameter 'directiveEndOffset' must not be be negative. Specified value was "
+ + directiveEndOffset + ".");
+ }
+ this.directiveEndOffset = directiveEndOffset;
+ }
+
+ /**
+ * Gets the include directive end offset.
+ *
+ * @return The include directive end offset, a non-negative integer.
+ */
+ public int getDirectiveEndOffset() {
+ return directiveEndOffset;
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserFileReferenceType.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserFileReferenceType.java
new file mode 100644
index 00000000..de62c379
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserFileReferenceType.java
@@ -0,0 +1,38 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.parser;
+
+/**
+ * The possible types of referenced files.
+ *
+ * @author Peter Dell
+ */
+public final class CompilerSourceParserFileReferenceType {
+
+ /**
+ * Creation is private.
+ */
+ private CompilerSourceParserFileReferenceType() {
+ }
+
+ public final static int NONE=1;
+ public final static int SOURCE = 2;
+ public final static int BINARY = 3;
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserLineCallback.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserLineCallback.java
new file mode 100644
index 00000000..630a287b
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserLineCallback.java
@@ -0,0 +1,85 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.parser;
+
+/**
+ * Callback interface to react on the parsing of certain source file lines.
+ *
+ * @author Peter Dell
+ *
+ * @since 1.6.0
+ */
+public abstract class CompilerSourceParserLineCallback {
+ private String filePath;
+ private int lineNumber;
+
+ /**
+ * Creation is protected.
+ *
+ * @param filePath
+ * The absolute path of the source file, not empty and not
+ * null.
+ * @param lineNumber
+ * The line number, a non-negative integer or -1 to
+ * indicate that no line number is relevant.
+ */
+ protected CompilerSourceParserLineCallback(String filePath, int lineNumber) {
+ if (filePath == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'filePath' must not be null.");
+ }
+ if (lineNumber < 0) {
+ throw new IllegalArgumentException(
+ "Parameter 'lineNumber' must not be negative. Specified value is "
+ + lineNumber + ".");
+ }
+ this.filePath = filePath;
+ this.lineNumber = lineNumber;
+ }
+
+ /**
+ * Gets the path of the source file for which for which the callback shall
+ * be triggered.
+ *
+ * @return The absolute path of the source file, not empty and not
+ * null.
+ */
+ public final String getSourceFilePath() {
+ return filePath;
+ }
+
+ /**
+ * Gets the line number for which the callback shall be triggered.
+ *
+ * @return The line number, a non-negative integer or -1 to
+ * indicate that no line number is relevant.
+ */
+ public final int getLineNumber() {
+ return lineNumber;
+ }
+
+ // Most of the parameters are currently not used by the consumer.
+ public abstract void processLine(CompilerSourceParser compilerSourceParser,
+ CompilerSourceFile compilerSourceFile, int lineNumber,
+ int startOffset, int symbolOffset, boolean instructionFound,
+ int instructionOffset, String instruction, int operandOffset,
+ CompilerSourceParserTreeObject section);
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserTreeObject.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserTreeObject.java
new file mode 100644
index 00000000..b2faaa1f
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserTreeObject.java
@@ -0,0 +1,411 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.StyledString;
+
+import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * The object representing a node in the content outline tree.
+ *
+ * @author Peter Dell
+ * @author Andy Reek
+ */
+public final class CompilerSourceParserTreeObject {
+
+ private final CompilerSourceFile compilerSourceFile;
+
+ private final int startOffset;
+
+ private final int type;
+
+ private final String name;
+
+ private final String displayName;
+
+ private final String description;
+
+ private final StyledString styledString;
+
+ private final List children;
+
+ private CompilerSourceParserTreeObject parent;
+
+ private String treePath;
+
+ private String compoundName;
+
+ private CompilerSourceFile includedCompilerSourceFile;
+
+ /**
+ * Create a new instance.
+ *
+ * @param compilerSourceFile
+ * The source file to which this parser tree object belongs.
+ *
+ * @param startOffset
+ * The start offset of the instance, a non-negative integer.
+ * @param type
+ * The type of a instance, see
+ * {@link CompilerSourceParserTreeObjectType}.
+ * @param name
+ * The name of the tree object, not null. It is used
+ * to build the full tree path,
+ * @param displayName
+ * The display name of the tree object, not null. It
+ * is used in the tree view.
+ * @param description
+ * The description of the tree object, not null.
+ */
+ CompilerSourceParserTreeObject(CompilerSourceFile compilerSourceFile,
+ int startOffset, int type, String name, String displayName,
+ String description) {
+ if (compilerSourceFile == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerSourceFile' must not be null.");
+ }
+ if (startOffset < 0) {
+ throw new IllegalArgumentException(
+ "Parameter 'startOffset' must not be negative. Specified value is "
+ + startOffset + ".");
+ }
+ this.compilerSourceFile = compilerSourceFile;
+ this.startOffset = startOffset;
+
+ switch (type) {
+ case CompilerSourceParserTreeObjectType.DEFAULT:
+
+ case CompilerSourceParserTreeObjectType.DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION:
+
+ case CompilerSourceParserTreeObjectType.EQUATE_DEFINITION:
+ case CompilerSourceParserTreeObjectType.LABEL_DEFINITION:
+
+ case CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.LOCAL_SECTION:
+ case CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.PAGES_SECTION:
+ case CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.REPEAT_SECTION:
+
+ case CompilerSourceParserTreeObjectType.SOURCE_INCLUDE:
+ case CompilerSourceParserTreeObjectType.BINARY_INCLUDE:
+ case CompilerSourceParserTreeObjectType.BINARY_OUTPUT:
+
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown type " + type + ".");
+ }
+ if (name == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'name' must not be null.");
+ }
+ if (displayName == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'displayName' must not be null.");
+ }
+ if (description == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'description' must not be null.");
+ }
+ this.type = type;
+ this.name = name;
+ this.displayName = displayName;
+ this.description = description;
+
+ styledString = new StyledString(displayName);
+ if (description.length() > 0) {
+ styledString.append(" ");
+ styledString.append(description, StyledString.QUALIFIER_STYLER);
+ }
+ this.children = new ArrayList();
+ }
+
+ /**
+ * Gets the compiler source file, this parser tree object belongs to.
+ *
+ * @return The compiler source file, this parser tree object belongs to, not
+ * null.
+ */
+ public CompilerSourceFile getCompilerSourceFile() {
+ return compilerSourceFile;
+ }
+
+ /**
+ * Gets the start offset of this parser tree object in the compiler source
+ * file.
+ *
+ * @return The start offset of this parser tree object in the compiler
+ * source file, a non-negative integer.
+ */
+ public int getStartOffset() {
+ return startOffset;
+ }
+
+ /**
+ * Gets the type of the object.
+ *
+ * @return The type, see {@link CompilerSourceParserTreeObjectType}.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Gets the name of the object.
+ *
+ * @return The name, not null.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the compound name of the object.
+ *
+ * @return The compound name, not null.
+ */
+ public String getCompoundName() {
+ if (compoundName == null) {
+ char identifierSeparatorCharacter = compilerSourceFile
+ .getCompilerSyntax().getIdentifierSeparatorCharacter();
+ switch (type) {
+ case CompilerSourceParserTreeObjectType.DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION:
+ case CompilerSourceParserTreeObjectType.REPEAT_SECTION:
+ case CompilerSourceParserTreeObjectType.SOURCE_INCLUDE:
+ case CompilerSourceParserTreeObjectType.BINARY_INCLUDE:
+ case CompilerSourceParserTreeObjectType.BINARY_OUTPUT:
+ if (parent != null) {
+ compoundName = parent.getCompoundName();
+ } else {
+ compoundName = "";
+ }
+ return compoundName;
+ }
+
+ compoundName = name;
+
+ // Compound identifiers supported?
+ if (identifierSeparatorCharacter != CompilerSyntax.NO_CHARACTER) {
+
+ // Find next named parent.
+ CompilerSourceParserTreeObject namedParent = parent;
+ while (namedParent != null
+ // && namedParent.getType() !=
+ // CompilerSourceParserTreeObjectType.DEFINITION_SECTION
+ // && namedParent.getType() !=
+ // CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION
+ // && namedParent.getType() !=
+ // CompilerSourceParserTreeObjectType.REPEAT_SECTION
+ // && namedParent.getType() !=
+ // CompilerSourceParserTreeObjectType.SOURCE_INCLUDE
+ // && namedParent.getType() !=
+ // CompilerSourceParserTreeObjectType.BINARY_INCLUDE
+ // && namedParent.getType() !=
+ // CompilerSourceParserTreeObjectType.BINARY_OUTPUT
+
+ && namedParent.getType() != CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION
+ && namedParent.getType() != CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION
+ && namedParent.getType() != CompilerSourceParserTreeObjectType.LOCAL_SECTION
+ && namedParent.getType() != CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION
+ && namedParent.getType() != CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION) {
+ namedParent = namedParent.getParent();
+ }
+ if (namedParent != null
+ && StringUtility.isSpecified(compoundName)) {
+ String parentCompoundName;
+ parentCompoundName = parent.getCompoundName();
+ if (StringUtility.isSpecified(parentCompoundName)) {
+ compoundName = parentCompoundName
+ + identifierSeparatorCharacter + compoundName;
+ }
+ }
+ }
+ }
+
+ return compoundName;
+
+ }
+
+ /**
+ * Gets the display name of the object.
+ *
+ * @return The display name, not null.
+ */
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ /**
+ * Gets the unique tree path of this tree object within the tree.
+ *
+ * @return The unique tree path, not empty and not null.
+ */
+ public String getTreePath() {
+ if (treePath == null) {
+ treePath = "\"" + type + "/" + name + "\"";
+ if (parent != null) {
+ treePath = parent.getTreePath() + "/" + treePath;
+ }
+ }
+ return treePath;
+ }
+
+ /**
+ * Gets the description of the object.
+ *
+ * @return The description, not null.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Gets the styled string of the object.
+ *
+ * @return The styled string, not null.
+ */
+ public StyledString getStyledString() {
+ return styledString;
+ }
+
+ /**
+ * Gets the parent object of the tree object.
+ *
+ * @return The parent, may be null.
+ */
+ public CompilerSourceParserTreeObject getParent() {
+ return parent;
+ }
+
+ /**
+ * Sets a new parent.
+ *
+ * @param parent
+ * The new parent, may be null.
+ */
+ final void setParent(CompilerSourceParserTreeObject parent) {
+ this.parent = parent;
+ this.treePath = null;
+ }
+
+ /**
+ * Determines if this tree object has children.
+ *
+ * @return true if this tree object has children,
+ * false otherwise.
+ */
+ public boolean hasChildren() {
+ return !children.isEmpty();
+ }
+
+ /**
+ * Gets all children of the tree object.
+ *
+ * @return The array of children, not null..
+ */
+ public Object[] getChildrenAsArray() {
+ return children.toArray(new Object[0]);
+ }
+
+ /**
+ * Gets all children of the tree object.
+ *
+ * @return The array of children, not null. Do not modify.
+ */
+ public List getChildren() {
+ return children;
+ }
+
+ /**
+ * Adds a new Child.
+ *
+ * @param child
+ * The new child, not null.
+ */
+ final void addChild(CompilerSourceParserTreeObject child) {
+ if (child == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'child' must not be null.");
+ }
+ if (child == this) {
+ throw new IllegalArgumentException(
+ "Parameter 'child' must not be this: " + toString());
+ }
+ children.add(child);
+ child.setParent(this);
+
+ }
+
+ /**
+ * Gets the included compiler source file for a SOURCE_INCLUDE tree object.
+ *
+ * @return The included compiler source file or null.
+ */
+ final CompilerSourceFile setIncludedCompilerSourceFile() {
+ return includedCompilerSourceFile;
+ }
+
+ /**
+ * Sets the included compiler source file for a SOURCE_INCLUDE tree object.
+ *
+ * @param includedCompilerSourceFile
+ * The included compiler source file, may be null.
+ */
+ final void setIncludedCompilerSourceFile(
+ CompilerSourceFile includedCompilerSourceFile) {
+ if (type != CompilerSourceParserTreeObjectType.SOURCE_INCLUDE) {
+ throw new IllegalStateException("The type of this tree object is "
+ + type + " and not SOURCE_INCLUDE");
+ }
+ this.includedCompilerSourceFile = includedCompilerSourceFile;
+
+ }
+
+
+ @Override
+ public boolean equals(Object object) {
+ if (!(object instanceof CompilerSourceParserTreeObject)) {
+ return false;
+ }
+ CompilerSourceParserTreeObject other;
+ other = (CompilerSourceParserTreeObject) object;
+ return getTreePath().equals(other.getTreePath());
+ }
+
+ @Override
+ public int hashCode() {
+ return getTreePath().hashCode();
+
+ }
+
+ @Override
+ public String toString() {
+ return getTreePath();
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserTreeObjectType.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserTreeObjectType.java
new file mode 100644
index 00000000..6f74f2af
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourceParserTreeObjectType.java
@@ -0,0 +1,143 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.compiler.parser;
+
+import com.wudsn.ide.asm.Texts;
+
+/**
+ * Constant values for tree object types.
+ *
+ * @author Peter Dell
+ */
+public final class CompilerSourceParserTreeObjectType {
+
+ /**
+ * Creation is private.
+ */
+ private CompilerSourceParserTreeObjectType() {
+ }
+
+ /**
+ * Default-type
+ */
+ public static final int DEFAULT = 0;
+
+ public static final int DEFINITION_SECTION = 1;
+ public static final int IMPLEMENTATION_SECTION = 2;
+
+ public static final int EQUATE_DEFINITION = 3;
+ public static final int LABEL_DEFINITION = 4;
+
+ public static final int ENUM_DEFINITION_SECTION = 5;
+ public static final int STRUCTURE_DEFINITION_SECTION = 6;
+ public static final int LOCAL_SECTION = 7;
+ public static final int MACRO_DEFINITION_SECTION = 8;
+ public static final int PAGES_SECTION = 9;
+ public static final int PROCEDURE_DEFINITION_SECTION = 10;
+ public static final int REPEAT_SECTION = 11;
+
+ public static final int SOURCE_INCLUDE = 12;
+ public static final int BINARY_INCLUDE = 13;
+ public static final int BINARY_OUTPUT = 14;
+
+ /**
+ * Gets the localized text for a compiler source parser tree object type.
+ *
+ * @param type
+ * The type, see constants of this class.
+ * @return The localized text, may be empty but not null.
+ */
+ public static String getText(int type) {
+ String result;
+ switch (type) {
+ case DEFAULT:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFAULT;
+ break;
+ case DEFINITION_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_DEFINITION_SECTION;
+ break;
+ case IMPLEMENTATION_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_IMPLEMENTATION_SECTION;
+ break;
+ case EQUATE_DEFINITION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_EQUATE_DEFINITION;
+ break;
+ case LABEL_DEFINITION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LABEL_DEFINITION;
+ break;
+ case ENUM_DEFINITION_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_ENUM_DEFINITION_SECTION;
+ break;
+ case STRUCTURE_DEFINITION_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_STRUCTURE_DEFINITION_SECTION;
+ break;
+ case LOCAL_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_LOCAL_SECTION;
+ break;
+ case MACRO_DEFINITION_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_MACRO_DEFINITION_SECTION;
+ break;
+ case PAGES_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PAGES_SECTION;
+ break;
+ case PROCEDURE_DEFINITION_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_PROCEDURE_DEFINITION_SECTION;
+ break;
+ case REPEAT_SECTION:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_REPEAT_SECTION;
+ break;
+ case SOURCE_INCLUDE:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_SOURCE_INCLUDE;
+ break;
+ case BINARY_INCLUDE:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_INCLUDE;
+ break;
+ case BINARY_OUTPUT:
+ result = Texts.COMPILER_SOURCE_PARSER_TREE_OBJECT_TYPE_BINARY_OUTPUT;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown type " + type + ".");
+ }
+ return result;
+
+ }
+
+ /**
+ * Determines if instructions are allowed in the given type of section.
+ *
+ * @param type
+ * The type of the tree object, {link
+ * {@link CompilerSourceParserTreeObjectType}
+ * @return true if instructions are allowed, false
+ * otherwise.
+ *
+ * @since 1.6.0
+ */
+ public static boolean areInstructionsAllowed(int type) {
+ // Within ENUM_DEFINITION_SECTION everything is an equate.
+ // Within STRUCTURE_DEFINITION_SECTION everything is a label.
+ switch (type) {
+ case CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION:
+ return false;
+ default:
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourcePartitionScanner.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourcePartitionScanner.java
new file mode 100644
index 00000000..8e3e08c0
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/parser/CompilerSourcePartitionScanner.java
@@ -0,0 +1,141 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.EndOfLineRule;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+
+import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
+import com.wudsn.ide.asm.editor.AssemblerEditor;
+
+/**
+ * A partition scanner for the comments and strings.
+ *
+ * @author Peter Dell
+ * @author Andy Reek
+ */
+public final class CompilerSourcePartitionScanner extends
+ RuleBasedPartitionScanner {
+
+ /**
+ * Name for the single line comment partition.
+ */
+ public static final String PARTITION_COMMENT_SINGLE = "partition.comment.single"; //$NON-NLS-1$
+
+ /**
+ * Name for the multiple lines comment partition.
+ */
+ public static final String PARTITION_COMMENT_MULTIPLE = "partition.comment.multiple"; //$NON-NLS-1$
+
+ /**
+ * Name for the string partition.
+ */
+ public static final String PARTITION_STRING = "partition.string"; //$NON-NLS-1$
+
+ /**
+ * Creates a new instance.
+ *
+ * Called by
+ * {@link AssemblerEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)}
+ * .
+ *
+ * @param compilerSyntax
+ * The compiler syntax, not null.
+ */
+ public CompilerSourcePartitionScanner(CompilerSyntax compilerSyntax) {
+ if (compilerSyntax == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerSyntax' must not be null.");
+ }
+ IToken commentSingleToken = new Token(PARTITION_COMMENT_SINGLE);
+ IToken commentMultipleToken = new Token(PARTITION_COMMENT_MULTIPLE);
+ IToken stringToken = new Token(PARTITION_STRING);
+
+ List rules = new ArrayList();
+ for (String singleLineCommentDelimiter : compilerSyntax
+ .getSingleLineCommentDelimiters()) {
+
+ // A "*" is only a comment start token if it is followed by a space
+ // or a tab.
+ // It is allowed as part of an expression to refer to the program
+ // counter.
+ if (singleLineCommentDelimiter.equals("*")) {
+ rules.add(new EndOfLineRule(singleLineCommentDelimiter + " ",
+ commentSingleToken));
+ rules.add(new EndOfLineRule(singleLineCommentDelimiter + "\t",
+ commentSingleToken));
+ } else {
+ rules.add(new EndOfLineRule(singleLineCommentDelimiter,
+ commentSingleToken));
+ }
+ }
+ List multipleLinesCommentDelimiters = compilerSyntax
+ .getMultipleLinesCommentDelimiters();
+ for (int i = 0; i < multipleLinesCommentDelimiters.size();) {
+ String startSequence = multipleLinesCommentDelimiters.get(i++);
+ String endSequence = multipleLinesCommentDelimiters.get(i++);
+ rules.add(new MultiLineRule(startSequence, endSequence,
+ commentMultipleToken));
+ }
+
+ for (String stringDelimiter : compilerSyntax.getStringDelimiters()) {
+ rules.add(new SingleLineRule(stringDelimiter, stringDelimiter,
+ stringToken));
+ }
+
+
+ IPredicateRule[] rulesArray = new IPredicateRule[rules.size()];
+ rules.toArray(rulesArray);
+ setPredicateRules(rulesArray);
+ }
+
+ /**
+ * Creates a new FastPartitioner based on this partition scanner and
+ * connects it to the document.
+ *
+ * @param document
+ * The document, not null.
+ */
+ public void createDocumentPartitioner(IDocument document) {
+
+ if (document == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'document' must not be null.");
+ }
+ FastPartitioner partitioner = new FastPartitioner(this, new String[] {
+ CompilerSourcePartitionScanner.PARTITION_COMMENT_SINGLE,
+ CompilerSourcePartitionScanner.PARTITION_COMMENT_MULTIPLE,
+ CompilerSourcePartitionScanner.PARTITION_STRING });
+ partitioner.connect(document);
+ document.setDocumentPartitioner(partitioner);
+
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/CompilerSyntax.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/CompilerSyntax.java
new file mode 100644
index 00000000..c01c76f5
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/CompilerSyntax.java
@@ -0,0 +1,936 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.syntax;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.wudsn.ide.asm.CPU;
+import com.wudsn.ide.asm.compiler.CompilerRegistry;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Container for a set of directives, legal, illegal and pseudo opcodes and
+ * their properties.
+ *
+ * @author Peter Dell
+ * @author Daniel Mitte
+ *
+ */
+public final class CompilerSyntax {
+
+ public static final char NO_CHARACTER = (char) 0;
+
+ private static final class XMLHandler extends DefaultHandler {
+
+ // Completion proposal auto activation characters, possibly empty array
+ // of characters.
+ String completionProposalAutoActivationCharactersText;
+
+ // Single line delimiters, list of strings separated by spaces.
+ String singleLineCommentDelimitersText;
+
+ // Single line delimiters, list of strings separated by spaces.
+ String multipleLinesCommentDelimitersText;
+
+ // Single line delimiters, non empty array of characters.
+ String stringDelimiterCharactersText;
+
+ // The (possibly empty) string of character pairs which define the begin
+ // and end of a named or unnamed (folding) block.
+ String blockDefinitionCharactersText;
+
+ // The boolean value indicating if identifiers are case sensitive or
+ // not.
+ boolean identifiersCaseSensitive;
+
+ // The string containing all allowed identifier start characters.
+ String identifierStartCharactersText;
+
+ // The string containing all allowed identifier start characters.
+ String identifierPartCharactersText;
+
+ // The string containing the character which separates two parts of a
+ // compound identifier or
+ // the empty string if compound identifiers are not supported.
+ String identifierSeparatorCharacterText;
+
+ // The string containing the character which end a label definition or
+ // the empty string if label definitions end at the first white space.
+ String labelDefinitionSuffixCharacterText;
+
+ // The string containing the character which start a macro usage or
+ // the empty string if macro usages are not prefixed with a character.
+ String macroUsagePrefixCharacterText;
+
+ // The boolean value indicating if instructions are case sensitive or
+ // not.
+ boolean instructionsCaseSensitive;
+
+ // Default file extension to be added if it is missing for source
+ // include directives.
+ String sourceIncludeDefaultExtension;
+
+ List instructionsList;
+
+ public XMLHandler() {
+ instructionsList = new ArrayList();
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (qName == null) {
+ throw new IllegalArgumentException("Parameter 'qName' must not be null.");
+ }
+ if (attributes == null) {
+ throw new IllegalArgumentException("Parameter 'attributes' must not be null.");
+ }
+
+ if (qName.equals("instructionset")) {
+
+ // Completion proposal auto activation characters
+ completionProposalAutoActivationCharactersText = attributes
+ .getValue("completionProposalAutoActivationCharacters");
+ if (completionProposalAutoActivationCharactersText == null) {
+ throw new SAXException("No completionProposalAutoActivationCharacters specified.");
+ }
+
+ // Single lines comments.
+ singleLineCommentDelimitersText = attributes.getValue("singleLineCommentDelimiters");
+ if (singleLineCommentDelimitersText == null) {
+ throw new SAXException("No singleLineCommentDelimiters specified.");
+ }
+ if (StringUtility.isEmpty(singleLineCommentDelimitersText)) {
+ throw new SAXException("Attribute singleLineCommentDelimiterst must not be empty.");
+ }
+
+ // Multiple lines comments.
+ multipleLinesCommentDelimitersText = attributes.getValue("multipleLinesCommentDelimiters");
+ if (multipleLinesCommentDelimitersText == null) {
+ throw new SAXException("No multipleLinesCommentDelimiters specified.");
+ }
+
+ // Strings.
+ stringDelimiterCharactersText = attributes.getValue("stringDelimiterCharacters");
+ if (stringDelimiterCharactersText == null) {
+ throw new SAXException("No stringDelimiterCharacters specified.");
+ }
+ if (StringUtility.isEmpty(stringDelimiterCharactersText)) {
+ throw new SAXException("Attribute stringDelimiterCharacters must not be empty.");
+ }
+
+ // Block definition characters
+ blockDefinitionCharactersText = attributes.getValue("blockDefinitionCharacters");
+ if (blockDefinitionCharactersText == null) {
+ throw new SAXException("No blockDefinitionCharacters specified.");
+ }
+ if (blockDefinitionCharactersText.length() % 2 != 0) {
+ throw new SAXException("Attribute blockDefinitionCharacters must and even number of characters.");
+ }
+
+ // Identifiers: Case sensitive.
+ String value = attributes.getValue("identifiersCaseSensitive");
+ if (value == null) {
+ throw new SAXException("No identifiersCaseSensitive specified.");
+ }
+ if (!value.equals("true") && !value.equals("false")) {
+ throw new SAXException("Attribute identifiersCaseSensitive must be \"true\" or \"false\".");
+ }
+ identifiersCaseSensitive = Boolean.parseBoolean(value);
+
+ // Identifiers: Start characters.
+ identifierStartCharactersText = attributes.getValue("identifierStartCharacters");
+ if (identifierStartCharactersText == null) {
+ throw new SAXException("No identifierStartCharacters specified.");
+ }
+ if (StringUtility.isEmpty(identifierStartCharactersText)) {
+ throw new SAXException("Attribute identifierStartCharacters must not be empty.");
+ }
+
+ // Identifiers: Start characters.
+ identifierPartCharactersText = attributes.getValue("identifierPartCharacters");
+ if (identifierPartCharactersText == null) {
+ throw new SAXException("No identifierPartCharacters specified.");
+ }
+ if (StringUtility.isEmpty(identifierPartCharactersText)) {
+ throw new SAXException("Attribute identifierPartCharacters must not be empty.");
+ }
+
+ // Identifiers: Separator character.
+ identifierSeparatorCharacterText = attributes.getValue("identifierSeparatorCharacter");
+ if (identifierSeparatorCharacterText == null) {
+ throw new SAXException("No identifierSeparatorCharacter specified.");
+ }
+ if (identifierSeparatorCharacterText.length() > 1) {
+ throw new SAXException(
+ "Attribute identifierSeparatorCharacter must not contain more than 1 characters.");
+ }
+
+ // Identifiers: Label definition suffix character.
+ labelDefinitionSuffixCharacterText = attributes.getValue("labelDefinitionSuffixCharacter");
+ if (labelDefinitionSuffixCharacterText == null) {
+ throw new SAXException("No labelDefinitionSuffixCharacter specified.");
+ }
+ if (labelDefinitionSuffixCharacterText.length() > 1) {
+ throw new SAXException(
+ "Attribute labelDefinitionSuffixCharacter must not contain more than 1 characters.");
+ }
+
+ // Identifiers: Macro usage prefix character.
+ macroUsagePrefixCharacterText = attributes.getValue("macroUsagePrefixCharacter");
+ if (macroUsagePrefixCharacterText == null) {
+ throw new SAXException("No macroUsagePrefixCharacter specified.");
+ }
+ if (macroUsagePrefixCharacterText.length() > 1) {
+ throw new SAXException(
+ "Attribute macroUsagePrefixCharacter must not contain more than 1 characters.");
+ }
+
+ // Instructions case sensitive.
+ value = attributes.getValue("instructionsCaseSensitive");
+ if (value == null) {
+ throw new SAXException("No instructionsCaseSensitive specified.");
+ }
+ if (!value.equals("true") && !value.equals("false")) {
+ throw new SAXException("Attribute instructionsCaseSensitive must be \"true\" or \"false\".");
+ }
+ instructionsCaseSensitive = Boolean.parseBoolean(value);
+
+ // Source include default extension.
+ sourceIncludeDefaultExtension = attributes.getValue("sourceIncludeDefaultExtension");
+ if (sourceIncludeDefaultExtension == null) {
+ throw new SAXException("No sourceIncludeDefaultExtension specified.");
+ }
+
+ } else if (qName.equals("opcodes")) {
+ // Nothing to do.
+ } else {
+
+ // Begin parsing of instructions.
+ String cpusString;
+ Set cpus;
+ String name;
+ String title;
+ String proposal;
+ String typeString;
+ int type;
+
+ name = attributes.getValue("name");
+ if (name == null) {
+ throw new SAXException("No name specified for '" + qName + "'.");
+ }
+
+ cpusString = attributes.getValue("cpus");
+ if (cpusString == null) {
+ throw new SAXException("No CPUs specified for '" + name + "'.");
+ }
+ cpus = new TreeSet();
+ StringTokenizer tokenizer = new StringTokenizer(cpusString, ",");
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ boolean found = false;
+
+ // Wild card?
+ if (token.endsWith("*")) {
+ token = token.substring(0, token.length() - 1);
+ for (CPU cpu : CPU.values()) {
+ if (cpu.name().startsWith(token) || cpu == CPU.MOS65C02 && token.equals("MOS6502")) {
+ cpus.add(cpu);
+ found = true;
+ }
+ }
+ } else {
+ // Exact match
+ for (CPU cpu : CPU.values()) {
+ if (cpu.name().equals(token)) {
+ cpus.add(cpu);
+ found = true;
+ }
+ }
+ }
+ if (!found) {
+ throw new SAXException("No cpu matches the cpus '" + cpusString + "' for '" + name + "'.");
+ }
+ }
+
+ title = attributes.getValue("title");
+ if (title == null) {
+ throw new SAXException("No title specified for '" + name + "'.");
+ }
+
+ typeString = attributes.getValue("type");
+ if (typeString == null) {
+ typeString = "";
+ }
+
+ proposal = attributes.getValue("proposal");
+ if (qName.equals("constant")) {
+ // Constants always have a simple proposal
+ proposal = name + "_";
+ }
+ if (proposal == null) {
+ throw new SAXException("No proposal specified for '" + name + "'.");
+ }
+
+ // TODO Have constant as own instruction class
+ if (qName.equals("constant")) {
+ qName = "directive";
+ typeString = "DIRECTIVE";
+ }
+
+ if (qName.equals("directive")) {
+
+ // Default and default nesting for folding blocks and
+ // sections.
+ if (typeString.equals("DIRECTIVE")) {
+ type = InstructionType.DIRECTIVE;
+ } else if (typeString.equals("BEGIN_IMPLEMENTATION_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_IMPLEMENTATION_SECTION_DIRECTIVE;
+ } else if (typeString.equals("BEGIN_FOLDING_BLOCK_DIRECTIVE")) {
+ type = InstructionType.BEGIN_FOLDING_BLOCK_DIRECTIVE;
+ } else if (typeString.equals("END_FOLDING_BLOCK_DIRECTIVE")) {
+ type = InstructionType.END_FOLDING_BLOCK_DIRECTIVE;
+ } else if (typeString.equals("END_SECTION_DIRECTIVE")) {
+ type = InstructionType.END_SECTION_DIRECTIVE;
+ }
+
+ // Begin of sections.
+ else if (typeString.equals("BEGIN_ENUM_DEFINITION_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_ENUM_DEFINITION_SECTION_DIRECTIVE;
+ } else if (typeString.equals("BEGIN_STRUCTURE_DEFINITION_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_STRUCTURE_DEFINITION_SECTION_DIRECTIVE;
+ } else if (typeString.equals("BEGIN_LOCAL_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_LOCAL_SECTION_DIRECTIVE;
+ } else if (typeString.equals("BEGIN_MACRO_DEFINITION_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_MACRO_DEFINITION_SECTION_DIRECTIVE;
+ } else if (typeString.equals("BEGIN_PAGES_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_PAGES_SECTION_DIRECTIVE;
+ } else if (typeString.equals("BEGIN_PROCEDURE_DEFINITION_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_PROCEDURE_DEFINITION_SECTION_DIRECTIVE;
+ } else if (typeString.equals("BEGIN_REPEAT_SECTION_DIRECTIVE")) {
+ type = InstructionType.BEGIN_REPEAT_SECTION_DIRECTIVE;
+ }
+
+ // File references.
+ else if (typeString.equals("SOURCE_INCLUDE_DIRECTIVE")) {
+ type = InstructionType.SOURCE_INCLUDE_DIRECTIVE;
+ } else if (typeString.equals("BINARY_INCLUDE_DIRECTIVE")) {
+ type = InstructionType.BINARY_INCLUDE_DIRECTIVE;
+ } else if (typeString.equals("BINARY_OUTPUT_DIRECTIVE")) {
+ type = InstructionType.BINARY_OUTPUT_DIRECTIVE;
+ } else if (typeString.equals("")) {
+ throw new SAXException("No directive type specified for directive '" + name + "'.");
+ } else {
+ throw new SAXException("Unknown directive type '" + typeString + "' for directive '" + name
+ + "'.");
+ }
+ instructionsList.add(new Directive(cpus, type, instructionsCaseSensitive, name, title, proposal));
+ } else if (qName.equals("opcode") || qName.equals("illegalopcode") || qName.equals("pseudoopcode")) {
+
+ if (qName.equals("opcode")) {
+ type = InstructionType.LEGAL_OPCODE;
+ } else if (qName.equals("illegalopcode")) {
+ type = InstructionType.ILLEGAL_OPCODE;
+ } else if (qName.equals("pseudoopcode")) {
+ type = InstructionType.PSEUDO_OPCODE;
+ } else {
+ throw new SAXException("Unknown qName '" + qName + "'.");
+ }
+
+ String flags = attributes.getValue("flags");
+ if (flags == null) {
+ flags = "@todo flags";
+ }
+ String modes = attributes.getValue("modes");
+ if (modes == null) {
+ modes = "todo=$00";
+ }
+
+ // Currently only KickAss uses case sensitive instructions
+ // and they are lower case. There this logic is applied here
+ // instead of having an additional XML attribute to control
+ // the lower/upper case setting for opcodes.
+ if (instructionsCaseSensitive) {
+ name = name.toLowerCase();
+ proposal = proposal.toLowerCase();
+ }
+ instructionsList.add(new Opcode(cpus, type, instructionsCaseSensitive, name, title, proposal, cpus
+ .contains(CPU.MOS65816), flags, modes));
+ }
+ }
+ }
+ }
+
+ private String compilerId;
+
+ private char[] completionProposalAutoActivationCharacters;
+
+ private List singleLineCommentDelimiters;
+
+ private List multipleLinesCommentDelimiters;
+
+ private List stringDelimiters;
+
+ private String blockDefinitionCharacters;
+ private char blockDefinitionStartCharacter;
+ private char blockDefinitionEndCharacter;
+
+ private boolean identifiersCaseSensitive;
+
+ private String identifierStartCharacters;
+ private boolean identifierStartCharactersArray[];
+
+ private String identifierPartCharacters;
+ private boolean identifierPartCharactersArray[];
+
+ private char identifierSeparatorCharacter;
+
+ private char labelDefinitionSuffixCharacter;
+
+ private char macroUsagePrefixCharacter;
+
+ private boolean instructionsCaseSensitive;
+
+ private String sourceIncludeDefaultExtension;
+
+ private List instructionList;
+ private Map instructionSets;
+
+ /**
+ * Creates new instance. Called by {@link CompilerRegistry}.
+ *
+ * @param compilerId
+ * The compiler id, not empty and null.
+ */
+ public CompilerSyntax(String compilerId) {
+ if (compilerId == null) {
+ throw new IllegalArgumentException("Parameter 'compilerId' must not be null.");
+ }
+ if (StringUtility.isEmpty(compilerId)) {
+ throw new IllegalArgumentException("Parameter 'compilerId' must not be empty.");
+ }
+ this.compilerId = compilerId;
+ }
+
+ /**
+ * Load XML data.
+ *
+ * @param compilerClasses
+ * The list of compiler classes for which the XML files shall be
+ * loaded, not empty and not null. The content of
+ * subsequent files will extend the content of previous files.
+ */
+ public void loadXMLData(List> compilerClasses) {
+
+ if (compilerClasses == null) {
+ throw new IllegalArgumentException("Parameter 'compilerClasses' must not be null.");
+ }
+ if (compilerClasses.isEmpty()) {
+ throw new IllegalArgumentException("Parameter 'compilerClasses' must not be empty.");
+ }
+ XMLHandler xmlHandler;
+ xmlHandler = new XMLHandler();
+ for (int i = 0; i < compilerClasses.size(); i++) {
+ Class> compilerClass = compilerClasses.get(i);
+ if (compilerClass == null) {
+ throw new IllegalArgumentException("Parameter 'compilerClasses[" + i + "]' must not be null.");
+ }
+
+ SAXParser parser;
+ try {
+ parser = SAXParserFactory.newInstance().newSAXParser();
+ } catch (ParserConfigurationException ex) {
+ throw new RuntimeException(
+ "Cannot create parser for compiler class '" + compilerClass.getName() + "'.", ex);
+ } catch (SAXException ex) {
+ throw new RuntimeException(
+ "Cannot create parser for compiler class '" + compilerClass.getName() + "'.", ex);
+ }
+
+ String syntaxFileName = "/" + compilerClass.getName().replace('.', '/') + ".xml";
+ try {
+
+ InputStream inputStream = compilerClass.getResourceAsStream(syntaxFileName);
+ parser.parse(inputStream, xmlHandler);
+ } catch (SAXParseException ex) {
+ throw new RuntimeException("Cannot create parser for file '" + syntaxFileName + "'. Error in line "
+ + ex.getLineNumber() + ", column " + ex.getColumnNumber() + ".", ex);
+ } catch (SAXException ex) {
+ throw new RuntimeException("Cannot create parser for file '" + syntaxFileName + "'.", ex);
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot create parser for file '" + syntaxFileName + "'.", ex);
+ }
+ }
+
+ // Completion proposal auto activation characters
+ completionProposalAutoActivationCharacters = xmlHandler.completionProposalAutoActivationCharactersText
+ .toCharArray();
+
+ // Single line comments.
+ String delimiterText = xmlHandler.singleLineCommentDelimitersText;
+ if (delimiterText == null) {
+ throw new IllegalStateException("Attribute 'singleLineCommentDelimiters' is no set.");
+ }
+ StringTokenizer tokenizer = new StringTokenizer(delimiterText, " ");
+ singleLineCommentDelimiters = new ArrayList(tokenizer.countTokens());
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ singleLineCommentDelimiters.add(token);
+ }
+ singleLineCommentDelimiters = Collections.unmodifiableList(singleLineCommentDelimiters);
+
+ // Multiple lines comments.
+ delimiterText = xmlHandler.multipleLinesCommentDelimitersText;
+ if (delimiterText == null) {
+ throw new IllegalStateException("Attribute 'singleLineCommentDelimiters' is no set.");
+ }
+ tokenizer = new StringTokenizer(delimiterText, " ");
+ int tokenCount = tokenizer.countTokens();
+ if ((tokenCount & 1) == 1) {
+ throw new IllegalStateException("Attribute 'multipleLinesCommentDelimiters' has an odd number of tokens: '"
+ + delimiterText + "'.");
+ }
+ multipleLinesCommentDelimiters = new ArrayList(tokenCount);
+ while (tokenizer.hasMoreTokens()) {
+ multipleLinesCommentDelimiters.add(tokenizer.nextToken());
+ }
+ multipleLinesCommentDelimiters = Collections.unmodifiableList(multipleLinesCommentDelimiters);
+
+ // Strings.
+ delimiterText = xmlHandler.stringDelimiterCharactersText;
+ if (delimiterText == null) {
+ throw new IllegalStateException("Attribute 'stringDelimiters' is not set.");
+ }
+ stringDelimiters = new ArrayList(delimiterText.length());
+ for (int i = 0; i < delimiterText.length(); i++) {
+ stringDelimiters.add(delimiterText.substring(i, i + 1));
+ }
+ stringDelimiters = Collections.unmodifiableList(stringDelimiters);
+
+ // Block definitions.
+ if (xmlHandler.blockDefinitionCharactersText == null) {
+ throw new IllegalArgumentException("Attribute 'blockDefinitionCharacters' is not set.");
+ }
+ blockDefinitionCharacters = xmlHandler.blockDefinitionCharactersText;
+ if (blockDefinitionCharacters.length() > 0) {
+ if (blockDefinitionCharacters.length() == 2) {
+ blockDefinitionStartCharacter = blockDefinitionCharacters.charAt(0);
+ blockDefinitionEndCharacter = blockDefinitionCharacters.charAt(1);
+ } else {
+ throw new IllegalArgumentException("Attribute 'blockDefinitionCharacters' has the value '"
+ + blockDefinitionCharacters + "' and does not have 2 characters.");
+ }
+ } else {
+ blockDefinitionStartCharacter = NO_CHARACTER;
+ blockDefinitionEndCharacter = NO_CHARACTER;
+ }
+
+ // Identifiers: Case sensitive.
+ identifiersCaseSensitive = xmlHandler.identifiersCaseSensitive;
+
+ // Identifiers: Start characters.
+ if (xmlHandler.identifierStartCharactersText == null) {
+ throw new IllegalArgumentException("Attribute 'identifierStartCharacters' is not set.");
+ }
+ identifierStartCharacters = xmlHandler.identifierStartCharactersText;
+ identifierStartCharactersArray = createBooleanArray(identifierStartCharacters);
+
+ // Identifiers: Start characters.
+ if (xmlHandler.identifierPartCharactersText == null) {
+ throw new IllegalArgumentException("Attribute 'identifierPartCharacters' is not set.");
+ }
+ identifierPartCharacters = xmlHandler.identifierPartCharactersText;
+ identifierPartCharactersArray = createBooleanArray(identifierPartCharacters);
+
+ // Identifiers: Separator characters.
+ if (xmlHandler.identifierSeparatorCharacterText == null) {
+ throw new IllegalArgumentException("Attribute 'identifierSeparatorCharacter' is not set.");
+ }
+ if (xmlHandler.identifierSeparatorCharacterText.length() == 0) {
+ identifierSeparatorCharacter = NO_CHARACTER;
+ } else {
+ identifierSeparatorCharacter = xmlHandler.identifierSeparatorCharacterText.charAt(0);
+ }
+
+ // Identifiers: Label definition suffix character.
+ if (xmlHandler.labelDefinitionSuffixCharacterText == null) {
+ throw new IllegalArgumentException("Attribute 'labelDefinitionSuffixCharacterText' is not set.");
+ }
+ if (xmlHandler.labelDefinitionSuffixCharacterText.length() == 0) {
+ labelDefinitionSuffixCharacter = NO_CHARACTER;
+ } else {
+ labelDefinitionSuffixCharacter = xmlHandler.labelDefinitionSuffixCharacterText.charAt(0);
+ }
+
+ // Identifiers: Macro usage prefix character
+ if (xmlHandler.macroUsagePrefixCharacterText == null) {
+ throw new IllegalArgumentException("Attribute 'macroUsagePrefixCharacterText' is not set.");
+ }
+ if (xmlHandler.macroUsagePrefixCharacterText.length() == 0) {
+ macroUsagePrefixCharacter = NO_CHARACTER;
+ } else {
+ macroUsagePrefixCharacter = xmlHandler.macroUsagePrefixCharacterText.charAt(0);
+ }
+
+ // Instructions case sensitive.
+ instructionsCaseSensitive = xmlHandler.instructionsCaseSensitive;
+
+ // Source include default extension.
+ sourceIncludeDefaultExtension = xmlHandler.sourceIncludeDefaultExtension;
+
+ instructionList = Collections.unmodifiableList(xmlHandler.instructionsList);
+
+ // Create instruction set map.
+ instructionSets = new TreeMap();
+ }
+
+ static boolean[] createBooleanArray(String string) {
+ int length = string.length();
+ int max = 0;
+ for (int i = 0; i < length; i++) {
+ char c = string.charAt(i);
+ if (c > max) {
+ max = c;
+ }
+ }
+ boolean[] result = new boolean[max + 1];
+
+ for (int i = 0; i < length; i++) {
+ char c = string.charAt(i);
+ result[c] = true;
+ }
+ return result;
+ }
+
+ /**
+ * Gets the completion proposal auto activation characters.
+ *
+ * @return The array of completion proposal auto activation characters, may
+ * be empty, not null.
+ */
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ if (completionProposalAutoActivationCharacters == null) {
+ throw new IllegalStateException("Attribute 'completionProposalAutoActivationCharacters' is not set.");
+ }
+ return completionProposalAutoActivationCharacters;
+ }
+
+ /**
+ * Gets the delimiter prefixes for single line comments.
+ *
+ * @return The unmodifiable list of delimiter prefixes for single line
+ * comments, not empty and not null.
+ */
+ public List getSingleLineCommentDelimiters() {
+ if (singleLineCommentDelimiters == null) {
+ throw new IllegalStateException("Attribute 'singleLineCommentDelimiters' is not set.");
+ }
+ return singleLineCommentDelimiters;
+ }
+
+ /**
+ * Gets the delimiter prefixes for multiple lines comments.
+ *
+ * @return The unmodifiable list of delimiter prefixes for single line
+ * comments, not empty and not null. The list contains
+ * an even number of entries where two entries constitute the start
+ * sequence and the end sequence of the multiple lines rules.
+ */
+ public List getMultipleLinesCommentDelimiters() {
+ if (multipleLinesCommentDelimiters == null) {
+ throw new IllegalStateException("Attribute 'multipleLinesCommentDelimiters' is not set.");
+ }
+ return multipleLinesCommentDelimiters;
+ }
+
+ /**
+ * Gets the delimiter characters for strings.
+ *
+ * @return The unmodifiable list of delimiter characters for strings, not
+ * empty and not null.
+ */
+ public List getStringDelimiters() {
+ if (stringDelimiters == null) {
+ throw new IllegalStateException("Attribute 'stringDelimiters' is not set.");
+ }
+ return stringDelimiters;
+ }
+
+ /**
+ * Gets the (possibly empty) string of character pairs which define the
+ * begin and end of a named or unnamed (folding) block.
+ *
+ * @return The string of character pairs which define the begin and end of a
+ * named or unnamed (folding) block, may be empty, not
+ * null.
+ * @since 1.6.1
+ */
+ public String getBlockDefinitionCharacters() {
+ return blockDefinitionCharacters;
+ }
+
+ /**
+ * Gets the block definition start character if defined.
+ *
+ * @return The block definition start character or {@link #NO_CHARACTER}.
+ */
+ public char getBlockDefinitionStartCharacter() {
+ return blockDefinitionStartCharacter;
+ }
+
+ /**
+ * Gets the block definition start character if defined.
+ *
+ * @return The block definition start character or {@link #NO_CHARACTER}.
+ */
+ public char getBlockDefinitionEndCharacter() {
+ return blockDefinitionEndCharacter;
+ }
+
+ /**
+ * Determines if identifiers are case sensitive.
+ *
+ * @return true if identifiers are case sensitive,
+ * false otherwise.
+ *
+ * @since 1.6.1
+ */
+ public boolean areIdentifiersCaseSensitive() {
+ return identifiersCaseSensitive;
+ }
+
+ /**
+ * Determines if a character can be the start or part of an identifier.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be the start of an
+ * identifier, false otherwise.
+ */
+ public boolean isIdentifierCharacter(char c) {
+ return isIdentifierStartCharacter(c) || isIdentifierPartCharacter(c)
+ || (c == identifierSeparatorCharacter && c != NO_CHARACTER);
+ }
+
+ /**
+ * Gets the valid identifier start characters.
+ *
+ * @return The non empty string of identifier start characters, not
+ * null.
+ *
+ * @since 1.6.3
+ */
+ public String getIdentifierStartCharacters() {
+ return identifierStartCharacters;
+ }
+
+ /**
+ * Determines if a character can be the start of an identifier.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be the start of an
+ * identifier, false otherwise.
+ *
+ * @since 1.6.1
+ */
+ public boolean isIdentifierStartCharacter(char c) {
+ return c < identifierStartCharactersArray.length && identifierStartCharactersArray[c];
+ }
+
+ /**
+ * Gets the valid identifier part characters.
+ *
+ * @return The non empty string of identifier part characters, not
+ * null.
+ *
+ * @since 1.6.3
+ */
+ public String getIdentifierPartCharacters() {
+ return identifierPartCharacters;
+ }
+
+ /**
+ * Determines if a character can be the part of an identifier.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be part of an identifier,
+ * false otherwise.
+ * @since 1.6.1
+ */
+ public boolean isIdentifierPartCharacter(char c) {
+ return c < identifierPartCharactersArray.length && identifierPartCharactersArray[c];
+ }
+
+ /**
+ * Gets the character which separates two parts of a compound identifier.
+ *
+ * @return The character which separates two parts of a compound identifier
+ * or {@link #NO_CHARACTER} if compound identifiers are not
+ * supported.
+ */
+ public char getIdentifierSeparatorCharacter() {
+ return identifierSeparatorCharacter;
+ }
+
+ /**
+ * Determines if a character can be part of an identifier and separates two
+ * parts of a compound identifier characters.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be part of an identifier
+ * and separates two parts of a compound identifier,
+ * false otherwise.
+ * @since 1.6.1
+ */
+ public boolean isIdentifierSeparatorCharacter(char c) {
+ return (c != NO_CHARACTER) && (c == identifierSeparatorCharacter);
+ }
+
+ /**
+ * Gets the character which end a label definition, e.g. ':'.
+ *
+ * @return The character which ends a label definition or
+ * {@link #NO_CHARACTER} if label definitions end at the first white
+ * space.
+ *
+ * @since 1.6.1
+ */
+ public char getLabelDefinitionSuffixCharacter() {
+ return labelDefinitionSuffixCharacter;
+ }
+
+ /**
+ * Gets the character which separates two parts of a compound identifier.
+ *
+ * @return The character which start a macro usage or {@link #NO_CHARACTER}
+ * if macro usages are not prefixed with a character.
+ *
+ * @since 1.6.1
+ */
+ public char getMacroUsagePrefixCharacter() {
+ return macroUsagePrefixCharacter;
+ }
+
+ /**
+ * Determines if instructions are case sensitive.
+ *
+ * @return true if instructions are case sensitive,
+ * false otherwise.
+ *
+ * @since 1.6.1
+ */
+ public boolean areInstructionsCaseSensitive() {
+ return instructionsCaseSensitive;
+ }
+
+ /**
+ * Determines if a character can be the start of a number.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be the start of a number,
+ * false otherwise.
+ *
+ * @since 1.6.1
+ */
+ public boolean isNumberStartCharacter(char c) {
+ return c == '$' || c == '%' || c == '~' || (c >= '0' && c <= '9');
+ }
+
+ /**
+ * Determines if a character can be the part of a number.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be part of a number,
+ * false otherwise.
+ * @since 1.6.1
+ */
+ public boolean isNumberPartCharacter(char c) {
+ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
+ }
+
+ /**
+ * Gets the default extension (excluding the period) to use in case source
+ * include file name does not end with an extension.
+ *
+ * @return Gets the default extension (excluding the period) to use in case
+ * source include file name does not end with an extension, may be
+ * empty, not null.
+ */
+ public String getSourceIncludeDefaultExtension() {
+ if (sourceIncludeDefaultExtension == null) {
+ throw new IllegalStateException("Variable 'sourceIncludeDefaultExtension' not yet initialized.");
+ }
+ return sourceIncludeDefaultExtension;
+ }
+
+ /**
+ * Gets the instruction set for a CPU.
+ *
+ * @param cpu
+ * The CPU this which the allowed list of instructions shall be
+ * returned, not null.
+ * @return The set of instructions supported by the compiler for the
+ * specified CPU, not null.
+ *
+ * @since 1.6.1
+ */
+ public InstructionSet getInstructionSet(CPU cpu) {
+ if (cpu == null) {
+ throw new IllegalArgumentException("Parameter 'cpu' must not be null.");
+ }
+ InstructionSet result;
+ synchronized (instructionSets) {
+ result = instructionSets.get(cpu);
+ if (result == null) {
+ result = new InstructionSet(this, instructionList, cpu);
+ instructionSets.put(cpu, result);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return compilerId;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/CompilerSyntaxUtility.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/CompilerSyntaxUtility.java
new file mode 100644
index 00000000..3da119b0
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/CompilerSyntaxUtility.java
@@ -0,0 +1,110 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.syntax;
+
+import com.wudsn.ide.asm.Texts;
+
+/**
+ * Utility class for compiler syntax and instructions.
+ *
+ * @author Peter Dell
+ * @since 1.6.1
+ */
+public final class CompilerSyntaxUtility {
+
+ /**
+ * Creation private.
+ */
+ private CompilerSyntaxUtility() {
+
+ }
+
+ /**
+ * Gets the image path for an instruction type image.
+ *
+ * @param instruction
+ * The instruction, not null.
+ * @return The image path for the instruction type image, not empty and not
+ * null.
+ */
+ public static String getTypeImagePath(Instruction instruction) {
+ if (instruction == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'instruction' must not be null.");
+ }
+ String path;
+
+ if (instruction instanceof Directive) {
+ path = "instruction-type-directive-16x16.gif";
+ } else {
+ Opcode opcode = (Opcode) instruction;
+ switch (opcode.getType()) {
+ case InstructionType.LEGAL_OPCODE:
+ path = "instruction-type-legal-opcode-16x16.gif";
+ break;
+ case InstructionType.ILLEGAL_OPCODE:
+ path = "instruction-type-illegal-opcode-16x16.gif";
+ break;
+ case InstructionType.PSEUDO_OPCODE:
+ path = "instruction-type-pseudo-opcode-16x16.gif";
+ break;
+ default:
+ throw new IllegalStateException("Unknown opcode type "
+ + opcode.getType() + ".");
+ }
+
+ }
+ return path;
+ }
+
+ /**
+ * Gets the text for an instruction type.
+ *
+ * @param instruction
+ * The instruction, not null.
+ * @return The text for the instruction type image, may be empty, not
+ * null.
+ */
+ public static String getTypeText(Instruction instruction) {
+ String text;
+
+ if (instruction instanceof Directive) {
+ text = Texts.COMPILER_SYNTAX_INSTRUCTION_DIRECTIVE;
+ } else {
+ Opcode opcode = (Opcode) instruction;
+ switch (opcode.getType()) {
+ case InstructionType.LEGAL_OPCODE:
+ text = Texts.COMPILER_SYNTAX_LEGAL_OPCODE;
+ break;
+ case InstructionType.ILLEGAL_OPCODE:
+ text = Texts.COMPILER_SYNTAX_ILLEGAL_OPCODE;
+ break;
+ case InstructionType.PSEUDO_OPCODE:
+ text = Texts.COMPILER_SYNTAX_PSEUDO_OPCODE;
+ break;
+ default:
+ throw new IllegalStateException("Unknown opcode type "
+ + opcode.getType() + ".");
+ }
+
+ }
+ return text;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Directive.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Directive.java
new file mode 100644
index 00000000..eb982852
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Directive.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.syntax;
+
+import java.util.Set;
+
+import com.wudsn.ide.asm.CPU;
+
+public final class Directive extends Instruction {
+
+ Directive(Set cpus, int type, boolean caseSensitive,
+ String name, String title, String proposal) {
+ super(cpus, type, caseSensitive, name, title, proposal);
+
+ switch (type) {
+ case InstructionType.DIRECTIVE:
+ case InstructionType.BEGIN_IMPLEMENTATION_SECTION_DIRECTIVE:
+ case InstructionType.BEGIN_FOLDING_BLOCK_DIRECTIVE:
+ case InstructionType.END_FOLDING_BLOCK_DIRECTIVE:
+ case InstructionType.END_SECTION_DIRECTIVE:
+
+ case InstructionType.BEGIN_ENUM_DEFINITION_SECTION_DIRECTIVE:
+ case InstructionType.BEGIN_STRUCTURE_DEFINITION_SECTION_DIRECTIVE:
+ case InstructionType.BEGIN_LOCAL_SECTION_DIRECTIVE:
+ case InstructionType.BEGIN_MACRO_DEFINITION_SECTION_DIRECTIVE:
+ case InstructionType.BEGIN_PROCEDURE_DEFINITION_SECTION_DIRECTIVE:
+ case InstructionType.BEGIN_PAGES_SECTION_DIRECTIVE:
+ case InstructionType.BEGIN_REPEAT_SECTION_DIRECTIVE:
+
+ case InstructionType.SOURCE_INCLUDE_DIRECTIVE:
+ case InstructionType.BINARY_INCLUDE_DIRECTIVE:
+ case InstructionType.BINARY_OUTPUT_DIRECTIVE:
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown type " + type
+ + " for directive '" + name + "'.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Instruction.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Instruction.java
new file mode 100644
index 00000000..456755dd
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Instruction.java
@@ -0,0 +1,205 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.syntax;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import com.wudsn.ide.asm.CPU;
+import com.wudsn.ide.base.common.NumberFactory;
+
+public abstract class Instruction implements Comparable {
+
+ public static final char CURSOR = '_';
+ public static final char NEWLINE = '\n';
+
+ private Set cpus;
+ private int type;
+ private String name;
+ private String upperCaseName;
+ private String lowerCaseName;
+ private String title;
+ private String formattedTitle;
+ private String styledTitle;
+ private int[] styledTitleOffsets;
+ private String proposal;
+
+ protected Instruction(Set cpus, int type, boolean caseSensitive,
+ String name, String title, String proposal) {
+ if (cpus == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'cpus' must not be null.");
+ }
+ if (name == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'name' must not be null.");
+ }
+ if (title == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'title' must not be null for instruction '"
+ + name + "'.");
+ }
+ if (proposal == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'proposal' must not be null for instruction '"
+ + name + "'.");
+ }
+ this.cpus = cpus;
+ this.type = type;
+ this.name = name;
+ if (caseSensitive) {
+ this.upperCaseName = name;
+ this.lowerCaseName = name;
+ } else {
+ this.upperCaseName = name.toUpperCase();
+ this.lowerCaseName = name.toLowerCase();
+ }
+ this.title = title;
+
+ int length = title.length();
+ StringBuilder mnemonicBuilder = new StringBuilder(3);
+ StringBuilder formattedTitleBuilder = new StringBuilder(length);
+ StringBuilder styledTitleBuilder = new StringBuilder(length);
+ List styledTitleOffsetsList = new ArrayList(10);
+ for (int i = 0; i < length; i++) {
+ char c = title.charAt(i);
+ char fc;
+ if (c == '_') {
+ i++;
+ if (i >= title.length()) {
+ throw new RuntimeException("Instruction '" + name
+ + "' has invalid title '" + title + "'.");
+ }
+ c = title.charAt(i);
+ fc = Character.toUpperCase(c);
+ mnemonicBuilder.append(fc);
+ styledTitleOffsetsList.add(NumberFactory
+ .getInteger(styledTitleBuilder.length()));
+ } else {
+ fc = c;
+ }
+ formattedTitleBuilder.append(fc);
+ styledTitleBuilder.append(c);
+ }
+ this.formattedTitle = formattedTitleBuilder.toString();
+ this.styledTitle = styledTitleBuilder.toString();
+ int size = styledTitleOffsetsList.size();
+ this.styledTitleOffsets = new int[size];
+ for (int i = 0; i < size; i++) {
+ this.styledTitleOffsets[i] = styledTitleOffsetsList.get(i)
+ .intValue();
+ }
+
+ proposal = proposal.replace("\\n", "" + NEWLINE);
+ if (!proposal.startsWith(name)) {
+ throw new RuntimeException("Proposal '" + proposal
+ + "' of instruction '" + name + "' does not start with '"
+ + name + "'.");
+ }
+ if (proposal.indexOf(CURSOR) == -1) {
+
+ throw new RuntimeException("Proposal '" + proposal
+ + "' of instruction '" + name
+ + "' does not contain cursor positioning via '_'.");
+ }
+
+ this.proposal = proposal;
+
+ // Remove all special characters like
+ StringBuilder mnemonicNameBuilder = new StringBuilder(upperCaseName);
+ for (int i = 0; i < mnemonicNameBuilder.length(); i++) {
+ if (!Character.isLetter(mnemonicNameBuilder.charAt(i))
+ && !Character.isDigit(mnemonicNameBuilder.charAt(i))) {
+ mnemonicNameBuilder.deleteCharAt(i);
+ }
+ }
+
+ String mnemonic = mnemonicBuilder.toString();
+ String mnemonicName = mnemonicNameBuilder.toString();
+ if (!mnemonicName.equalsIgnoreCase(mnemonic)) {
+ throw new RuntimeException("Menmonic '" + mnemonic
+ + "' derived from title '" + title
+ + "' with of instruction '" + name
+ + "' does match mnemonic '" + mnemonicName
+ + " derived from the name'.");
+
+ }
+ }
+
+ public Set getCPUs() {
+ return cpus;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public final String getName() {
+ return name;
+ }
+
+ public final String getUpperCaseName() {
+ return upperCaseName;
+ }
+
+ public final String getLowerCaseName() {
+ return lowerCaseName;
+ }
+
+ public final String getTitle() {
+ return title;
+ }
+
+ public final String getFormattedTitle() {
+ return formattedTitle;
+ }
+
+ public final String getStyledTitle() {
+ return styledTitle;
+ }
+
+ public final int[] getStyledTitleOffsets() {
+ return styledTitleOffsets;
+ }
+
+ /**
+ * Gets the upper case proposal text for the instruction. By default the
+ * proposal is the same as the {@link #getName()}. In case the instruction
+ * has a mandatory parameter, a space is added. In case the proposal span
+ * several line, they are separated via {@link #NEWLINE}. The position of
+ * the cursor is defined by the character {@link #CURSOR}.
+ *
+ * @return The proposal, not empty, not null.
+ */
+ public final String getProposal() {
+ return proposal;
+ }
+
+ @Override
+ public final int compareTo(Instruction o) {
+ return name.compareToIgnoreCase(o.name);
+ }
+
+ @Override
+ public final String toString() {
+ return "type=" + type + ", name=" + name;
+ }
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/InstructionSet.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/InstructionSet.java
new file mode 100644
index 00000000..4c1eec09
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/InstructionSet.java
@@ -0,0 +1,273 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.syntax;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.wudsn.ide.asm.CPU;
+import com.wudsn.ide.asm.compiler.CompilerRegistry;
+import com.wudsn.ide.asm.compiler.syntax.Opcode.OpcodeAddressingMode;
+
+/**
+ * Container for a set of directives, legal, illegal and pseudo opcodes and
+ * their properties.
+ *
+ * TODO Maintain address modes for all illegal opcodes for online help
+ *
+ * @author Peter Dell
+ * @since 1.6.1
+ */
+public final class InstructionSet {
+
+ private CompilerSyntax compilerSyntax;
+
+ private boolean instructionStartCharactersArray[];
+ private boolean instructionPartCharactersArray[];
+
+ private List instructionsList;
+
+ private Map instructionsMap;
+
+ /**
+ * Array list of opcode addressing modes.
+ *
+ * @since 1.7.0
+ */
+ private List> opcodeAddessingModesList;
+
+ private List fileReferenceInstructionsList;
+
+ /**
+ * Creates new instance. Called by {@link CompilerRegistry}.
+ *
+ * @param compilerSyntax
+ * The compiler syntax, not null.
+ *
+ * @param instructionsList
+ * The non-filtered list of compiler instructions.
+ * @param cpu
+ * The cpu to filter by, not null.
+ */
+ InstructionSet(CompilerSyntax compilerSyntax, List instructionsList, CPU cpu) {
+
+ if (compilerSyntax == null) {
+ throw new IllegalArgumentException("Parameter 'compilerSyntax' must not be null.");
+ }
+ if (instructionsList == null) {
+ throw new IllegalArgumentException("Parameter 'instructionsList' must not be null.");
+ }
+ if (cpu == null) {
+ throw new IllegalArgumentException("Parameter 'cpu' must not be null.");
+ }
+ // Compute the list of all include instructions.
+ this.compilerSyntax = compilerSyntax;
+ this.instructionsList = new ArrayList(instructionsList.size());
+ instructionsMap = new TreeMap();
+
+ opcodeAddessingModesList = new ArrayList>(Opcode.MAX_OPCODES);
+ for (int i = 0; i < Opcode.MAX_OPCODES; i++) {
+ opcodeAddessingModesList.add(new ArrayList());
+ }
+ fileReferenceInstructionsList = new ArrayList(10);
+
+ // Collect all start and part characters.
+ boolean caseSenstive = compilerSyntax.areIdentifiersCaseSensitive();
+ StringBuilder instructionStartCharacters = new StringBuilder(512);
+ StringBuilder instructionPartCharacters = new StringBuilder(2048);
+
+ for (Instruction instruction : instructionsList) {
+ if (!instruction.getCPUs().contains(cpu)) {
+ continue;
+ }
+ this.instructionsList.add(instruction);
+
+ // If not case sensitive, the upper case and lower case
+ // representation is allowed
+ if (caseSenstive) {
+ instructionStartCharacters.append(instruction.getName().substring(0, 1));
+ instructionPartCharacters.append(instruction.getName().substring(1));
+ instructionsMap.put(instruction.getName(), instruction);
+
+ } else {
+ instructionStartCharacters.append(instruction.getUpperCaseName().substring(0, 1));
+ instructionPartCharacters.append(instruction.getUpperCaseName().substring(1));
+ instructionStartCharacters.append(instruction.getLowerCaseName().substring(0, 1));
+ instructionPartCharacters.append(instruction.getLowerCaseName().substring(1));
+ instructionsMap.put(instruction.getUpperCaseName(), instruction);
+ }
+
+ switch (instruction.getType()) {
+ case InstructionType.LEGAL_OPCODE:
+ case InstructionType.ILLEGAL_OPCODE:
+ case InstructionType.PSEUDO_OPCODE:
+ Opcode opcode = (Opcode) instruction;
+ for (OpcodeAddressingMode opcodeAddressingMode : opcode.getAddressingModes()) {
+ // Even if an instruction is supported by all CPUs, not all
+ // addressing modes may be supported by the CPU,
+ if (opcodeAddressingMode.getCPUs().contains(cpu)) {
+ List list = opcodeAddessingModesList.get(opcodeAddressingMode
+ .getOpcodeValue());
+ if (list == null) {
+ list = new ArrayList();
+ }
+ list.add(opcodeAddressingMode);
+ }
+ }
+ break;
+
+ case InstructionType.SOURCE_INCLUDE_DIRECTIVE:
+ case InstructionType.BINARY_INCLUDE_DIRECTIVE:
+ case InstructionType.BINARY_OUTPUT_DIRECTIVE:
+ fileReferenceInstructionsList.add(instruction);
+ break;
+
+ }
+
+ }
+
+ instructionStartCharactersArray = CompilerSyntax.createBooleanArray(instructionStartCharacters.toString());
+ instructionPartCharactersArray = CompilerSyntax.createBooleanArray(instructionPartCharacters.toString());
+
+ this.instructionsList = Collections.unmodifiableList(this.instructionsList);
+ instructionsMap = Collections.unmodifiableMap(instructionsMap);
+ fileReferenceInstructionsList = Collections.unmodifiableList(fileReferenceInstructionsList);
+ }
+
+ /**
+ * Gets the compiler syntax.
+ *
+ * @return The compiler syntax, not null.
+ */
+ public CompilerSyntax getCompilerSyntax() {
+ return compilerSyntax;
+ }
+
+ /**
+ * Determines if instructions are case sensitive.
+ *
+ * @return true if instructions are case sensitive,
+ * false otherwise.
+ *
+ * @since 1.6.1
+ */
+ public boolean areInstructionsCaseSensitive() {
+ return compilerSyntax.areInstructionsCaseSensitive();
+ }
+
+ /**
+ * Determines if a character can be the start of an instruction.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be the start of an
+ * instruction, false otherwise.
+ *
+ * @since 1.6.1
+ */
+ public boolean isInstructionStartCharacter(char c) {
+ return c < instructionStartCharactersArray.length && instructionStartCharactersArray[c];
+ }
+
+ /**
+ * Determines if a character can be the part of an instruction.
+ *
+ * @param c
+ * The character to be checked.
+ * @return true if the character can be part of an instruction,
+ * false otherwise.
+ * @since 1.6.1
+ */
+ public boolean isInstructionPartCharacter(char c) {
+ return c < instructionPartCharactersArray.length && instructionPartCharactersArray[c];
+ }
+
+ /**
+ * Gets the list of all instructions.
+ *
+ * @return The unmodifiable list of instructions, not null.
+ */
+ public List getInstructions() {
+
+ if (instructionsList == null) {
+ throw new IllegalStateException("Variable 'instructionsList' not yet initialized.");
+ }
+ return instructionsList;
+ }
+
+ /**
+ * Gets list of opcode address modes for the given opcode value. Only
+ * instances that are support by the CPU of the instruction set are
+ * returned.
+ *
+ * @param opcodeValue
+ * The opcode value.
+ * @return The list of opcode address modes, may be empty, not
+ * null.
+ *
+ * @since 1.7.0
+ */
+ public List getOpcodeAddressingModes(int opcodeValue) {
+ if (opcodeAddessingModesList == null) {
+ throw new IllegalStateException("Variable 'opcodeAddessingModesList' not yet initialized.");
+ }
+ List result = null;
+ if (opcodeValue > 0 && opcodeValue < opcodeAddessingModesList.size()) {
+ result = opcodeAddessingModesList.get(opcodeValue);
+ }
+ if (result == null) {
+ result = Collections.emptyList();
+ }
+ return result;
+ }
+
+ /**
+ * Gets an instruction by its upper case name.
+ *
+ * @param instructionName
+ * The upper case name
+ *
+ * @return The instruction or null.
+ */
+ public Instruction getInstruction(String instructionName) {
+ return instructionsMap.get(instructionName);
+ }
+
+ /**
+ * Gets the list of all include instructions.
+ *
+ * @return The unmodifiable list of include instructions, not
+ * null.
+ */
+ public List getFileReferenceInstructions() {
+ if (fileReferenceInstructionsList == null) {
+ throw new IllegalStateException("Variable 'fileReferenceInstructionsList' not yet initialized.");
+ }
+ return fileReferenceInstructionsList;
+ }
+
+ @Override
+ public String toString() {
+ return compilerSyntax.toString() + ": " + instructionsMap.keySet().toString();
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/InstructionType.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/InstructionType.java
new file mode 100644
index 00000000..b11b608d
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/InstructionType.java
@@ -0,0 +1,63 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.syntax;
+
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParserTreeObjectType;
+
+/**
+ * Instruction types as defined in the XML syntax definition. See also
+ * {@link CompilerSourceParserTreeObjectType}.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class InstructionType {
+ /**
+ * Creation is private.
+ */
+ private InstructionType() {
+
+ }
+
+ // Types of directives.
+ public static final int DIRECTIVE = 100;
+ public static final int BEGIN_IMPLEMENTATION_SECTION_DIRECTIVE = 101;
+ public static final int BEGIN_FOLDING_BLOCK_DIRECTIVE = 102;
+ public static final int END_FOLDING_BLOCK_DIRECTIVE = 103;
+ public static final int END_SECTION_DIRECTIVE = 104;
+
+ public static final int BEGIN_ENUM_DEFINITION_SECTION_DIRECTIVE = 105;
+ public static final int BEGIN_STRUCTURE_DEFINITION_SECTION_DIRECTIVE = 106;
+ public static final int BEGIN_LOCAL_SECTION_DIRECTIVE = 107;
+ public static final int BEGIN_MACRO_DEFINITION_SECTION_DIRECTIVE = 108;
+ public static final int BEGIN_PROCEDURE_DEFINITION_SECTION_DIRECTIVE = 109;
+ public static final int BEGIN_PAGES_SECTION_DIRECTIVE = 110;
+ public static final int BEGIN_REPEAT_SECTION_DIRECTIVE = 111;
+
+ public static final int SOURCE_INCLUDE_DIRECTIVE = 120;
+ public static final int BINARY_INCLUDE_DIRECTIVE = 121;
+ public static final int BINARY_OUTPUT_DIRECTIVE = 122;
+
+
+ // Types of opcodes.
+ public static final int LEGAL_OPCODE = 200;
+ public static final int ILLEGAL_OPCODE = 201;
+ public static final int PSEUDO_OPCODE = 202;
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Opcode.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Opcode.java
new file mode 100644
index 00000000..55fcd537
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/syntax/Opcode.java
@@ -0,0 +1,199 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.syntax;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import com.wudsn.ide.asm.CPU;
+
+public final class Opcode extends Instruction {
+
+ public static final int MAX_OPCODES = 256;
+
+ public final static class OpcodeAddressingMode {
+ private Opcode opcode;
+ private Set cpus;
+ private String addressingMode;
+ private int opcodeValue;
+
+ OpcodeAddressingMode(Opcode opcode, Set cpus, String addressingMode, int opcodeValue) {
+ if (opcode == null) {
+ throw new IllegalArgumentException("Parameter 'opcode' must not be null.");
+ }
+ if (cpus == null) {
+ throw new IllegalArgumentException("Parameter 'cpus' must not be null for opcode '" + opcode.getName()
+ + "'.");
+ }
+ if (addressingMode == null) {
+ throw new IllegalArgumentException("Parameter 'addressingMode' must not be nullfor opcode '"
+ + opcode.getName() + "'.");
+ }
+ if (opcodeValue < 0 || opcodeValue > 255) {
+ throw new IllegalArgumentException("Parameter 'opcodeValue' has value " + opcodeValue + " for opcode '"
+ + opcode.getName() + "' but must be between $00 and $ff.");
+
+ }
+ this.opcode = opcode;
+ this.cpus = cpus;
+ this.addressingMode = addressingMode;
+ this.opcodeValue = opcodeValue;
+ }
+
+ public Opcode getOpcode() {
+ return opcode;
+ }
+
+ public Set getCPUs() {
+ return cpus;
+ }
+
+ public String getAddressingMode() {
+ return addressingMode;
+ }
+
+ public String getFormattedText() {
+
+ StringBuffer result = new StringBuffer(opcode.getName());
+ if (addressingMode.equals("imp")) {
+
+ } else if (addressingMode.equals("imm")) {
+ result.append(" #$nn");
+ } else if (addressingMode.equals("zp")) {
+ result.append(" zp");
+ } else if (addressingMode.equals("zpx")) {
+ result.append(" zp,x");
+ } else if (addressingMode.equals("zpy")) {
+ result.append(" zp,y");
+ } else if (addressingMode.equals("izx")) {
+ result.append(" (zp,x)");
+ } else if (addressingMode.equals("izy")) {
+ result.append(" (zp),y");
+ } else if (addressingMode.equals("abs")) {
+ result.append(" abs");
+ } else if (addressingMode.equals("abx")) {
+ result.append(" abs,x");
+ } else if (addressingMode.equals("aby")) {
+ result.append(" abs,y");
+ } else if (addressingMode.equals("ind")) {
+ result.append(" (abs)");
+ } else if (addressingMode.equals("rel")) {
+ result.append(" rel");
+ } else
+
+ // 65816 modes
+ if (addressingMode.equals("abl")) {
+ result.append(" adr (long)");
+ } else if (addressingMode.equals("bm")) {
+ result.append(" $nn,$nn");
+ } else if (addressingMode.equals("dp")) {
+ result.append(" (zp)");
+ } else if (addressingMode.equals("ial")) {
+ result.append(" abs (long)");
+ } else if (addressingMode.equals("iax")) {
+ result.append(" (abs,x)");
+ } else if (addressingMode.equals("idp")) {
+ result.append(" (zp)");
+ } else if (addressingMode.equals("rell")) {
+ result.append(" rel (long)");
+ } else {
+ throw new RuntimeException("Unmapped addressing mode " + addressingMode + " for opcode "
+ + opcode.getName());
+ }
+
+ return result.toString();
+ }
+
+ public int getOpcodeValue() {
+ return opcodeValue;
+ }
+ }
+
+ private boolean w65816;
+ private String flags;
+ private String modes;
+ private List addressingModes;
+
+ Opcode(Set cpus, int type, boolean instructionsCaseSensitive, String name, String title, String proposal,
+ boolean w65816, String flags, String modes) {
+
+ super(cpus, type, instructionsCaseSensitive, name, title, proposal);
+ switch (type) {
+ case InstructionType.LEGAL_OPCODE:
+ case InstructionType.ILLEGAL_OPCODE:
+ case InstructionType.PSEUDO_OPCODE:
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown type " + type + " for opcode '" + name + "'.");
+ }
+ if (flags == null) {
+ throw new IllegalArgumentException("Parameter 'flags' must not be null for opcode '" + name + "'.");
+ }
+ if (modes == null) {
+ throw new IllegalArgumentException("Parameter 'modes' must not be null for opcode '" + name + "'.");
+
+ }
+ this.w65816 = w65816;
+ this.flags = flags;
+ this.modes = modes;
+ addressingModes = new ArrayList();
+ Set addressingModeCPUs = cpus;
+ for (String mode : modes.split(",")) {
+ mode = mode.trim();
+ String values[] = mode.split("=");
+ String addressingMode = values[0];
+ String value = values[1].substring(1);
+ int index = value.indexOf("[");
+ if (index >= 0) {
+ String[] cpuNameList = value.substring(index + 1, value.length() - 1).split(";");
+ value = value.substring(0, index);
+ addressingModeCPUs = new TreeSet();
+ for (String cpuName : cpuNameList) {
+ addressingModeCPUs.add(CPU.valueOf(cpuName));
+ }
+ }
+ int opcode = Integer.parseInt(value, 16);
+ OpcodeAddressingMode addressingModeInstance = new OpcodeAddressingMode(this, addressingModeCPUs,
+ addressingMode, opcode);
+ addressingModes.add(addressingModeInstance);
+ }
+
+ }
+
+ public boolean isW65816() {
+ return w65816;
+ }
+
+ public String getFlags() {
+ return flags;
+ }
+
+ public String getModes() {
+ return modes;
+ }
+
+ public List getAddressingModes() {
+ return addressingModes;
+ }
+
+}
\ No newline at end of file
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/writer/AppleFileWriter.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/writer/AppleFileWriter.java
new file mode 100644
index 00000000..8db967c1
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/writer/AppleFileWriter.java
@@ -0,0 +1,343 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.compiler.writer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+
+import com.webcodepro.applecommander.storage.Disk;
+import com.webcodepro.applecommander.storage.DiskFullException;
+import com.webcodepro.applecommander.storage.FileEntry;
+import com.webcodepro.applecommander.storage.FormattedDisk;
+import com.wudsn.ide.asm.Texts;
+import com.wudsn.ide.asm.compiler.CompilerFileWriter;
+import com.wudsn.ide.asm.compiler.CompilerFiles;
+import com.wudsn.ide.base.common.FileUtility;
+import com.wudsn.ide.base.common.MarkerUtility;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Compiler file writer for Apple II
+ *
+ * @author Peter Dell
+ * @since 1.6.3
+ */
+public final class AppleFileWriter extends CompilerFileWriter {
+
+ private final static String HELLO_ENTRY_NAME = "HELLO";
+ private final static String OUTPUT_IMAGE_ENTRY_NAME = "WORLD";
+
+ private final class AppleSoftTokens {
+ public final static byte PRINT = (byte) 0xba;
+ public final static byte CHRS = (byte) 0xe7;
+ public final static byte CALL = (byte) 0x8c;
+
+ // public String[] tokenNames = { "END", "FOR ", "NEXT ", "DATA ",
+ // "INPUT ", "DEL", "DIM ", "READ ", "GR", "TEXT", "PR#", "IN#",
+ // "CALL ", "PLOT", "HLIN ", "VLIN ", "HGR2", "HGR", "HCOLOR=",
+ // "HPLOT ", "DRAW ", "XDRAW ", "HTAB ", "HOME", "ROT=", "SCALE=",
+ // "SHLOAD", "TRACE", "NOTRACE", "NORMAL", "INVERSE", "FLASH",
+ // "COLOR=", "POP", "VTAB ", "HIMEM:", "LOMEM:", "ONERR ",
+ // "RESUME", "RECALL", "STORE", "SPEED=", "LET ", "GOTO ", "RUN",
+ // "IF ", "RESTORE", "& ", "GOSUB ", "RETURN", "REM ", "STOP",
+ // "ON ", "WAIT", "LOAD", "SAVE", "DEF", "POKE ", "PRINT ",
+ // "CONT", "LIST", "CLEAR", "GET ", "NEW", "TAB(", "TO ", "FN",
+ // "SPC(", "THEN ", "AT ", "NOT ", "STEP ", "+ ", "- ", "* ",
+ // "/ ", "^ ", "AND ", "OR ", "> ", "= ", "< ", "SGN", "INT",
+ // "ABS", "USR", "FRE", "SCRN(", "PDL", "POS ", "SQR", "RND",
+ // "LOG", "EXP", "COS", "SIN", "TAN", "ATN", "PEEK", "LEN",
+ // "STR$", "VAL", "ASC", "CHR$", "LEFT$", "RIGHT$", "MID$" };
+
+ // public int[] tokenAddresses = { 0xD870, 0xD766, 0xDCF9, 0xD995,
+ // 0xDBB2,
+ // 0xF331, 0xDFD9, 0xDBE2, 0xF390, 0xF399, 0xF1E5, 0xF1DE, 0xF1D5,
+ // 0xF225, 0xF232, 0xF241, 0xF3D8, 0xF3E2, 0xF6E9, 0xF6FE, 0xF769,
+ // 0xF76F, 0xF7E7, 0xFC58, 0xF721, 0xF727, 0xF775, 0xF26D, 0xF26F,
+ // 0xF273, 0xF277, 0xF280, 0xF24F, 0xD96B, 0xF256, 0xF286, 0xF2A6,
+ // 0xF2CB, 0xF318, 0xF3BC, 0xF39F, 0xF262, 0xDA46, 0xD93E, 0xD912,
+ // 0xD9C9, 0xD849, 0x03F5, 0xD921, 0xD96B, 0xD9DC, 0xD86E, 0xD9EC,
+ // 0xE784, 0xD8C9, 0xD8B0, 0xE313, 0xE77B, 0xFDAD5, 0xD896,
+ // 0xD6A5, 0xD66A, 0xDBA0, 0xD649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // 0, 0, 0, 0, 0, 0, 0, 0, 0xEB90, 0xEC23, 0xEBAF, 0x000A, 0xE2DE,
+ // 0xD412, 0xDFCD, 0xE2FF, 0xEE8D, 0xEFAE, 0xE941, 0xEF09, 0xEFEA,
+ // 0xEFF1, 0xF03A, 0xF09E, 0xE764, 0xE6D6, 0xE3C5, 0xE707, 0xE6E5,
+ // 0xE646, 0xE65A, 0xE686, 0xE691 };
+ }
+
+ @Override
+ public boolean createOrUpdateDiskImage(CompilerFiles files) {
+ String imageFilePath = files.outputFilePathWithoutExtension + ".dsk";
+ String outputImageEntryName = OUTPUT_IMAGE_ENTRY_NAME;
+ String outputImageEntryTitle = "Loading " + files.outputFileNameWithoutExtension;
+ boolean autoCreate = true;
+
+ if (StringUtility.isSpecified(imageFilePath)) {
+ File imageFile = new File(imageFilePath);
+ if (!imageFile.exists()) {
+
+ // When auto creation is active, we copy a template file.
+ // This is the only way to get a disk image which is not only
+ // formatted but also has a boot loader which runs "HELLO".
+ if (autoCreate) {
+ String resource = "/lib/AppleDos.dsk";
+ InputStream inputStream = Disk.class.getClassLoader().getResourceAsStream(resource);
+ if (inputStream == null) {
+ throw new RuntimeException("Cannot get input stream for '" + resource + "'");
+ }
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[8192];
+ int count;
+ do {
+ try {
+ count = inputStream.read(buffer);
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot read input stream for '" + resource + "'", ex);
+ }
+
+ if (count > 0) {
+ bos.write(buffer, 0, count);
+
+ }
+ } while (count > -1);
+
+ try {
+ bos.close();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ try {
+ FileUtility.writeBytes(imageFile, bos.toByteArray());
+ } catch (CoreException ex) {
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, ex.getStatus().getSeverity(), "{0}",
+ ex.getStatus().getMessage());
+ return false;
+ }
+
+ } else { // no auto creation
+
+ // ERROR: Disk image file '{0}' does not exist. Create a
+ // bootable disk image where the output file '{1}' can be
+ // stored.
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, IMarker.SEVERITY_ERROR,
+ Texts.MESSAGE_E132, imageFilePath, outputImageEntryName);
+ return false;
+ }
+ }
+ if (!imageFile.canWrite()) {
+ // ERROR: Disk image file '{0}' is not writeable. Make the disk
+ // image file writeable, so the output file '{1}' can be stored.
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, IMarker.SEVERITY_ERROR, Texts.MESSAGE_E133,
+ imageFilePath, outputImageEntryName);
+ return false;
+ }
+ }
+ Disk disk;
+ try {
+ disk = new Disk(imageFilePath);
+ } catch (IOException ex) {
+ // ERROR: Disk image file '{0}' cannot be opened for reading. System
+ // error: {1}
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, IMarker.SEVERITY_ERROR, Texts.MESSAGE_E134,
+ imageFilePath, ex.getMessage());
+ return false;
+ }
+
+ FormattedDisk[] formattedDisks = disk.getFormattedDisks();
+ if (formattedDisks == null || formattedDisks.length == 0) {
+ // ERROR: Disk image file '{0}' does not contain a valid file
+ // system. Make sure the disk image is properly formatted, so
+ // the output file '{1}' can be stored.
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, IMarker.SEVERITY_ERROR, Texts.MESSAGE_E135,
+ imageFilePath, outputImageEntryName);
+ return false;
+ }
+
+ byte[] outputFileContent;
+ try {
+ outputFileContent = FileUtility.readBytes(files.outputFile, 65536, true);
+ } catch (CoreException ex) {
+ // ERROR: Cannot read output file.
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, ex.getStatus().getSeverity(), "{0}", ex
+ .getStatus().getMessage());
+ return false;
+ }
+
+ FormattedDisk formattedDisk;
+ try {
+ formattedDisk = formattedDisks[0];
+ // Create HELLO with dummy address.
+ createHello(formattedDisk, outputImageEntryName, outputImageEntryTitle, 1234);
+
+ FileEntry entry = formattedDisk.getFile(outputImageEntryName);
+ if (entry == null) {
+ entry = formattedDisk.createFile();
+ // TODO This is required due to a BUG in AppleCommander
+ entry.setFilename(outputImageEntryName);
+ }
+ entry.setFiletype("B");
+
+ String fileName = files.outputFileName.toLowerCase();
+ int length = outputFileContent.length;
+ byte[] content = outputFileContent;
+ if (entry.needsAddress()) {
+ int address;
+ if (fileName.endsWith(".b") && length > 4) {
+ // // AppleDos 3.3 binary file:
+ // start-lo,start-hi,length-lo,length-hi,data
+ address = getWord(outputFileContent, 0);
+ length = length - 4;
+ content = getData(outputFileContent, 4);
+ } else if (fileName.endsWith(".prg") && length > 2) {
+ // C64 program file
+ // start-lo,start-hi,data
+ address = getWord(outputFileContent, 0);
+ length = length - 2;
+ content = getData(outputFileContent, 2);
+ } else if (fileName.endsWith(".xex") && length > 6
+ && ((getWord(outputFileContent, 0) & 0xffff) == 0xffff)) {
+ // AtariDOS 2.5 binary file:
+ // $ff,$ff,start-lo,start-hi,end-lo,end-hi,data
+ address = getWord(outputFileContent, 2);
+ length = length - 6;
+ content = getData(outputFileContent, 6);
+ } else {
+ // ERROR: Output file {0} has unknown executable file
+ // extension or content. File extensions ".b", ".prg" and
+ // ".xex" are allowed.
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, IMarker.SEVERITY_ERROR,
+ Texts.MESSAGE_E138, files.outputFilePath);
+ return false;
+ }
+ // Method setAddress must be called after method setFileData!
+ entry.setFileData(content);
+ entry.setAddress(address);
+ // Update HELLO with acual start address.
+ createHello(formattedDisk, outputImageEntryName, outputImageEntryTitle, address);
+ } else {
+ entry.setFileData(outputFileContent);
+
+ }
+
+ } catch (DiskFullException ex) {
+ // ERROR: Disk image file '{0}' is full. System
+ // error: {1}
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, IMarker.SEVERITY_ERROR, Texts.MESSAGE_E136,
+ imageFilePath, ex.getMessage());
+ return false;
+
+ }
+
+ try {
+ formattedDisk.save();
+
+ } catch (IOException ex) {
+
+ // ERROR: Disk image file '{0}' cannot be opened for writing. System
+ // error: {1}
+ MarkerUtility.createMarker(files.mainSourceFile.iFile, 0, IMarker.SEVERITY_ERROR, Texts.MESSAGE_E137,
+ imageFilePath, ex.getMessage());
+ return false;
+ }
+
+ return true;
+
+ }
+
+ private static FileEntry createHello(FormattedDisk formattedDisk, String outputImageEntryName,
+ String outputImageEntryTitle, int runAddress) throws DiskFullException {
+ if (formattedDisk == null) {
+ throw new IllegalArgumentException("Parameter 'formattedDisk' must not be null.");
+ }
+ if (outputImageEntryName == null) {
+ throw new IllegalArgumentException("Parameter 'OUTPUT_IMAGE_ENTRY_NAME' must not be null.");
+ }
+ if (StringUtility.isEmpty(outputImageEntryName)) {
+ throw new IllegalArgumentException("Parameter 'OUTPUT_IMAGE_ENTRY_NAME' must not be empty.");
+ }
+ if (outputImageEntryTitle == null) {
+ throw new IllegalArgumentException("Parameter 'outputImageEntryTitle' must not be null.");
+ }
+ FileEntry entry;
+
+ entry = formattedDisk.getFile(HELLO_ENTRY_NAME);
+ if (entry == null) {
+ entry = formattedDisk.createFile();
+ entry.setFilename(HELLO_ENTRY_NAME);
+ }
+ entry.setFiletype("A");
+ byte[] program;
+ try {
+ // See "Beneath Apple DOS.pdf", 4-11/12 for the binary and AppleSoft
+ // file format.
+ // See http://www.textfiles.com/apple/ANATOMY/cmd.brun.bload.txt for
+ // the bug in the BRUN routine. Instead of BRUN now BLOAD is sent to
+ // DOS via PRINT CHR$(4) and the program is started via CALL.
+ // 10 PRINT "LOADING " : PRINT CHR$(4);"BRUN WORLD" : CALL
+ //
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ bos.write(new byte[] { 0x00, 0x08, 0x0A, 0x00 });
+ bos.write(new byte[] { AppleSoftTokens.PRINT, '"' });
+ bos.write(outputImageEntryTitle.getBytes("US-ASCII"));
+ bos.write(new byte[] { '"', ':' });
+ bos.write(new byte[] { AppleSoftTokens.PRINT, AppleSoftTokens.CHRS, '(', '4', ')', ';', '"', 'B', 'L', 'O',
+ 'A', 'D', ' ' });
+ bos.write(outputImageEntryName.getBytes("US-ASCII"));
+ bos.write(new byte[] { '"', ':', AppleSoftTokens.CALL });
+ bos.write(Integer.toString(runAddress).getBytes("US-ASCII"));
+ bos.write(new byte[] { 0, 0, 0 });
+ program = bos.toByteArray();
+ program[0] = (byte) (program.length);
+ } catch (UnsupportedEncodingException ex) {
+ throw new RuntimeException(ex);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ // Byte is the line length in bytes
+ entry.setFileData(program);
+ return entry;
+ }
+
+ private static int getWord(byte[] bytes, int index) {
+ if (bytes == null) {
+ throw new IllegalArgumentException("Parameter 'bytes' must not be null.");
+ }
+
+ return (0xff & bytes[index]) + 256 * (0xff & bytes[index + 1]);
+ }
+
+ private static byte[] getData(byte[] bytes, int index) {
+ if (bytes == null) {
+ throw new IllegalArgumentException("Parameter 'bytes' must not be null.");
+ }
+ int length = bytes.length - index;
+ byte[] result = new byte[length];
+ System.arraycopy(bytes, index, result, 0, length);
+ return result;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpoinDebugModelPresentation.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpoinDebugModelPresentation.java
new file mode 100644
index 00000000..70a473d3
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpoinDebugModelPresentation.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor;
+
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.debug.ui.IValueDetailListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.ide.IDE;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+
+/**
+ * Implementation class for extension
+ * "com.wudsn.ide.asm.editor.AssemblerBreakpoinDebugModelPresentation". This is
+ * the binding logic which enables navigation from transient and persistent
+ * break point markers to the corresponding editor.
+ *
+ * @author Peter Dell
+ */
+public class AssemblerBreakpoinDebugModelPresentation implements IDebugModelPresentation {
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ @Override
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ @Override
+ public void removeListener(ILabelProviderListener listener) {
+
+ }
+
+ @Override
+ public IEditorInput getEditorInput(Object element) {
+ AssemblerBreakpoint assemblerBreakpoint = (AssemblerBreakpoint) element;
+ IEditorInput result = assemblerBreakpoint.getEditorInput();
+ if (result == null) {
+ IWorkbenchWindow activeWindow = AssemblerPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow();
+ if (activeWindow == null) {
+ return null;
+ }
+ IWorkbenchPage activePage = activeWindow.getActivePage();
+ if (activePage == null) {
+ return null;
+ }
+ IEditorPart part;
+ try {
+ part = IDE.openEditor(activePage, assemblerBreakpoint.getMarker(), false);
+ } catch (PartInitException ex) {
+ return null;
+ }
+ return part.getEditorInput();
+ }
+ return result;
+ }
+
+ @Override
+ public String getEditorId(IEditorInput input, Object element) {
+ AssemblerBreakpoint assemblerBreakpoint = (AssemblerBreakpoint) element;
+ return assemblerBreakpoint.getEditorId();
+ }
+
+ @Override
+ public void setAttribute(String attribute, Object value) {
+
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return null;
+ }
+
+ @Override
+ public String getText(Object element) {
+ return null;
+ }
+
+ @Override
+ public void computeDetail(IValue value, IValueDetailListener listener) {
+
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpoint.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpoint.java
new file mode 100644
index 00000000..72e00810
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpoint.java
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.LineBreakpoint;
+import org.eclipse.ui.IEditorInput;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+import com.wudsn.ide.asm.Texts;
+import com.wudsn.ide.base.common.NumberUtility;
+import com.wudsn.ide.base.common.TextUtility;
+
+/**
+ * Implementation class for assembler breakpoints. See
+ * http://eclipse.org/articles/Article-Debugger/how-to.html for details.
+ *
+ * @author Peter Dell
+ * @since 1.6.1
+ *
+ */
+
+public final class AssemblerBreakpoint extends LineBreakpoint {
+
+ /**
+ * Attributes stored with the marker.
+ */
+ public static final String EDITOR_ID = "editorId";
+
+ /**
+ * Grouping ID for all breakpoint of this type.
+ */
+ public static final String DEBUG_MODEL_ID = AssemblerPlugin.ID;
+
+ /**
+ * Marker type as defined by the extension
+ * "org.eclipse.core.resources.markers"
+ */
+ public static final String MARKER_TYPE = "org.eclipse.debug.core.lineBreakpointMarker";
+
+ private IEditorInput editorInput;
+
+ /**
+ * Default constructor is required for the breakpoint manager to re-create
+ * persisted breakpoints. After instantiating a breakpoint, the
+ * setMarker(...) method is called to restore this breakpoint's
+ * attributes.
+ */
+ public AssemblerBreakpoint() {
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public Object getAdapter(Class adapter) {
+ if (adapter.isAssignableFrom(IMarker.class)) {
+ return getMarker();
+ }
+ if (adapter.isAssignableFrom(IResource.class)) {
+ // IResource result = getMarker().getResource();
+ // System.out.println(adapter.getName() + ":" + result);
+ // return result;
+ }
+ return super.getAdapter(adapter);
+ }
+
+ /**
+ * Constructs a line breakpoint on the given resource at the given line
+ * number. The line number is 1-based (i.e. the first line of a file is line
+ * number 1).
+ *
+ * @param editorId
+ * The editor id, not null.
+ *
+ * @param editorInput
+ * The editor input, not null.
+ * @param resource
+ * The file on which to set the breakpoint, not null
+ * .
+ * @param lineNumber
+ * The line number of the breakpoint, a positive integer.
+ * @param description
+ * The description of the break point, may be empty not
+ * null.
+ * @throws CoreException
+ * if unable to create the breakpoint
+ */
+ public AssemblerBreakpoint(final String editorId, IEditorInput editorInput, final IResource resource,
+ final int lineNumber, final String description) throws CoreException {
+ if (editorId == null) {
+ throw new IllegalArgumentException("Parameter 'editorId' must not be null.");
+ }
+ if (editorInput == null) {
+ throw new IllegalArgumentException("Parameter 'editorInput' must not be null.");
+ }
+ if (resource == null) {
+ throw new IllegalArgumentException("Parameter 'resource' must not be null.");
+ }
+ if (lineNumber < 1) {
+ throw new IllegalArgumentException("Parameter 'lineNumber' must be positive. Specified value is "
+ + lineNumber + ".");
+ }
+ if (description == null) {
+ throw new IllegalArgumentException("Parameter 'description' must not be null.");
+ }
+ this.editorInput = editorInput;
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ @Override
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IMarker marker = resource.createMarker(MARKER_TYPE);
+ // This must be the first operation before setting marker
+ // attributes.
+ setMarker(marker);
+
+ marker.setAttribute(EDITOR_ID, editorId);
+ marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE);
+ marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
+ marker.setAttribute(IBreakpoint.ID, getModelIdentifier());
+ marker.setAttribute(
+ IMarker.MESSAGE,
+ TextUtility.format(Texts.ASSEMBLER_BREAKPOINT_MARKER_MESSAGE, resource.getName(),
+ NumberUtility.getLongValueDecimalString(lineNumber), description));
+
+ }
+ };
+ run(getMarkerRule(resource), runnable);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier()
+ */
+ @Override
+ public String getModelIdentifier() {
+ return DEBUG_MODEL_ID;
+ }
+
+ final String getEditorId() {
+ return getMarker().getAttribute(EDITOR_ID, null);
+ }
+
+ final void setEditorInput(IEditorInput editorInput) {
+ this.editorInput = editorInput;
+ }
+
+ final IEditorInput getEditorInput() {
+ return editorInput;
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpointAdapterFactory.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpointAdapterFactory.java
new file mode 100644
index 00000000..8a600f65
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpointAdapterFactory.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPart;
+
+import com.wudsn.ide.asm.Texts;
+
+/**
+ * Factory for {@AssemblerBreakpointsTarget}
+ * instances. Used by extension
+ * "org.eclipse.debug.ui.toggleBreakpointsTargetFactories"
+ *
+ * @author Peter Dell
+ * @since 1.6.1
+ */
+public final class AssemblerBreakpointAdapterFactory implements
+ IToggleBreakpointsTargetFactory {
+
+ private String TARGET_ID = AssemblerBreakpointsTarget.class.getName();
+ private Set defaultSet;
+
+ public AssemblerBreakpointAdapterFactory() {
+ defaultSet = new HashSet();
+ defaultSet.add(TARGET_ID);
+ }
+
+ @Override
+ public Set getToggleTargets(IWorkbenchPart part,
+ ISelection selection) {
+ if (part instanceof AssemblerEditor) {
+ return defaultSet;
+ }
+ return Collections.emptySet();
+ }
+
+ @Override
+ public String getDefaultToggleTarget(IWorkbenchPart part,
+ ISelection selection) {
+ if (part instanceof AssemblerEditor) {
+ return TARGET_ID;
+ }
+ return null;
+ }
+
+ @Override
+ public IToggleBreakpointsTarget createToggleTarget(String targetID) {
+ if (TARGET_ID.equals(targetID)) {
+ return new AssemblerBreakpointsTarget();
+ }
+ return null;
+ }
+
+ @Override
+ public String getToggleTargetName(String targetID) {
+ return Texts.ASSEMBLER_BREAKPOINT_TOGGLE_TYPE_MENU_TEXT;
+ }
+
+ @Override
+ public String getToggleTargetDescription(String targetID) {
+ return TARGET_ID;
+ }
+
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpointsTarget.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpointsTarget.java
new file mode 100644
index 00000000..c27045ef
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerBreakpointsTarget.java
@@ -0,0 +1,168 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+package com.wudsn.ide.asm.editor;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Target which creates {@link AssemblerBreakpoint} instances. Used by
+ * {@link AssemblerBreakpointAdapterFactory}.
+ */
+public final class AssemblerBreakpointsTarget implements IToggleBreakpointsTarget {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleLineBreakpoints
+ * (org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ AssemblerEditor assemblerEditor = getEditor(part);
+ if (assemblerEditor != null) {
+ IBreakpointManager breakPointManager = DebugPlugin.getDefault().getBreakpointManager();
+ String editorId=assemblerEditor.getClass().getName();
+ IEditorInput editorInput = assemblerEditor.getEditorInput();
+ IResource resource = (IResource) editorInput.getAdapter(IResource.class);
+ ITextSelection textSelection = (ITextSelection) selection;
+ int lineNumber = textSelection.getStartLine();
+ IBreakpoint[] breakpoints = breakPointManager.getBreakpoints(AssemblerBreakpoint.DEBUG_MODEL_ID);
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint breakpoint = breakpoints[i];
+ if (resource.equals(breakpoint.getMarker().getResource())) {
+ if (((ILineBreakpoint) breakpoint).getLineNumber() == (lineNumber + 1)) {
+ // Remove existing breakpoint
+ breakpoint.delete();
+ return;
+ }
+ }
+ }
+ // Create line breakpoint (doc line numbers start at 0)
+ String description;
+ IDocumentProvider provider = assemblerEditor.getDocumentProvider();
+ IDocument document = provider.getDocument(assemblerEditor.getEditorInput());
+ try {
+ int startOffset = document.getLineOffset(lineNumber);
+ int lineLength = document.getLineLength(lineNumber);
+ description = document.get(startOffset, lineLength).trim();
+ description = description.replace('\t', ' ');
+ } catch (BadLocationException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ // No break points on empty lines
+ if (StringUtility.isEmpty(description)) {
+ return;
+ }
+ AssemblerBreakpoint breakpoint = new AssemblerBreakpoint(editorId, editorInput, resource, lineNumber + 1, description);
+ breakPointManager.addBreakpoint(breakpoint);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#
+ * canToggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return getEditor(part) != null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleMethodBreakpoints
+ * (org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#
+ * canToggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints
+ * (org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleWatchpoints
+ * (org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+
+ /**
+ * Determines of the specified workbench part is an assembler editor with a
+ * valid resource.
+ *
+ * @param part
+ * The editor part or null.
+ * @return The assembler editor or null.
+ */
+ private AssemblerEditor getEditor(IWorkbenchPart part) {
+ if (part instanceof AssemblerEditor) {
+ AssemblerEditor assemblerEditor = (AssemblerEditor) part;
+ if (assemblerEditor.getCurrentFile() != null) {
+ return assemblerEditor;
+ }
+ }
+ return null;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentAssistProcessor.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentAssistProcessor.java
new file mode 100644
index 00000000..3e76dbad
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentAssistProcessor.java
@@ -0,0 +1,573 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.StyledString.Styler;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.TextStyle;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+import com.wudsn.ide.asm.compiler.CompilerFiles;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceFile;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParser;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParserLineCallback;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParserTreeObject;
+import com.wudsn.ide.asm.compiler.syntax.CompilerSyntax;
+import com.wudsn.ide.asm.compiler.syntax.Directive;
+import com.wudsn.ide.asm.compiler.syntax.Instruction;
+import com.wudsn.ide.asm.compiler.syntax.InstructionSet;
+import com.wudsn.ide.asm.compiler.syntax.InstructionType;
+import com.wudsn.ide.asm.compiler.syntax.Opcode;
+import com.wudsn.ide.asm.preferences.AssemblerPreferences;
+import com.wudsn.ide.base.common.StringUtility;
+
+/**
+ * Class for content assist. Creates the content assist list.
+ *
+ * @author Peter Dell
+ * @author Daniel Mitte
+ */
+final class AssemblerContentAssistProcessor implements IContentAssistProcessor {
+
+ /**
+ * Empty styler
+ */
+ private final static class InstructionStyler extends Styler {
+
+ InstructionStyler() {
+ }
+
+ @Override
+ public void applyStyles(TextStyle textStyle) {
+
+ }
+ }
+
+ /**
+ * Underline styler
+ */
+ private final static class HighlightStyler extends Styler {
+
+ HighlightStyler() {
+ }
+
+ @Override
+ public void applyStyles(TextStyle textStyle) {
+ textStyle.underline = true;
+
+ }
+ }
+
+ /**
+ * Callback to find out if a given line already contains an instruction.
+ *
+ * @since 1.6.0
+ */
+ private static final class SourceParserCallback extends
+ CompilerSourceParserLineCallback {
+ private boolean instructionFound;
+ private int instructionEndOffset;
+
+ /**
+ * Create a new callback.
+ *
+ * @param filePath
+ * The absolute path of the source file, not empty and not
+ * null.
+ * @param lineNumber
+ * The line number, a non-negative integer or -1
+ * to indicate that no line number is relevant.
+ */
+ public SourceParserCallback(String filePath, int lineNumber) {
+ super(filePath, lineNumber);
+ }
+
+ @Override
+ public void processLine(CompilerSourceParser compilerSourceParser,
+ CompilerSourceFile compilerSourceFile, int lineNumber,
+ int startOffset, int symbolOffset, boolean instructionFound,
+ int instructionOffset, String instruction, int operandOffset,
+ CompilerSourceParserTreeObject section) {
+
+ this.instructionFound = instructionFound;
+ if (instructionFound) {
+ instructionEndOffset = instructionOffset + instruction.length();
+ } else {
+ instructionEndOffset = -1;
+ }
+ }
+
+ /**
+ * Determines if the specified line in the source file already contains
+ * an instruction.
+ *
+ * @return true if the specified line in the source file
+ * already contains an instruction, false
+ * otherwise.
+ */
+ public boolean wasInstructionFound() {
+ return instructionFound;
+ }
+
+ /**
+ * Gets the offset of the last character of the instruction if an
+ * instruction was found.
+ *
+ * @return The offset or -1 if no instruction was found.
+ */
+ public int getInstructionEndOffset() {
+ return instructionEndOffset;
+ }
+ }
+
+ private AssemblerEditor editor;
+
+ private Image directiveImage;
+ private Image legalOpcodeImage;
+ private Image illegalOpcodeImage;
+ private Image pseudoOpcodeImage;
+ private Styler instructionStyler;
+ private Styler highlightStyler;
+
+ /**
+ * Creates a new instance.
+ *
+ * Called by
+ * {@link AssemblerSourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer)}
+ * .
+ *
+ * @param editor
+ * The assembler editor for which this instance is created, not
+ * null.
+ */
+ AssemblerContentAssistProcessor(AssemblerEditor editor) {
+ if (editor == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'editor' must not be null.");
+ }
+
+ this.editor = editor;
+
+ AssemblerPlugin plugin = editor.getPlugin();
+ directiveImage = plugin
+ .getImage("instruction-type-directive-16x16.gif");
+ legalOpcodeImage = plugin
+ .getImage("instruction-type-legal-opcode-16x16.gif");
+ illegalOpcodeImage = plugin
+ .getImage("instruction-type-illegal-opcode-16x16.gif");
+ pseudoOpcodeImage = plugin
+ .getImage("instruction-type-pseudo-opcode-16x16.gif");
+ instructionStyler = new InstructionStyler();
+ highlightStyler = new HighlightStyler();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
+ int offset) {
+ if (viewer == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'viewer' must not be null.");
+ }
+ ITextSelection selection = (ITextSelection) viewer
+ .getSelectionProvider().getSelection();
+
+ int selectionOffset = offset;
+
+ if (selection.getOffset() != offset) {
+ selectionOffset = selection.getOffset();
+ }
+
+ List proposalList = new ArrayList();
+
+ // Convert offset into line number.
+ int lineNumber;
+ int lineOffset;
+ try {
+ lineNumber = viewer.getDocument().getLineOfOffset(offset);
+ lineOffset = viewer.getDocument().getLineOffset(lineNumber);
+ } catch (BadLocationException ex) {
+ lineNumber = -1;
+ lineOffset = -1;
+ }
+
+ // Parse the current assembler file and try to find the line in the
+ // correct source file.
+ CompilerFiles files = AssemblerEditorFilesLogic.createInstance(editor).createCompilerFiles();
+ if (files==null){
+ return null;
+ }
+ SourceParserCallback compilerSourceCallback = new SourceParserCallback(
+ files.sourceFile.filePath, lineNumber);
+ CompilerSourceParser compilerSourceParser = editor
+ .createCompilerSourceParser();
+ CompilerSourceFile compilerSourceFile = compilerSourceParser
+ .createCompilerSourceFile(files.sourceFile.file,
+ viewer.getDocument());
+ compilerSourceParser.parse(compilerSourceFile, compilerSourceCallback);
+
+ // If there is no instruction in the line yet or the cursor is exactly
+ // at the last character of that instruction, propose one.
+ if (!compilerSourceCallback.wasInstructionFound()
+ || selectionOffset == lineOffset
+ + compilerSourceCallback.getInstructionEndOffset()) {
+ String prefix = getPrefix(viewer,
+ compilerSourceParser.getCompilerSyntax(), selectionOffset,
+ false);
+ Region region = new Region(selectionOffset - prefix.length(),
+ prefix.length() + selection.getLength());
+ addInstructionProposals(region, prefix, proposalList);
+ } else {
+ // Otherwise propose to use an identifier as operand.
+ String prefix = getPrefix(viewer,
+ compilerSourceParser.getCompilerSyntax(), selectionOffset,
+ true);
+ Region region = new Region(selectionOffset - prefix.length(),
+ prefix.length() + selection.getLength());
+ addIdentifierProposals(region, prefix, compilerSourceFile,
+ proposalList);
+ }
+
+ // If there is no proposal entry, return null instead of an empty array.
+ int size = proposalList.size();
+ if (proposalList.size() == 0) {
+ return null;
+ }
+
+ return proposalList.toArray(new ICompletionProposal[size]);
+ }
+
+ /**
+ * Gets the prefix of the document starting at a given offset to the start
+ * of the document until a space or control character is found.
+ *
+ * @param viewer
+ * The viewer, not null.
+ * @param compilerSyntax
+ * The compiler syntax, not null.
+ * @param offset
+ * The offset, a non-negative integer.
+ * @param onlyIdentifiers
+ * true if only identifier characters shall be
+ * considered as part of the prefix.
+ *
+ * @return The prefix, may be empty, not null.
+ */
+ private String getPrefix(ITextViewer viewer, CompilerSyntax compilerSyntax,
+ int offset, boolean onlyIdentifiers) {
+ if (viewer == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'viewer' must not be null.");
+ }
+ if (compilerSyntax == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerSyntax' must not be null.");
+ }
+ int i = offset;
+ IDocument document = viewer.getDocument();
+
+ int l = document.getLength();
+ if (i > l) {
+ return "";
+ }
+
+ try {
+ while (i > 0) {
+ char ch = document.getChar(i - 1);
+
+ if (onlyIdentifiers) {
+ if (!compilerSyntax.isIdentifierCharacter(ch)) {
+ break;
+ }
+ } else {
+ if (Character.isWhitespace(ch)) {
+ break;
+ }
+ }
+
+ i--;
+ }
+
+ return document.get(i, offset - i);
+ } catch (BadLocationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private void addInstructionProposals(Region region, String prefix,
+ List proposalList) {
+ if (region == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'region' must not be null.");
+ }
+ if (prefix == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'prefix' must not be null.");
+ }
+ if (proposalList == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'proposalList' must not be null.");
+ }
+ AssemblerPreferences assemblerPreferences = editor.getPlugin()
+ .getPreferences();
+
+ int offset = region.getOffset();
+ boolean lowerCase;
+
+ // Prefix is empty or prefix does not end with a letter but for
+ // example "."
+ if (StringUtility.isEmpty(prefix)
+ || !Character.isLetter(prefix.charAt(prefix.length() - 1))) {
+ String defaultCase;
+ defaultCase = assemblerPreferences
+ .getEditorContentAssistProcessorDefaultCase();
+ lowerCase = AssemblerContentAssistProcessorDefaultCase.LOWER_CASE
+ .equals(defaultCase);
+ } else {
+ char lastchar = prefix.charAt(prefix.length() - 1);
+ lowerCase = ((lastchar < 'a') || (lastchar > 'z')) ? false : true;
+ }
+
+ CompilerSourceParser compilerSourceParser = editor
+ .createCompilerSourceParser();
+ InstructionSet instructionSet = compilerSourceParser
+ .getInstructionSet();
+
+ boolean caseSenstive = instructionSet.areInstructionsCaseSensitive();
+ if (!caseSenstive) {
+ prefix = prefix.toUpperCase();
+ }
+
+ List instructions = instructionSet.getInstructions();
+ for (int i = 0; i < instructions.size(); i++) {
+ Instruction instruction = instructions.get(i);
+
+ String name = null;
+ if (caseSenstive) {
+ if (instruction.getName().indexOf(prefix) == 0) {
+ name = instruction.getName();
+ }
+ } else {
+ if (instruction.getUpperCaseName().indexOf(prefix) == 0) {
+
+ name = lowerCase ? instruction.getLowerCaseName()
+ : instruction.getUpperCaseName();
+ }
+ }
+
+ if (name != null) {
+ Image image;
+
+ if (instruction instanceof Directive) {
+ image = directiveImage;
+ } else {
+ Opcode opcode = (Opcode) instruction;
+ switch (opcode.getType()) {
+ case InstructionType.LEGAL_OPCODE:
+ image = legalOpcodeImage;
+ break;
+ case InstructionType.ILLEGAL_OPCODE:
+ image = illegalOpcodeImage;
+
+ break;
+ case InstructionType.PSEUDO_OPCODE:
+ image = pseudoOpcodeImage;
+ break;
+ default:
+ throw new IllegalStateException("Unknown opcode type "
+ + opcode.getType() + ".");
+ }
+ }
+
+ String separator = " - ";
+ String displayString = name + separator
+ + instruction.getTitle();
+ StyledString styledDisplayString = new StyledString();
+ styledDisplayString.append(name);
+ styledDisplayString.append(separator);
+ int start = styledDisplayString.length();
+ styledDisplayString.append(instruction.getStyledTitle());
+ styledDisplayString.setStyle(0, name.length(),
+ instructionStyler);
+ int[] offsets = instruction.getStyledTitleOffsets();
+
+ for (int j = 0; j < offsets.length; j++) {
+ styledDisplayString.setStyle(start + offsets[j], 1,
+ highlightStyler);
+ }
+
+ // Adapt proposal.
+ String proposal = instruction.getProposal();
+ proposal = lowerCase ? proposal.toLowerCase() : proposal;
+ int proposalIndex;
+ int newCursorOffset;
+ // Must be positive.
+ proposalIndex = proposal.indexOf('_');
+ // Remove cursor positioning.
+ proposal = proposal.replace("_", "");
+ // Apply leading tabulator.
+ proposal = proposal.replace("\n", "\n\t");
+ newCursorOffset = offset + proposalIndex;
+
+ proposalList.add(new AssemblerInstructionCompletionProposal(
+ proposal, offset, region.getLength(), newCursorOffset,
+ image, displayString, styledDisplayString, null));
+ }
+ }
+ }
+
+ // TODO Handle prefixes which contain "." or end with it.
+ // TODO Handle identifier case sensitivity correctly
+ private void addIdentifierProposals(Region region, String prefix,
+ CompilerSourceFile compilerSourceFile,
+ List proposalList) {
+ if (region == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'region' must not be null.");
+ }
+ if (prefix == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'prefix' must not be null.");
+ }
+ if (compilerSourceFile == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'compilerSourceFile' must not be null.");
+ }
+ if (proposalList == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'proposalList' must not be null.");
+ }
+
+ CompilerSourceParserTreeObjectLabelProvider imageProvider = new CompilerSourceParserTreeObjectLabelProvider();
+ IStyledLabelProvider styledStringProvider = imageProvider
+ .getStyledStringProvider();
+ int regionOffset = region.getOffset();
+ int regionLength = region.getLength();
+ String lowerCasePrefix = prefix.toLowerCase();
+
+ // Find last separator as basis for the prefix.
+ char identifierSeparatorCharacter = editor.getCompilerDefinition()
+ .getSyntax().getIdentifierSeparatorCharacter();
+ if (identifierSeparatorCharacter != CompilerSyntax.NO_CHARACTER) {
+ int index = lowerCasePrefix
+ .lastIndexOf(identifierSeparatorCharacter);
+ if (index >= 0) {
+ regionOffset += index + 1;
+ regionLength -= index + 1;
+ lowerCasePrefix = lowerCasePrefix.substring(index + 1);
+ }
+ }
+ List identifiers = compilerSourceFile
+ .getIdentifiers();
+ String separator = " - ";
+ for (int i = 0; i < identifiers.size(); i++) {
+ CompilerSourceParserTreeObject element = identifiers.get(i);
+ String lowerCaseName = element.getName().toLowerCase();
+ if (lowerCaseName.indexOf(lowerCasePrefix) == 0) {
+ String proposal = element.getName();
+ Image image = imageProvider.getImage(element);
+ String displayName;
+ String description;
+ String displayString;
+ displayName = element.getDisplayName();
+ description = element.getDescription();
+ if (StringUtility.isSpecified(description)) {
+ displayString = displayName + separator + description;
+ } else {
+ displayString = displayName;
+
+ }
+ StyledString styledDisplayString = styledStringProvider
+ .getStyledText(element);
+
+ int newCursorOffset = regionOffset + proposal.length();
+
+ proposalList.add(new AssemblerInstructionCompletionProposal(
+ proposal, regionOffset, regionLength, newCursorOffset,
+ image, displayString, styledDisplayString, null));
+ }
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IContextInformation[] computeContextInformation(ITextViewer viewer,
+ int offset) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ CompilerSyntax compilerSyntax = editor.getCompilerDefinition()
+ .getSyntax();
+ char[] result = compilerSyntax
+ .getCompletionProposalAutoActivationCharacters();
+ if (result.length == 0) {
+ result = null;
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public char[] getContextInformationAutoActivationCharacters() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getErrorMessage() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IContextInformationValidator getContextInformationValidator() {
+ return null;
+ }
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentAssistProcessorDefaultCase.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentAssistProcessorDefaultCase.java
new file mode 100644
index 00000000..a8e3c450
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentAssistProcessorDefaultCase.java
@@ -0,0 +1,39 @@
+/**
+* Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor;
+
+/**
+ * Constant definition for completion proposals.
+ *
+ * @author Peter Dell
+ *
+ */
+public final class AssemblerContentAssistProcessorDefaultCase {
+
+ /**
+ * Creation is private.
+ */
+ private AssemblerContentAssistProcessorDefaultCase() {
+
+ }
+
+ public static final String UPPER_CASE = "UPPER_CASE";
+ public static final String LOWER_CASE = "LOWER_CASE";
+}
diff --git a/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentOutlinePage.java b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentOutlinePage.java
new file mode 100644
index 00000000..a8d9d14b
--- /dev/null
+++ b/com.wudsn.ide.asm/src/com/wudsn/ide/asm/editor/AssemblerContentOutlinePage.java
@@ -0,0 +1,590 @@
+/**
+ * Copyright (C) 2009 - 2014 Peter Dell
+ *
+ * This file is part of WUDSN IDE.
+ *
+ * WUDSN IDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * WUDSN IDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WUDSN IDE. If not, see .
+ */
+
+package com.wudsn.ide.asm.editor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ContentViewer;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+
+import com.wudsn.ide.asm.AssemblerPlugin;
+import com.wudsn.ide.asm.Texts;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceFile;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParserTreeObject;
+import com.wudsn.ide.asm.compiler.parser.CompilerSourceParserTreeObjectType;
+import com.wudsn.ide.base.common.Profiler;
+import com.wudsn.ide.base.common.RunnableWithLogging;
+
+/**
+ * Outline page for the assembler editor.
+ *
+ * @author Peter Dell.
+ * @author Andy Reek
+ */
+final class AssemblerContentOutlinePage extends ContentOutlinePage {
+
+ /*
+ * Toggle action to toggle the sorting in the outline tree. The state of the
+ * action will be persisted along with the file in the editor. If there is
+ * no state store yet along with in the file, the default is taken from the
+ * last file which was opened.
+ */
+ private static final class OutlineViewerSortAction extends Action {
+ private static final QualifiedName CHECKED = new QualifiedName(
+ "OutlineViewerSortAction", "Checked");
+
+ final AssemblerEditor editor;
+ final TreeViewer treeViewer;
+
+ /**
+ * Creates a new sort action.
+ *
+ * @param editor
+ * The editor which holds the respective file, not
+ * null.
+ * @param treeViewer
+ * The tree viewer which displays the outline.
+ */
+ public OutlineViewerSortAction(AssemblerEditor editor,
+ TreeViewer treeViewer) {
+ super("", AS_CHECK_BOX);
+ if (editor == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'editor' must not be null.");
+ }
+ if (treeViewer == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'treeViewer' must not be null.");
+ }
+ setToolTipText(Texts.ASSEMBLER_CONTENT_OUTLINE_SORT_BUTTON_TOOL_TIP);
+ ImageDescriptor imageDescriptor = AbstractUIPlugin
+ .imageDescriptorFromPlugin(AssemblerPlugin.ID,
+ "icons/outline-sort.gif");
+ setImageDescriptor(imageDescriptor);
+ this.editor = editor;
+ this.treeViewer = treeViewer;
+
+ String checkedProperty;
+ try {
+ IFile iFile = editor.getCurrentIFile();
+ if (iFile != null) {
+ checkedProperty = iFile.getPersistentProperty(CHECKED);
+ } else {
+ checkedProperty = "";
+ }
+ } catch (CoreException ignore) {
+ checkedProperty = null;
+ }
+ if (checkedProperty == null) {
+ checkedProperty = editor.getPlugin().getProperty(CHECKED);
+ }
+
+ boolean checked = Boolean.parseBoolean(checkedProperty);
+ setChecked(checked);
+
+ }
+
+ @Override
+ public void run() {
+
+ // Get current state and update the UI.
+ boolean checked = isChecked();
+ setChecked(checked);
+
+ // Store the property.
+ String checkedProperty = Boolean.toString(checked);
+ try {
+ IFile iFile = editor.getCurrentIFile();
+ if (iFile != null) {
+ iFile.setPersistentProperty(CHECKED, checkedProperty);
+ }
+ } catch (CoreException ex) {
+ editor.getPlugin().logError("Cannot set property {0}",
+ new Object[] { CHECKED }, ex);
+ }
+ editor.getPlugin().setProperty(CHECKED, checkedProperty);
+
+ // Refresh the tree viewer.
+ BusyIndicator.showWhile(treeViewer.getControl().getDisplay(),
+ new RunnableWithLogging() {
+ @Override
+ protected void runWithLogging() {
+ treeViewer.refresh(false);
+ }
+ });
+ }
+ }
+
+ private static final class OutlineViewerComparator extends ViewerComparator {
+ private final OutlineViewerSortAction sortAction;
+
+ OutlineViewerComparator(OutlineViewerSortAction sortAction) {
+ if (sortAction == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'sortAction' must not be null.");
+ }
+ this.sortAction = sortAction;
+ }
+
+ @Override
+ public int category(Object element) {
+ int result;
+ CompilerSourceParserTreeObject object = (CompilerSourceParserTreeObject) element;
+
+ // Treat equate definition and label definition as equal.
+ result = object.getType();
+
+ switch (object.getType()) {
+ case CompilerSourceParserTreeObjectType.DEFAULT:
+ case CompilerSourceParserTreeObjectType.DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.IMPLEMENTATION_SECTION:
+ break;
+
+ case CompilerSourceParserTreeObjectType.EQUATE_DEFINITION:
+ result = CompilerSourceParserTreeObjectType.EQUATE_DEFINITION;
+ break;
+ case CompilerSourceParserTreeObjectType.LABEL_DEFINITION:
+ result = CompilerSourceParserTreeObjectType.EQUATE_DEFINITION;
+ break;
+
+ case CompilerSourceParserTreeObjectType.ENUM_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.STRUCTURE_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.LOCAL_SECTION:
+ case CompilerSourceParserTreeObjectType.MACRO_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.PAGES_SECTION:
+ case CompilerSourceParserTreeObjectType.PROCEDURE_DEFINITION_SECTION:
+ case CompilerSourceParserTreeObjectType.REPEAT_SECTION:
+ break;
+
+ case CompilerSourceParserTreeObjectType.SOURCE_INCLUDE:
+ case CompilerSourceParserTreeObjectType.BINARY_INCLUDE:
+ break;
+
+ default:
+ throw new RuntimeException("Element '" + object.getName()
+ + "' has unknown type " + object.getType() + ".");
+
+ }
+ return result;
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+
+ if (!sortAction.isChecked()) {
+ return 0;
+ }
+
+ int cat1 = category(e1);
+ int cat2 = category(e2);
+
+ // Never sort definition or implementation sections.
+ if (cat1 == CompilerSourceParserTreeObjectType.DEFINITION_SECTION
+ && cat2 == CompilerSourceParserTreeObjectType.DEFINITION_SECTION) {
+ return 0;
+ }
+
+ if (cat1 != cat2) {
+ return cat1 - cat2;
+ }
+
+ String name1;
+ String name2;
+
+ if (viewer == null || !(viewer instanceof ContentViewer)) {
+ name1 = e1.toString();
+ name2 = e2.toString();
+ } else {
+ IBaseLabelProvider prov = ((ContentViewer) viewer)
+ .getLabelProvider();
+ if (prov instanceof ILabelProvider) {
+ ILabelProvider lprov = (ILabelProvider) prov;
+ name1 = lprov.getText(e1);
+ name2 = lprov.getText(e2);
+ } else {
+ name1 = e1.toString();
+ name2 = e2.toString();
+ }
+ }
+ if (name1 == null) {
+ name1 = "";//$NON-NLS-1$
+ }
+ if (name2 == null) {
+ name2 = "";//$NON-NLS-1$
+ }
+
+ // Use direct comparison as identified are ASCII only.
+ return name1.compareTo(name2);
+
+ }
+ }
+
+ /**
+ * Editor updater for selection changes in the content outline page.
+ */
+ private final static class EditorUpdater extends RunnableWithLogging {
+ private final Profiler profiler;
+
+ private final AssemblerEditor editor;
+ private final AssemblerContentOutlinePage outlinePage;
+ private final TreeViewer viewer;
+ private final AssemblerContentOutlineTreeContentProvider contentProvider;
+
+ EditorUpdater(AssemblerEditor editor,
+ AssemblerContentOutlinePage outlinePage, TreeViewer viewer) {
+ if (editor == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'editor' must not be null.");
+ }
+ if (outlinePage == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'outlinePage' must not be null.");
+ }
+ if (viewer == null) {
+ throw new IllegalArgumentException(
+ "Parameter 'viewer' must not be null.");
+ }
+ this.editor = editor;
+ this.outlinePage = outlinePage;
+ this.viewer = viewer;
+ this.contentProvider = (AssemblerContentOutlineTreeContentProvider) viewer
+ .getContentProvider();
+ profiler = new Profiler(this);
+
+ }
+
+ /**
+ * Triggers a new
+ * {@link AssemblerContentOutlineTreeContentProvider#parse} run and
+ * updates the display.
+ */
+ @Override
+ protected void runWithLogging() {
+ synchronized (outlinePage) {
+ try {
+ outlinePage.inputUpdateCounter++;
+ runSynchronized();
+ } finally {
+ outlinePage.inputUpdateCounter--;
+ }
+ }
+ }
+
+ private void runSynchronized() {
+ // Stop drawing the control.
+ Control control = viewer.getControl();
+
+ // Check if this call is caused by closing the editor.
+ if (control.isDisposed()) {
+ return;
+ }
+
+ profiler.begin("runSynchronized");
+
+ profiler.begin("updateOutline");
+ control.setRedraw(false);
+
+ // Remember the currently selected tree object in the content
+ // outline tree viewer.
+ ISelection selection = viewer.getSelection();
+ Object[] expandedElements = viewer.getExpandedElements();
+
+ // Trigger the the new parse run.
+ viewer.setInput(outlinePage.input);
+ // viewer.refresh(); Not required?
+
+ profiler.begin("expandElements");
+ if (expandedElements.length > 0) {
+ viewer.setExpandedElements(expandedElements);
+ } else {
+ viewer.expandToLevel(2);
+ }
+ profiler.end("expandElements");
+
+ restoreSelection(selection);
+ // Now that all changes are done, draw the control again.
+ control.setRedraw(true);
+ profiler.end("updateOutline");
+
+ // // Reselect the previous text selection in the editor.
+ // editor.getSelectionProvider().setSelection(textSelection);
+
+ CompilerSourceFile compilerSourceFile;
+ compilerSourceFile = contentProvider.getCompilerSourceFile();
+
+ // Update the identifiers to be highlighted
+ profiler.begin("updateIdentifiers");
+ editor.updateIdentifiers(compilerSourceFile);
+ profiler.end("updateIdentifiers");
+
+ // Update the folding structure.
+ profiler.begin("updateFoldingStructure");
+ List foldingPositions;
+ if (compilerSourceFile != null) {
+ foldingPositions = compilerSourceFile.getFoldingPositions();
+ } else {
+ foldingPositions = Collections.emptyList();
+ }
+ editor.updateFoldingStructure(foldingPositions);
+
+ profiler.end("updateFoldingStructure");
+
+ profiler.end("runSynchronized");
+
+ }
+
+ private void restoreSelection(ISelection selection) {
+ if (selection instanceof TreeSelection) {
+ TreeSelection treeSelection = (TreeSelection) selection;
+ TreePath[] selectedTreePaths = treeSelection.getPaths();
+ List reselectedTreePaths = new ArrayList(
+ selectedTreePaths.length);
+ for (int i = 0; i < selectedTreePaths.length; i++) {
+ TreePath treePath = selectedTreePaths[i];
+ List treeObjects = contentProvider
+ .getCompilerSourceFile().getSections();
+
+ List