Compare commits

...

242 Commits

Author SHA1 Message Date
Uffe Jakobsen
a5bc7a48bd Added README.md 2020-09-17 21:39:37 +02:00
marcobaye
4901f44fdd updated syntax file for "joe" editor
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@295 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-26 23:25:53 +00:00
marcobaye
d59b45036d "Cannot open input file" error message now contains file name.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@294 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-24 16:31:36 +00:00
marcobaye
88cc8cd886 small fix to RISC OS makefile
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@293 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-22 22:31:33 +00:00
marcobaye
5b1fabc1f5 got rid of another init
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@292 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-20 18:00:20 +00:00
marcobaye
beb1e178cd got rid of most of the *_init() functions
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@291 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-16 17:39:13 +00:00
marcobaye
2be25080aa internal cleanup: keyword trees are now only built when needed.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@290 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-15 14:55:22 +00:00
marcobaye
aa8d766e6c made docs match online help
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@289 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-12 13:15:45 +00:00
marcobaye
b2b14cb176 minor cleanup, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@288 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-08-12 12:31:06 +00:00
marcobaye
b03b217979 disabled all indexed addressing for m65's "quad" mode, except for LDQ.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@287 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-29 23:30:33 +00:00
marcobaye
3db33bafb5 nmos6502 mode now also accepts ALR mnemonic (alias for ASR)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@286 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-28 23:08:07 +00:00
marcobaye
26168e6752 small change in tests, improved 65816 register length checking
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@285 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-28 13:13:26 +00:00
marcobaye
2acece9c60 added test script
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@284 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-28 12:57:26 +00:00
marcobaye
6dd15f7116 added BITQ and ASRQ to m65 cpu.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@283 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-27 23:37:36 +00:00
marcobaye
f87ddbb5e6 added last cpu test source and expected output
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@282 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-27 22:58:10 +00:00
marcobaye
32d59eafa3 still more test sources and expected outputs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@281 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-27 22:09:27 +00:00
marcobaye
a3d36ca156 more test sources and expected outputs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@280 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-27 21:25:39 +00:00
marcobaye
78390cb632 added more test sources
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@279 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-27 19:47:07 +00:00
marcobaye
465da8c139 several small changes:
fixed a bug where "number out of range" error led to bogus "label already defined" errors
 made "number out of range" errors more specific (8/16/24 bit range)
 re-phrased two error messages
 cleaned up docs concerning "command/opcode/mnemonic/instruction"
 added test program to trigger "out of range" errors
 internal cleanup concerning INW/DEW/JAM mnemonics


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@278 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-18 13:50:46 +00:00
marcobaye
62dd48ab9f fixed another typo in docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@277 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-17 13:19:38 +00:00
marcobaye
b8f9bb9d36 minor changes only (FIXMEs and docs)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@276 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-17 11:47:05 +00:00
marcobaye
ca08a1d150 started work on !watch and !trace (commented out), minor cleanup, no changes
in functionality


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@275 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-12 18:46:06 +00:00
marcobaye
eb138ae785 added experimental support for 16MiB outbuf using "--test"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@274 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-07-04 13:43:20 +00:00
marcobaye
70b9ee222d tweaked docs and removed some comments, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@273 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-30 09:24:30 +00:00
marcobaye
a7dd713d93 cleaned up list of cpu types and added opcode table(s) for m65 cpu
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@272 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-29 15:10:42 +00:00
marcobaye
a534d9c28a put hashbang info in change log
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@271 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-29 09:55:58 +00:00
marcobaye
94f36db2e5 added support for hashbang lines (if file starts with '#', line is ignored)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@270 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-29 09:53:03 +00:00
marcobaye
21cc635bc8 added library files making use of the new string features:
<cbm/msbstring.a> defines macro to store a string with msb set in last character,
<cbm/multicolor.a> defines macros to "paint" 4-color graphics via strings.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@269 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 22:48:10 +00:00
marcobaye
ecca1552d0 added another test program
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@268 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 22:14:41 +00:00
marcobaye
d0c824c60a added library file for easy splitting of tables into low and high bytes
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@267 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 18:59:08 +00:00
marcobaye
d2683cc64d Release 0.97: Now with string symbols, lists, backslash escaping,
"unpseudopc" operator, MEGA65 support, !while, else if, and a CLI switch to
mimic older versions.
Make sure to read "docs/Changes.txt" and "docs/Upgrade.txt"!


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@266 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 18:56:55 +00:00
marcobaye
ca6b6d8771 rewritten docs/Upgrade.txt
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@265 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 12:18:35 +00:00
marcobaye
7038cecfec fixed error in docs/Errors.txt
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@264 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 09:24:56 +00:00
marcobaye
8f432f6aa7 docs only
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@263 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 00:30:43 +00:00
marcobaye
9d637eee25 comments only, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@262 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-28 00:05:35 +00:00
marcobaye
c85081cbe4 allowed # characters in MVP/MVN syntax
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@261 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-26 10:45:20 +00:00
marcobaye
296ecefa6c explained more errors in docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@260 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-23 15:30:49 +00:00
marcobaye
a5851cd51a removed a few lines that are not really needed
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@259 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-22 22:24:28 +00:00
marcobaye
6c869568cd amended last change, now depends on v0.97
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@258 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-22 20:40:38 +00:00
marcobaye
aa51fde056 Added warning about unusual number of digits in binary literals,
and a CLI switch to disable that warning.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@257 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-22 20:32:38 +00:00
marcobaye
9f5ac5b212 fixed buffer overrun when printing long ints on 64bit machines
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@256 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-22 13:39:27 +00:00
marcobaye
1441da12ac removed useless code concerning FITS_BYTE flag
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@255 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-22 11:09:43 +00:00
marcobaye
cf167a34e4 added alternative expected output for trigonometric example
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@254 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-22 11:08:53 +00:00
marcobaye
be72f71faa simplified state machine of expression parser
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@253 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 22:30:06 +00:00
marcobaye
89344d34ee added more auto-conversions from 1-char-strings to integer
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@252 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 19:51:55 +00:00
marcobaye
1261960cad adjusted docs (added !WHILE, ELSE IF, etc)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@251 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 19:06:12 +00:00
marcobaye
7f736ceccb added "nmos6502" as an alias for "6510"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@250 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 17:24:38 +00:00
marcobaye
3039db71e6 made sure stuff like LDA#"X" keeps working in future version
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@249 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 16:19:05 +00:00
marcobaye
b8679e7f06 added is_number(), is_list() and is_string() functions
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@248 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 15:25:37 +00:00
marcobaye
ceabdfb4a0 added backslash sequences \0, \t, \n and \r
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@247 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 15:21:27 +00:00
marcobaye
85f0c32ff4 fixed convert-to-lower-case function so keywords may contain underscore in future
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@246 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-21 15:16:38 +00:00
marcobaye
5b37c4d24e cleanup (moved functions between files; no change in functionality!)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@245 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-20 16:45:37 +00:00
marcobaye
beb875ff2b refactored (added a union)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@244 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-20 16:11:08 +00:00
marcobaye
562ce98f75 changing a list now needs !set
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@243 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-20 14:54:43 +00:00
marcobaye
fc913eefb6 adjusted docs to future syntax change
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@242 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-20 13:57:16 +00:00
marcobaye
28e196caab added <m65/std.a> to library, with macro to load 32-bit immediate constant
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@241 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-19 22:35:23 +00:00
marcobaye
c3e651f4ca pseudo opcodes like !by, !wo, !tx and friends now accept lists
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@240 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-18 23:38:24 +00:00
marcobaye
eca73fb335 simplified handling of special operators
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@239 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-18 10:15:53 +00:00
marcobaye
64aa52da35 fixed operator priority bug (see test program added in svn rev 232)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@238 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-17 00:37:19 +00:00
marcobaye
326f36fd4f refactoring, about to remove "try to reduce stacks" state
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@237 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-16 23:51:22 +00:00
marcobaye
c2978f7e15 "unpseudopc" operator & now also works with program counter *
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@236 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-16 23:12:44 +00:00
marcobaye
f9a2f5f698 got rid of DEFINED flag by making UNDEFINED its own number type
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@235 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-16 22:44:54 +00:00
marcobaye
929fefe0e6 added opcode table for NMOS6502 cpu
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@234 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-16 12:29:48 +00:00
marcobaye
b32320d5f3 comments only
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@233 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-16 10:46:07 +00:00
marcobaye
430b225208 added failing test program, fix will follow realsoonnow(tm)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@232 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-15 13:05:14 +00:00
marcobaye
f64780a3bd added typedef for "bits"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@231 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-14 00:26:38 +00:00
marcobaye
2671eef384 added a bunch of "const"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@230 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-13 23:18:51 +00:00
marcobaye
1199c75025 more test programs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@229 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-13 23:12:06 +00:00
marcobaye
4643e841f9 symbol assignment refactoring seems to be finished now
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@228 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-13 23:11:10 +00:00
marcobaye
395dcf55f3 fixed a dependency in Makefiles
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@227 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-13 22:42:14 +00:00
marcobaye
8bf6bcd6eb fixed bug introduced in svn rev 217: !for threw "too late for postfix" with wrong line number
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@226 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-13 09:32:21 +00:00
marcobaye
ec2b7515ca fixed bugs: trig functions did not clear FITS_BYTE flag, comparisons did not set it!
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@225 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-10 13:12:25 +00:00
marcobaye
7c82984075 added test source for expression parser
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@224 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-09 22:51:45 +00:00
marcobaye
da12925408 started checking in test sources
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@223 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-09 18:52:49 +00:00
marcobaye
0588f0fffe improved error handling of "--cpu" and "--format" switches. started putting m65 in docs.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@222 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-09 15:58:48 +00:00
marcobaye
1f74a6b8fd comments only
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@221 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-08 17:25:50 +00:00
marcobaye
a165279e88 changed symbol usage counter to "has been read" boolean
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@220 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-08 17:01:17 +00:00
marcobaye
93cea56d88 fixed bug introduced in svn rev 214 ("Too late for postfix" error)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@219 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-07 13:05:01 +00:00
marcobaye
b17203faa7 lists can now be concatenated using '+'
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@218 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-06 12:01:44 +00:00
marcobaye
77e945ce88 symbol assigment refactoring nearing completion...
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@217 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-05 15:15:12 +00:00
marcobaye
02a35ac468 more refactoring
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@216 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-05 09:51:10 +00:00
marcobaye
61d5144faa removed unused vars
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@215 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-05 08:57:09 +00:00
marcobaye
00d0462f74 refactored symbol assignment (unfinished)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@214 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-05 01:11:51 +00:00
marcobaye
72fc28e84c comments only
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@213 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-04 14:31:15 +00:00
marcobaye
9db5ad6fdb first step to refactor symbol assignments
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@212 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-03 16:30:13 +00:00
marcobaye
7a0f9f9528 disabled NOP mnemonic on m65 cpu
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@211 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-03 11:02:16 +00:00
marcobaye
5ea2a03174 removed warning about decimal mode from m65 cpu
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@210 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-03 00:51:09 +00:00
marcobaye
f164b737ad in 6510 mode, DOP/TOP can now also be written as NOP
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@209 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-02 15:09:36 +00:00
marcobaye
8c751f3552 removed 0.93 dialect, as it was buggy and not really useful
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@208 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-06-01 17:49:46 +00:00
marcobaye
8a3bdb265f added "--dialect" CLI switch to set which older version to mimic
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@207 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-31 20:55:38 +00:00
marcobaye
8e4857de4c can now mimic older versions, but still needs a CLI switch to select one
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@206 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-31 15:04:12 +00:00
marcobaye
c03d1145f6 made warning about "pointer at $ff" depend on cpu flag
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@205 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-31 13:07:40 +00:00
marcobaye
64a29e4504 amended docs on illegals
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@204 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-31 13:04:21 +00:00
marcobaye
47b1fab4fe more work to be able to mimic older versions
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@203 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-29 23:33:03 +00:00
marcobaye
9bbac556d3 worked on error messages
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@202 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-29 22:03:04 +00:00
marcobaye
af4a918f18 comments only
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@201 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-29 16:53:13 +00:00
marcobaye
5bcb80ac47 moved stuff around
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@200 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-29 14:30:03 +00:00
marcobaye
8169cf6e06 changed 6510 to nmos6502 internally
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@199 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-29 13:04:28 +00:00
marcobaye
8c8f425559 some renaming/cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@198 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-29 10:57:01 +00:00
marcobaye
2ad075911b enabled !while and new warning about parentheses
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@197 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-28 18:43:49 +00:00
marcobaye
dddf3f3d10 '&' operator (for un-pseudopc-ing) seems to be finished
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@196 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-28 18:40:40 +00:00
marcobaye
636080ce25 started work on '&' operator
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@195 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-27 20:25:42 +00:00
marcobaye
3c9f21cebd fixed date
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@194 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-27 20:06:11 +00:00
marcobaye
a6eae58032 internal cleanup for next change
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@193 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-27 17:32:48 +00:00
marcobaye
78e7c32507 strings now support "+", "=" and "!=" operators
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@192 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-26 12:55:14 +00:00
marcobaye
bc0cd5b8ea "!warn" and friends now support list and string symbols
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@191 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-25 23:12:19 +00:00
marcobaye
98ae73381d updated error messages
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@190 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-24 21:16:50 +00:00
marcobaye
64a4b336b0 small change so associativity of powerof operator can be made configurable later on
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@189 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-24 20:19:19 +00:00
marcobaye
d407faab1c removed old version of !if/else/!ifdef/!ifndef algo.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@188 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-24 19:52:10 +00:00
marcobaye
486febcef4 tiny refactoring, preparing to get rid of another fn
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@187 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-23 23:38:13 +00:00
marcobaye
0173eaf777 cleanup, now only output.c accesses CPU_state.pc
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@186 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-22 20:55:36 +00:00
marcobaye
dfca72688b support for m65 should be finished now
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@185 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-21 23:46:11 +00:00
marcobaye
8eddb4f4bc started suuport for MEGA65 cpu (not finished yet)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@184 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-21 19:36:59 +00:00
marcobaye
c1d8f90fae minor refactoring
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@183 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-20 16:39:19 +00:00
marcobaye
f5e7f23311 fix: values of quoted characters with msb set are now positive
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@182 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 21:04:57 +00:00
marcobaye
cd09855098 expression parser now knows about lists, strings, indexing and len().
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@181 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 20:41:12 +00:00
marcobaye
ba168a3ea5 added backslash escaping (to try it, use --test --test)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@180 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 17:35:04 +00:00
marcobaye
916bf9cbc8 part 4 of 4 of preparations for backslash escaping
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@179 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 16:28:36 +00:00
marcobaye
5b0989ac31 minor refactoring, moved a function
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@178 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 14:33:51 +00:00
marcobaye
768c80219b part 3 of 4 of preparations for backslash escaping
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@177 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 14:16:13 +00:00
marcobaye
101c04e413 more refactoring to prepare for backslash escaping
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@176 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 13:04:39 +00:00
marcobaye
beaf86da5b refactored a bit to prepare for backslash escaping
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@175 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 11:09:46 +00:00
marcobaye
3448cda3df bugfix: unterminated strings could cause crashes
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@174 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-19 09:41:54 +00:00
marcobaye
2fbbc0324e added comments for next change
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@173 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-18 23:47:15 +00:00
marcobaye
c64ffcfced fix for previous commit
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@172 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-18 22:50:11 +00:00
marcobaye
688c00f31b changed a bool to an enum
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@171 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-18 22:10:01 +00:00
marcobaye
4eb3ffa149 "Garbage data at end of statement" message now includes the unexpected character.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@170 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-18 21:51:43 +00:00
marcobaye
c07f373b53 added code for indexing (commented out atm)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@169 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-15 15:33:00 +00:00
marcobaye
665c579470 more work on special operators
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@168 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-15 13:46:17 +00:00
marcobaye
5ba17ccfc4 added error output for "unsupported operation"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@167 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-15 11:39:00 +00:00
marcobaye
4e0d82ac69 added "len" operator, still disabled
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@166 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-14 17:36:09 +00:00
marcobaye
ccaf576e8a added text fields to operator and type structs (for better error messages later on), also renamed some stuff
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@165 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-14 14:01:30 +00:00
marcobaye
ff11dec18c tiny cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@164 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-14 10:35:54 +00:00
marcobaye
7c732fca59 renamed stuff
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@163 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-14 10:19:21 +00:00
marcobaye
c055688355 small fix in docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@162 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-14 10:04:39 +00:00
marcobaye
a7ec38bff5 changed operator passing from enum to struct ptr, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@161 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-14 00:04:20 +00:00
marcobaye
fd2ac55392 new priority values, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@160 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-13 23:53:03 +00:00
marcobaye
365306428b added warnings about binary/octal/hex numbers without any digits, will be error in future! also renamed a function.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@159 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-13 23:45:03 +00:00
marcobaye
40afd3311a cleaned up expression handler, it's now able to handle more than just ints/floats
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@158 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-13 23:26:40 +00:00
marcobaye
3300c9d468 added some TODO/FIXME comments
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@157 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-13 16:53:52 +00:00
marcobaye
dac11ba8c7 finished ELSE IF functionality. currently needs "--test", will be enabled in next release.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@156 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-12 15:08:24 +00:00
marcobaye
16fb63deda planned ELSE IF functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@155 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-12 10:51:37 +00:00
marcobaye
20e04e22bc fix for previous commit: do not complain about () inside []
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@154 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-11 12:42:47 +00:00
marcobaye
4c938480fc added warning about parentheses for mnemonics without indirect addressing. currently needs "--test", will be enabled in next release.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@153 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-11 11:13:06 +00:00
marcobaye
abdea30e33 fixed behaviour of NOT operator concerning type checking: address refs are now negated.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@152 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-10 22:01:04 +00:00
marcobaye
e908284773 refactored handler function for "float with dyadic operator"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@151 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-10 21:35:50 +00:00
marcobaye
f7c52d747c split handler function for dyadic operators into int and float functions. refactored int, still need to do float.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@150 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-10 12:33:41 +00:00
marcobaye
75bd395f2f more renaming
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@149 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-09 23:16:27 +00:00
marcobaye
440dc697ad split handler function for monadic operators into int and float functions
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@148 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-09 23:01:51 +00:00
marcobaye
4cad44f3ec renamed a bunch of stuff
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@147 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-09 20:58:08 +00:00
marcobaye
2b1c9d06bd refactored expression parser (more to come)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@146 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-09 19:26:40 +00:00
marcobaye
55f303c05e minor refactoring
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@145 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-08 17:42:10 +00:00
marcobaye
c1f62fdef5 step 3 to fix ALU_* calls
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@144 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-08 13:22:15 +00:00
marcobaye
4b81e40c63 minor cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@143 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-08 12:22:07 +00:00
marcobaye
38952534f4 cleanup concerning pc assignments
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@142 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-08 09:43:52 +00:00
marcobaye
7d4200faa4 step 2 to fix ALU_* calls
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@141 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-08 00:34:46 +00:00
marcobaye
60603c7350 step 1 to fix ALU_* calls
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@140 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-07 23:32:06 +00:00
marcobaye
a4943e1f40 more cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@139 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-06 12:27:32 +00:00
marcobaye
bc0efebb3e cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@138 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-06 11:40:06 +00:00
marcobaye
2c104118eb now "--test" enables "!while {}"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@137 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-06 10:00:32 +00:00
marcobaye
5c459cad56 added "!while" pseudo opcode (will be enabled in next release)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@136 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-05 22:56:11 +00:00
marcobaye
4565070849 improved "Value not defined" output: Now all undefined symbols of expression
are reported, but never more than once.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@135 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-02 21:59:20 +00:00
marcobaye
ef3cbbe340 fixed float macros in library to make sure they work with future versions of ACME
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@134 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-02 15:38:02 +00:00
marcobaye
d1ac849272 still more cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@133 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-02 14:58:17 +00:00
marcobaye
54defa1add cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@132 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-02 11:28:15 +00:00
marcobaye
e3e68af762 more cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@131 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-02 10:40:10 +00:00
marcobaye
7286e00855 typedef'd boolean to make source more readable. added "--test" option
(unused atm). no change in functionality.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@130 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-05-01 21:01:23 +00:00
marcobaye
bf074b830d just added comments for future cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@129 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-30 16:34:09 +00:00
marcobaye
669f95c238 renamed a bunch of stuff, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@128 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-28 16:02:09 +00:00
marcobaye
0a4c13bb2e internal cleanup, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@127 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-28 11:18:22 +00:00
marcobaye
c4a88fa738 internal cleanup: instead of "value exists" flag, there is now a "expression is empty" field
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@126 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-26 22:26:05 +00:00
marcobaye
68b4409b1c internal cleanup: moved "indirect" flag from result to expression struct
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@125 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-26 20:14:39 +00:00
marcobaye
41f9534b99 more internal cleanup
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@124 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-26 18:53:14 +00:00
marcobaye
a4afd81f42 some internal cleanup concerning empty expressions
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@123 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-26 16:24:34 +00:00
marcobaye
c6f443d581 minor fix for output of segment list. no other change in functionality, only
internal cleanup (added some comments and TODOs)


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@122 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-25 10:20:52 +00:00
marcobaye
2ad798bef2 ACME release 0.96.5: Added "//" comments, added "--ignore-zeroes" and "--strict-segments" CLI switches.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@121 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-04-14 00:28:31 +00:00
marcobaye
63d26a9c82 ACME_Lib: various minor edits
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@120 4df02467-bbd4-4a76-a152-e7ce94205b78
2020-02-28 20:40:18 +00:00
hoeppie
f22907849c Add win32 ico and properties
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@119 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-12-23 01:36:24 +00:00
hoeppie
06e2612a5b Update creating (c) year in win32 file, depends now on version.h
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@118 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-12-23 00:28:25 +00:00
marcobaye
07a7a00b1a ACME_Lib: reformatted ted.a and add 264/petscii.a
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@117 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-08-05 23:39:15 +00:00
marcobaye
c68cefcab0 ACME_Lib: minor tweaks
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@116 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-07-29 14:24:33 +00:00
marcobaye
a57a7b6c68 ACME_Lib: added a directory for the 264 series
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@115 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-07-28 23:33:43 +00:00
marcobaye
81f2d3f683 ACME_Lib: a bit more info on CIAs and VIC
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@114 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-07-28 22:16:51 +00:00
marcobaye
8fc1d4c738 updated toacme: v0.15 new removes leading '+' signs when converting
sources from "Professional Assembler".


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@113 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-04-25 20:26:10 +00:00
marcobaye
e1744c0008 added #define to allow to make segments warnings into errors (no change in
functionality)


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@112 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-04-20 21:12:05 +00:00
marcobaye
238eb5d626 tiny comment in lib
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@111 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-04-09 08:09:20 +00:00
marcobaye
cefa89c138 added 65ce02 and 4502 opcode tables to docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@110 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-03-19 00:37:46 +00:00
marcobaye
c4487b9239 added r65c02 and w65c02 opcode tables to docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@109 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-03-18 22:24:47 +00:00
marcobaye
c262cbe7b4 added 65816 opcode table to docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@108 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-03-18 21:56:19 +00:00
marcobaye
6604877b54 added 65c02 opcode table to docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@107 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-03-18 21:26:38 +00:00
marcobaye
aa611df8b7 added 6502 opcode table to docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@106 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-03-18 21:13:41 +00:00
marcobaye
75d52177cc fixed typo
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@105 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-02-01 11:28:39 +00:00
marcobaye
99d866e2e8 Some small changes in source, no change in functionality.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@104 4df02467-bbd4-4a76-a152-e7ce94205b78
2019-02-01 11:23:28 +00:00
hoeppie
fb81d868d6 Update from 2015 to 2018
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@103 4df02467-bbd4-4a76-a152-e7ce94205b78
2018-11-16 15:26:07 +00:00
marcobaye
b31e6c4e70 ACME_Lib: changed macro parameters to cheap locals (there should be no change in functionality)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@102 4df02467-bbd4-4a76-a152-e7ce94205b78
2018-08-05 15:33:15 +00:00
marcobaye
6ff2e95da8 ACME_Lib: edited c64/float.a so register usage is mentioned consistently.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@101 4df02467-bbd4-4a76-a152-e7ce94205b78
2018-07-05 16:59:37 +00:00
marcobaye
a123239d2d ACME_Library: added ref to ioerror.a file.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@100 4df02467-bbd4-4a76-a152-e7ce94205b78
2018-06-30 21:05:16 +00:00
marcobaye
b3d818da39 ACME_Lib: added some more comments
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@99 4df02467-bbd4-4a76-a152-e7ce94205b78
2018-06-30 20:59:42 +00:00
marcobaye
bc68e36127 ACME_Lib: changed "kernel" to "kernal" in various comments
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@98 4df02467-bbd4-4a76-a152-e7ce94205b78
2018-01-29 15:59:20 +00:00
marcobaye
9628f69f4e ACME release 0.96.4: Fixed bug in zero page wrap-around warnings. Added "!xor" pseudo op. Added "-I" CLI switch.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@97 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-12-22 22:55:36 +00:00
marcobaye
f23a38de8c fixed native mode interrupt vectors in library file <65816/std.a>
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@96 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-11-03 17:48:49 +00:00
marcobaye
3867147615 Fixed docs to include two error messages. Fixed a typo, no change in functionality.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@95 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-11-03 15:14:55 +00:00
marcobaye
7cb100c480 ACME release 0.96.3: Added "!hex" and "!skip" pseudoops. Added cheap locals.
Added CLI switch to change pseudoop prefix to '.'
Fixed a bug in expression parser and added a warning.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@94 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-10-29 23:29:07 +00:00
marcobaye
e1683b1e28 more minor comment changes
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@93 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-10-21 20:23:22 +00:00
marcobaye
47f09e9804 a bit of internal cleanup of names and comments, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@92 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-10-21 19:59:56 +00:00
marcobaye
a6daa92e63 tiny change in docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@91 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-10-21 19:01:48 +00:00
marcobaye
071778e2c1 Library: added some comments and an alias for "k_plot"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@90 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-10-21 18:41:09 +00:00
marcobaye
a5e984f158 comments only
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@89 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-10-16 17:01:44 +00:00
hoeppie
53a8e9ab79 Typo in setRelease.sh fixed
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@88 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-06-17 23:04:59 +00:00
marcobaye
bb484d683e updated toacme to include undocumented opcode "shx $1234,y"
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@87 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-03-21 20:44:12 +00:00
marcobaye
a915eef8e9 ACME release 0.96.2: Error output now in color using ANSI escape codes. Thanks to Clifford Carnmo for submitting this patch!
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@86 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-03-10 12:19:15 +00:00
hoeppie
2e0c8fc9f0 Update Windows-Resource-Erzeugung
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@85 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-02-12 00:33:37 +00:00
marcobaye
899f8c3b0c rearranged some data tables
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@84 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-01-08 22:16:43 +00:00
marcobaye
a21ff667a8 tweaked docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@83 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-01-05 20:26:51 +00:00
marcobaye
5120d12af4 tweaked docs/cputypes.txt
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@82 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-01-05 17:02:13 +00:00
marcobaye
9603d13031 ACME release 0.96.1: Fixed bug where 65ce02's "(zp),z" addressing mode could be used in 65816 mode.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@81 4df02467-bbd4-4a76-a152-e7ce94205b78
2017-01-05 10:39:19 +00:00
marcobaye
4979302d0d tweaked docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@80 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-12-29 12:02:12 +00:00
marcobaye
90dd2e0a36 fixed typo in docs
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@79 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-12-28 21:03:38 +00:00
marcobaye
294fe25c36 ACME Release 0.96: Added experimental support for instruction sets of Rockwell 65C02, WDC 65C02(S), CSG 65CE02 and CSG 4502.
Stack indexing can now be given either as ",s" or as ",sp" (only relevant for 65816 and 65CE02).


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@78 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-12-28 20:32:00 +00:00
marcobaye
681cbda33e examples: fixed Makefile to use correct file format for trigonometry example
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@77 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-12-27 12:29:09 +00:00
marcobaye
c0a78ccec6 Library: changed names for MMU registers $d507-$d50a, because "high" and "low" are ambiguous. ;)
Sorry for any inconveniences...


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@76 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-10-10 21:30:51 +00:00
marcobaye
222f06c905 ACME Release 0.95.8: Errors in macros are now shown with call stack.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@75 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-10-08 12:19:12 +00:00
marcobaye
7fd4bc6539 Library: fixed cbm/baserror.a for basic3.5
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@74 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-08-08 14:48:00 +00:00
marcobaye
a63007c0f9 internal cleanup (zone -> scope), no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@73 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-08-05 09:59:07 +00:00
marcobaye
d53d0992aa moved version info to separate header file
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@72 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-07-19 08:11:58 +00:00
marcobaye
a8d89e373a Library: more comments for basic10
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@71 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-06-06 09:25:33 +00:00
marcobaye
f1e5dff122 Library: renamed cbm/c64/memmove.a to memcopy.a and fixed comments. Thanks Mike!
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@70 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-06-05 14:23:39 +00:00
marcobaye
a6ca824eb7 Library: added cbm/c64/memmove.a with a macro to call $a3bf in basic interpreter
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@69 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-06-05 12:33:05 +00:00
marcobaye
5240b5eff4 Comments and whitespace only, no change in functionality.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@68 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-02-21 23:08:02 +00:00
marcobaye
9dcb622b3d Tweaked some CLI error messages and renamed some functions, no change in functionality.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@67 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-02-21 12:58:22 +00:00
marcobaye
fcbebf8343 ACME Release 0.95.7: Added pseudo opcodes to output big-endian values
(not really worth a separate release, but I wanted to get the changes
out of my system)
toacme Release 0.13: started work on converter for "Oliver Stiller's
Professional Assembler"


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@66 4df02467-bbd4-4a76-a152-e7ce94205b78
2016-02-16 23:11:04 +00:00
marcobaye
651b059e67 Tiny change to support compilers without snprintf(). Added Makefile for examples.
No change in functionality.



git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@65 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-08-16 20:19:00 +00:00
marcobaye
ba348db03e Used #ifdef to make sure GNU-C-specific stuff only is used with GCC (so now it compiles with VS).
No change in functionality.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@64 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-06-20 14:44:17 +00:00
marcobaye
8d2719db8a Release 0.95.6 (intermediate release): Removed ANC from DTV2 mode, "Value not defined"
message now includes symbol name, fixed bug in type system (!for loop counters), added
address() as alternative to addr(), fixed bug in report listing generator (CR in input
caused additional blank lines in output).


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@63 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-06-14 23:16:23 +00:00
marcobaye
9c3d91adfa Library: added comment for fac1_divide_by_10 ($bafe) because result is always positive
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@62 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-03-01 15:54:11 +00:00
marcobaye
c3e12f91db Library: added symbol for c64 float call $bcf3, also fixed typo
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@61 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-03-01 15:36:59 +00:00
marcobaye
b2afe0d5f4 updated "toacme" sources to current version (release 0.12 from 2015-02-04),
now including a converter for "VisAss".


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@60 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-02-12 00:57:01 +00:00
marcobaye
b451573f00 updated "toacme" sources to version 0.11 from 2012-10-08 (source cleanup)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@59 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-02-12 00:43:02 +00:00
marcobaye
b11d8771e6 updated "toacme" sources to version 0.10 from 2006-10-04 (better support for illegals)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@58 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-02-12 00:38:22 +00:00
marcobaye
8689aac860 updated "toacme" sources to version 0.9 from 2006-03-12 (improved Giga-Assembler conversion)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@57 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-02-12 00:32:11 +00:00
marcobaye
6cd245dc76 added "toacme" docs (program is release 0.8 from 2005-06-16, btw)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@56 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-02-12 00:22:38 +00:00
marcobaye
56ee1d304e Added "toacme" source code converter to "contrib" directory.
Do not compile it yet, I have more (newer) versions to commit... ;)


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@55 4df02467-bbd4-4a76-a152-e7ce94205b78
2015-02-11 23:18:55 +00:00
189 changed files with 14410 additions and 3913 deletions

45
ACME_Lib/6502/split.a Normal file
View File

@ -0,0 +1,45 @@
;ACME 0.97
!set split_cache = [] ; start every pass with an empty cache
!ifdef lib_6502_split_a !eof
lib_6502_split_a = 1
!macro split_lo @args {
+split_putbytes 0, @args
!set split_cache = split_cache + @args
}
!macro split_hi @args {
+split_putbytes 8, @args
!set split_cache = split_cache + @args
}
!macro split_lo {
+split_putbytes 0, split_cache
!set split_cache = []
}
!macro split_hi {
+split_putbytes 8, split_cache
!set split_cache = []
}
!macro split_putbytes @shift, @bytes {
!if len(@bytes) {
!for @idx, 0, len(@bytes) - 1 {
!by (@bytes[@idx] >> @shift) & $ff
}
}
}
!eof
; these macros can be used to split address tables in two separate
; parts for high- and low-bytes. example:
table_hi
+split_hi [$0123, $4567, $89ab, $cdef] ; writes $01, $45, $89, $cd
+split_hi [$1122, $3344, $5566, $7788] ; writes $11, $33, $55, $77
table_lo
+split_lo ; writes $23, $67, $ab, $ef, $22, $44, $66, $88 from cache
; of course you can also put the low bytes first:
table_lo
+split_lo [$0123, $4567, $89ab, $cdef] ; writes $23, $67, $ab, $ef
+split_lo [$1122, $3344, $5566, $7788] ; writes $22, $44, $66, $88
table_hi
+split_hi ; writes $01, $45, $89, $cd, $11, $33, $55, $77 from cache

View File

@ -1,4 +1,4 @@
;ACME 0.95
;ACME 0.96.4
!ifdef lib_6502_std_a !eof
lib_6502_std_a = 1
@ -22,57 +22,57 @@ lib_6502_std_a = 1
}
; increase 16-bit counter
!macro inc16 .t {
inc .t
!macro inc16 @t {
inc @t
bne +
inc .t + 1
inc @t + 1
+
}
; far branches
!macro bcc .t {
!macro bcc @t {
bcs +
jmp .t
jmp @t
+
}
!macro bcs .t {
!macro bcs @t {
bcc +
jmp .t
jmp @t
+
}
!macro beq .t {
!macro beq @t {
bne +
jmp .t
jmp @t
+
}
!macro bne .t {
!macro bne @t {
beq +
jmp .t
jmp @t
+
}
!macro bmi .t {
!macro bmi @t {
bpl +
jmp .t
jmp @t
+
}
!macro bpl .t {
!macro bpl @t {
bmi +
jmp .t
jmp @t
+
}
!macro bvc .t {
!macro bvc @t {
bvs +
jmp .t
jmp @t
+
}
!macro bvs .t {
!macro bvs @t {
bvc +
jmp .t
jmp @t
+
}

View File

@ -1,7 +1,7 @@
;ACME 0.95
;ACME 0.96.4
!ifdef lib_65816_std_a !eof
lib_65816_std_a = 1
lib_65816_std_a = 2
; Labels and macros for Western Digital's 65c816 processor
@ -12,11 +12,12 @@ lib_65816_std_a = 1
cpu_e_reset = $fffc
cpu_e_irq = $fffe
cpu_n_cop = $fff4
cpu_n_brk = $fff6
cpu_n_abort = $fff8
cpu_n_nmi = $fffa
cpu_n_irq = $fffe
cpu_n_cop = $ffe4
cpu_n_brk = $ffe6
cpu_n_abort = $ffe8
cpu_n_nmi = $ffea
; no reset vector for native mode because reset always enters emulation mode
cpu_n_irq = $ffee
}
!macro cpu_emu {; switch to emulation mode
@ -71,11 +72,11 @@ lib_65816_std_a = 1
+i8
}
!macro inc24 .t {; increase 24-bit counter
inc .t
!macro inc24 @t {; increase 24-bit counter
inc @t
bne +
inc .t + 1
inc @t + 1
bne +
inc .t + 2
inc @t + 2
+
}

6
ACME_Lib/cbm/264/basic.a Normal file
View File

@ -0,0 +1,6 @@
;ACME 0.96.4
!ifdef lib_cbm_264_basic_a !eof
lib_cbm_264_basic_a = 1
!source <cbm/basic3.5.a>

View File

@ -0,0 +1,46 @@
;ACME 0.96.4
!ifdef lib_cbm_264_petscii_a !eof
lib_cbm_264_petscii_a = 1
!source <cbm/petscii.a>
; the sixteen predefined color/luma combinations available via petscii:
petscii_BLACK = 144 ; $00 here's the actual bits given to TED
petscii_WHITE = 5 ; $71 (first digit is luma bits,
petscii_RED = 28 ; $32 second digit is color nibble)
petscii_CYAN = 159 ; $63
petscii_PURPLE = 156 ; $44
petscii_GREEN = 30 ; $35
petscii_BLUE = 31 ; $46
petscii_YELLOW = 158 ; $77
petscii_ORANGE = 129 ; $48
petscii_BROWN = 149 ; $29
petscii_YELLOWGREEN = 150 ; $5a
petscii_PINK = 151 ; $6b
petscii_BLUEGREEN = 152 ; $5c
petscii_LIGHTBLUE = 153 ; $6d
petscii_DARKBLUE = 154 ; $2e
petscii_LIGHTGREEN = 155 ; $5f
; switching character set (same as C64)
petscii_LOCK = 8 ; forbid CBM-shift (C128 uses 11 instead)
petscii_UNLOCK = 9 ; allow CBM-shift (C128 uses 12 instead)
petscii_LOWERCASE = 14 ; switch to lowercase/uppercase character set
petscii_UPPERCASE = 142 ; switch to uppercase/graphics character set
; 264-specific stuff
petscii_FLASHON = 130 ; (C128 uses 15 instead)
petscii_FLASHOFF = 131 ; (C128 uses 143 instead)
; function keys
petscii_F1 = 133
petscii_F3 = 134
petscii_F5 = 135
petscii_F7 = 136
petscii_F2 = 137
petscii_F4 = 138
petscii_F6 = 139
petscii_HELP = 140 ; (C128 uses 132 instead)
petscii_ESCAPE = 27

215
ACME_Lib/cbm/264/ted.a Normal file
View File

@ -0,0 +1,215 @@
;ACME 0.96.4
!ifdef lib_cbm_264_ted_a !eof
lib_cbm_264_ted_a = 1
; Text Display (TED) 7360/8360
; Definitions:
; HiRes: High resolution (320x200 pixels, two colors per 8x8 block)
; MCM: Multi-color mode (160x200 pixels, four colors per 4x8 block)
; Text mode: Pixel data is taken from charset, index/color/luminance is
; taken from video ram.
; Bitmap mode: Pixel data is taken from 8 KiB bitmap, color/luminance is taken
; from video ram.
; ECM: Extended color mode. Like HiRes text mode, but instead of 256
; different characters on a shared background color, 64 different
; characters on four different background colors are displayed.
; MC text mode is actually a mixed mode: each character position has its own
; bit to decide whether it is displayed in HiRes or MC.
; info taken from
; http://mclauchlan.site.net.au/scott/C=Hacking/C-Hacking12/gfx.html (Document Revision B)
; http://www.zimmers.net/anonftp/pub/cbm/maps/C16.MemoryMap
; Video RAM is $0800 bytes
; in text mode:
; first $0400 bytes is color/luminance info:
; %7....... flash (ignored in MCM and ECM)
; %.654.... luminance
; %....3... MCM: multicolor flag
; %.....210 MCM: color
; %....3210 HiRes and ECM: color
; second $0400 bytes hold screen codes:
; %76543210 HiRes and MCM: screen code (in HiRes, bit 7 can
; be configured to be "hardware reverse",
; see register $ff07)
; %76...... ECM: background color index (see registers
; $ff15..$ff18)
; %..543210 ECM: screen code
; in bitmap mode:
; CAUTION!
; LOW nibble of luma corresponds to HIGH nibble of color and vice versa!
; first $0400 bytes is luminance info:
; %7....... unused
; %.654.... luminance of %0 HiRes pixels or %01 MC pixels
; %....3... unused
; %.....210 luminance of %1 HiRes pixels or %10 MC pixels
; second $0400 bytes is color info:
; %7654.... color of %1 pixels or %10 MC pixels
; %....3210 color of %0 pixels or %01 MC pixels
; colors:
tedcolor_BLACK = $0 ; ignores luminance, black is always black!
tedcolor_WHITE = $1 ; actually gray, only max luminance gives white
tedcolor_RED = $2
tedcolor_CYAN = $3
tedcolor_PURPLE = $4
tedcolor_GREEN = $5
tedcolor_BLUE = $6
tedcolor_YELLOW = $7 ; needs high luminance to look yellow...
; these cannot be used as main color in MCM:
tedcolor_ORANGE = $8
tedcolor_BROWN = $9
tedcolor_YELLOWGREEN = $a
tedcolor_PINK = $b
tedcolor_BLUEGREEN = $c
tedcolor_LIGHTBLUE = $d
tedcolor_DARKBLUE = $e
tedcolor_LIGHTGREEN = $f
; the color names are somewhat useless, because they refer not to the sixteen
; base colors, but to the sixteen pre-defined luminance/color combinations
; available by pressing the ctrl or cbm key with a digit key (see the ROM table
; at $e143 for these combined values).
; for a "nice" color display, use this order: 2,8,9,7,a,f,5,c,3,d,6,e,4,b,
; that will give a red/yellow/green/blue/purple spectrum.
; to display the whole palette, try this program:
; 10 for i = 0 to 15:color 1, 1
; 20 read c$:print " " c$ " ";
; 30 poke 194, 128:for lu = 0 to 7
; 40 color 1, dec(c$) + 1, lu
; 50 print " ";
; 60 next:print:next:color 1, 1
; 70 data 0,1,2,8,9,7,a,f
; 80 data 5,c,3,d,6,e,4,b
; TED registers
!addr ted_base = $ff00
; timers
ted_timer1_lo = ted_base + $00 ; decrements from the last value written into it
ted_timer1_hi = ted_base + $01
ted_timer2_lo = ted_base + $02 ; runs freely from $ffff
ted_timer2_hi = ted_base + $03
ted_timer3_lo = ted_base + $04 ; runs freely from $ffff
ted_timer3_hi = ted_base + $05
; mode bits
ted_vertctrl = ted_base + $06 ; mostly the same as VIC's $d011
tedvert_TEST = %#....... ; internal test, it should be 0
tedvert_EBCM = %.#...... ; extended background color mode
tedvert_BITMAP = %..#..... ; bitmap mode
tedvert_ENABLE = %...#.... ; display enable (0: blank screen)
tedvert_25ROWS = %....#... ; 0: 24 rows, 1: 25 rows
tedvert_SMOOTH = %.....### ; vertical smooth scroll (std: %011, higher values move text down)
ted_horzctrl = ted_base + $07 ; most similar VIC-reg is $d016
tedhorz_256CHRS = %#....... ; 0: 128 characters and hardware reverse, 1: 256 characters
tedhorz_NTSC = %.#...... ; 0: PAL, 1: NTSC
tedhorz_FREEZE = %..#..... ; if set, TED stops its counters and screen-generating, only single clock and refresh cycles remain.
tedhorz_MULTI = %...#.... ; multicolor mode
tedhorz_40COLS = %....#... ; 0: 38 columns, 1: 40 columns
tedhorz_SMOOTH = %.....### ; horizontal smooth scroll (std: %000, higher values move text right)
; i/o
ted_keyboard = ted_base + $08 ; keyboard input latch (write to trigger sampling, then read input byte)
; to scan keyboard, write output byte to $fd30, then write $ff here (to disable joysticks) and read input byte.
; to scan joysticks, write $ff to $fd30 (to disable keyboard), then write SELECT value here and read input byte.
tedjoy1_SELECT = %#####.## ; d2 low selects joy #1
tedjoy2_SELECT = %######.# ; d1 low selects joy #2
; CAUTION, the joystick bits are low-active, so invert input byte before using these:
tedjoy2_FIRE = %#.......
tedjoy1_FIRE = %.#......
tedjoy_RIGHT = %....#...
tedjoy_LEFT = %.....#..
tedjoy_DOWN = %......#.
tedjoy_UP = %.......#
; interrupts
ted_irq = ted_base + $09 ; interrupt request register
; if bit is set, interrupt has occurred.
; to acknowledge interrupts, write back the value read from this register
; (setting bits clears them, i.e. writing $82 clears ACTIVE and RASTER
; but does not change the COUNTER bits)
tedirq_ACTIVE = %#....... ; 1: TED is signalling interrupt to cpu
tedirq_COUNTER3 = %.#...... ; 1: counter #3 underflow
; %..#..... ; always 1 (unused)
tedirq_COUNTER2 = %...#.... ; 1: counter #2 underflow
tedirq_COUNTER1 = %....#... ; 1: counter #1 underflow
; %.....#.. ; always 1 (light pen, not implemented)
tedirq_RASTER = %......#. ; 1: raster line reached
; %.......# ; always 1 (unused)
ted_mask = ted_base + $0a ; interrupt mask register (enable/disable)
; if bit is set, interrupt is enabled.
; use the tedirq_* constants from above.
; %#....... ; always 1 (unused)
;COUNTER3 = %.#...... ; 1: enable counter #3 underflow interrupt
; = %..#..... ; always 1 (unused)
;COUNTER2 = %...#.... ; 1: enable counter #2 underflow interrupt
;COUNTER1 = %....#... ; 1: enable counter #1 underflow interrupt
; = %.....#.. ; always 1 (light pen, not implemented)
;RASTER = %......#. ; 1: enable raster line interrupt
tedmask_LINEBIT8= %.......# ; bit 8 of raster line register $ff0b (see below)
ted_line = ted_base + $0b ; raster line to trigger interrupt. bit 8 is in bit 0 of $ff0a (see above)
; hardware cursor, given as screen offset (0...999). use 1000 or greater to hide.
ted_hwcursor_hi = ted_base + $0c ; %765432.. are unused, %......10 are MSBs of hw cursor offset
ted_hwcursor_lo = ted_base + $0d ; hardware cursor offset (low byte)
; sound
; to calculate the register values:
; NTSC: reg = 1024 - (111860.781 / frequency_in_Hz)
; PAL: reg = 1024 - (111840.45 / frequency_in_Hz)
ted_sound1_low = ted_base + $0e ; low 8 bits of voice #1 frequency
ted_sound2_low = ted_base + $0f ; low 8 bits of voice #2 frequency
ted_sound2_hi = ted_base + $10 ; bits 7..2 are unused, bits 1..0 are the highmost 2 bits of voice #2 frequency
ted_sound_ctrl = ted_base + $11 ; sound control register
tedsound_DA = %#....... ; D/A mode (sound reload)
tedsound_NOISE2 = %.#...... ; voice #2 noise on/off
tedsound_SQUARE2= %..#..... ; voice #2 square wave on/off (if you set both, the square will sound)
tedsound_ONOFF1 = %...#.... ; voice #1 on/off
tedsound_VOLUME = %....#### ; volume, maximum value is 8
ted_misc = ted_base + $12 ; some memory and some sound bits:
; = %##...... ; unused
tedmisc_BITMAP = %..###... ; a15/a14/a13 of bitmap in memory
tedmisc_ROMCHAR = %.....#.. ; 0: charset is in RAM, 1: charset is in ROM
tedmisc_SOUNDMSB= %......## ; highmost bits of voice #1 frequency
ted_mem = ted_base + $13 ;
tedmem_CHARGEN = %######.. ; high address bits of character generator
tedmem_SCLOCK = %......#. ; 1: force single clock mode
tedmem_ROM = %.......# ; read-only: ROM is active over $8000
ted_videoram = ted_base + $14 ; bits 7..3 are the high address bits of video ram
; color registers
; %7....... unused
; %.654.... luminance
; %....3210 color
ted_background = ted_base + $15 ; color for %00 pixels (or %0 in HiRes)
ted_color1 = ted_base + $16 ; color for %01 pixels (MCM and ECM)
ted_color2 = ted_base + $17 ; color for %10 pixels (MCM and ECM)
ted_color3 = ted_base + $18 ; color for %11 pixels (MCM graphics and ECM)
ted_border = ted_base + $19
; current character position
ted_charpos_hi = ted_base + $1a ; bits 1..0 are highmost bits
ted_charpos_lo = ted_base + $1b ; low bits of actual character position
; current raster position (writable!)
ted_vertical_hi = ted_base + $1c ; bit 0 is msb of raster line
ted_vertical_lo = ted_base + $1d ; low 8 bits of raster line
ted_horizontal = ted_base + $1e ; horizontal position (given in double pixels)
ted_count = ted_base + $1f
; = %#....... ; always 1 (unused)
tedcount_FLASH = %.####... ; flashing counter
tedcount_CHAR = %.....### ; raster line in character row (r/w!)
; pseudo registers
; these are not really registers inside TED, but here they are, anyway:
!addr ted_enable_roms = $ff3e ; any write here enables ROMs above $8000
!addr ted_enable_rams = $ff3f ; any write here enables RAM above $8000

View File

@ -36,13 +36,14 @@ baserror_UNDEFINED_FUNCTION = 27
baserror_VERIFY = 28
baserror_LOAD = 29
baserror_BREAK = 30
; from here on, basic 7 only:
; basic 3.5 and higher:
baserror_CANT_RESUME = 31
baserror_LOOP_NOT_FOUND = 32
baserror_LOOP_WITHOUT_DO = 33
baserror_DIRECT_MODE_ONLY = 34
baserror_NO_GRAPHICS_AREA = 35
baserror_BAD_DISK = 36
; basic 7 and higher:
baserror_BEND_NOT_FOUND = 37
baserror_LINE_NUMBER_TOO_LARGE = 38 ; for RENUMBER
baserror_UNRESOLVED_REFERENCE = 39 ; for RENUMBER

View File

@ -1,4 +1,4 @@
;ACME 0.94.4
;ACME 0.96.4
!ifdef lib_cbm_basic10_a !eof
lib_cbm_basic10_a = 1
@ -18,33 +18,49 @@ token_DIR = $ee ; was called DIRECTORY in basic v7
!macro b_DIR {!by token_DIR} ; aka DIRECTORY
; STASH/FETCH/SWAP are all decoded to DMA:
!macro b_DMA {!by $fe, $1f}
!macro b_DMA {!by $fe, $1f} ; command, length, source, target, subcommand
; extended token $fe $20 isn't used ($20 is ' ')
;!macro b_DMA {!by $fe, $21}
; extended token $fe $22 isn't used ($20 is '"')
;!macro b_DMA {!by $fe, $23}
; renamed function:
!macro b_LPEN {!by $ce, $04:!pet '('} ; was called PEN in basic7
; basic7 defines functions up to $ce, $0a (POINTER)
; new functions:
;!macro b_ {!by $ce, $0b:!pet '('} ; ?
!macro b_PIXEL {!by $ce, $0c:!pet '('} ; return pixel color
!macro b_RPALETTE {!by $ce, $0d:!pet '('} ; return palette color
; new instructions:
!macro b_TYPE {!by $fe, $27}
!macro b_TYPE {!by $fe, $27} ; display sequential disk file
!macro b_BVERIFY {!by $fe, $28}
!macro b_ECTORY {!by $fe, $29} ; no-op in case someone types "DIRECTORY"?
!macro b_ERASE {!by $fe, $2a}
!macro b_FIND {!by $fe, $2b}
!macro b_CHANGE {!by $fe, $2c}
!macro b_SET {!by $fe, $2d}
!macro b_ERASE {!by $fe, $2a} ; delete file
!macro b_FIND {!by $fe, $2b} ; search in basic program
!macro b_CHANGE {!by $fe, $2c} ; edit program
!macro b_SET {!by $fe, $2d} ; set system parameter
!macro b_SCREEN {!by $fe, $2e}
!macro b_POLYGON {!by $fe, $2f}
!macro b_ELLIPSE {!by $fe, $30}
!macro b_VIEWPORT {!by $fe, $31}
!macro b_GCOPY {!by $fe, $32}
!macro b_PEN {!by $fe, $33}
!macro b_PALETTE {!by $fe, $34}
!macro b_DMODE {!by $fe, $35}
!macro b_DPAT {!by $fe, $36}
!macro b_VIEWPORT {!by $fe, $31} ; unimplemented?
!macro b_GCOPY {!by $fe, $32} ; copy graphics
!macro b_PEN {!by $fe, $33} ; set pen color
!macro b_PALETTE {!by $fe, $34} ; set palette color
!macro b_DMODE {!by $fe, $35} ; set draw mode
!macro b_DPAT {!by $fe, $36} ; set draw pattern
!macro b_PIC {!by $fe, $37}
!macro b_GENLOCK {!by $fe, $38}
!macro b_FOREGROUND {!by $fe, $39}
!macro b_FOREGROUND {!by $fe, $39} ; set foreground color
; extended token $fe $3a isn't used ($3a is ':')
!macro b_BACKGROUND {!by $fe, $3b}
!macro b_BORDER {!by $fe, $3c}
!macro b_HIGHLIGHT {!by $fe, $3d}
!macro b_BACKGROUND {!by $fe, $3b} ; set background color
!macro b_BORDER {!by $fe, $3c} ; set border color
!macro b_HIGHLIGHT {!by $fe, $3d} ; set highlight color
!macro b_MOUSE {!by $fe, $3e} ; set mouse parameters
!macro b_RMOUSE {!by $fe, $3f} ; read mouse position
!macro b_DISK {!by $fe, $40} ; send disc command
!macro b_CURSOR {!by $fe, $41} ; place text cursor?
;!macro b_ {!by $fe, $42} ; ?
!macro b_LOADIFF {!by $fe, $43} ; load IFF graphics
!macro b_SAVEIFF {!by $fe, $44} ; save IFF graphics
!macro b_EDIT {!by $fe, $45} ; switch between program and text editing

View File

@ -9,26 +9,28 @@ lib_cbm_c128_kernal_a = 1
!address {
k_spin_spout = $ff47
k_close_all = $ff4a
k_c64mode = $ff4d
k_c64mode = $ff4d ; enter c64 mode (so does not return)
k_dma_call = $ff50
k_boot_call = $ff53
k_phoenix = $ff56
k_lkupla = $ff59
k_lkupsa = $ff5c
k_lkupla = $ff59 ; find channel with file number A
k_lkupsa = $ff5c ; find channel with secondary address Y
k_swapper = $ff5f
k_dlchr = $ff62
k_pfkey = $ff65
k_setbnk = $ff68
k_setbnk = $ff68 ; set banks for file name and load/save calls
k_getcfg = $ff6b
k_jsrfar = $ff6e
k_jmpfar = $ff71
k_indfet = $ff74
k_indsta = $ff77
k_indcmp = $ff7a
k_primm = $ff7d
k_primm = $ff7d ; "print immediate" - output string without having to setup a pointer:
; string must follow JSR $ff7d in memory, code execution will resume after terminating zero.
; A/X/Y are preserved
k_release_number = $ff80
}
!source <cbm/kernal.a> ; $ff81-$fff5 is backward compatible to older machines
!source <cbm/kernal.a> ; $ff81-$fff5 is mostly compatible to older machines
; $fff6/$fff7 are unused (ff ff)
!address {
k_indirect128mode = $fff8 ; indirect vector, without JMP command!

View File

@ -1,7 +1,7 @@
;ACME 0.95
!ifdef lib_cbm_c128_mmu_a !eof
lib_cbm_c128_mmu_a = 1
lib_cbm_c128_mmu_a = 2
; Memory Management Unit (MMU) 8722
@ -12,10 +12,10 @@ lib_cbm_c128_mmu_a = 1
; configuration register
mmu_cr_d500 = $d500 ; same as "mmu_cr" at $ff00. Use "mmu_cr" instead, as that is *always* available.
; preconfiguration registers (internal format just like mmu_cr)
mmu_pcr_a = $d501 ; c128 kernel default is $3f (BANK 0)
mmu_pcr_b = $d502 ; c128 kernel default is $7f (BANK 1)
mmu_pcr_c = $d503 ; c128 kernel default is $01 (BANK 14)
mmu_pcr_d = $d504 ; c128 kernel default is $41 (all system roms, with ram 1)
mmu_pcr_a = $d501 ; c128 kernal default is $3f (BANK 0)
mmu_pcr_b = $d502 ; c128 kernal default is $7f (BANK 1)
mmu_pcr_c = $d503 ; c128 kernal default is $01 (BANK 14)
mmu_pcr_d = $d504 ; c128 kernal default is $41 (all system roms, with ram 1)
}
; contents of cr and all four pcr:
mmu_CR_RAMBANK_MASK = %##...... ; this controls which RAM bank is used in areas where RAM is enabled
@ -25,7 +25,7 @@ mmu_CR_RAMBANK_2 = %#....... ; on an unmodified c128, there is no ram bank 2 (0
mmu_CR_RAMBANK_3 = %##...... ; on an unmodified c128, there is no ram bank 3 (1 will be used instead)
mmu_CR_HIGH_MASK = %..##.... ; this controls the "high area" (c000..ffff), but i/o (d000..dfff) is separate
;mmu_CR_HIGH_SYSROM = %........ ; editor, charset (or i/o, see below), kernel
;mmu_CR_HIGH_SYSROM = %........ ; editor, charset (or i/o, see below), kernal
mmu_CR_HIGH_INTFUNCROM = %...#....
mmu_CR_HIGH_EXTFUNCROM = %..#.....
mmu_CR_HIGH_RAM = %..##....
@ -57,10 +57,10 @@ mmu_CR_BANK8 = $2a ; 32 KiB bank 0; 32 KiB EFROM with i/o overlay
mmu_CR_BANK9 = $6a ; 32 KiB bank 1; 32 KiB EFROM with i/o overlay
mmu_CR_BANK10 = $aa ; 32 KiB bank 2; 32 KiB EFROM with i/o overlay
mmu_CR_BANK11 = $ea ; 32 KiB bank 3; 32 KiB EFROM with i/o overlay
mmu_CR_BANK12 = $06 ; 32 KiB bank 0; 16 KiB IFROM; 16 KiB kernel with i/o overlay
mmu_CR_BANK13 = $0a ; 32 KiB bank 0; 16 KiB EFROM; 16 KiB kernel with i/o overlay
mmu_CR_BANK14 = $01 ; 16 KiB bank 0; 32 KiB basic; 16 KiB kernel with font overlay
mmu_CR_BANK15 = $00 ; 16 KiB bank 0; 32 KiB basic; 16 KiB kernel with i/o overlay
mmu_CR_BANK12 = $06 ; 32 KiB bank 0; 16 KiB IFROM; 16 KiB kernal with i/o overlay
mmu_CR_BANK13 = $0a ; 32 KiB bank 0; 16 KiB EFROM; 16 KiB kernal with i/o overlay
mmu_CR_BANK14 = $01 ; 16 KiB bank 0; 32 KiB basic; 16 KiB kernal with font overlay
mmu_CR_BANK15 = $00 ; 16 KiB bank 0; 32 KiB basic; 16 KiB kernal with i/o overlay
; An unmodified C128 does not have a "ram bank 2" or "ram bank 3".
; Whenever one of these is activated, ram banks 0 and 1 will be used instead.
; IFROM means internal function ROM (socket U36)
@ -71,13 +71,13 @@ mmu_CR_BANK15 = $00 ; 16 KiB bank 0; 32 KiB basic; 16 KiB kernel with i/o overla
mmu_mcr = $d505
}
; contents:
mmu_MCR_40COLUMNS = %#....... ; 40/80 key: 0 means pressed, 1 means released (writable! if cleared, will always read as 0!)
mmu_MCR_C64MODE = %.#...... ; setting this bit makes the MMU disappear from the memory map :)
mmu_MCR_EXROM = %..#..... ; if zero on boot, system will enter c64 mode (writable!)
mmu_MCR_GAME = %...#.... ; if zero on boot, system will enter c64 mode (writable!)
mmu_MCR_FSDIR_OUTPUT = %....#... ; direction of fast serial bus
mmu_MCR_40COLUMNS = %#....... ; (pin 48) 40/80 key: 0 means pressed, 1 means released (writable! if cleared, will always read as 0!)
mmu_MCR_C64MODE = %.#...... ; (pin 47) setting this bit makes the MMU disappear from the memory map :)
mmu_MCR_EXROM = %..#..... ; (pin 46) if zero on boot, system will enter c64 mode (writable!)
mmu_MCR_GAME = %...#.... ; (pin 45) if zero on boot, system will enter c64 mode (writable!)
mmu_MCR_FSDIR_OUTPUT = %....#... ; (pin 44) direction of fast serial bus
mmu_MCR_UNUSED = %.....##. ; always set
mmu_MCR_8502MODE = %.......# ; setting this to zero switches to Z80 cpu
mmu_MCR_8502MODE = %.......# ; (pin 43 inverted) setting this to zero switches to Z80 cpu
!address {
; ram configuration register
@ -108,11 +108,13 @@ mmu_RCR_SHARESIZE_8K = %......#.
mmu_RCR_SHARESIZE_16K = %......##
!address {
; page pointers. writes to "high" register will be latched (reading gives old value) until "low" register is written to
mmu_p0low = $d507 ; page 0 pointer low (a8..a15), default $00
mmu_p0high = $d508 ; page 0 pointer high (a16..a19), default $00 (on an unmodified c128, only bit0 is meaningful)
mmu_p1low = $d509 ; page 1 pointer low (a8..a15), default $01
mmu_p1high = $d50a ; page 1 pointer high (a16..a19), default $00 (on an unmodified c128, only bit0 is meaningful)
; page pointers for zero page and stack:
; write to "bank" register will be latched (reading gives old value)
; until "page" register is written to as well.
mmu_zp_page = $d507 ; address bits a8..a15, default $00
mmu_zp_bank = $d508 ; address bits a16..a19, default $0 (on an unmodified c128, only bit0 is meaningful)
mmu_stack_page = $d509 ; address bits a8..a15, default $01
mmu_stack_bank = $d50a ; address bits a16..a19, default $0 (on an unmodified c128, only bit0 is meaningful)
}
mmu_PxH_UNUSED = %####.... ; always set
@ -146,10 +148,10 @@ mmu_VR_VERSION_MASK = %....#### ; mmu version 0
; load configuration registers:
; a read access will return the value of the corresponding preconfiguration register
; any write access will copy the value of the corresponding preconfiguration register to mmu_cr
mmu_lcr_a = $ff01 ; c128 kernel default is $3f (BANK 0)
mmu_lcr_b = $ff02 ; c128 kernel default is $7f (BANK 1)
mmu_lcr_c = $ff03 ; c128 kernel default is $01 (BANK 14)
mmu_lcr_d = $ff04 ; c128 kernel default is $41 (all system roms, with ram 1)
mmu_lcr_a = $ff01 ; c128 kernal default is $3f (BANK 0)
mmu_lcr_b = $ff02 ; c128 kernal default is $7f (BANK 1)
mmu_lcr_c = $ff03 ; c128 kernal default is $01 (BANK 14)
mmu_lcr_d = $ff04 ; c128 kernal default is $41 (all system roms, with ram 1)
; the c128 ROMs contain a look-up table to convert bank numbers to their
; corresponding configuration register values:

View File

@ -1,4 +1,4 @@
;ACME 0.94.4
;ACME 0.96.4
!ifdef lib_cbm_c128_petscii_a !eof
lib_cbm_c128_petscii_a = 1
@ -25,8 +25,8 @@ petscii_LBLUE = 154
petscii_GRAY3 = 155: petscii_DWHITE = 155: petscii_LGRAY = 155
; switching character set
petscii_LOCK = 11 ; forbid CBM-shift (C64 uses 8)
petscii_UNLOCK = 12 ; allow CBM-shift (C64 uses 9)
petscii_LOCK = 11 ; forbid CBM-shift (C64 uses 8 instead)
petscii_UNLOCK = 12 ; allow CBM-shift (C64 uses 9 instead)
petscii_LOWERCASE = 14 ; switch to lowercase/uppercase character set
petscii_UPPERCASE = 142 ; switch to uppercase/graphics character set
@ -39,12 +39,12 @@ petscii_F7 = 136: petscii_F8 = 140
; C128-specific stuff
petscii_UNDERLINEON = 2
petscii_UNDERLINEOFF = 130
petscii_FLASHON = 15
petscii_FLASHOFF = 143
petscii_FLASHON = 15 ; (264 series machines use 130 instead)
petscii_FLASHOFF = 143 ; (264 series machines use 131 instead)
petscii_BELL = 7
petscii_TAB = 9
petscii_SETTAB = 24
petscii_LINEFEED = 10
petscii_ESCAPE = 27
petscii_SHIFTSTOP = 131
petscii_HELP = 132
petscii_HELP = 132 ; (264 series machines use 140 instead)

View File

@ -1,19 +1,22 @@
;ACME 0.95
;ACME 0.96.4
!ifdef lib_cbm_c128_vic_a !eof
lib_cbm_c128_vic_a = 1
!source <cbm/c64/vic.a> ; registers 0..2e
!address {
; registers only present in the C128 variant of this chip:
vic_keyboard = $d02f
vic_clock = $d030
vic_keyboard = vic_base + $2f
; %76543... always set
; %.....210 output pins for extended keyboard layout
vic_clock = vic_base + $30
; %765432.. always set
; %......1. "test" bit: 0 = normal, 1 = system clock changes raster line
; %.......0 system clock: 0 = 1 MHz, 1 = 2 MHz (VIC bus cycles will be given to CPU instead)
; the c128 ROMs contain two copies of a look-up table to convert vic color
; values to their corresponding petscii color codes:
; rom4_* needs "low rom area" enabled ($4000..$7fff)
; romc_* needs "high rom area" enabled ($c000..$ffff)
rom4_vic_to_petscii_color_table = $76b5 ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b
romc_vic_to_petscii_color_table = $ce4c ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b
}
!addr rom4_vic_to_petscii_color_table = $76b5 ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b
!addr romc_vic_to_petscii_color_table = $ce4c ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b

View File

@ -1,23 +1,27 @@
;ACME 0.95
;ACME 0.96.4
!ifdef lib_cbm_c64_cia1_a !eof
lib_cbm_c64_cia1_a = 1
!address {
cia1_pra = $dc00
cia1_prb = $dc01
cia1_ddra = $dc02
cia1_ddrb = $dc03
cia1_ta_lo = $dc04
cia1_ta_hi = $dc05
cia1_tb_lo = $dc06
cia1_tb_hi = $dc07
cia1_tod10ths = $dc08
cia1_todsec = $dc09
cia1_todmin = $dc0a
cia1_todhr = $dc0b
cia1_sdr = $dc0c
cia1_icr = $dc0d
cia1_cra = $dc0e
cia1_crb = $dc0f
}
!source <cbm/cia.a> ; chip stuff (same for both cias)
; stuff for cia 1 only:
!addr cia1_base = $dc00
cia1_pra = cia1_base + cia_port_a ; PA0..PA4 are joy port 2 PA6+PA7 select paddle port(s)
cia1_prb = cia1_base + cia_port_b ; PB0..PB4 are joy port 1
; both ports are used for keyboard matrix
cia1_ddra = cia1_base + cia_data_direction_a
cia1_ddrb = cia1_base + cia_data_direction_b
cia1_ta_lo = cia1_base + cia_timer_a_low
cia1_ta_hi = cia1_base + cia_timer_a_high
cia1_tb_lo = cia1_base + cia_timer_b_low
cia1_tb_hi = cia1_base + cia_timer_b_high
cia1_tod10ths = cia1_base + cia_timeofday_10ths
cia1_todsec = cia1_base + cia_timeofday_seconds
cia1_todmin = cia1_base + cia_timeofday_minutes
cia1_todhr = cia1_base + cia_timeofday_hours
cia1_sdr = cia1_base + cia_serial_data
cia1_icr = cia1_base + cia_interrupt_control
cia1_cra = cia1_base + cia_control_a
cia1_crb = cia1_base + cia_control_b
; the interrupt output is connected to CPU's /IRQ input
; in the C128, the shift register is used for the fast serial port (burst mode)

View File

@ -1,23 +1,32 @@
;ACME 0.95
;ACME 0.96.4
!ifdef lib_cbm_c64_cia2_a !eof
lib_cbm_c64_cia2_a = 1
!address {
cia2_pra = $dd00
cia2_prb = $dd01
cia2_ddra = $dd02
cia2_ddrb = $dd03
cia2_ta_lo = $dd04
cia2_ta_hi = $dd05
cia2_tb_lo = $dd06
cia2_tb_hi = $dd07
cia2_tod10ths = $dd08
cia2_todsec = $dd09
cia2_todmin = $dd0a
cia2_todhr = $dd0b
cia2_sdr = $dd0c
cia2_icr = $dd0d
cia2_cra = $dd0e
cia2_crb = $dd0f
}
!source <cbm/cia.a> ; chip stuff (same for both cias)
; stuff for cia 2 only:
!addr cia2_base = $dd00
cia2_pra = cia2_base + cia_port_a
; %7....... DATA in (0 means GND)
; %.6...... CLK in (0 means GND)
; %..5..... DATA out (gets inverted, so 1 means GND)
; %...4.... CLK out (gets inverted, so 1 means GND)
; %....3... ATN out (gets inverted, so 1 means GND)
; %.....2.. PA2 (pin M at user port, 0 means GND)
; %......10 VIC bank (gets inverted, so value %11 means address $0000)
cia2_prb = cia2_base + cia_port_b
cia2_ddra = cia2_base + cia_data_direction_a
cia2_ddrb = cia2_base + cia_data_direction_b
cia2_ta_lo = cia2_base + cia_timer_a_low
cia2_ta_hi = cia2_base + cia_timer_a_high
cia2_tb_lo = cia2_base + cia_timer_b_low
cia2_tb_hi = cia2_base + cia_timer_b_high
cia2_tod10ths = cia2_base + cia_timeofday_10ths
cia2_todsec = cia2_base + cia_timeofday_seconds
cia2_todmin = cia2_base + cia_timeofday_minutes
cia2_todhr = cia2_base + cia_timeofday_hours
cia2_sdr = cia2_base + cia_serial_data
cia2_icr = cia2_base + cia_interrupt_control
cia2_cra = cia2_base + cia_control_a
cia2_crb = cia2_base + cia_control_b
; the interrupt output is connected to CPU's /NMI input

View File

@ -1,7 +1,7 @@
;ACME 0.95
;ACME 0.96.4
!ifdef lib_cbm_c64_float_a !eof
lib_cbm_c64_float_a = 1
lib_cbm_c64_float_a = 2
; Here are some definitions to help you call the floating-point functions of the
; C64's BASIC ROM. They work on "float registers", which are actually just
@ -18,33 +18,33 @@ lib_cbm_c64_float_a = 1
; convenience macros:
; some float functions need a memory address in A (low) and Y (high)
!macro movAY .adr {
lda #<.adr
ldy #>.adr
; some float functions need a memory address in YYAA
!macro movYYAA @addr {
lda #<@addr
ldy #>@addr
}
; ...or in X (low) and Y (high)
!macro movXY .adr {
ldx #<.adr
ldy #>.adr
; ...or in YYXX
!macro movYYXX @addr {
ldx #<@addr
ldy #>@addr
}
; other float functions expect or output a value in Y (low) and A (high)
!macro movYA .val {
ldy #<.val
lda #>.val
; other float functions expect or output a value in AAYY
!macro movAAYY @val {
ldy #<@val
lda #>@val
}
!macro ldYA .adr {
ldy .adr
lda .adr + 1
!macro ldAAYY @addr {
ldy @addr
lda @addr + 1
}
!macro stYA .adr {
sty .adr
sta .adr + 1
!macro stAAYY @addr {
sty @addr
sta @addr + 1
}
; ...or in X (low) and A (high)
!macro ldXA .adr {
ldx .adr
lda .adr + 1
; ...or in AAXX
!macro ldAAXX @addr {
ldx @addr
lda @addr + 1
}
!address {
@ -69,49 +69,71 @@ lib_cbm_c64_float_a = 1
; functions - a few points to note:
; fac1/2 might get clobbered even if not mentioned in the function's name,
; because stuff like fac1_times_memAY will load the value from memory
; because stuff like fac1_times_memYYAA will load the value from memory
; into fac2 first.
; for subtraction and division, the left operand is in fac2, the right operand in fac1.
fac1_print = $aabc ; print string representation of contents of fac1
fac1_to_signedYA = $b1aa ; might throw ILLEGAL QUANTITY
fac1_to_signedAAYY = $b1aa ; might throw ILLEGAL QUANTITY
fac1_to_signed16 = $b1bf ; might throw ILLEGAL QUANTITY
fac1_read_signedYA = $b391 ; convert 16 bit signed int to float
fac1_read_signedAAYY = $b391 ; convert 16 bit signed int to float
fac1_read_unsignedY = $b3a2 ; convert 8 bit unsigned int to float
fac1_read_string = $b7b5 ; $22/23 must point to string, A must be string length
fac1_to_unsignedYA = $b7f7 ; might throw ILLEGAL QUANTITY (result is also in $14/15)
fac1_to_unsignedAAYY = $b7f7 ; might throw ILLEGAL QUANTITY (result is also in $14/15)
fac1_add_point5 = $b849 ; for rounding, call this before fac1_int
fac1_memAY_minus_fac1 = $b850 ; subtract fac1 from mflpt value
fac1_memYYAA_minus_fac1 = $b850 ; subtract fac1 from mflpt value
fac1_fac2_minus_fac1 = $b853
fac1_add_memAY = $b867 ; add mflpt value
fac1_add_memYYAA = $b867 ; add mflpt value
fac1_add_fac2 = $b86a
fac1_log = $b9ea ; LOG()
fac1_times_memAY = $ba28 ; multiply by mflpt value
fac2_read_memAY = $ba8c ; load mflpt value from memory into fac2
fac1_times_memYYAA = $ba28 ; multiply by mflpt value
fac2_read_memYYAA = $ba8c ; load mflpt value from memory into fac2
fac2_read_mem_via0x22ptr = $ba90 ; load mflpt value from memory into fac2
fac1_times_10 = $bae2
fac1_divide_by_10 = $bafe
fac1_divide_memAY_by_fac1 = $bb0f ; divide mflpt value by fac1 value
fac1_read_memAY = $bba2 ; load mflpt value from memory into fac1
fac1_divide_by_10 = $bafe ; CAUTION: result is always positive!
fac1_divide_memYYAA_by_fac1 = $bb0f ; divide mflpt value by fac1 value
fac1_read_memYYAA = $bba2 ; load mflpt value from memory into fac1
fac1_read_mem_via0x22ptr = $bba6 ; load mflpt value from memory into fac1
fac1_to_memXY = $bbd4 ; store fac1 to memory as mflpt
fac1_to_memYYXX = $bbd4 ; store fac1 to memory as mflpt
fac1_read_fac2 = $bbfc ; copy fac2 to fac1
fac2_read_fac1 = $bc0c ; copy fac1 to fac2
fac1_sign_to_A = $bc2b ; $ff, $0, $1 for negative, zero, positive
fac1_sgn = $bc39 ; SGN()
fac1_abs = $bc58 ; ABS()
fac1_compare_to_memAY = $bc5b ; compare to mflpt value in memory
fac1_compare_to_memYYAA = $bc5b ; compare to mflpt value in memory
fac1_to_signed32 = $bc9b
fac1_int = $bccc ; INT()
fac1_print_unsignedXA = $bdcd
fac1_to_string = $bddd ; string is stored at $0100 (address returned in AY)
fac1_read_string0 = $bcf3 ; use b7b5 instead; this only works after calling CHRGET
fac1_print_unsignedAAXX = $bdcd
fac1_to_string = $bddd ; string is stored at $0100 (address returned in YYAA)
fac1_sqr = $bf71 ; SQR()
fac1_fac2_to_the_power_of_memAY = $bf78
fac1_fac2_to_the_power_of_memYYAA = $bf78
fac1_negate = $bfb4
fac1_exp = $bfed ; EXP()
; end of basic rom jumps to start of kernel rom!
; end of basic rom jumps to start of kernal rom!
fac1_rnd = $e097 ; RND()
fac1_cos = $e264 ; COS()
fac1_sin = $e26b ; SIN()
fac1_tan = $e2b4 ; TAN()
fac1_atn = $e30e ; ATN()
}
; wrappers for names from older version of this file:
!macro movAY @addr { +movYYAA @addr }
!macro movXY @addr { +movYYXX @addr }
!macro movYA @val { +movAAYY @val }
!macro ldYA @addr { +ldAAYY @addr }
!macro stYA @addr { +stAAYY @addr }
!macro ldXA @addr { +ldAAXX @addr }
fac1_to_signedYA = fac1_to_signedAAYY
fac1_read_signedYA = fac1_read_signedAAYY
fac1_to_unsignedYA = fac1_to_unsignedAAYY
fac1_memAY_minus_fac1 = fac1_memYYAA_minus_fac1
fac1_add_memAY = fac1_add_memYYAA
fac1_times_memAY = fac1_times_memYYAA
fac2_read_memAY = fac2_read_memYYAA
fac1_divide_memAY_by_fac1 = fac1_divide_memYYAA_by_fac1
fac1_read_memAY = fac1_read_memYYAA
fac1_to_memXY = fac1_to_memYYXX
fac1_compare_to_memAY = fac1_compare_to_memYYAA
fac1_print_unsignedXA = fac1_print_unsignedAAXX
fac1_fac2_to_the_power_of_memAY = fac1_fac2_to_the_power_of_memYYAA

View File

@ -0,0 +1,33 @@
;ACME 0.96.4
!ifdef lib_cbm_c64_memcopy_a !eof
lib_cbm_c64_memcopy_a = 1
; this macro inserts code to copy a memory block.
; it calls a function from the basic interpreter, so:
; - BASIC ROM must be banked in
; - the source block must be readable (so no RAM hidden under BASIC, Kernal, or I/O)
; - the target block must be writable (so no RAM hidden under I/O)
; higher addresses are copied first, so:
; - moving data to higher addresses works even if areas overlap
; - moving data to lower addresses only works if areas do not overlap
!macro basic_memcopy @src_start, @src_end, @target_start {
!addr @z_target_end = $58
!addr @z_src_end = $5a
!addr @z_src_start = $5f
!addr @fn = $a3bf
lda #<@src_start
ldx #>@src_start
sta @z_src_start
stx @z_src_start + 1
lda #<@src_end
ldx #>@src_end
sta @z_src_end
stx @z_src_end + 1
lda #<(@target_start + @src_end - @src_start)
ldx #>(@target_start + @src_end - @src_start)
sta @z_target_end
stx @z_target_end + 1
jsr @fn
}

View File

@ -47,8 +47,8 @@ rec_COMMAND_FETCH = %#.#....# ; starting and then reload values.
; Upgraded units and clones may have more, but the REC chip will always
; "wrap around" after eight banks if crossing bank borders!
; amount of bytes to process
rec_amount_low = $df07
rec_amount_high = $df08
rec_amount_low = $df07 ; using $0000 results in
rec_amount_high = $df08 ; 64 KiB being transferred
; when to request interrupts
rec_irqctrl = $df09
}

View File

@ -1,8 +1,25 @@
;ACME 0.95
;ACME 0.96.4
!ifdef lib_cbm_c64_vic_a !eof
lib_cbm_c64_vic_a = 1
; This is from Christian Bauer's VIC text: {
; 6566: designed for static RAM, never used in C64/128
; 6567/8562: C64, NTSC
; 6569/8565: C64, PAL
; 6572: Drean C64, PAL-N
; 8564: C128, NTSC
; 8566: C128, PAL
; PAL chips generate 312 lines with 63 cycles per line.
; PAL-N chips generate 312 lines with 65 cycles per line.
; NTSC chips generate 263 lines with 65 cycles per line.
; Very early NTSC chips (6567R56A) have an off-by-one
; error, they generate 262 lines with 64 cycles per line.
; }
; The c128 version is officially called "VIC-IIe".
; It has two additional registers and more pins.
; color codes
viccolor_BLACK = $0
viccolor_WHITE = $1
@ -21,58 +38,85 @@ viccolor_LGREEN = $d
viccolor_LBLUE = $e
viccolor_GRAY3 = $f
!address {
; register addresses
vic_xs0 = $d000
vic_ys0 = $d001
vic_xs1 = $d002
vic_ys1 = $d003
vic_xs2 = $d004
vic_ys2 = $d005
vic_xs3 = $d006
vic_ys3 = $d007
vic_xs4 = $d008
vic_ys4 = $d009
vic_xs5 = $d00a
vic_ys5 = $d00b
vic_xs6 = $d00c
vic_ys6 = $d00d
vic_xs7 = $d00e
vic_ys7 = $d00f
vic_msb_xs = $d010
vic_controlv = $d011 ; vertical control (and much other stuff)
vic_line = $d012 ; raster line
vic_xlp = $d013 ; light pen coordinates
vic_ylp = $d014
vic_sactive = $d015 ; sprites: active
vic_controlh = $d016 ; horizontal control (and much other stuff)
vic_sdy = $d017 ; sprites: double height
vic_ram = $d018 ; RAM pointer
vic_irq = $d019
vic_irqmask = $d01a
vic_sback = $d01b ; sprites: background mode
vic_smc = $d01c ; sprites: multi color mode
vic_sdx = $d01d ; sprites: double width
vic_ss_collided = $d01e ; sprite-sprite collision detect
vic_sd_collided = $d01f ; sprite-data collision detect
; color registers
vic_cborder = $d020 ; border color
vic_cbg = $d021 ; general background color
vic_cbg0 = $d021
vic_cbg1 = $d022 ; background color 1 (for EBC and MC text mode)
vic_cbg2 = $d023 ; background color 2 (for EBC and MC text mode)
vic_cbg3 = $d024 ; background color 3 (for EBC mode)
vic_sc01 = $d025 ; sprite color for MC-bitpattern %01
vic_sc11 = $d026 ; sprite color for MC-bitpattern %11
vic_cs0 = $d027 ; sprite colors
vic_cs1 = $d028
vic_cs2 = $d029
vic_cs3 = $d02a
vic_cs4 = $d02b
vic_cs5 = $d02c
vic_cs6 = $d02d
vic_cs7 = $d02e
}
!addr vic_base = $d000
; sprite coordinates:
vic_xs0 = vic_base + $00
vic_ys0 = vic_base + $01
vic_xs1 = vic_base + $02
vic_ys1 = vic_base + $03
vic_xs2 = vic_base + $04
vic_ys2 = vic_base + $05
vic_xs3 = vic_base + $06
vic_ys3 = vic_base + $07
vic_xs4 = vic_base + $08
vic_ys4 = vic_base + $09
vic_xs5 = vic_base + $0a
vic_ys5 = vic_base + $0b
vic_xs6 = vic_base + $0c
vic_ys6 = vic_base + $0d
vic_xs7 = vic_base + $0e
vic_ys7 = vic_base + $0f
vic_msb_xs = vic_base + $10 ; bit 8 of x position (one bit per sprite)
vic_controlv = vic_base + $11 ; vertical control and other stuff:
; %7....... "bit 8" of $d012
; %.6...... extended background color mode (1=on)
; %..5..... 0 = text mode, 1 = bitmap mode
; %...4.... display enable: 0 = disable (border only), 1 = enable VIC only checks this once per frame!
; %....3... lines: 0 = 24, 1 = 25 ; if set, upper and lower border gain 4 pixels each
; %.....210 vertical smooth scroll (default %011), screen contents are moved down by this amount
vic_line = vic_base + $12 ; raster line (also see bit 7 of $d011) reading returns current value, writing sets interrupt value
vic_xlp = vic_base + $13 ; light pen coordinates, x (only half the resolution)
vic_ylp = vic_base + $14 ; light pen coordinates, y
vic_sactive = vic_base + $15 ; sprite enable (one bit per sprite)
vic_controlh = vic_base + $16 ; horizontal control and other stuff:
; %76...... always set
; %..5..... "test", should be 0
; %...4.... 0 = hires, 1 = multicolor
; %....3... columns: 0 = 38, 1 = 40 ; if set, left border gains 7 pixels and right border gains 9 pixels
; %.....210 horizontal smooth scroll (default %000), screen contents are moved to the right by this amount
vic_sdy = vic_base + $17 ; sprites, double height (one bit per sprite)
vic_ram = vic_base + $18 ; RAM pointer
; %7654.... which K of VIC bank is video ram (default %0001)
; %....321. text: which 2K of VIC bank is character set (default %010)
; %.......0 text: unused
; %....3... bitmap: which 8K of VIC bank is bitmap
; %.....210 bitmap: unused
vic_irq = vic_base + $19 ; writing back acknowledges!
; %7....... 1: VIC requested interrupt
; %.654.... always set
; %....3... 1: light pen active
; %.....2.. 1: sprite-sprite collision
; %......1. 1: sprite-data collision
; %.......0 1: raster interrupt
vic_irqmask = vic_base + $1a
; %7654.... always set
; %....3... 1: enable lightpen interrupt
; %.....2.. 1: enable sprite-sprite collision interrupt
; %......1. 1: enable sprite-data collision interrupt
; %.......0 1: enable raster interrupt
vic_sback = vic_base + $1b ; sprites, background (one bit per sprite)
vic_smc = vic_base + $1c ; sprites, multicolor (one bit per sprite)
vic_sdx = vic_base + $1d ; sprites, double width (one bit per sprite)
vic_ss_collided = vic_base + $1e ; sprites, sprite collision (one bit per sprite) reading clears register!
vic_sd_collided = vic_base + $1f ; sprites, data collision (one bit per sprite) reading clears register!
; color registers (high nibbles are always %1111):
vic_cborder = vic_base + $20 ; border color
vic_cbg = vic_base + $21 ; general background color
vic_cbg0 = vic_base + $21
vic_cbg1 = vic_base + $22 ; background color 1 (for EBC and MC text mode)
vic_cbg2 = vic_base + $23 ; background color 2 (for EBC and MC text mode)
vic_cbg3 = vic_base + $24 ; background color 3 (for EBC mode)
vic_sc01 = vic_base + $25 ; sprite color for MC-bitpattern %01
vic_sc11 = vic_base + $26 ; sprite color for MC-bitpattern %11
; individual sprite colors (in MC mode, these are used for bit pattern %10):
vic_cs0 = vic_base + $27 ; sprite 0 color
vic_cs1 = vic_base + $28 ; sprite 1 color
vic_cs2 = vic_base + $29 ; sprite 2 color
vic_cs3 = vic_base + $2a ; sprite 3 color
vic_cs4 = vic_base + $2b ; sprite 4 color
vic_cs5 = vic_base + $2c ; sprite 5 color
vic_cs6 = vic_base + $2d ; sprite 6 color
vic_cs7 = vic_base + $2e ; sprite 7 color
; See <cbm/c128/vic.a> for the C128's two additional registers at $d02f/$d030.
; They are accessible even in C64 mode and $d030 can garble the video output,
; so be careful not to write to it accidentally in a C64 program!

109
ACME_Lib/cbm/cia.a Normal file
View File

@ -0,0 +1,109 @@
;ACME 0.96.4
!ifdef lib_cbm_cia_a !eof
lib_cbm_cia_a = 1
; CBM's "complex interface adapter" chip, known as 6526.
; A newer version of this chip was initially called 8521, but later the name was
; changed back to 6526 again.
; There are two of these in a C64/128 computer, and one in 1570/1571 drives.
; pinout:
; ____ ____
; | V |
; GND | 1 40 | cnt clock for shift register
; / pa0 | 2 39 | sp data for shift register
; | pa1 | 3 38 | a0 \
; | pa2 | 4 37 | a1 |_ address
; Port _| pa3 | 5 36 | a2 | bus
; A | pa4 | 6 35 | a3 /
; | pa5 | 7 34 | /reset
; | pa6 | 8 33 | d0 \
; \ pa7 | 9 32 | d1 |
; / pb0 | 10 31 | d2 |
; | pb1 | 11 30 | d3 |_ data
; | pb2 | 12 29 | d4 | bus
; Port _| pb3 | 13 28 | d5 |
; B | pb4 | 14 27 | d6 |
; | pb5 | 15 26 | d7 /
; | pb6 | 16 25 | 0in clock
; \ pb7 | 17 24 | /flag
; /pc | 18 23 | /cs chip select
; tod_clk | 19 22 | r/w
; +5V | 20 21 | /irq
; |_________|
; register offsets:
; two 8-bit ports:
cia_port_a = $0
cia_port_b = $1
cia_data_direction_a = $2 ; clear means input,
cia_data_direction_b = $3 ; set means output
; two 16-bit timers, can be combined to form a single 32-bit timer:
cia_timer_a_low = $4
cia_timer_a_high = $5
cia_timer_b_low = $6
cia_timer_b_high = $7
; reading returns current counter value,
; writing sets start value.
; in 32-bit mode, timer A is "low word" and timer B is "high word".
; TOD (time of day) clock, clocked with 50 or 60 Hz:
; (CAUTION, registers use binary coded decimal format)
cia_timeofday_10ths = $8 ; %....3210 0..9, counts 10ths of seconds
cia_timeofday_seconds = $9 ; %.6543210 0..59, as two BCD digits:
; %.654.... 0..5 "tens"
; %....3210 0..9 "ones"
cia_timeofday_minutes = $a ; %.6543210 0..59, as two BCD digits:
; %.654.... 0..5 "tens"
; %....3210 0..9 "ones"
cia_timeofday_hours = $b ; %7..43210 AM/PM and 1..12 as two BCD digits:
; %7....... 0 means AM, 1 means PM
; %...4.... 0..1 "tens"
; %....3210 0..9 "ones"
; when reading or writing time, start with hours and end with 10ths:
; accessing hours uncouples registers from clock, accessing 10ths re-couples them.
; if your read access does not start with the hours register,
; you have a race condition!
; shift register:
; msb is sent/received first. send clock is half of timer A's underflow rate.
cia_serial_data = $c
; control registers:
cia_interrupt_control = $d
; %7....... read: 1 = interrupt requested (reading clears register)
; write: 0 = disable interrupts indicated by set bits
; 1 = enable interrupts indicated by set bits
; %.65..... unused
; %...4.... negative edge on /flag detected
; %....3... shift register has finished sending or receiving
; %.....2.. time of day alarm
; %......1. timer B underflow
; %.......0 timer A underflow
cia_control_a = $e
; %7....... TOD clock: 0 means 60 Hz, 1 means 50 Hz
; %.6...... shift register direction: 0 = input, 1 = output
; %..5..... timer A clock: 0 = system clock, 1 = CNT
; %...4.... 1 = force load timer start value
; %....3... timer mode: 0 = continuous, 1 = one-shot (needs restart via bit 0)
; %.....2.. 0 = pulse on PB6, 1 = invert PB6
; %......1. 1 = timer underflow shows on PB6 (this forces PB6 to output)
; %.......0 0 stops timer, 1 starts timer
cia_control_b = $f
; %7....... TOD write mode: 0 = actual time, 1 = alarm time (it is not possible to _read_ the alarm time!)
; %.65..... timer B clock:
; %00 = system clock
; %01 = CNT
; %10 = underflow of timer A
; %11 = combination of %01 and %10
; %...4.... 1 = force load timer start value
; %....3... timer mode: 0 = continuous, 1 = one-shot (needs restart via bit 0)
; %.....2.. 0 = pulse on PB7, 1 = invert PB7
; %......1. 1 = timer underflow shows on PB7 (this forces PB7 to output)
; %.......0 0 stops timer, 1 starts timer

View File

@ -1,4 +1,4 @@
;ACME 0.94.5
;ACME 0.96.4
!ifdef lib_cbm_flpt_a !eof
lib_cbm_flpt_a = 1
@ -13,7 +13,7 @@ lib_cbm_flpt_a = 1
; This file contains a macro for writing floating point numbers in the six-byte
; "flpt" format, where the sign bit occupies the sixth byte.
; There are no interpreter functions to use this format, so you will have to
; write you own functions for "copy-mem-to-fac1", "copy-fac2-to-mem" etc.
; write your own functions for "copy-mem-to-fac1", "copy-fac2-to-mem" etc.
; Use the macro like this:
; +flpt 3.1415926 ; each use will take up six bytes of memory
@ -46,48 +46,49 @@ lib_cbm_flpt_a = 1
; this is ugly, but it gets the job done
; (if it's stupid, but it works, then it's not stupid)
!macro flpt .value {
!set .float = float(.value) ; make sure to do passes until value is defined
!ifndef .float {
!by $ff, $ff, $ff, $ff, $ff, $ff ; six place holder bytes
!macro flpt @value {
!set @float = float(@value)
!ifndef @float {
!by <@float, $ff, $ff, $ff, $ff, $ff ; six place holder bytes
; (first one depends on @float just to make sure more passes are done until value is defined)
} else {
; value is defined, so split up into sign and non-negative value
!if .float < 0 {
!set .sign = $80
!set .float = -.float
!if @float < 0 {
!set @sign = $80
!set @float = -@float
} else {
!set .sign = $00
!set @sign = $00
}
!if .float = 0 {
!if @float = 0 {
!by 0, 0, 0, 0, 0, 0 ; six zeroes (zero is represented by all bits zero)
} else {
; split up into exponent and mantissa
!set .exponent = 128 + 32 ; 128 is cbm's bias, 32 is this algo's bias
!set @exponent = 128 + 32 ; 128 is cbm's bias, 32 is this algo's bias
; if mantissa is too large, shift right and adjust exponent
!do while .float >= (2.0 ^ 32.0) {
!set .float = .float >> 1
!set .exponent = .exponent + 1
!do while @float >= (2.0 ^ 32.0) {
!set @float = @float >> 1
!set @exponent = @exponent + 1
}
; if mantissa is too small, shift left and adjust exponent
!do while .float < (2.0 ^ 31.0) {
!set .float = .float << 1
!set .exponent = .exponent - 1
!do while @float < (2.0 ^ 31.0) {
!set @float = @float << 1
!set @exponent = @exponent - 1
}
!if .exponent < 1 {
!if @exponent < 1 {
!warn "FLPT underflow, using zero instead"
!set .float = 0
!set .exponent = 0
!set .sign = 0
!set @float = 0
!set @exponent = 0
!set @sign = 0
}
!if .exponent > 255 {
!if @exponent > 255 {
!error "FLPT overflow"
}
!by .exponent
!by 255 & int(.float >> 24)
!by 255 & int(.float >> 16)
!by 255 & int(.float >> 8)
!by 255 & int(.float)
!by .sign
!by @exponent
!by 255 & int(@float >> 24)
!by 255 & int(@float >> 16)
!by 255 & int(@float >> 8)
!by 255 & int(@float)
!by @sign
}
}
}

View File

@ -3,7 +3,7 @@
!ifdef lib_cbm_ioerror_a !eof
lib_cbm_ioerror_a = 1
; if kernel i/o routine exits with carry set, A holds one of these:
; if kernal i/o routine exits with carry set, A holds one of these:
ioerror_BREAK = 0
ioerror_TOO_MANY_FILES = 1
ioerror_FILE_OPEN = 2

View File

@ -8,8 +8,10 @@ lib_cbm_kernal_a = 1
; There are alternative names for some calls.
!address {
; for additional c128 calls, see <cbm/c128/kernal.a>
k_cint = $ff81
k_ioinit = $ff84
; cbm-ii rom starts here:
k_ramtas = $ff87
k_restor = $ff8a
k_vector = $ff8d
@ -27,24 +29,58 @@ lib_cbm_kernal_a = 1
k_listen = $ffb1:k_listn = $ffb1
k_talk = $ffb4
k_readss = $ffb7
k_setlfs = $ffba
k_setnam = $ffbd ; A is length, X is ptr-low, Y is ptr-high
k_open = $ffc0
k_close = $ffc3:k_close_A = $ffc3
k_chkin = $ffc6:k_chkin_X = $ffc6
k_chkout = $ffc9:k_chkout_X = $ffc9:k_ckout = $ffc9
k_clrchn = $ffcc:k_clrch = $ffcc
k_chrin = $ffcf:k_basin = $ffcf
k_chrout = $ffd2:k_basout = $ffd2:k_bsout = $ffd2
k_load = $ffd5:k_load_AXY = $ffd5 ; A means verify, YYXX is desired load address (if channel == 0), returns end+1 in YYXX
k_save = $ffd8:k_save_AXY = $ffd8 ; A is zp address of start ptr(!), YYXX is end address (+1)
k_settim = $ffdb
k_rdtim = $ffde
k_stop = $ffe1
k_getin = $ffe4:k_get = $ffe4
k_setlfs = $ffba ; set file parameters (A = logical file number, X = device, Y = secondary address)
k_setnam = $ffbd ; set file name (A = length, YYXX = pointer)
; pet rom starts here:
; i/o calls: these may set C on error. in that case, A holds error code, see <cbm/ioerror.a> for the actual values.
k_open = $ffc0 ; open channel/file (call setlfs/setnam before!)
k_close = $ffc3:k_close_A = $ffc3 ; close channel/file (A = logical file number)
k_chkin = $ffc6:k_chkin_X = $ffc6 ; set input channel (X = logical file number)
k_chkout = $ffc9:k_chkout_X = $ffc9:k_ckout = $ffc9 ; set output channel (X = logical file number)
k_clrchn = $ffcc:k_clrch = $ffcc ; restore default input/output channels
k_chrin = $ffcf:k_basin = $ffcf ; read byte from current input channel (not the same as $ffe4, see note* below)
; A is result byte
; X is preserved
; Y gets clobbered by tape access (preserved by disk access)
k_chrout = $ffd2:k_basout = $ffd2:k_bsout = $ffd2 ; send byte to current output channel
; A/X/Y are preserved
k_load = $ffd5:k_load_AXY = $ffd5 ; load file to memory, or verify (call setlfs/setnam before!)
; A: zero means LOAD, nonzero means VERIFY
; YYXX is desired load address (only used if secondary address == 0), returns end address plus 1
k_save = $ffd8:k_save_AXY = $ffd8 ; save memory to file (call setlfs/setnam before!)
; A is zp address of start ptr(!)
; YYXX is end address plus 1
k_settim = $ffdb ; set time
k_rdtim = $ffde ; read time
k_stop = $ffe1 ; check STOP key
k_getin = $ffe4:k_get = $ffe4 ; get input byte (not the same as $ffcf, see note* below)
; A is result byte
; X is preserved
; Y gets clobbered by tape access (preserved by disk access)
k_clall = $ffe7
k_udtim = $ffea
k_scrorg = $ffed
k_plot = $fff0 ; get/set cursor (to set, clear carry)
k_iobase = $fff3
; pet rom stops here!?
k_scrorg = $ffed ; returns screen size (X = number of columns, Y = number of lines)
; CAUTION: the c128 uses a new format:
; c128: X/Y now return maximum values in current window (so 0..39/0..24 instead of 40/25).
; c128: A returns max column on current screen (39 or 79)
k_plot = $fff0:k_plot_CXY = $fff0 ; get/set cursor (X is line, Y is column)
; C = 0: set cursor position.
; C = 1: read cursor position.
k_iobase = $fff3 ; returns first i/o address (i.e. memory limit) in YYXX
; cbm-ii: $dc00
; vic20: $9110
; c64: $d000
; 264: $fd00
; c128: $d000
}
;note*
; the difference between CHRIN and GETIN depends on the current input device:
; input device 0 (keyboard): CHRIN reads from input buffer, GETIN reads from keyboard buffer
; (the same difference as between INPUT and GET in basic)
; input device 2 (rs232): CHRIN does some error handling, GETIN may just return zero on error.
; roughly speaking, CHRIN returns a "processed" byte while GETIN returns a "raw" byte.
; for devices on the IEC bus there should be no difference between the two calls.
; when reading from the console (keyboard/screen), a zero byte means "no data".
; do not expect a valid Z flag in this case! some devices may clobber the Z flag.

View File

@ -41,47 +41,48 @@ lib_cbm_mflpt_a = 1
; this is ugly, but it gets the job done
; (if it's stupid, but it works, then it's not stupid)
!macro mflpt .value {
!set .float = float(.value) ; make sure to do passes until value is defined
!ifndef .float {
!by $ff, $ff, $ff, $ff, $ff ; five place holder bytes
!macro mflpt @value {
!set @float = float(@value)
!ifndef @float {
!by <@float, $ff, $ff, $ff, $ff ; five place holder bytes
; (first one depends on @float just to make sure more passes are done until value is defined)
} else {
; value is defined, so split up into sign and non-negative value
!if .float < 0 {
!set .sign = $80
!set .float = -.float
!if @float < 0 {
!set @sign = $80
!set @float = -@float
} else {
!set .sign = $00
!set @sign = $00
}
!if .float = 0 {
!if @float = 0 {
!by 0, 0, 0, 0, 0 ; five zeroes (zero is represented by all bits zero)
} else {
; split up into exponent and mantissa
!set .exponent = 128 + 32 ; 128 is cbm's bias, 32 is this algo's bias
!set @exponent = 128 + 32 ; 128 is cbm's bias, 32 is this algo's bias
; if mantissa is too large, shift right and adjust exponent
!do while .float >= (2.0 ^ 32.0) {
!set .float = .float >> 1
!set .exponent = .exponent + 1
!do while @float >= (2.0 ^ 32.0) {
!set @float = @float >> 1
!set @exponent = @exponent + 1
}
; if mantissa is too small, shift left and adjust exponent
!do while .float < (2.0 ^ 31.0) {
!set .float = .float << 1
!set .exponent = .exponent - 1
!do while @float < (2.0 ^ 31.0) {
!set @float = @float << 1
!set @exponent = @exponent - 1
}
!if .exponent < 1 {
!if @exponent < 1 {
!warn "MFLPT underflow, using zero instead"
!set .float = 0
!set .exponent = 0
!set .sign = 0
!set @float = 0
!set @exponent = 0
!set @sign = 0
}
!if .exponent > 255 {
!if @exponent > 255 {
!error "MFLPT overflow"
}
!by .exponent
!by (127 & int(.float >> 24)) | .sign
!by 255 & int(.float >> 16)
!by 255 & int(.float >> 8)
!by 255 & int(.float)
!by @exponent
!by (127 & int(@float >> 24)) | @sign
!by 255 & int(@float >> 16)
!by 255 & int(@float >> 8)
!by 255 & int(@float)
}
}
}

20
ACME_Lib/cbm/msbstring.a Normal file
View File

@ -0,0 +1,20 @@
;ACME 0.97
; macro to store a petscii string with msb set in last byte
!macro msbstring @s {
!ct pet {
@l = len(@s)
!if @l < 1 {
!error "String is empty!"
}
!for @i, 0, @l - 1 {
!if $80 & @s[@i] {
!error "String already contains character(s) with MSB set!"
}
}
!for @i, 0, @l - 2 {
!byte @s[@i]
}
!byte $80 | @s[-1]
}
}

94
ACME_Lib/cbm/multicolor.a Normal file
View File

@ -0,0 +1,94 @@
;ACME 0.97
!ifdef lib_cbm_multicolor_a !eof
lib_cbm_multicolor_a = 1
; this file contains macros to convert strings into bit patterns.
; the idea is to use four different characters to indicate the four
; different bit patterns of multicolor graphics, so mc sprites can be
; "drawn" in the source code even though ACME does not support any
; four-based number system. see the end of this file for an example.
; macro to set "digit" characters
; example:
; +mc_set " .o#"
!macro mc_set .s {
!if is_number(.s) or is_list(.s) {
!error "Argument to +mc_set must be a string."
} else if len(.s) != 4 {
!error "Argument to +mc_set must be four characters."
} else {
!set multicolor_alphabet = .s
}
}
; macro to convert string to number
!macro mc_value ~.result, .in, .len {
!ifndef multicolor_alphabet {
!error "Called +mc_value before calling +mc_set."
} else if is_number(.in) or is_list(.in) {
!error "Argument to +mc_value must be a string."
} else if len(.in) != .len {
!error "Argument to +mc_value must have ", .len, " characters."
} else {
!set .result = 0
!for .idx, 0, (.len / 2) - 1 {
!set .char = .in[2 * .idx] ; get first of pair
!if .char != .in[2 * .idx + 1] { ; compare to second
!error "Characters in argument to +mc_value must be given in pairs."
} else {
!if .char = multicolor_alphabet[0] {
!set .result = (.result << 2)
} else if .char = multicolor_alphabet[1] {
!set .result = (.result << 2) + 1
} else if .char = multicolor_alphabet[2] {
!set .result = (.result << 2) + 2
} else if .char = multicolor_alphabet[3] {
!set .result = (.result << 2) + 3
} else {
!error "Characters in argument to +mc_value must be from alphabet set via +mc_set."
}
}
}
}
}
; macro for a multicolor byte (for charsets)
!macro mc_8 .in {
+mc_value ~.result, .in, 8
!by .result
}
; macro for a multicolor sprite line
!macro mc_be24 .in {
+mc_value ~.result, .in, 24
!be24 .result
}
!eof
; Here's an example on how to use this:
!to "mc-sprites.prg", cbm
*=$e00
+mc_set " .o#" ; set four characters
; and now use those four characters to "paint" the sprite:
+mc_be24 " "
+mc_be24 ".. .."
+mc_be24 ".... ...."
+mc_be24 "...... ##....## ......"
+mc_be24 " .................... "
+mc_be24 " .................... "
+mc_be24 " ................ "
+mc_be24 " ######........###### "
+mc_be24 " ..oo####....####oo.. "
+mc_be24 "##..oo ######## oo..##"
+mc_be24 "....oo oo....oo oo...."
+mc_be24 "......oooo....oooo......"
+mc_be24 "........................"
+mc_be24 "......oooo....oooo......"
+mc_be24 "....oooooooooooooooo...."
+mc_be24 ".... oooooooooooo ...."
+mc_be24 ".. ####oooooooo#### .."
+mc_be24 ".. ######oooo###### .."
+mc_be24 " ###### #### "
+mc_be24 " ###### ## "
+mc_be24 " "

13
ACME_Lib/m65/std.a Normal file
View File

@ -0,0 +1,13 @@
;ACME 0.96.5
!ifdef lib_m65_std_a !eof
lib_m65_std_a = 1
; macro to load immediate constant:
!macro movq @v {
; going from lsb to msb, so at least the N flag is correct:
lda #<@v
ldx #>@v
ldy #^@v
ldz #@v >>> 24
}

12
README.md Normal file
View File

@ -0,0 +1,12 @@
# ACME
Multi-platform cross-assembler for MOS 6502/65C02/6510/65816 CPUs
ACME is a free cross assembler released under the GNU GPL.
It can produce code for the following processors: 6502, 6510 (including illegal opcodes), 65c02 and 65816.
ACME supports the standard assembler stuff like global/local/anonymous labels, offset assembly, conditional assembly and looping assembly. It can include other source files as well as binaries while assembling.
Calculations can be done in integer or float mode.
Oh, and it is fast.
Imported from SourceForge SVN repository: https://sourceforge.net/projects/acme-crossass/
Release tags added - based on SVN commit messages

View File

@ -8,7 +8,7 @@ If you destroy your system, don't come whining to me.
--------------------
1) Copy the syntax file to the correct directory by typing:
cp acme.jsf /etc/joe/syntax/
cp acme.jsf /usr/share/joe/syntax/
2) Add the following lines to the "SECOND SECTION" of "/etc/joe/joerc":

View File

@ -4,6 +4,11 @@
# new in version 5: changed mnemo colors
# new in version 6: added !ifndef, !addr
# new in version 7: added !symbollist
# new in version 8: adjusted for ACME 0.97
# added backslash escaping,
# added "//" comments,
# added new mnemonics, keywords and pseudo opcodes,
# reduced colors for different instruction sets
# define colors
#
@ -18,16 +23,13 @@
=Call bold
=Comment green
=Constant cyan
=Escape bold cyan
=Keyword bold
=Pseudo bold
=Mnemo6502 bold yellow
=PCMnemo6502 bold red
=Mnemo6510 bg_red bold yellow
=PCMnemo6510 bg_red bold red
=Mnemo65c02 bg_cyan bold yellow
=PCMnemo65c02 bg_cyan bold red
=Mnemo65816 bg_blue bold yellow
=PCMnemo65816 bg_blue bold red
=MnemoExt bg_blue bold yellow
=PCMnemoExt bg_blue bold red
:reset Idle
* idle noeat
@ -36,6 +38,7 @@
:idle Idle
* idle
";" line_comment recolor=-1
"//" line_comment recolor=-1
":{\n" reset
"!.a-zA-Z_€-" checkstring recolor=-1 buffer
"+" anonf_or_macro recolor=-1
@ -101,10 +104,18 @@
:string Constant
* string
"\"" idle
"\\" string_escape recolor=-1
:string_escape Escape
* string
:char Constant
* char
"'" idle
"\\" char_escape recolor=-1
:char_escape Escape
* char
:ident Idle
* idle noeat
@ -117,10 +128,16 @@
"!by" pseudo
"!byte" pseudo
"!16" pseudo
"!le16" pseudo
"!be16" pseudo
"!wo" pseudo
"!word" pseudo
"!24" pseudo
"!le24" pseudo
"!be24" pseudo
"!32" pseudo
"!le32" pseudo
"!be32" pseudo
"!tx" pseudo
"!text" pseudo
"!raw" pseudo
@ -148,10 +165,17 @@
"!set" pseudo
"!macro" pseudo
"!if" pseudo
"!do" pseudo
"!for" pseudo
"!ifdef" pseudo
"!ifndef" pseudo
"else" keyword
"if" keyword
"ifdef" keyword
"ifndef" keyword
"!for" pseudo
"!while" pseudo
"!do" pseudo
"until" keyword
"while" keyword
"!al" pseudo
"!as" pseudo
"!rl" pseudo
@ -162,6 +186,10 @@
"!serious" pseudo
"!addr" pseudo
"!address" pseudo
"!h" pseudo
"!hex" pseudo
"!xor" pseudo
"!skip" pseudo
"ora" mnemo6502
"asl" mnemo6502
"and" mnemo6502
@ -205,9 +233,9 @@
"inx" mnemo6502
"nop" mnemo6502
"sed" mnemo6502
"jsr" mnemo6502
"brk" pcmnemo6502
"jmp" pcmnemo6502
"jsr" pcmnemo6502
"bpl" pcmnemo6502
"bmi" pcmnemo6502
"bvc" pcmnemo6502
@ -218,61 +246,149 @@
"beq" pcmnemo6502
"rti" pcmnemo6502
"rts" pcmnemo6502
"phy" mnemo65c02
"ply" mnemo65c02
"phx" mnemo65c02
"plx" mnemo65c02
"tsb" mnemo65c02
"trb" mnemo65c02
"stz" mnemo65c02
"bra" pcmnemo65c02
"wai" mnemo65816
"pei" mnemo65816
"per" mnemo65816
"mvp" mnemo65816
"mvn" mnemo65816
"rep" mnemo65816
"sep" mnemo65816
"pea" mnemo65816
"phd" mnemo65816
"tcs" mnemo65816
"pld" mnemo65816
"tsc" mnemo65816
"wdm" mnemo65816
"phk" mnemo65816
"tcd" mnemo65816
"tdc" mnemo65816
"phb" mnemo65816
"txy" mnemo65816
"plb" mnemo65816
"tyx" mnemo65816
"xba" mnemo65816
"xce" mnemo65816
"brl" pcmnemo65816
"cop" pcmnemo65816
"jml" pcmnemo65816
"jsl" pcmnemo65816
"rtl" pcmnemo65816
"stp" pcmnemo65816
"slo" mnemo6510
"rla" mnemo6510
"sre" mnemo6510
"rra" mnemo6510
"sax" mnemo6510
"lax" mnemo6510
"dcp" mnemo6510
"isc" mnemo6510
"anc" mnemo6510
"asr" mnemo6510
"arr" mnemo6510
"sbx" mnemo6510
"dop" mnemo6510
"top" mnemo6510
"lxa" mnemo6510
"jam" pcmnemo6510
"else" keyword
"until" keyword
"while" keyword
"phy" mnemoExt
"ply" mnemoExt
"phx" mnemoExt
"plx" mnemoExt
"tsb" mnemoExt
"trb" mnemoExt
"stz" mnemoExt
"bra" pcmnemoExt
"rmb0" mnemoExt
"bbr0" mnemoExt
"smb0" mnemoExt
"bbs0" mnemoExt
"rmb1" mnemoExt
"bbr1" mnemoExt
"smb1" mnemoExt
"bbs1" mnemoExt
"rmb2" mnemoExt
"bbr2" mnemoExt
"smb2" mnemoExt
"bbs2" mnemoExt
"rmb3" mnemoExt
"bbr3" mnemoExt
"smb3" mnemoExt
"bbs3" mnemoExt
"rmb4" mnemoExt
"bbr4" mnemoExt
"smb4" mnemoExt
"bbs4" mnemoExt
"rmb5" mnemoExt
"bbr5" mnemoExt
"smb5" mnemoExt
"bbs5" mnemoExt
"rmb6" mnemoExt
"bbr6" mnemoExt
"smb6" mnemoExt
"bbs6" mnemoExt
"rmb7" mnemoExt
"bbr7" mnemoExt
"smb7" mnemoExt
"bbs7" mnemoExt
"wai" mnemoExt
"pei" mnemoExt
"per" mnemoExt
"mvp" mnemoExt
"mvn" mnemoExt
"rep" mnemoExt
"sep" mnemoExt
"pea" mnemoExt
"phd" mnemoExt
"tcs" mnemoExt
"pld" mnemoExt
"tsc" mnemoExt
"wdm" mnemoExt
"phk" mnemoExt
"tcd" mnemoExt
"tdc" mnemoExt
"phb" mnemoExt
"txy" mnemoExt
"plb" mnemoExt
"tyx" mnemoExt
"xba" mnemoExt
"xce" mnemoExt
"brl" pcmnemoExt
"cop" mnemoExt
"jml" pcmnemoExt
"jsl" mnemoExt
"rtl" pcmnemoExt
"stp" pcmnemoExt
"slo" mnemoExt
"rla" mnemoExt
"sre" mnemoExt
"rra" mnemoExt
"sax" mnemoExt
"lax" mnemoExt
"dcp" mnemoExt
"isc" mnemoExt
"anc" mnemoExt
"ane" mnemoExt
"asr" mnemoExt
"arr" mnemoExt
"alr" mnemoExt
"sbx" mnemoExt
"sha" mnemoExt
"shx" mnemoExt
"shy" mnemoExt
"las" mnemoExt
"tas" mnemoExt
"dop" mnemoExt
"top" mnemoExt
"lxa" mnemoExt
"jam" pcmnemoExt
"map" mnemoExt
"eom" mnemoExt
"aug" mnemoExt
"sac" mnemoExt
"sir" mnemoExt
"orq" mnemoExt
"aslq" mnemoExt
"inq" mnemoExt
"bitq" mnemoExt
"andq" mnemoExt
"rolq" mnemoExt
"deq" mnemoExt
"asrq" mnemoExt
"eorq" mnemoExt
"lsrq" mnemoExt
"adcq" mnemoExt
"rorq" mnemoExt
"stq" mnemoExt
"ldq" mnemoExt
"cpq" mnemoExt
"sbcq" mnemoExt
"cle" mnemoExt
"see" mnemoExt
"tsy" mnemoExt
"inz" mnemoExt
"tys" mnemoExt
"dez" mnemoExt
"neg" mnemoExt
"taz" mnemoExt
"tab" mnemoExt
"bsr" mnemoExt
"tza" mnemoExt
"tba" mnemoExt
"ldz" mnemoExt
"cpz" mnemoExt
"dew" mnemoExt
"asw" mnemoExt
"phz" mnemoExt
"inw" mnemoExt
"row" mnemoExt
"phw" mnemoExt
"plz" mnemoExt
"lbpl" pcmnemoExt
"lbmi" pcmnemoExt
"lbvc" pcmnemoExt
"lbvs" pcmnemoExt
"lbra" pcmnemoExt
"lbcc" pcmnemoExt
"lbcs" pcmnemoExt
"lbne" pcmnemoExt
"lbeq" pcmnemoExt
"rtn" pcmnemoExt
done
"!a-zA-Z0-9" checkstring
# " \t" idle noeat
@ -283,17 +399,9 @@ done
* idle noeat
:pcmnemo6502 PCMnemo6502
* idle noeat
:mnemo65c02 Mnemo65c02
:mnemoExt MnemoExt
* idle noeat
:pcmnemo65c02 PCMnemo65c02
* idle noeat
:mnemo65816 Mnemo65816
* idle noeat
:pcmnemo65816 PCMnemo65816
* idle noeat
:mnemo6510 Mnemo6510
* idle noeat
:pcmnemo6510 PCMnemo6510
:pcmnemoExt PCMnemoExt
* idle noeat
:keyword Keyword
* idle noeat

View File

@ -1,27 +1,22 @@
;ACME 0.91 ; comments are green
;ACME 0.97 ; comments are green
!serious "This file is not meant to be assembled."
binary1=%00001000 ; label names are grey, constants are cyan
binary2=%....#...
octal=&0123456789 ; bad constants are bold red
decimal=63
hex1=0xcd
hex2=$ef
binary1 = %00001000 ; label names are grey, constants are cyan
binary2 = %....#...
octal = &0123456789 ; bad constants are bold red
decimal = 63
hex1 = 0xcd
hex2 = $ef
!sl "labeldump.l" ; strings are cyan
*=$1300
* = $1300
+dings ; macro calls are bold
else ; keyword: bold
!eof ; pseudo: bold
-- ; anonymous labels should be bold (white)
; 6502 mnemonics
nop ; normal ones are yellow
rts ; PC-changing ones are red
; illegals
dop ; most of them are yellow on red
jam ; this single one's red on red. Guess why.
; 65c02 extensions
stz ; normal ones are yellow on cyan
bra ; PC-changing ones (just "BRA") are red
; 65816 extensions
xce ; yellow on blue
cop ; PC-changing ones are red
; base 6502 mnemonics:
inx ; normal ones are yellow,
beq -- ; all that break sequential flow are red
rts
; all extended instruction sets:
stz ; normal ones are yellow on blue
bra ; flow-breaking ones are red

View File

@ -0,0 +1,58 @@
2015-02-04
Release 0.12
Added "VisAss" converter mode.
Removed "umlaut fixing" and just went ahead with UTF-8.
Fixed home page (used the ACME sourceforge page).
2012-10-08
Release 0.11
Beautified source, and added space after ',' in addressing modes.
2006-10-04
Release 0.10
Adjusted support for illegals to latest changes in ACME.
2006-03-12
Release 0.9
Improved "Giga Assembler" mode. Thanks to Andreas Paul for his help.
Fixed unimportant bug: Attempted to close output file twice.
2005-06-16
Release 0.8
Merged all converters into one program ("toacme").
2005-06-08
Release 0.7
2005-06-07
Release 0.6
2005-06-02
Release 0.5
Added converters for Flash8-AssBlaster and Giga-Assembler.
Added minimal disassembler.
2003-02-18
Release 0.4 beta
Now "marked labels" will be converted to global labels,
"unmarked labels" will be converted to local labels.
Now macro calls are converted correctly.
2003-02-12
Release 0.4 alpha
Thanks to Stefan Hübner for sending fixes for AssBlaster macro
problems and label scope.
2000-05-09
Release 0.03
Attempt on disassembly mode - quickly aborted :)
Illegal opcodes are commented out when generated.
1999-08-17?
Release 0.02 (indentation now two TABs instead of one)
Added DOS version.
1999-08-15
Release 0.01
(RISCOS version)

340
contrib/toacme/docs/COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,23 @@
ToACME
...source code file converter for ACME
Compiling and installing the executable
---------------------------------------
Change into the directory "toacme/src" that was created when
unpacking the archive and simply type "make". This will compile the
sources and produce an executable file.
If you have root access:
Change into superuser mode using "su" and type "make install" to move
the executable to the appropriate directory (system-wide install).
If you don't have root access:
Type "make userinstall" to move the executable to your "~/bin"
directory (user-specific install)
Feel free to adjust the Makefile to your specific needs.

View File

@ -0,0 +1,86 @@
VisAss, AssBlaster and Flash8-AssBlaster stuff
----------------------------------------------
The pseudo opcode "\kc" cannot be converted, because ACME does not
have a matching pseudo opcode. The converter will insert an
explanatory message in the output file.
The pseudo opcode "\st" is converted to "!eof". To decide whether this
makes sense or not is left as an exercise for the reader.
"Marked" AssBlaster labels are converted to global ACME labels.
"Unmarked" AssBlaster labels are converted to local ACME labels.
If your AssBlaster sources contain marked (!) labels which read like
mnemonics ("^lda", "^nop" "^sed" or the like), ACME will interpret
the converted versions like instructions.
THE CONVERTER DOES NOT HANDLE THIS PROBLEM YET, so you will have to
change such label names by hand. If binaries produced by ACME and
AssBlaster are the same size, you don't have this problem.
AssBlaster allows the characters '[', ']' and '^' to be used in label
names. These are converted to uppercase letters, which does not cause
any problems - it just looks a bit strange... :)
Empty comments (semicolons at end-of-line) are stripped.
AssBlaster claims to support the 6510's undocumented ("illegal")
instructions. Actually, when I checked, it confused some of the
mnemonics ("asr" and "arr"), and for "lax" and "aax" (aka "sax") it
actually generated wrong opcodes for some addressing modes.
There's a slight problem with macros: Source codes that assemble fine
with AssBlaster *might* give "label not defined" errors after ACME
conversion. This is because AssBlaster macros can access all labels,
while ACME macros can only access global labels (besides their
arguments, of course).
To fix such errors, you'll have to
a) make the macro code reference global labels instead of local ones
and
b) define those global labels, of course.
AssBlaster ACME (unfixed) ACME (fixed by you)
\md chk.c1,c2 !macro chk .c1,.c2 { !macro chk .c1,.c2 {
lda #c1 lda #.c1 lda #.c1
ldx #c2 ldx #.c2 ldx #.c2
jsr sub jsr .sub jsr sub ;<-FIX
\de } }
\ma chk.5,7 +chk 5,7 +chk 5,7
rts rts rts
sub: .sub .sub
rts; later rts; later sub ;<-FIX
rts; later
Hypra-Ass and Giga-Ass stuff
----------------------------
The following pseudo opcodes cannot be converted, because ACME does
not have any matching pseudo opcode. The converter will insert an
explanatory message in the output file.
.on (uses BASIC line numbers)
.go (uses BASIC line numbers)
.co (for chained assembly)
.dp (format rules)
.li (list on printer)
.st (stop output)
Empty comments (semicolons at end-of-line) are stripped.
There's a problem with macros: ACME macro parameters should be *local*
labels, but in Hypra-Ass and Giga-Ass, all labels are global.
THE CONVERTER DOES NOT HANDLE THIS PROBLEM, so you will have to fix
the macros manually:
Hypra-Ass ACME (unfixed) ACME (fixed by you)
.ma chk (c1,c2) !macro chk c1,c2 { !macro chk .c1,.c2 {
lda #c1 lda #c1 lda #.c1
ldx #c2 ldx #c2 ldx #.c2
jsr sub jsr sub jsr sub
.rt } }

View File

@ -0,0 +1,93 @@
ToACME
...source code file converter for ACME
Copyright
---------
ToACME - a source code converter for the ACME crossassembler
Copyright (C) 1998-2016 Marco Baye
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Introduction
------------
ToACME is a file converter for the ACME crossassembler. It is meant to
be a helpful tool for people switching from using another assembler to
using ACME. In such cases, ToACME can be used to convert the source
code files to ACME format.
Syntax and use
--------------
./toacme FORMAT_ID INPUT_FILE OUTPUT_FILE
Calling ToACME without any arguments will show a short message
containing copyright information and a list of all known input
formats.
If called with three arguments, ToACME will interpret the first one
as the format ID. It will then try to convert the input file,
writing the result to the output file.
Please keep in mind that this program cannot cope with *all*
features other assemblers may use. So after having converted your
sources, don't delete the original ones!
Make sure the conversion worked by assembling the new sources using
ACME and then comparing the resulting binaries with the ones your
previous assembler produced.
Known input formats
-------------------
Currently, ToACME supports these input file formats:
Format ID: source file format quality
--------------------------------------------------
object object code files poor
hypra C64: Hypra-Assembler ok
giga C64: Giga-Assembler ok
vis C64: VisAss untested
ab3 C64: AssBlaster 3.0 to 3.2 good
f8ab C64: Flash8-AssBlaster ok
prof C64: Professional Assembler poor (work in progress)
Contacting the author
---------------------
The newest version can be found at the ACME homepage:
http://sourceforge.net/projects/acme-crossass/
If you want to report a bug or make a suggestion, then simply send
an email to marco@baye.de
Credits
-------
Thanks to Stefan Hübner for fixing the AssBlaster macro conversion code.
Thanks to Andreas Paul for helping with the Giga-Assembler mode.
Thanks to Arndt Dettke for helping with the Hypra-Assembler mode.
Thanks to Hoogo for helping with the Professional Assembler mode.

View File

@ -0,0 +1,61 @@
CFLAGS = -O3 -Wall -Wstrict-prototypes
#LIBS = -lm
CC = gcc
RM = rm
#SRC =
PROGS = toacme
BINDIR = /usr/local/bin
USERBIN = $(HOME)/bin
all: $(PROGS)
vis.o: config.h acme.h io.h mnemo.h scr2iso.h vis.c
ab3.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h ab3.c
ab.o: config.h ab.h acme.h io.h scr2iso.h ab.c
f8ab.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h f8ab.c
giga.o: config.h acme.h gighyp.h io.h mnemo.h pet2iso.h giga.c
gighyp.o: config.h acme.h io.h pet2iso.h gighyp.h gighyp.c
hypra.o: config.h acme.h gighyp.h io.h pet2iso.h hypra.c
obj.o: config.h acme.h io.h mnemo.h obj.c
acme.o: config.h acme.h acme.c
main.o: config.h version.h main.c
mnemo.o: config.h mnemo.c
pet2iso.o: config.h pet2iso.h pet2iso.c
platform.o: config.h platform.h platform.c
prof.o: config.h prof.c
scr2iso.o: config.h scr2iso.h scr2iso.c
version.o: config.h version.c
toacme: vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o prof.o scr2iso.o version.o
$(CC) $(LIBS) $(CFLAGS) -o toacme vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o prof.o scr2iso.o version.o
strip toacme
clean:
-$(RM) -f *.o $(PROGS) *~ core
install: all
install -d $(BINDIR)
install $(PROGS) $(BINDIR)
userinstall: all
install -d $(USERBIN)
install $(PROGS) $(USERBIN)
# DO NOT DELETE

View File

@ -0,0 +1,62 @@
CFLAGS = -Wall -s -Wstrict-prototypes
#LIBS = -lm
CC = gcc
RM = rm
#SRC =
PROGS = toacme
#BINDIR = /usr/local/bin
#USERBIN = $(HOME)/bin
all: $(PROGS)
vis.o: config.h acme.h io.h mnemo.h scr2iso.h vis.c
ab3.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h ab3.c
ab.o: config.h ab.h acme.h io.h scr2iso.h ab.c
f8ab.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h f8ab.c
giga.o: config.h acme.h gighyp.h io.h mnemo.h pet2iso.h giga.c
gighyp.o: config.h acme.h io.h pet2iso.h gighyp.h gighyp.c
hypra.o: config.h acme.h gighyp.h io.h pet2iso.h hypra.c
obj.o: config.h acme.h io.h mnemo.h obj.c
acme.o: config.h acme.h acme.c
main.o: config.h version.h main.c
mnemo.o: config.h mnemo.c
pet2iso.o: config.h pet2iso.h pet2iso.c
platform.o: config.h platform.h platform.c
scr2iso.o: config.h scr2iso.h scr2iso.c
version.o: config.h version.c
toacme: vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o scr2iso.o version.o
$(CC) $(LIBS) $(CFLAGS) -o toacme.out vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o scr2iso.o version.o
copy /b \djgpp\bin\pmodstub.exe + toacme.out toacme_p.exe
djp toacme.exe
djp toacme_p.exe
clean:
del *.o
# -$(RM) -f *.o $(PROGS) *~ core
#install: all
# install -d $(BINDIR)
# install $(PROGS) $(BINDIR)
#userinstall: all
# install -d $(USERBIN)
# install $(PROGS) $(USERBIN)
# DO NOT DELETE

View File

@ -0,0 +1,59 @@
CFLAGS = -O3 -Wall -Wstrict-prototypes
#LIBS = -lm
CC = gcc
RM = rm
#SRC =
PROGS = toacme.exe
all: $(PROGS)
vis.o: config.h acme.h io.h mnemo.h scr2iso.h vis.c
ab3.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h ab3.c
ab.o: config.h ab.h acme.h io.h scr2iso.h ab.c
f8ab.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h f8ab.c
giga.o: config.h acme.h gighyp.h io.h mnemo.h pet2iso.h giga.c
gighyp.o: config.h acme.h io.h pet2iso.h gighyp.h gighyp.c
hypra.o: config.h acme.h gighyp.h io.h pet2iso.h hypra.c
obj.o: config.h acme.h io.h mnemo.h obj.c
acme.o: config.h acme.h acme.c
main.o: config.h version.h main.c
mnemo.o: config.h mnemo.c
pet2iso.o: config.h pet2iso.h pet2iso.c
platform.o: config.h platform.h platform.c
prof.o: config.h prof.c
scr2iso.o: config.h scr2iso.h scr2iso.c
version.o: config.h version.c
toacme.exe: vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o prof.o scr2iso.o version.o resource.res
$(CC) $(LIBS) $(CFLAGS) -o toacme vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o prof.o scr2iso.o version.o resource.res
strip toacme.exe
win/resource.rc: main.c
cd win; sh setRelease.sh
resource.res: win/resource.rc win/logo.ico
cd win; windres resource.rc -O coff -o ../resource.res
cp -f win/logo.ico .
clean:
-$(RM) -f *.o $(PROGS) *~ core resource.res logo.ico win/resource.rc
# DO NOT DELETE

View File

@ -0,0 +1,59 @@
CFLAGS = -O3 -Wall -Wstrict-prototypes -mthrowback -mlibscl -mno-poke-function-name
#LIBS = -lm
CC = gcc
RM = rm
#SRC =
PROGS = toacme
#BINDIR = /usr/local/bin
#USERBIN = $(HOME)/bin
all: $(PROGS)
vis.o: config.h acme.h io.h mnemo.h scr2iso.h vis.c
ab3.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h ab3.c
ab.o: config.h ab.h acme.h io.h scr2iso.h ab.c
f8ab.o: config.h ab.h acme.h io.h mnemo.h scr2iso.h f8ab.c
giga.o: config.h acme.h gighyp.h io.h mnemo.h pet2iso.h giga.c
gighyp.o: config.h acme.h io.h pet2iso.h gighyp.h gighyp.c
hypra.o: config.h acme.h gighyp.h io.h pet2iso.h hypra.c
obj.o: config.h acme.h io.h mnemo.h obj.c
acme.o: config.h acme.h acme.c
main.o: config.h version.h main.c
mnemo.o: config.h mnemo.c
pet2iso.o: config.h pet2iso.h pet2iso.c
platform.o: config.h platform.h platform.c
scr2iso.o: config.h scr2iso.h scr2iso.c
version.o: config.h version.c
toacme: vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o scr2iso.o version.o
$(CC) $(LIBS) $(CFLAGS) -o !Unsqueezed vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o scr2iso.o version.o
Squeeze -f -v !Unsqueezed toacme
#clean:
# -$(RM) -f *.o $(PROGS) *~ core
#install: all
# install -d $(BINDIR)
# install $(PROGS) $(BINDIR)
#userinstall: all
# install -d $(USERBIN)
# install $(PROGS) $(USERBIN)
# DO NOT DELETE

524
contrib/toacme/src/ab.c Normal file
View File

@ -0,0 +1,524 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2015 Marco Baye
// Have a look at "main.c" for further info
//
// stuff needed for "VisAss", "AssBlaster 3.x" and/or "Flash8-AssBlaster"
#include <stdio.h>
#include "ab.h"
#include "acme.h"
#include "mnemo.h"
#include "io.h"
#include "scr2iso.h"
// comparison:
// VisAss AssBlaster 3.x F8-AssBlaster
// 00- Mnemonics?
// 48- PseudoOps
// 80..86 Mnemonics 80..db Mnemonics
// 87..95 Illegals
// 96..c7 Mnemonics
// c8..d4 PseudoOps dc..ec PseudoOps
// d5..fe unused ed..fe unused
// ff line mark ff line mark ff line mark
// Mnemonic table in VisAss/AssBlaster 3.x order
const char *visass_ab3_mnemonic_table[] = {
NULL, // unused
MnemonicCPX, MnemonicCPY,
MnemonicLDX, MnemonicLDY,
MnemonicSTX, MnemonicSTY,
//============================= start of illegals =============================
MnemonicSAX, // broken in VisAss/AB3, see docs (called AAX)
MnemonicASR, // broken in VisAss/AB3, see docs
MnemonicARR, // broken in VisAss/AB3, see docs
MnemonicSBX, // (called AXS)
MnemonicDCP,
MnemonicDOP, // ACME uses a different opcode
MnemonicISC,
MnemonicJAM, // ACME uses a different opcode (called KIL)
"!error \"See the ToACME docs about the illegal opcode LAR.\";",
// broken in VisAss/AB3? see docs
MnemonicLAX, // broken in VisAss/AB3, see docs
MnemonicRLA, MnemonicRRA,
MnemonicSLO, MnemonicSRE,
MnemonicTOP, // ACME uses a different opcode
//============================== end of illegals ==============================
MnemonicADC, MnemonicAND, MnemonicASL,
MnemonicBIT,
MnemonicBCS, MnemonicBEQ, MnemonicBCC, MnemonicBMI,
MnemonicBNE, MnemonicBPL, MnemonicBVS, MnemonicBVC,
MnemonicBRK,
MnemonicCLC, MnemonicCLD, MnemonicCLI, MnemonicCLV,
MnemonicCMP,
MnemonicDEC, MnemonicDEX, MnemonicDEY,
MnemonicEOR,
MnemonicINC, MnemonicINX, MnemonicINY,
MnemonicJMP, MnemonicJSR,
MnemonicLDA,
MnemonicLSR,
MnemonicNOP,
MnemonicORA,
MnemonicPHA, MnemonicPHP, MnemonicPLA, MnemonicPLP,
MnemonicROL, MnemonicROR,
MnemonicRTI, MnemonicRTS,
MnemonicSBC,
MnemonicSEC, MnemonicSED, MnemonicSEI,
MnemonicSTA,
MnemonicTAX, MnemonicTAY, MnemonicTSX,
MnemonicTXA, MnemonicTXS, MnemonicTYA,
};
// PseudoOpcode table in VisAss/AssBlaster 3.x order
const char *visass_ab3_pseudo_opcode_table[] = {
NULL, // la NULL because ACME does not need a pseudo opcode for label defs
ACME_set_pc, // ba
ACME_po_byte, // by
ACME_po_fill, // br
ACME_po_pet, // tx
ACME_po_macro, // md see AB_PSEUDOOFFSET_MACRODEF
ACME_endmacro, // me
ACME_macro_call, // ma see AB_PSEUDOOFFSET_MACROCALL
ACME_po_eof, // st
ACME_po_scr, // ts
ACME_po_to, // to see AB_PSEUDOOFFSET_OUTFILE
ACME_po_word, // wo
"; ToACME: Cannot convert \\kc.\n", // kc
nothing // "nothing"
};
// constants
const char nothing[] = "doesnotmatter"; // rename to visass_nopseudoopcode
void visass_ab3_illegals(void)
{
IO_put_string(
"; ToACME: Adding pseudo opcode to enable undocumented (\"illegal\") opcodes:\n"
"\t!cpu 6510\n"
"; ToACME: Support for illegal opcodes is somewhat broken in VisAss/AssBlaster.\n"
"; ToACME: Make sure you read the ToACME docs to know what you'll have to\n"
"; ToACME: look out for.\n"
"; ToACME: Should work: DCP, DOP, ISC, JAM (called KIL in VisAss/AssBlaster),\n"
"; ToACME: RLA, RRA, SBX (was called AXS in AssBlaster), SLO, SRE, TOP.\n"
"; ToACME: Trouble: ARR, ASR, LAX, SAX (called AAX in VisAss/AssBlaster).\n"
);
}
// constants
// generate error/warning messages
const char error_unknown_addressing[] = "Conversion failed: AssBlaster file contains unknown addressing mode.\n";
const char error_unknown_compression[] = "Conversion failed: AssBlaster file contains unknown number compression.\n";
const char warning_unknown_number_format[] = "Warning: AssBlaster file uses unknown number format. Fallback to hexadecimal.\n";
#define SCREENCODE_UPARROW (0x1e)
// replacement characters for problematic label names
#define AB_LABELSPECIAL_NUL ('O') // AssBlaster uses only lower case
#define AB_LABELSPECIAL_LEFT ('L') // characters for labels, so these
#define AB_LABELSPECIAL_BACK ('B') // shouldn't cause any clashes.
#define AB_LABELSPECIAL_RIGHT ('R')
#define AB_LABELSPECIAL_UP ('A')
// meaning of input bytes
// 0x01-0x1f lower case screen codes (used for label names and comments)
#define AB_SPACE 0x20
// 0x20-0x3a special characters
#define AB_COMMENT 0x3b
// 0x3c-0x40 unused ?
// 0x41-0x5f upper case screen codes (used for comments)
// 0x60-0x7f unused ?
// 0x80-0xec differ between AssBlaster 3.x and Flash8-AssBlaster
// 0xed-0xfe unused ?
// 0xff end-of-line
#define AB_PSEUDOOFFSET_MACRODEF 5 // in AB3 and F8AB
#define AB_PSEUDOOFFSET_MACROCALL 7 // indices in PO table
#define AB_PSEUDOOFFSET_OUTFILE 10 // are equal
// after mnemonic or pseudo opcode, numbers may follow:
#define AB_NUMVAL_FLAGBIT 0x80 // indicates packed number
// pre- and postfixes for addressing modes
// don't care whether argument is 8, 16 or 24 bits wide
const char *addressing_modes[][2] = {
{"", "" }, // ($00=%.....) implied
{" ", "" }, // ($01=%....1) absolute
{" ", ", x" }, // ($02=%...1.) absolute,x
{" ", ", y" }, // ($03=%...11) absolute,y
{" #", "" }, // ($04=%..1..) immediate
{NULL, NULL }, // ($05=%..1.1) unused (indirect-y)
{NULL, NULL }, // ($06=%..11.) unused (indirect-y)
{NULL, NULL }, // ($07=%..111) unused (indirect-y)
{" (", "), y" }, // ($08=%.1...) indirect-y
{" (", ", x)" }, // ($09=%.1..1) indirect-x
{" ", "" }, // ($0a=%.1.1.) relative (=absolute, actually)
{" (", ")" }, // ($0b=%.1.11) indirect
// above: used by both AB3 and F8AB (except $0a, which is no longer
// used by F8AB. But it's indistinguishable from $01 anyway).
// FIXME - what does AB3 do with the other unused addressing modes?
// I think old AB3 sources may also use mode 0c!
// below: used by F8AB only
{NULL, NULL }, // ($0c=%.11..) unused (indirect-x)
{" [", "]" }, // ($0d=%.11.1) indirect long
{NULL, NULL }, // ($0e=%.111.) unused (absolute)
{NULL, NULL }, // ($0f=%.1111) unused (absolute-x)
{" ", "" }, // ($10=%1....) MVP/MVN in F8AB: arg1.arg2
#define MVP_MVN_ADDRMODE 0x10
{NULL, NULL }, // ($11=%1...1) unused (indirect)
{NULL, NULL }, // ($12=%1..1.) unused (indirect long)
{" [", "], y" }, // ($13=%1..11) indirect-y long
{NULL, NULL }, // ($14=%1.1..) unused (absolute)
{" ", ", s" }, // ($15=%1.1.1) stack-relative
{" (", ", s), y" }, // ($16=%1.11.) stack-relative-indirect-y
// from here on, unused (indirect-y)
// addressing mode $10 (for MVP/MVN) is displayed and stored by F8AB
// as "arg1.arg2" instead of "arg1,arg2". Therefore the following
// constant is used to fix it on-the-fly.
};
// variables
struct vab *conf;
// functions
//
static void generate_errors(int err_bits)
{
if (err_bits & AB_ERRBIT_UNKNOWN_ADDRMODE) {
fputs(error_unknown_addressing, stderr);
fprintf(global_output_stream, "; ToACME: %s", error_unknown_addressing);
}
if (err_bits & AB_ERRBIT_UNKNOWN_NUMBER_COMPRESSION) {
fputs(error_unknown_compression, stderr);
fprintf(global_output_stream, "; ToACME: %s", error_unknown_compression);
}
if (err_bits & AB_ERRBIT_UNKNOWN_NUMBER_FORMAT) {
fputs(warning_unknown_number_format, stderr);
fprintf(global_output_stream, "; ToACME: %s", warning_unknown_number_format);
}
}
// convert macro/label name character.
// AssBlaster allows '^', '[' and ']' in names, so replace these chars.
static char conv_name_char(char byte)
{
byte = SCR2ISO(byte);
switch (byte) {
case 0x40:
return AB_LABELSPECIAL_NUL;
case '[':
return AB_LABELSPECIAL_LEFT;
case '\\':
return AB_LABELSPECIAL_BACK;
case ']':
return AB_LABELSPECIAL_RIGHT;
case '^':
return AB_LABELSPECIAL_UP;
default:
return byte;
}
}
// output binary representation of value
void AB_output_binary(unsigned long int value)
{
int mask = 128;
if (value > 0xff)
AB_output_binary(value >> 8);
value &= 0xff;
while (mask) {
IO_put_byte((value & mask) ? '1' : '0');
mask >>= 1;
}
}
// output hex representation of value
void AB_output_hexadecimal(unsigned long int value)
{
if (value > 0xff)
AB_output_hexadecimal(value >> 8);
IO_put_low_byte_hex(value);
}
// convert and send macro/label name (until illegal character comes along)
static void pipe_global_name(void)
{
while ((GotByte < 0x20) || ((GotByte >= '0') && (GotByte <= '9'))) {
IO_put_byte(conv_name_char(GotByte));
IO_get_byte();
}
}
// convert and send label name (until illegal character comes along)
// level 1
static void pipe_name(void)
{
if (conf->flags & VABFLAG_ADD_DOT) {
// Dieser kleine Hack macht alle lokalen ABL-Labels
// Auch unter ACME lokal. nur mit '^' global markierte
// Labels werden auch global übernommen ...
if (GotByte == SCREENCODE_UPARROW)
IO_get_byte(); // global: ^witharrow => witharrow
else
IO_put_byte('.'); // local: allothers => .allothers
}
pipe_global_name(); // this does exactly what is needed
}
// parse quoted strings
static void parse_quoted(void) // now GotByte = unhandled opening quote
{
IO_put_byte('"');
IO_get_byte();
while ((GotByte != AB_ENDOFLINE) && (GotByte != '"')) {
IO_put_byte(SCR2ISO(GotByte));
IO_get_byte();
}
IO_put_byte('"');
// closing quote is handled, but EndOfLine must remain unhandled
if (GotByte == '"')
IO_get_byte();
}
// parse label names, quoted strings, operators, literal values etc.
// read until AB_ENDOFLINE or AB_COMMENT. Returns error bits.
// level 1
// AB uses a full stop character ('.') in some inconvenient places, for example
// after macro names (at definitions and calls) and in the MVP/MVN addressing
// mode. The kluge variable "dot_replacement" is used to replace the '.'
// character with the correct character for ACME.
static int parse_unspecified(char dot_replacement)
{
int err_bits = 0;
while ((GotByte != AB_ENDOFLINE) && (GotByte != AB_COMMENT)) {
// kluge: replace '.' character with current replacement and
// remember not to replace anymore from now on.
if (GotByte == '.') {
GotByte = dot_replacement; // use replacement
dot_replacement = '.'; // in future, keep
}
if (GotByte & AB_NUMVAL_FLAGBIT) {
err_bits |= conf->number_parser();
continue;
}
if (GotByte < 0x20) {
pipe_name();
continue;
}
if (GotByte == '"') {
parse_quoted();
continue;
}
IO_put_byte(SCR2ISO(GotByte));
IO_get_byte();
}
return err_bits;
}
// parse macro call or start of definition (beware of full stops).
// returns error bits.
static int parse_macro_stuff(void) // now GotByte = unhandled byte
{
// I guess local macros are useless, so don't
// do the scope fixing as for macro names!
pipe_global_name();
return parse_unspecified(SPACE); // output macro arguments
}
// process mnemonics (real opcodes). returns error bits.
// level 1
static int parse_mnemo(int mnemonic_offset)
{
const char *mnemonic,
*pre,
*post;
int addressing_mode,
dot_replacement = '.',
err_bits = 0;
if (conf->address_mode_count > 2) {
addressing_mode = IO_get_byte(); // get addressing mode
} else {
addressing_mode = 1; // dummy mode for VisAss
}
IO_get_byte(); // and fetch next (not handled here)
mnemonic = conf->mnemonics[mnemonic_offset];
if (mnemonic == NULL) {
fputs("Found unused mnemo code in input file.\n", stderr);
mnemonic = "!error \"ToACME found unused mnemo code in input file\":";
}
fprintf(global_output_stream, "\t\t%s", mnemonic);
// determine prefix and postfix of addressing mode
if (addressing_mode < conf->address_mode_count) {
pre = addressing_modes[addressing_mode][0];
post = addressing_modes[addressing_mode][1];
if (addressing_mode == MVP_MVN_ADDRMODE)
dot_replacement = ','; // replace '.' with ','
} else {
pre = NULL;
post = NULL;
}
// if addressing mode is invalid, set error bit
// output prefix (or space if invalid)
if ((pre == NULL) || (post == NULL)) {
err_bits |= AB_ERRBIT_UNKNOWN_ADDRMODE;
fprintf(stderr, "Found an unknown addressing mode bit pattern ($%x). Please tell my programmer.\n", addressing_mode);
}
if (pre)
IO_put_string(pre);
else
IO_put_byte(SPACE);
err_bits |= parse_unspecified(dot_replacement); // output arg
if (post)
IO_put_string(post);
return err_bits;
}
// process pseudo opcodes. returns error bits.
// level 1
static int parse_pseudo_opcode(int pseudo_offset)
{
const char *pseudo_opcode;
int err_bits = 0;
IO_get_byte(); // and fetch next (not handled here)
pseudo_opcode = conf->pseudo_opcodes[pseudo_offset];
if (pseudo_opcode != nothing)
IO_put_string("\t\t");
else
pseudo_opcode = NULL;
if (pseudo_opcode) {
IO_put_string(pseudo_opcode);
}
// check for special cases
switch (pseudo_offset) {
case AB_PSEUDOOFFSET_MACROCALL: // (in ACME: '+')
// ACME does not like spaces after the macro call char
err_bits |= parse_macro_stuff();
break;
case AB_PSEUDOOFFSET_MACRODEF: // macro definition
IO_put_byte(SPACE); // but here a space looks good :)
err_bits |= parse_macro_stuff();
IO_put_string(" {");
break;
case AB_PSEUDOOFFSET_OUTFILE: // outfile selection
IO_put_byte(SPACE); // but here a space looks good :)
err_bits |= parse_unspecified('.'); // output arg(s)
IO_put_string(ACME_cbmformat);
break;
default: // all other pseudo opcodes
if ((pseudo_opcode)
&& (GotByte != AB_ENDOFLINE)
&& (GotByte != AB_COMMENT))
IO_put_byte(SPACE); // but here a space looks good :)
err_bits |= parse_unspecified('.'); // output pseudo opcode's arg(s)
}
return err_bits;
}
// main routine for AssBlaster conversion (works for both AB3 and F8AB).
// call with first byte of first line pre-read (in GotByte)!
void AB_main(struct vab *client_config)
{
int err_bits;
const char *comment_indent;
int length_byte;
int handled;
conf = client_config;
ACME_switch_to_pet();
// convert lines until EndOfFile
while (!IO_reached_eof) {
err_bits = 0; // no errors yet (in this line)
handled = 0;
if (conf->flags & VABFLAG_HASLENGTHBYTE) {
length_byte = GotByte;
IO_get_byte();
}
comment_indent = "\t";
if (GotByte >= conf->first_mnemonic
&& (GotByte < conf->first_mnemonic + conf->mnemonic_count)) {
handled = 1;
err_bits |= parse_mnemo(GotByte - conf->first_mnemonic);
}
if (GotByte >= conf->first_pseudo_opcode
&& (GotByte < conf->first_pseudo_opcode + conf->pseudo_opcode_count)) {
handled = 1;
err_bits |= parse_pseudo_opcode(GotByte - conf->first_pseudo_opcode);
}
if (GotByte >= conf->first_unused_byte_value
&& (GotByte != AB_ENDOFLINE)) {
handled = 1;
fprintf(global_output_stream, "; ToACME: AssBlaster file used unknown code ($%x). ", GotByte);
IO_get_byte(); // fetch next
err_bits |= parse_unspecified('.'); // output remainder
}
if (handled == 0) {
switch (GotByte) {
case 0: // empty line
IO_get_byte(); // skip this byte
break;
case AB_COMMENT: // early comment
comment_indent = "";
break; // ignore now, act later
case AB_SPACE: // empty line or late comment
comment_indent = "\t\t\t\t";
IO_get_byte(); // skip this space
// output whatever found
err_bits |= parse_unspecified('.');
break;
default: // implied label definition
pipe_name();
}
}
// everything might be followed by a comment, so check
if (GotByte == AB_COMMENT) {
// skip empty comments by checking next byte
if (IO_get_byte() != AB_ENDOFLINE) {
// something's there, so pipe until end of line
IO_put_string(comment_indent);
IO_put_byte(';');
do
IO_put_byte(SCR2ISO(GotByte));
while (IO_get_byte() != AB_ENDOFLINE);
}
}
// now check whether line generated any errors
if (err_bits)
generate_errors(err_bits);
// if not at end-of-line, something's fishy
if (GotByte != AB_ENDOFLINE) {
if (GotByte == '\0') {
IO_put_string("; ToACME: found $00 - looks like end-of-file marker.");
} else {
fputs("Found data instead of end-of-line indicator!?.\n", stderr);
IO_put_string("; ToACME: Garbage at end-of-line:");
do
IO_put_byte(SCR2ISO(GotByte));
while (IO_get_byte() != AB_ENDOFLINE);
}
}
IO_put_byte('\n');
// read first byte of next line
IO_get_byte();
}
}

51
contrib/toacme/src/ab.h Normal file
View File

@ -0,0 +1,51 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// stuff needed for "VisAss", "AssBlaster 3.x" and "Flash8-AssBlaster"
#ifndef ab_H
#define ab_H
#include "config.h"
// Definition of "Type of VisAss/AssBlaster" structure
struct vab {
int flags;
int (*number_parser) (void);
const char **pseudo_opcodes;
const char **mnemonics;
int address_mode_count;
int first_mnemonic;
int mnemonic_count;
int first_pseudo_opcode;
int pseudo_opcode_count;
int first_unused_byte_value;
int unused_values_count;
};
#define VABFLAG_HASLENGTHBYTE (1u << 0)
#define VABFLAG_ADD_DOT (1u << 1)
// Constants
extern const char nothing[];
#define AB_ENDOFLINE 0xff
// meaning of internal error word. errors are collected until *after* a line
// has been finished so the warning messages don't interfere with the generated
// source code.
#define AB_ERRBIT_UNKNOWN_ADDRMODE (1u << 0)
#define AB_ERRBIT_UNKNOWN_NUMBER_COMPRESSION (1u << 1) // SIZEMASK invalid
#define AB_ERRBIT_UNKNOWN_NUMBER_FORMAT (1u << 2) // FORMATMASK invalid
extern const char *visass_ab3_mnemonic_table[];
extern const char *visass_ab3_pseudo_opcode_table[];
// Prototypes
extern void visass_ab3_illegals(void);
extern void AB_output_binary(unsigned long int value);
extern void AB_output_hexadecimal(unsigned long int value);
extern void AB_main(struct vab *client_config);
#endif

114
contrib/toacme/src/ab3.c Normal file
View File

@ -0,0 +1,114 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2015 Marco Baye
// Have a look at "main.c" for further info
//
// AssBlaster 3.x stuff
#include <stdlib.h>
#include <stdio.h>
#include "config.h"
#include "ab.h"
#include "acme.h"
#include "io.h"
#include "scr2iso.h"
// constants
#define AB3_ADDRESSING_MODES 12
// parse AssBlaster's packed number format. returns error bits.
//#define AB_NUMVAL_FLAGBIT 0x80 // 10000000 indicates packed number
#define AB3_NUMVAL_ADD_1 0x40 // 01000000
#define AB3_NUMVAL_ADD_256 0x20 // 00100000
#define AB3_NUMVAL_FORMATMASK 0x1a // 00011010
#define AB3_NUMVAL__FORMAT_HEX 0x10 // 00010000=16 (oh bob, the base is
#define AB3_NUMVAL__FORMAT_DEC 0x0a // 00001010=10 given directly, without
#define AB3_NUMVAL__FORMAT_BIN 0x02 // 00000010= 2 any encoding... :))
#define AB3_NUMVAL_SIZEMASK 0x05 // 00000101
#define AB3_NUMVAL__SIZE_0 0x01 // 00000001
#define AB3_NUMVAL__SIZE_1 0x04 // 00000100
#define AB3_NUMVAL__SIZE_2 0x00 // 00000000
static int parse_number(void) // now GotByte = first byte of packed number
{
int flags = GotByte,
err_bits = 0;
unsigned long int value = 0,
add = 0;
// decode value
if (flags & AB3_NUMVAL_ADD_1)
add += 1;
if (flags & AB3_NUMVAL_ADD_256)
add += 256;
switch (flags & AB3_NUMVAL_SIZEMASK) {
case AB3_NUMVAL__SIZE_0: // no bytes follow (0, 1, 256, 257)
value = add;
break;
case AB3_NUMVAL__SIZE_1: // one byte follows (2 to 511)
value = add + IO_get_byte();
break;
case AB3_NUMVAL__SIZE_2: // two bytes follow (512 to 65535)
value = add + IO_get_le16();
break;
default: // unknown number compression
// remember to generate error
err_bits |= AB_ERRBIT_UNKNOWN_NUMBER_COMPRESSION;
}
// continue parsing on next byte
IO_get_byte();
// decode output format
switch (flags & AB3_NUMVAL_FORMATMASK) {
case AB3_NUMVAL__FORMAT_BIN:
IO_put_byte('%');
AB_output_binary(value);
break;
case AB3_NUMVAL__FORMAT_DEC:
fprintf(global_output_stream, "%lu", value);
break;
case AB3_NUMVAL__FORMAT_HEX:
hex_fallback: IO_put_byte('$');
AB_output_hexadecimal(value);
break;
default: // unknown output format
// remember to warn
err_bits |= AB_ERRBIT_UNKNOWN_NUMBER_FORMAT;
goto hex_fallback;
}
return err_bits;
}
// config struct for shared VisAss/AB code
struct vab ab3_conf = {
VABFLAG_ADD_DOT,
parse_number,
visass_ab3_pseudo_opcode_table,
visass_ab3_mnemonic_table,
AB3_ADDRESSING_MODES,
// meaning of input bytes (0x80-0xec differ between AB3 and F8AB)
0x80, // first mnemonic
40, // count
0xc8, // first pseudo opcode
13, // count
0xd5, // first unused value
42 // count
};
// main
void ab3_main(void)
{
IO_set_input_padding(AB_ENDOFLINE);
visass_ab3_illegals();
IO_process_load_address();
// first byte after load address should be AB_ENDOFLINE in AB3 sources
if (IO_get_byte() == AB_ENDOFLINE) {
IO_get_byte(); // skip it and pre-read first valid byte
fputs("Input has AB3 header.\n", stderr);
} else {
fputs("Input does not have any known AB3 header.\n", stderr);
}
AB_main(&ab3_conf);
}

47
contrib/toacme/src/acme.c Normal file
View File

@ -0,0 +1,47 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// ACME syntax
#include "acme.h"
#include "io.h"
// constants
// pseudo opcodes
const char ACME_po_to[] = "!to";
const char ACME_cbmformat[] = ", cbm";
const char ACME_po_sl[] = "!sl";
const char ACME_set_pc[] = "*=";
const char ACME_po_source[] = "!src";
const char ACME_po_byte[] = "!byte";
const char ACME_po_word[] = "!word";
const char ACME_po_fill[] = "!fill";
const char ACME_po_pet[] = "!pet";
const char ACME_po_scr[] = "!scr";
const char ACME_po_macro[] = "!macro";
const char ACME_endmacro[] = "}; (end of macro definition)\n";
const char ACME_macro_call[] = "+";
const char ACME_po_if[] = "!if";
const char ACME_else[] = "} else {";
const char ACME_endif[] = "}; (end of conditional assembly)\n";
const char ACME_po_eof[] = "!eof";
// pseudo opcodes for 65816 (used by Flash8-AssBlaster)
const char ACME_po_al[] = "!al";
const char ACME_po_as[] = "!as";
const char ACME_po_rl[] = "!rl";
const char ACME_po_rs[] = "!rs";
// functions
// output pseudo opcode to make ACME use PetSCII encoding
void ACME_switch_to_pet(void)
{
IO_put_string(
"; ToACME: Adding pseudo opcode to use PetSCII encoding by default:\n"
"!convtab pet\n"
);
}

41
contrib/toacme/src/acme.h Normal file
View File

@ -0,0 +1,41 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// ACME syntax
#ifndef acme_H
#define acme_H
// constants
// pseudo opcodes and related keywords
extern const char ACME_po_to[];
extern const char ACME_cbmformat[];
extern const char ACME_po_sl[];
extern const char ACME_set_pc[];
extern const char ACME_po_source[];
extern const char ACME_po_byte[];
extern const char ACME_po_word[];
extern const char ACME_po_fill[];
extern const char ACME_po_pet[];
extern const char ACME_po_scr[];
extern const char ACME_po_macro[];
extern const char ACME_endmacro[];
extern const char ACME_macro_call[];
extern const char ACME_po_if[];
extern const char ACME_else[];
extern const char ACME_endif[];
extern const char ACME_po_eof[];
// pseudo opcodes for 65816 cpu
extern const char ACME_po_al[];
extern const char ACME_po_as[];
extern const char ACME_po_rl[];
extern const char ACME_po_rs[];
// prototypes
extern void ACME_switch_to_pet(void);
#endif

View File

@ -0,0 +1,22 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// Configurable stuff
// ...this file gets included by almost all others, even *.h files
#ifndef config_H
#define config_H
// constants
#define SPACE 0x20
#define SHIFTSPACE 0xa0
#ifndef FALSE
typedef int bool;
#define FALSE 0
#define TRUE 1
#endif
#endif

265
contrib/toacme/src/f8ab.c Normal file
View File

@ -0,0 +1,265 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2015 Marco Baye
// Have a look at "main.c" for further info
//
// Flash8-AssBlaster stuff
#include <stdlib.h>
#include <stdio.h>
#include "config.h"
#include "ab.h"
#include "acme.h"
#include "mnemo.h"
#include "io.h"
#include "scr2iso.h"
// constants
#define F8AB_ADDRESSING_MODES 23 // (FIXME - check back later!)
// mnemonic table in Flash8-AssBlaster order (without: JML, WDM)
static const char *mnemonic_table[] = {
MnemonicADC, // $80 6502
MnemonicAND, // $81 6502
MnemonicASL, // $82 6502
MnemonicBCC, // $83 6502
MnemonicBCS, // $84 6502
MnemonicBEQ, // $85 6502
MnemonicBIT, // $86 6502
MnemonicBMI, // $87 6502
MnemonicBNE, // $88 6502
MnemonicBPL, // $89 6502
MnemonicBRA, // $8a 65c02
MnemonicBRK, // $8b 6502
MnemonicBRL, // $8c 65816
MnemonicBVC, // $8d 6502
MnemonicBVS, // $8e 6502
MnemonicCLC, // $8f 6502
MnemonicCLD, // $90 6502
MnemonicCLI, // $91 6502
MnemonicCLV, // $92 6502
MnemonicCMP, // $93 6502
MnemonicCOP, // $94 65816
MnemonicCPX, // $95 6502
MnemonicCPY, // $96 6502
MnemonicDEC, // $97 F8AB uses DEA as the 65816's "DEC implied"
MnemonicDEC, // $98 6502
MnemonicDEX, // $99 6502
MnemonicDEY, // $9a 6502
MnemonicEOR, // $9b 6502
MnemonicINC, // $9c F8AB uses INA as the 65816's "INC implied"
MnemonicINC, // $9d 6502
MnemonicINX, // $9e 6502
MnemonicINY, // $9f 6502
// MnemonicJML (65816) seems to be unknown to F8AB ...
MnemonicJMP, // $a0 6502
MnemonicJSL, // $a1 65816 ...but it *does* know JSL? Strange.
MnemonicJSR, // $a2 6502
MnemonicLDA, // $a3 6502
MnemonicLDX, // $a4 6502
MnemonicLDY, // $a5 6502
MnemonicLSR, // $a6 6502
"+F8AB_BROKEN_MVN", // $a7 65816 F8AB uses non-standard argument
"+F8AB_BROKEN_MVP", // $a8 65816 ordering with MVP/MVN
MnemonicNOP, // $a9 6502
MnemonicORA, // $aa 6502
MnemonicPEA, // $ab 65816
MnemonicPEI, // $ac 65816
MnemonicPER, // $ad 65816
MnemonicPHA, // $ae 6502
MnemonicPHB, // $af 65816
MnemonicPHD, // $b0 65816
MnemonicPHK, // $b1 65816
MnemonicPHP, // $b2 6502
MnemonicPHX, // $b3 65c02
MnemonicPHY, // $b4 65c02
MnemonicPLA, // $b5 6502
MnemonicPLB, // $b6 65816
MnemonicPLD, // $b7 65816
MnemonicPLP, // $b8 6502
MnemonicPLX, // $b9 65c02
MnemonicPLY, // $ba 65c02
MnemonicREP, // $bb 65816
MnemonicROL, // $bc 6502
MnemonicROR, // $bd 6502
MnemonicRTI, // $be 6502
MnemonicRTL, // $bf 65816
MnemonicRTS, // $c0 6502
MnemonicSBC, // $c1 6502
MnemonicSED, // $c2 6502 strange order - SED before SEC?
MnemonicSEC, // $c3 6502
MnemonicSEI, // $c4 6502
MnemonicSEP, // $c5 65816
MnemonicSTA, // $c6 6502
MnemonicSTP, // $c7 65816
MnemonicSTX, // $c8 6502
MnemonicSTY, // $c9 6502
MnemonicSTZ, // $ca 65c02
MnemonicTAX, // $cb 6502
MnemonicTAY, // $cc 6502
MnemonicTCD, // $cd 65816
MnemonicTCS, // $ce 65816
MnemonicTDC, // $cf 65816
MnemonicTRB, // $d0 65c02
MnemonicTSB, // $d1 65c02
MnemonicTSC, // $d2 65816
MnemonicTSX, // $d3 6502
MnemonicTXA, // $d4 6502
MnemonicTXS, // $d5 6502
MnemonicTXY, // $d6 65816
MnemonicTYA, // $d7 6502
MnemonicTYX, // $d8 65816
MnemonicWAI, // $d9 65816
// MnemonicWDM (65816) seems to be unknown to F8AB.
MnemonicXBA, // $da 65816
MnemonicXCE, // $db 65816
};
// PseudoOpcode table in Flash8-AssBlaster order
static const char *pseudo_opcode_table[] = {
NULL, // (la) $dc // NULL because ACME does not need a pseudo opcode for label defs
ACME_set_pc, // (ba) $dd
ACME_po_byte, // (by) $de
ACME_po_fill, // (br) $df
ACME_po_pet, // (tx) $e0
ACME_po_macro, // (md) $e1 (see AB_PSEUDOOFFSET_MACRODEF)
ACME_endmacro, // (de) $e2
ACME_macro_call, // (ma) $e3 (see AB_PSEUDOOFFSET_MACROCALL)
ACME_po_eof, // (st) $e4
// ACME_po_scr is not available in F8AB. Huh?!
"; ToACME: Cannot convert \\wa.\n", // (wa) $e5
ACME_po_to, // (on) $e6 (see AB_PSEUDOOFFSET_OUTFILE)
ACME_po_word, // (wo) $e7
"; ToACME: Cannot convert \\kc.\n", // (kc) $e8
ACME_po_rl, // (rl) $e9
ACME_po_rs, // (rs) $ea
ACME_po_al, // (al) $eb
ACME_po_as, // (as) $ec
// 0xed-0xfe are unused in F8AB
// (FIXME - true? I only checked 0xed)
};
// parse AssBlaster's packed number format. returns error bits.
//#define AB_NUMVAL_FLAGBIT 0x80 // 10000000 indicates packed number
#define F8AB_NUMVAL_ADD_65536 0x40 // 01000000
#define F8AB_NUMVAL_ADD_256 0x20 // 00100000
#define F8AB_NUMVAL_ADD_1 0x10 // 00010000
#define F8AB_NUMVAL_FORMATMASK 0x0c // 00001100
#define F8AB_NUMVAL__FORMAT_BIN 0x00 // 00000000
#define F8AB_NUMVAL__FORMAT_DEC 0x04 // 00000100
#define F8AB_NUMVAL__FORMAT_HEX 0x08 // 00001000
#define F8AB_NUMVAL__FORMAT_ILL 0x0c // 00001100 never used by F8AB
#define F8AB_NUMVAL_SIZEMASK 0x03 // 00000011
#define F8AB_NUMVAL__SIZE_0 0x00 // 00000000
#define F8AB_NUMVAL__SIZE_1 0x01 // 00000001
#define F8AB_NUMVAL__SIZE_2 0x02 // 00000010
#define F8AB_NUMVAL__SIZE_3 0x03 // 00000011
static int parse_number(void) // now GotByte = first byte of packed number
{
int flags = GotByte,
err_bits = 0;
unsigned long int value = 0,
add = 0;
// decode value
if (flags & F8AB_NUMVAL_ADD_65536)
add += 65536;
if (flags & F8AB_NUMVAL_ADD_256)
add += 256;
if (flags & F8AB_NUMVAL_ADD_1)
add += 1;
switch (flags & F8AB_NUMVAL_SIZEMASK) {
case F8AB_NUMVAL__SIZE_0: // no bytes follow (0, 1, 256, 257)
value = add;
break;
case F8AB_NUMVAL__SIZE_1: // one byte follows (2 to 511)
value = add + IO_get_byte();
break;
case F8AB_NUMVAL__SIZE_2: // two bytes follow (512 to 65535)
value = add + IO_get_le16();
break;
case F8AB_NUMVAL__SIZE_3: // three bytes follow (anything else)
value = add + IO_get_le24();
}
// continue parsing on next byte
IO_get_byte();
// decode output format
switch (flags & F8AB_NUMVAL_FORMATMASK) {
case F8AB_NUMVAL__FORMAT_BIN:
IO_put_byte('%');
AB_output_binary(value);
break;
case F8AB_NUMVAL__FORMAT_DEC:
fprintf(global_output_stream, "%lu", value);
break;
case F8AB_NUMVAL__FORMAT_HEX:
hex_fallback: IO_put_byte('$');
AB_output_hexadecimal(value);
break;
default: // unknown output format
// remember to warn
err_bits |= AB_ERRBIT_UNKNOWN_NUMBER_FORMAT;
goto hex_fallback;
}
return err_bits;
}
// config struct for shared ab code
struct vab f8ab_conf = {
VABFLAG_ADD_DOT,
parse_number,
pseudo_opcode_table,
mnemonic_table,
F8AB_ADDRESSING_MODES,
// meaning of input bytes (0x80-0xec differ between AB3 and F8AB)
0x80, // first mnemonic
92, // count
0xdc, // first pseudo opcode
17, // count
0xed, // first unused value
18 // count
};
// main
void f8ab_main(void) {
const char *header_message;
header_message = "Input does not have any known F8AB header.\n";
IO_set_input_padding(AB_ENDOFLINE);
IO_put_string(
"; ToACME: Adding pseudo opcode to enable 65816 opcodes:\n"
"\t!cpu 65816\n"
"; ToACME: Adding two macros to fix F8AB's non-standard argument order\n"
"; ToACME: concerning MVP/MVN. While the commands are assembled with\n"
"; ToACME: the destination bank byte first, the WDC docs say that in\n"
"; ToACME: source codes, the source bank byte is given first.\n"
"; ToACME: In other words: The macros make sure that assembling this\n"
"; ToACME: source with ACME will produce the same binary F8AB produced.\n"
"\t!macro F8AB_BROKEN_MVP .dest, .source {mvp .source, .dest}\n"
"\t!macro F8AB_BROKEN_MVN .dest, .source {mvn .source, .dest}\n"
);
IO_process_load_address();
// most AB files have this format:
// load_address_low, load_address_high, AB_ENDOFLINE, actual content
// newer versions of F8AB seem to use this:
// $ff, $00, $00, $03, AB_ENDOFLINE, actual content
if (IO_get_byte() == AB_ENDOFLINE) {
IO_get_byte(); // skip it and pre-read first valid byte
header_message = "Input has F8AB 1.0 header.\n";
} else {
if ((GotByte == 0)
&& (IO_get_byte() == 3)
&& (IO_get_byte() == AB_ENDOFLINE)) {
IO_get_byte();// skip and pre-read first valid byte
header_message = "Input has F8AB 1.2 header.\n";
}
}
fputs(header_message, stderr);
AB_main(&f8ab_conf);
}

198
contrib/toacme/src/giga.c Normal file
View File

@ -0,0 +1,198 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// "GigaAss" stuff
#include <stdio.h>
#include "config.h"
#include "acme.h"
#include "gighyp.h"
#include "mnemo.h"
#include "io.h"
#include "pet2iso.h"
// constants
// token-to-(pseudo)opcode conversion table (FIXME)
const char *giga_token[] = {
"FIXME-CALL", // $a0 .CALL
ACME_po_macro, // $a1 .MACRO (see MACRO_DEF_TOKEN below)
ACME_endmacro, // $a2 .ENDMACRO
NULL, // $a3 .GLOBAL (ACME does not need a pseudo
NULL, // $a4 .EQUATE opcode for label definitions)
// these are indented in the output file
ACME_po_byte, // $a5 .BYTE
ACME_po_word, // $a6 .WORD
ACME_po_fill, // $a7 .DS
ACME_po_pet, // $a8 .TEXT (see MACRO_TEXT below)
ACME_po_to, // $a9 .OBJECT (see MACRO_OUTFILE below)
ACME_set_pc, // $aa .BASE
"FIXME-CODE", // $ab .CODE
"FIXME-ON", // $ac .ON
"FIXME-GOTO", // $ad .GOTO
ACME_po_if, // $ae .IF
ACME_else, // $af .ELSE
ACME_endif, // $b0 .ENDIF
ACME_po_sl, // $b1 .SYMBOLS
"FIXME-LISTING", // $b2 .LISTING
ACME_po_eof, // $b3 .END
"FIXME-STOP", // $b4 .STOP
"FIXME-PAGE", // $b5 .PAGE
"FIXME-NOCODE", // $b6 .NOCODE
"FIXME-START", // $b7 .START
"FIXME-NOEXP", // $b8 .NOEXP
"FIXME-$b9", // $b9
"FIXME-$ba", // $ba
"FIXME-$bb", // $bb
"FIXME-$bc", // $bc
"FIXME-$bd", // $bd
"FIXME-$be", // $be
"FIXME-$bf", // $bf
// these are indented in the output file
MnemonicCPX, // $c0
MnemonicCPY, // $c1
MnemonicLDX, // $c2
MnemonicLDY, // $c3
MnemonicCMP, // $c4
MnemonicADC, // $c5
MnemonicAND, // $c6
MnemonicDEC, // $c7
MnemonicEOR, // $c8
MnemonicINC, // $c9
MnemonicLDA, // $ca
MnemonicASL, // $cb
MnemonicBIT, // $cc
MnemonicLSR, // $cd
MnemonicORA, // $ce
MnemonicROL, // $cf
MnemonicROR, // $d0
MnemonicSBC, // $d1
MnemonicSTA, // $d2
MnemonicSTX, // $d3
MnemonicSTY, // $d4
MnemonicJMP, // $d5
MnemonicJSR, // $d6
MnemonicTXA, // $d7
MnemonicTAX, // $d8
MnemonicTYA, // $d9
MnemonicTAY, // $da
MnemonicTSX, // $db
MnemonicTXS, // $dc
MnemonicPHP, // $dd
MnemonicPLP, // $de
MnemonicPHA, // $df
MnemonicPLA, // $e0
MnemonicBRK, // $e1
MnemonicRTI, // $e2
MnemonicRTS, // $e3
MnemonicNOP, // $e4
MnemonicCLC, // $e5
MnemonicSEC, // $e6
MnemonicCLI, // $e7
MnemonicSEI, // $e8
MnemonicCLV, // $e9
MnemonicCLD, // $ea
MnemonicSED, // $eb
MnemonicDEY, // $ec
MnemonicINY, // $ed
MnemonicDEX, // $ee
MnemonicINX, // $ef
MnemonicBPL, // $f0
MnemonicBMI, // $f1
MnemonicBVC, // $f2
MnemonicBVS, // $f3
MnemonicBCC, // $f4
MnemonicBCS, // $f5
MnemonicBNE, // $f6
MnemonicBEQ, // $f7
"FIXME-$f8", // $f8
"FIXME-$f9", // $f9
"FIXME-$fa", // $fa
"FIXME-$fb", // $fb
"FIXME-$fc", // $fc
"FIXME-$fd", // $fd
"FIXME-$fe", // $fe
"FIXME-$ff", // $ff
};
// functions
// I don't know whether it's correct, but I had to start somewhere
#define FIRST_TOKEN 0xa0
#define MACRO_DEF_TOKEN 0xa1 // ugly kluge to add '{' at end of statement
#define MACRO_TEXT 0xa8 // ugly kluge for giga string specialties
#define MACRO_OUTFILE 0xa9 // ugly kluge for adding outfile format
// process opcode or pseudo opcode (tokenized)
static int process_tokenized(void)
{
const char *token;
int flags = 0;
if (GotByte < FIRST_TOKEN) {
// macro call?
IO_put_byte('+'); // add macro call character
// fprintf(global_output_stream, "small value:$%x", GotByte);
} else {
switch (GotByte) {
case MACRO_DEF_TOKEN:
flags |= FLAG_ADD_LEFT_BRACE;
break;
case MACRO_TEXT:
flags |= FLAG_ADD_ZERO | FLAG_CHANGE_LEFTARROW;
break;
case MACRO_OUTFILE:
flags |= FLAG_ADD_CBM;
}
flags |= FLAG_INSERT_SPACE;
token = giga_token[GotByte - FIRST_TOKEN];
if (token != NULL)
IO_put_string(token);
IO_get_byte();
}
return flags;
}
// When tokens are known, maybe use the PseudoOpcode function from hypra?
// ...for now deleted
// [...]
// main routine for GigaAss conversion
void giga_main(void)
{
int indent;
IO_set_input_padding(0);
IO_process_load_address();
ACME_switch_to_pet();
// loop: once for every line in the file
while (!IO_reached_eof) {
// skip link pointer (if it's zero, report as end marker)
if (IO_get_le16() == 0)
IO_put_string("; ToACME: Found BASIC end marker.\n");
IO_get_le16(); // skip line number
// process line
IO_get_byte();
if ((GotByte == SPACE) || (GotByte == ';')
|| (GotByte == '\0') || (GotByte > 0x7f))
indent = 0;
else
indent = GigaHypra_label_definition();
// skip spaces
while (GotByte == SPACE)
IO_get_byte();
// if there is an opcode, process it
if ((GotByte != ';') && (GotByte != '\0')) {
GigaHypra_indent(indent);
GigaHypra_argument(process_tokenized());
}
// skip comment, if there is one
if (GotByte == ';')
GigaHypra_comment();
// end of line
IO_put_byte('\n');
}
}

158
contrib/toacme/src/gighyp.c Normal file
View File

@ -0,0 +1,158 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// stuff needed for both "Hypra-Ass" and "Giga-Ass"
#include "acme.h"
#include "gighyp.h"
#include "io.h"
#include "pet2iso.h"
// called with GotByte == ';'
void GigaHypra_comment(void)
{
// check whether anything follows (empty comments => empty lines)
if (IO_get_byte()) {
IO_put_byte(';');
do
IO_put_byte(PET2ISO(GotByte));
while (IO_get_byte());
}
}
// process operator
void GigaHypra_operator(void) // '!' was last read
{
char middle = PET2ISO(IO_get_byte());
if ((middle != ';') && (middle != '\0')) {
if (IO_get_byte() == '!') {
switch (middle) {
case 'n':
IO_put_byte('!');
break;
case 'o':
IO_put_byte('|');
break;
case 'a':
IO_put_byte('&');
break;
case '=':
IO_put_byte('=');
break;
case '<':
IO_put_string(" < ");
break;
case '>':
IO_put_string(" > ");
break;
default:
IO_put_byte('!');
IO_put_byte(middle);
IO_put_byte('!');
}
IO_get_byte();
} else {
IO_put_byte('!');
IO_put_byte(middle);
}
} else {
IO_put_byte('!');
}
// exit with unused byte pre-read
}
// output one or two TABs
void GigaHypra_indent(int indent)
{
if (indent < 8)
IO_put_byte('\t');
IO_put_byte('\t');
}
// Process opcode and arguments
void GigaHypra_argument(int flags)
{
int paren = 0; // number of open parentheses (to close)
// if needed, add separating space between opcode and argument
if ((flags & FLAG_INSERT_SPACE) && (GotByte != SPACE)
&& (GotByte != ';') && (GotByte != '\0'))
IO_put_byte(SPACE);
// character loop
while ((GotByte != ';') && (GotByte != '\0')) {
if (GotByte == '!')
GigaHypra_operator();
if (GotByte == '"') {
// don't parse inside quotes
IO_put_byte(GotByte);
IO_get_byte();
while ((GotByte != '\0') && (GotByte != '"')) {
if ((GotByte == 0x5f)
&& (flags & FLAG_CHANGE_LEFTARROW))
IO_put_string("\", 13,\"");
else
IO_put_byte(PET2ISO(GotByte));
IO_get_byte();
}
IO_put_byte('"');
if (GotByte == '"') {
IO_get_byte();
if ((GotByte == '\0')
&& (flags & FLAG_ADD_ZERO))
IO_put_string(", 0");
}
} else {
// most characters go here
switch (GotByte) {
case '(':
if (flags & FLAG_SKIP_OPENING) {
flags &= ~FLAG_SKIP_OPENING;
flags |= FLAG_SKIP_CLOSING;
} else {
paren++;
IO_put_byte(PET2ISO(GotByte));
}
break;
case ')':
if ((flags & FLAG_SKIP_CLOSING) && (paren == 0)) {
flags &= ~FLAG_SKIP_CLOSING;
} else {
paren--;
IO_put_byte(PET2ISO(GotByte));
}
break;
case SHIFTSPACE:
IO_put_byte(SPACE);
break;
default:
IO_put_byte(PET2ISO(GotByte));
}
IO_get_byte();
}
}
if (flags & FLAG_ADD_CBM)
IO_put_string(ACME_cbmformat);
if (flags & FLAG_ADD_LEFT_BRACE)
IO_put_byte('{');
}
// convert and send label name.
// returns length (for proper indentation).
int GigaHypra_label_definition(void)
{
int count = 0;
do {
IO_put_byte(PET2ISO(GotByte));
count++;
IO_get_byte();
} while ((GotByte != SPACE) && (GotByte != ';') && (GotByte != '\0'));
return count;
}

View File

@ -0,0 +1,33 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// stuff needed for both "Hypra-Ass" and "Giga-Ass"
#ifndef gigahypra_H
#define gigahypra_H
#include "config.h"
// Constants
#define FLAG_INSERT_SPACE (1u << 0) // insert space before arg
#define FLAG_ADD_LEFT_BRACE (1u << 1) // add '{' at end of statement
#define FLAG_ADD_CBM (1u << 2) // add file format indicator
#define FLAG_ADD_ZERO (1u << 3) // giga string specialty:
// open quote at end of line is *normal*. Closed quote: add ",0".
#define FLAG_SKIP_OPENING (1u << 4) // strip '(' before args
#define FLAG_SKIP_CLOSING (1u << 5) // strip ')' after args
#define FLAG_CHANGE_LEFTARROW (1u << 6) // giga string specialty:
// '_' (left arrow on C64) is transformed to CR (0x0d).
// Prototypes
extern void GigaHypra_comment(void);
extern void GigaHypra_operator(void);
extern void GigaHypra_indent(int indent);
extern void GigaHypra_argument(int flags);
extern int GigaHypra_label_definition(void);
#endif

219
contrib/toacme/src/hypra.c Normal file
View File

@ -0,0 +1,219 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// "HypraAss" stuff
#include <stdio.h>
#include "config.h"
#include "acme.h"
#include "gighyp.h"
#include "io.h"
#include "pet2iso.h"
// functions
// complain about unknown pseudo opcodes
static void complain(char a, char b)
{
IO_put_string("; ToACME: .");
if (a)
IO_put_byte(a);
if (b)
IO_put_byte(b);
IO_put_string(" cannot be converted\n");
}
// handle ".ba" and ".by"
static int process_po_b(char second)
{
int flags = 0;
switch (second) {
case 'a': // ".ba" = set base address
IO_put_string(ACME_set_pc);
break;
case 'y': // ".by" = insert bytes
IO_put_string(ACME_po_byte);
flags |= FLAG_INSERT_SPACE;
break;
default:
complain('b', second);
}
return flags;
}
// handle ".ei", ".el", ".en" and ".eq"
static int process_po_e(char second)
{
int flags = 0;
switch (second) {
case 'i': // ".ei" = endif
IO_put_string(ACME_endif);
break;
case 'l': // ".el" = else
IO_put_string(ACME_else);
break;
case 'n': // ".en" = end
IO_put_string(ACME_po_eof);
flags |= FLAG_INSERT_SPACE;
break;
case 'q': // ".eq" = label def
break;
default:
complain('e', second);
}
return flags;
}
// handle ".tx" and ".ts"
static int process_po_t(char second)
{
int flags = 0;
switch (second) {
case 'x': // ".tx" = insert string
IO_put_string(ACME_po_pet);
flags |= FLAG_INSERT_SPACE;
break;
case 's': // ".ts" = screen code string
IO_put_string(ACME_po_scr);
flags |= FLAG_INSERT_SPACE;
break;
default:
complain('t', second);
}
return flags;
}
#define ARE(a, b) ((first == a) && (second == b))
// process pseudo opcode
static int process_pseudo_opcode(void) // '.' was last read
{
int first,
second;
// get first byte. if illegal, complain and exit immediately
first = PET2ISO(IO_get_byte());
if ((first == SPACE) || (first == ';') || (first == '\0')) {
complain(first, '\0');
return 0;
}
// get second byte. if illegal, complain and exit immediately
second = PET2ISO(IO_get_byte());
if ((second == SPACE) || (second == ';') || (second == '\0')) {
complain(first, second);
return 0;
}
IO_get_byte();// pre-read unused byte
// check pseudo opcodes (switch/case was actually harder to read)
if (first == 'b') { // handle ".ba" and ".by"
process_po_b(second);
return FLAG_INSERT_SPACE;
}
if (first == 'e') // handle ".ei", ".el", ".en" and ".eq"
return process_po_e(second);
if (first == 't') // handle ".tx" and ".ts"
return process_po_t(second);
if (ARE('.', '.')) { // "..." = macro call
IO_put_string(ACME_macro_call);
return FLAG_INSERT_SPACE | FLAG_SKIP_OPENING;
}
if (ARE('m', 'a')) { // ".ma" = macro definition
IO_put_string(ACME_po_macro);
return FLAG_INSERT_SPACE | FLAG_SKIP_OPENING | FLAG_ADD_LEFT_BRACE;
}
if (ARE('o', 'b')) { // ".ob" = output to file
IO_put_string(ACME_po_to);
return FLAG_INSERT_SPACE | FLAG_ADD_CBM;
}
if (ARE('s', 'y')) { // ".sy" = symbol dump
IO_put_string(ACME_po_sl);
IO_put_string("\"symboldump.txt\";");
return 0;
}
if (ARE('i', 'f')) { // ".if" = cond. assembly
IO_put_string(ACME_po_if);
return FLAG_INSERT_SPACE | FLAG_ADD_LEFT_BRACE;
}
if (ARE('g', 'l')) // ".gl" = global label def
return 0;
if (ARE('a', 'p')) // ".ap" = append source
IO_put_string(ACME_po_source);
else if (ARE('r', 't')) // ".rt" = end of macro def
IO_put_string(ACME_endmacro);
else if (ARE('w', 'o')) // ".wo" = insert words
IO_put_string(ACME_po_word);
else
complain(first, second);
return FLAG_INSERT_SPACE;
}
// process opcode
static void real_opcode(void) // character was last read
{
IO_put_byte(PET2ISO(GotByte));
IO_get_byte();
if ((GotByte == SPACE) || (GotByte == ';') || (GotByte == '\0'))
return;
IO_put_byte(PET2ISO(GotByte));
IO_get_byte();
if ((GotByte == SPACE) || (GotByte == ';') || (GotByte == '\0'))
return;
IO_put_byte(PET2ISO(GotByte));
IO_get_byte(); // exit with unused byte pre-read
}
// main routine for HypraAss conversion
void hypra_main(void)
{
int indent;
IO_set_input_padding(0);
IO_process_load_address();
ACME_switch_to_pet();
// loop: once for every line in the file
while (!IO_reached_eof) {
// skip link pointer (if it's zero, report as end marker)
if (IO_get_le16() == 0)
IO_put_string("; ToACME: Found BASIC end marker.\n");
IO_get_le16(); // skip line number
// process line
IO_get_byte();
indent = 0;
if ((GotByte != SPACE) && (GotByte != ';') && (GotByte != '\0'))
indent = GigaHypra_label_definition();
// skip spaces
while (GotByte == SPACE)
IO_get_byte();
// if there is an opcode, process it
if ((GotByte != ';') && (GotByte != '\0')) {
GigaHypra_indent(indent);
// branch to relevant routine
if (GotByte == '.') {
GigaHypra_argument(process_pseudo_opcode());
} else {
real_opcode();
GigaHypra_argument(FLAG_INSERT_SPACE);
}
}
// skip comment, if there is one
if (GotByte == ';')
GigaHypra_comment();
// end of line
IO_put_byte('\n');
}
}

118
contrib/toacme/src/io.c Normal file
View File

@ -0,0 +1,118 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// input/output
#include <stdio.h>
#include "config.h"
#include "io.h"
// variables
int padding_value;
FILE *global_input_stream;
FILE *global_output_stream;
int GotByte = 0;
bool IO_reached_eof = FALSE;
// input functions
// set byte sent after EOF
inline void IO_set_input_padding(int pad)
{
padding_value = pad;
}
// fetch and buffer byte
int IO_get_byte(void)
{
int w;
if (IO_reached_eof) {
GotByte = padding_value;
} else {
w = getc(global_input_stream);
if (w == EOF)
IO_reached_eof = TRUE;
GotByte = w;
}
return GotByte;
}
// read little-endian 16-bit value
unsigned int IO_get_le16(void)
{
unsigned int result = IO_get_byte();
// CAUTION! using
// return(IO_get_byte() | (IO_get_byte() << 8));
// would be compiler-dependent
return result | (IO_get_byte() << 8);
}
// read little-endian 24-bit value
unsigned int IO_get_le24(void)
{
unsigned int result = IO_get_le16();
// CAUTION! see above
return result | (IO_get_byte() << 16);
}
// output functions
// output string
inline void IO_put_string(const char string[])
{
fputs(string, global_output_stream);
}
// write byte to output file
inline void IO_put_byte(char b)
{
putc(b, global_output_stream);
}
// output low nibble of argument as hexadecimal digit
static void put_low_nibble_hex(int v)
{
putc("0123456789abcdef"[v & 15], global_output_stream);
}
// output low byte of argument as two hexadecimal digits
void IO_put_low_byte_hex(int v)
{
put_low_nibble_hex(v >> 4);
put_low_nibble_hex(v);
}
// output low 16 bits of arg as four hexadecimal digits
void IO_put_low_16b_hex(int w)
{
IO_put_low_byte_hex(w >> 8);
IO_put_low_byte_hex(w);
}
// read load address from input file and write as comment to output file
void IO_process_load_address(void)
{
int load_address;
load_address = IO_get_le16();
IO_put_string("; ToACME: Original source code file had load address $");
IO_put_low_16b_hex(load_address);
IO_put_byte('\n');
}

33
contrib/toacme/src/io.h Normal file
View File

@ -0,0 +1,33 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// input/output
#ifndef io_H
#define io_H
#include <stdio.h>
#include "config.h"
// variables
extern int GotByte;
extern bool IO_reached_eof;
extern FILE *global_input_stream;
extern FILE *global_output_stream;
// prototypes
extern void IO_set_input_padding(int);
extern int IO_get_byte(void);
extern unsigned int IO_get_le16(void); // get little-endian 16-bit value
extern unsigned int IO_get_le24(void); // get little-endian 24-bit value
extern void IO_put_string(const char string[]);
extern void IO_put_byte(char b);
extern void IO_put_low_byte_hex(int v);
extern void IO_put_low_16b_hex(int w);
extern void IO_process_load_address(void);
#endif

77
contrib/toacme/src/main.c Normal file
View File

@ -0,0 +1,77 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2015 Marco Baye
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "acme.h"
#include "io.h"
#include "platform.h"
#include "version.h"
// guess what
int main(int argc, char *argv[])
{
// handle "toacme -h" and "toacme --help" just like "toacme"
if (argc == 2) {
if ((strcmp(argv[1], "-h") == 0)
|| (strcmp(argv[1], "--help") == 0))
argc = 1;
}
// "toacme" without any switches gives info and exits successfully
if (argc == 1) {
version_show_info(argv[0]);
return EXIT_SUCCESS;
}
// check argument count
if (argc != 4) {
fputs("Wrong number of arguments.\n", stderr);
return EXIT_FAILURE;
}
// check format id
if (version_parse_id(argv[1])) {
fputs("Unknown format id.\n", stderr);
return EXIT_FAILURE;
}
// be nice and ensure input and output are different
if (strcmp(argv[2], argv[3]) == 0) {
fputs("Input and output files must be different.\n", stderr);
return EXIT_FAILURE;
}
// try to open input file
global_input_stream = fopen(argv[2], "rb");
if (global_input_stream == NULL) {
fputs("Cannot open input file.\n", stderr);
return EXIT_FAILURE;
}
// try to open output file
global_output_stream = fopen(argv[3], "w");
if (global_output_stream == NULL) {
fputs("Cannot open output file.\n", stderr);
return EXIT_FAILURE;
}
// do the actual work
version_main();
// and then tidy up and exit
fclose(global_output_stream);
PLATFORM_SETFILETYPE_TEXT(argv[3]);
fclose(global_input_stream);
return EXIT_SUCCESS;
}

122
contrib/toacme/src/mnemo.c Normal file
View File

@ -0,0 +1,122 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// assembler mnemonics
// mnemonics of legal 6502 instructions
const char MnemonicADC[] = "adc",
MnemonicAND[] = "and",
MnemonicASL[] = "asl",
MnemonicBCC[] = "bcc",
MnemonicBCS[] = "bcs",
MnemonicBEQ[] = "beq",
MnemonicBIT[] = "bit",
MnemonicBMI[] = "bmi",
MnemonicBNE[] = "bne",
MnemonicBPL[] = "bpl",
MnemonicBRK[] = "brk",
MnemonicBVC[] = "bvc",
MnemonicBVS[] = "bvs",
MnemonicCLC[] = "clc",
MnemonicCLD[] = "cld",
MnemonicCLI[] = "cli",
MnemonicCLV[] = "clv",
MnemonicCMP[] = "cmp",
MnemonicCPX[] = "cpx",
MnemonicCPY[] = "cpy",
MnemonicDEC[] = "dec",
MnemonicDEX[] = "dex",
MnemonicDEY[] = "dey",
MnemonicEOR[] = "eor",
MnemonicINC[] = "inc",
MnemonicINX[] = "inx",
MnemonicINY[] = "iny",
MnemonicJMP[] = "jmp",
MnemonicJSR[] = "jsr",
MnemonicLDA[] = "lda",
MnemonicLDX[] = "ldx",
MnemonicLDY[] = "ldy",
MnemonicLSR[] = "lsr",
MnemonicNOP[] = "nop",
MnemonicORA[] = "ora",
MnemonicPHA[] = "pha",
MnemonicPHP[] = "php",
MnemonicPLA[] = "pla",
MnemonicPLP[] = "plp",
MnemonicROL[] = "rol",
MnemonicROR[] = "ror",
MnemonicRTI[] = "rti",
MnemonicRTS[] = "rts",
MnemonicSBC[] = "sbc",
MnemonicSEC[] = "sec",
MnemonicSED[] = "sed",
MnemonicSEI[] = "sei",
MnemonicSTA[] = "sta",
MnemonicSTX[] = "stx",
MnemonicSTY[] = "sty",
MnemonicTAX[] = "tax",
MnemonicTAY[] = "tay",
MnemonicTSX[] = "tsx",
MnemonicTXA[] = "txa",
MnemonicTXS[] = "txs",
MnemonicTYA[] = "tya";
// mnemonics of undocumented ("illegal") 6502 instructions
const char MnemonicSLO[] = " SLO",
MnemonicRLA[] = " RLA",
MnemonicSRE[] = " SRE",
MnemonicRRA[] = " RRA",
MnemonicSAX[] = " SAX",
MnemonicLAX[] = " LAX",
MnemonicDCP[] = " DCP",
MnemonicISC[] = " ISC",
MnemonicANC[] = " ANC",
MnemonicARR[] = " ARR",
MnemonicASR[] = " ASR",
MnemonicSBX[] = " SBX",
MnemonicDOP[] = " DOP",
MnemonicTOP[] = " TOP",
MnemonicSHX[] = " SHX",
MnemonicJAM[] = " JAM";
// mnemonics of 65c02 instructions
const char MnemonicBRA[] = "bra",
MnemonicPHX[] = "phx",
MnemonicPHY[] = "phy",
MnemonicPLX[] = "plx",
MnemonicPLY[] = "ply",
MnemonicSTZ[] = "stz",
MnemonicTRB[] = "trb",
MnemonicTSB[] = "tsb";
// mnemonics of 65816 instructions
const char MnemonicJML[] = "jml",
MnemonicJSL[] = "jsl",
MnemonicMVN[] = "mvn",
MnemonicMVP[] = "mvp",
MnemonicPEI[] = "pei",
MnemonicBRL[] = "brl",
MnemonicPER[] = "per",
MnemonicCOP[] = "cop",
MnemonicPEA[] = "pea",
MnemonicREP[] = "rep",
MnemonicSEP[] = "sep",
MnemonicPHB[] = "phb",
MnemonicPHD[] = "phd",
MnemonicPHK[] = "phk",
MnemonicPLB[] = "plb",
MnemonicPLD[] = "pld",
MnemonicRTL[] = "rtl",
MnemonicSTP[] = "stp",
MnemonicTCD[] = "tcd",
MnemonicTCS[] = "tcs",
MnemonicTDC[] = "tdc",
MnemonicTSC[] = "tsc",
MnemonicTXY[] = "txy",
MnemonicTYX[] = "tyx",
MnemonicWAI[] = "wai",
MnemonicWDM[] = "wdm",
MnemonicXBA[] = "xba",
MnemonicXCE[] = "xce";

View File

@ -0,0 +1,74 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// 6502 mnemonics
#ifndef mnemo_H
#define mnemo_H
// mnemonics of legal 6502 instructions
extern const char MnemonicADC[], MnemonicSBC[];
extern const char MnemonicAND[], MnemonicEOR[], MnemonicORA[];
extern const char MnemonicASL[], MnemonicLSR[];
extern const char MnemonicBCC[], MnemonicBCS[];
extern const char MnemonicBEQ[], MnemonicBNE[];
extern const char MnemonicBMI[], MnemonicBPL[];
extern const char MnemonicBRK[], MnemonicRTI[];
extern const char MnemonicBVC[], MnemonicBVS[];
extern const char MnemonicCLC[], MnemonicSEC[];
extern const char MnemonicCLD[], MnemonicSED[];
extern const char MnemonicCLI[], MnemonicSEI[];
extern const char MnemonicBIT[], MnemonicCLV[], MnemonicNOP[];
extern const char MnemonicCMP[], MnemonicCPX[], MnemonicCPY[];
extern const char MnemonicDEC[], MnemonicDEX[], MnemonicDEY[];
extern const char MnemonicINC[], MnemonicINX[], MnemonicINY[];
extern const char MnemonicJMP[], MnemonicJSR[], MnemonicRTS[];
extern const char MnemonicLDA[], MnemonicLDX[], MnemonicLDY[];
extern const char MnemonicPHA[], MnemonicPLA[];
extern const char MnemonicPHP[], MnemonicPLP[];
extern const char MnemonicROL[], MnemonicROR[];
extern const char MnemonicSTA[], MnemonicSTX[], MnemonicSTY[];
extern const char MnemonicTSX[], MnemonicTXA[], MnemonicTAY[];
extern const char MnemonicTYA[], MnemonicTAX[], MnemonicTXS[];
// mnemonics of undocumented ("illegal") 6502 instructions
extern const char MnemonicANC[], MnemonicARR[], MnemonicASR[];
extern const char MnemonicDCP[], MnemonicDOP[], MnemonicISC[];
extern const char MnemonicJAM[], MnemonicLAX[], MnemonicRLA[];
extern const char MnemonicRRA[], MnemonicSAX[], MnemonicSBX[];
extern const char MnemonicSLO[], MnemonicSRE[], MnemonicTOP[];
extern const char MnemonicSHX[];
// mnemonics of 65c02 instructions
extern const char MnemonicBRA[];
extern const char MnemonicPHX[], MnemonicPHY[];
extern const char MnemonicPLX[], MnemonicPLY[];
extern const char MnemonicSTZ[];
extern const char MnemonicTRB[], MnemonicTSB[];
// mnemonics of 65816 instructions
extern const char MnemonicJML[], MnemonicJSL[];
extern const char MnemonicMVN[], MnemonicMVP[];
extern const char MnemonicPEI[];
extern const char MnemonicBRL[];
extern const char MnemonicPER[];
extern const char MnemonicCOP[];
extern const char MnemonicPEA[];
extern const char MnemonicREP[], MnemonicSEP[];
extern const char MnemonicPHB[];
extern const char MnemonicPHD[];
extern const char MnemonicPHK[];
extern const char MnemonicPLB[];
extern const char MnemonicPLD[];
extern const char MnemonicRTL[];
extern const char MnemonicSTP[];
extern const char MnemonicTCD[], MnemonicTCS[];
extern const char MnemonicTDC[], MnemonicTSC[];
extern const char MnemonicTXY[], MnemonicTYX[];
extern const char MnemonicWAI[];
extern const char MnemonicWDM[];
extern const char MnemonicXBA[], MnemonicXCE[];
#endif

277
contrib/toacme/src/obj.c Normal file
View File

@ -0,0 +1,277 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// disassembly stuff
#include <stdio.h>
#include "config.h"
#include "acme.h"
#include "mnemo.h"
#include "io.h"
// constants
// 6502 code table (mnemonics only) *illegals*
const char *mnemo_of_code[] = {
MnemonicBRK, MnemonicORA, " JAM;0x02", MnemonicSLO, // $00-$03
" DOP;0x04", MnemonicORA, MnemonicASL, MnemonicSLO, // $04-$07
MnemonicPHP, MnemonicORA, MnemonicASL, "!by$0b;ANC#", // $08-$0b
" TOP;0x0c", MnemonicORA, MnemonicASL, MnemonicSLO, // $0c-$0f
MnemonicBPL, MnemonicORA, " JAM;0x12", MnemonicSLO, // $10-$13
" DOP;0x14", MnemonicORA, MnemonicASL, MnemonicSLO, // $14-$17
MnemonicCLC, MnemonicORA, " NOP;0x1a", MnemonicSLO, // $18-$1b
" TOP;0x1c", MnemonicORA, MnemonicASL, MnemonicSLO, // $1c-$1f
MnemonicJSR, MnemonicAND, " JAM;0x22", MnemonicRLA, // $20-$23
MnemonicBIT, MnemonicAND, MnemonicROL, MnemonicRLA, // $24-$27
MnemonicPLP, MnemonicAND, MnemonicROL, "!by$2b;ANC#", // $28-$2b
MnemonicBIT, MnemonicAND, MnemonicROL, MnemonicRLA, // $2c-$2f
MnemonicBMI, MnemonicAND, " JAM;0x32", MnemonicRLA, // $30-$33
" DOP;0x34", MnemonicAND, MnemonicROL, MnemonicRLA, // $34-$37
MnemonicSEC, MnemonicAND, " NOP;0x3a", MnemonicRLA, // $38-$3b
" TOP;0x3c", MnemonicAND, MnemonicROL, MnemonicRLA, // $3c-$3f
MnemonicRTI, MnemonicEOR, " JAM;0x42", MnemonicSRE, // $40-$43
" DOP;0x44", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $44-$47
MnemonicPHA, MnemonicEOR, MnemonicLSR, MnemonicASR, // $48-$4b
MnemonicJMP, MnemonicEOR, MnemonicLSR, MnemonicSRE, // $4c-$4f
MnemonicBVC, MnemonicEOR, " JAM;0x52", MnemonicSRE, // $50-$53
" DOP;0x54", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $54-$57
MnemonicCLI, MnemonicEOR, " NOP;0x5a", MnemonicSRE, // $58-$5b
" TOP;0x5c", MnemonicEOR, MnemonicLSR, MnemonicSRE, // $5c-$5f
MnemonicRTS, MnemonicADC, " JAM;0x62", MnemonicRRA, // $60-$63
" DOP;0x64", MnemonicADC, MnemonicROR, MnemonicRRA, // $64-$67
MnemonicPLA, MnemonicADC, MnemonicROR, MnemonicARR, // $68-$6b
MnemonicJMP, MnemonicADC, MnemonicROR, MnemonicRRA, // $6c-$6f
MnemonicBVS, MnemonicADC, " JAM;0x72", MnemonicRRA, // $70-$73
" DOP;0x74", MnemonicADC, MnemonicROR, MnemonicRRA, // $74-$77
MnemonicSEI, MnemonicADC, " NOP;0x7a", MnemonicRRA, // $78-$7b
" TOP;0x7c", MnemonicADC, MnemonicROR, MnemonicRRA, // $7c-$7f
" DOP;0x80", MnemonicSTA, " DOP;0x82", MnemonicSAX, // $80-$83
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $84-$87
MnemonicDEY, " DOP;0x89", MnemonicTXA, NULL, // $88-$8b
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $8c-$8f
MnemonicBCC, MnemonicSTA, " JAM;0x92", NULL, // $90-$93
MnemonicSTY, MnemonicSTA, MnemonicSTX, MnemonicSAX, // $94-$97
MnemonicTYA, MnemonicSTA, MnemonicTXS, NULL, // $98-$9b
NULL, MnemonicSTA, MnemonicSHX, NULL, // $9c-$9f
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $a0-$a3
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $a4-$a7
MnemonicTAY, MnemonicLDA, MnemonicTAX, NULL, // $a8-$ab
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $ac-$af
MnemonicBCS, MnemonicLDA, " JAM;0xb2", MnemonicLAX, // $b0-$b3
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $b4-$b7
MnemonicCLV, MnemonicLDA, MnemonicTSX, NULL, // $b8-$bb
MnemonicLDY, MnemonicLDA, MnemonicLDX, MnemonicLAX, // $bc-$bf
MnemonicCPY, MnemonicCMP, " DOP;0xc2", MnemonicDCP, // $c0-$c3
MnemonicCPY, MnemonicCMP, MnemonicDEC, MnemonicDCP, // $c4-$c7
MnemonicINY, MnemonicCMP, MnemonicDEX, MnemonicSBX, // $c8-$cb
MnemonicCPY, MnemonicCMP, MnemonicDEC, MnemonicDCP, // $cc-$cf
MnemonicBNE, MnemonicCMP, " JAM;0xd2", MnemonicDCP, // $d0-$d3
" DOP;0xd4", MnemonicCMP, MnemonicDEC, MnemonicDCP, // $d4-$d7
MnemonicCLD, MnemonicCMP, " NOP;0xda", MnemonicDCP, // $d8-$db
" TOP;0xdc", MnemonicCMP, MnemonicDEC, MnemonicDCP, // $dc-$df
MnemonicCPX, MnemonicSBC, " DOP;0xe2", MnemonicISC, // $e0-$e3
MnemonicCPX, MnemonicSBC, MnemonicINC, MnemonicISC, // $e4-$e7
MnemonicINX, MnemonicSBC, MnemonicNOP, "!by$eb;SBC#", // $e8-$eb
MnemonicCPX, MnemonicSBC, MnemonicINC, MnemonicISC, // $ec-$ef
MnemonicBEQ, MnemonicSBC, " JAM;0xf2", MnemonicISC, // $f0-$f3
" DOP;0xf4", MnemonicSBC, MnemonicINC, MnemonicISC, // $f4-$f7
MnemonicSED, MnemonicSBC, " NOP;0xfa", MnemonicISC, // $f8-$fb
" TOP;0xfc", MnemonicSBC, MnemonicINC, MnemonicISC, // $fc-$ff
};
// output 2-digit hex argument with correct addressing mode
static void put_argument2(const char pre[], int byte, const char post[])
{
IO_put_string(pre);
IO_put_low_byte_hex(byte);
IO_put_string(post);
}
// output 4-digit hex argument with correct addressing mode
static void put_argument4(const char pre[], int word, const char post[])
{
IO_put_string(pre);
IO_put_low_16b_hex(word);
IO_put_string(post);
}
static int pc; // needed by "relative" addressing mode handler
// addressing mode handler functions
// all of these output the opcode's argument and return the number to add
// to the program counter
// addressing mode handler function for 1-byte-instructions
static int am_implied(void)
{
return 1;
}
// addressing mode handler functions for 2-byte-instructions
static int am_immediate(void)
{
put_argument2(" #$", IO_get_byte(), "");
if (GotByte > 15) {
fprintf(global_output_stream, " ; (= %d", GotByte);
if ((GotByte > 31) && (GotByte != 127))
fprintf(global_output_stream, " = '%c'", GotByte);
IO_put_byte(')');
}
return 2;
}
static int am_absolute8(void)
{
put_argument2(" $", IO_get_byte(), "");
return 2;
}
static int am_abs_x8(void)
{
put_argument2(" $", IO_get_byte(), ", x");
return 2;
}
static int am_abs_y8(void)
{
put_argument2(" $", IO_get_byte(), ", y");
return 2;
}
static int am_indirect_x(void)
{
put_argument2(" ($", IO_get_byte(), ", x)");
return 2;
}
static int am_indirect_y(void)
{
put_argument2(" ($", IO_get_byte(), "), y");
return 2;
}
static int am_relative(void)
{
put_argument4(" L", pc + 2 + (signed char) IO_get_byte(), "");
return 2;
}
// addressing mode handler functions for 3-byte-instructions
static int am_absolute16(void)
{
put_argument4(" L", IO_get_le16(), "");
return 3;
}
static int am_abs_x16(void)
{
put_argument4(" L", IO_get_le16(), ", x");
return 3;
}
static int am_abs_y16(void)
{
put_argument4(" L", IO_get_le16(), ", y");
return 3;
}
static int am_indirect16(void)
{
put_argument4(" (L", IO_get_le16(), ")");
return 3;
}
// 6502 code table (addressing mode handler functions)
// all ANC/DOP/TOP are given as "implied", so the argument is not processed
int (*addressing_mode_of_code[])(void) = {
am_implied, am_indirect_x, am_implied, am_indirect_x, // $00-$03
am_implied, am_absolute8, am_absolute8, am_absolute8, // $04-$07
am_implied, am_immediate, am_implied, am_implied, // $08-$0b
am_implied, am_absolute16, am_absolute16, am_absolute16, // $0c-$0f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $10-$13
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $14-$17
am_implied, am_abs_y16, am_implied, am_abs_y16, // $18-$1b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $1c-$1f
am_absolute16, am_indirect_x, am_implied, am_indirect_x, // $20-$23
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $24-$27
am_implied, am_immediate, am_implied, am_implied, // $28-$2b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $2c-$2f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $30-$33
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $34-$37
am_implied, am_abs_y16, am_implied, am_abs_y16, // $38-$3b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $3c-$3f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $40-$43
am_implied, am_absolute8, am_absolute8, am_absolute8, // $44-$47
am_implied, am_immediate, am_implied, am_immediate, // $48-$4b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $4c-$4f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $50-$53
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $54-$57
am_implied, am_abs_y16, am_implied, am_abs_y16, // $58-$5b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $5c-$5f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $60-$63
am_implied, am_absolute8, am_absolute8, am_absolute8, // $64-$67
am_implied, am_immediate, am_implied, am_immediate, // $68-$6b
am_indirect16, am_absolute16, am_absolute16, am_absolute16, // $6c-$6f
am_relative, am_indirect_y, am_implied, am_indirect_y, // $70-$73
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $74-$77
am_implied, am_abs_y16, am_implied, am_abs_y16, // $78-$7b
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $7c-$7f
am_implied, am_indirect_x, am_implied, am_indirect_x, // $80-$83
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $84-$87
am_implied, am_implied, am_implied, am_implied, // $88-$8b
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $8c-$8f
am_relative, am_indirect_y, am_implied, am_implied, // $90-$93
am_abs_x8, am_abs_x8, am_abs_y8, am_abs_y8, // $94-$97
am_implied, am_abs_y16, am_implied, am_implied, // $98-$9b
am_implied, am_abs_x16, am_abs_y16, am_implied, // $9c-$9f
am_immediate, am_indirect_x, am_immediate, am_indirect_x, // $a0-$a3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $a4-$a7
am_implied, am_immediate, am_implied, am_implied, // $a8-$ab
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $ac-$af
am_relative, am_indirect_y, am_implied, am_indirect_y, // $b0-$b3
am_abs_x8, am_abs_x8, am_abs_y8, am_abs_y8, // $b4-$b7
am_implied, am_abs_y16, am_implied, am_implied, // $b8-$bb
am_abs_x16, am_abs_x16, am_abs_y16, am_abs_y16, // $bc-$bf
am_immediate, am_indirect_x, am_implied, am_indirect_x, // $c0-$c3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $c4-$c7
am_implied, am_immediate, am_implied, am_immediate, // $c8-$cb
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $cc-$cf
am_relative, am_indirect_y, am_implied, am_indirect_y, // $d0-$d3
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $d4-$d7
am_implied, am_abs_y16, am_implied, am_abs_y16, // $d8-$db
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $dc-$df
am_immediate, am_indirect_x, am_implied, am_indirect_x, // $e0-$e3
am_absolute8, am_absolute8, am_absolute8, am_absolute8, // $e4-$e7
am_implied, am_immediate, am_implied, am_implied, // $e8-$eb
am_absolute16, am_absolute16, am_absolute16, am_absolute16, // $ec-$ef
am_relative, am_indirect_y, am_implied, am_indirect_y, // $f0-$f3
am_implied, am_abs_x8, am_abs_x8, am_abs_x8, // $f4-$f7
am_implied, am_abs_y16, am_implied, am_abs_y16, // $f8-$fb
am_implied, am_abs_x16, am_abs_x16, am_abs_x16, // $fc-$ff
};
// output mnemonic of given byte
static void output_mnemonic(int byte)
{
const char *mnemo = mnemo_of_code[byte];
if (mnemo)
IO_put_string(mnemo);
else
put_argument2("$", byte, "");
}
// main routine for disassembly
void obj_main(void)
{
IO_set_input_padding(0);
// process load address
pc = IO_get_le16();
put_argument4("\t\t*=$", pc, "\n");
IO_get_byte();
while (!IO_reached_eof) {
put_argument4("L", pc, "\t\t");
output_mnemonic(GotByte);
pc += addressing_mode_of_code[GotByte]();
IO_put_byte('\n');
IO_get_byte();
}
// report end-of-file
IO_put_string("; ToACME: Reached end-of-file.\n");
}

View File

@ -0,0 +1,46 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// Converting CBM PetSCII code to ISO 8859/1
#include "pet2iso.h"
// constants
// conversion table
const char PET2ISO_table[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};

View File

@ -0,0 +1,18 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// Converting CBM PetSCII code to ISO 8859/1
#ifndef pet2iso_H
#define pet2iso_H
#include "config.h"
// constants
extern const char PET2ISO_table[256]; // conversion table
#define PET2ISO(v) (PET2ISO_table[(unsigned char) v])
#endif

View File

@ -0,0 +1,34 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// Platform specific stuff
#include "platform.h"
#ifdef __riscos__
//
// RISC OS
//
#include <kernel.h> // defines _kernel_swi_regs
#define OS_FILE 0x00008 // constant to call relevant SWI
// setting the created files' types
void platform_set_file_type_text(const char *filename)
{
_kernel_swi_regs register_set;
register_set.r[0] = 18;// = SetFileType
register_set.r[1] = (int) filename;
register_set.r[2] = 0xfff;
_kernel_swi(OS_FILE, &register_set, &register_set);
}
#else
//
// other OS (not that much here)
//
#endif

View File

@ -0,0 +1,24 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2015 Marco Baye
// Have a look at "main.c" for further info
//
// Platform specific stuff
#ifndef platform_H
#define platform_H
// check for RISC OS
#ifdef __riscos__
#define PLATFORM_VERSION "Ported to RISC OS by Marco Baye."
#define PLATFORM_SETFILETYPE_TEXT(a) platform_set_file_type_text(a);
extern void platform_set_file_type_text(const char *filename);
#endif
// all other platforms
#ifndef PLATFORM_VERSION
#define PLATFORM_VERSION "Platform independent version."
#define PLATFORM_SETFILETYPE_TEXT(a)
#endif
#endif

120
contrib/toacme/src/prof.c Normal file
View File

@ -0,0 +1,120 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2019 Marco Baye
// Have a look at "main.c" for further info
//
// "Professional Ass by Oliver Stiller" stuff (NOT "Profi-Ass" by Data Becker!)
// Kickoff:
// http://www.forum64.de/wbb4/index.php?thread/60047-toacme-demn%C3%A4chst-als-win32-release/
#include <stdio.h>
//#include "config.h"
//#include "acme.h"
//#include "mnemo.h"
#include "io.h"
#include "scr2iso.h"
// format of input files:
// load address, lo
// load address, hi
// for each line:
// total line length, including this byte
// amount of indentation
// actual line as screen code (this part might be missing in case of empty line)
// total line length, including this byte (yes, the same value again, for upscrolling)
// that's it!
// special directives:
// '.' is for pseudo opcodes?
// .setpc is *=
// .fill (length, data) ?
// .b is !by, .w is !wo, .macro reads a macro argument?
// .goto is used to skip macro definitions?!
// what do .begin and .end do? local label scope?
// .print str$(*-$1060) wow... O_o
// '-' prefix means local label definition?
// '+' prefix means global label definition?
// '_' starts a macro definition? ".endmacro" ends definition?
// '*' prefix is a macro call?
#define TABSIZE 8 // anything else is heresy
#define REV_START ";-=#"
#define REV_END "#=-"
enum linestate {
LINESTATE_REMOVEPLUS, // before label def
LINESTATE_DOUBLENEXTSPACE, // entered when removing '+'
LINESTATE_NOTHINGSPECIAL // afterward
};
// main
void prof_main(void)
{
int length1,
indent,
ii,
byte,
hibit,
length2;
enum linestate linestate;
IO_set_input_padding(0);
IO_process_load_address();
for (;;) {
length1 = IO_get_byte();
if (length1 == EOF)
break;
if (length1 < 3) {
fprintf(stderr, "Error: Short line (%d bytes), stopping.\n", length1);
return;
}
// read amount of indentation and output tabs/spaces
indent = IO_get_byte();
if (indent < 0) {
fprintf(stderr, "Error: Negative indentation (%d)\n", indent);
} else {
for (ii = 0; ii + TABSIZE <= indent; ii += TABSIZE)
IO_put_byte('\t');
for (; ii < indent; ii++)
IO_put_byte(' ');
}
// now convert line
hibit = 0;
linestate = LINESTATE_REMOVEPLUS;
for (ii = 0; ii < length1 - 3; ii++) {
byte = IO_get_byte();
if ((byte & 128) != hibit) {
hibit = byte & 128;
IO_put_string(hibit ? REV_START : REV_END);
}
byte = SCR2ISO(byte & 127);
// outside of comments, remove leading '+'
if (hibit == 0) {
if (byte == '+') {
if (linestate == LINESTATE_REMOVEPLUS) {
linestate = LINESTATE_DOUBLENEXTSPACE;
continue; // eat '+'
}
} else if (byte == ' ') {
if (linestate == LINESTATE_DOUBLENEXTSPACE) {
linestate = LINESTATE_NOTHINGSPECIAL;
IO_put_byte(' '); // add space to compensate for eaten '+'
}
} else {
// any other char -> do not remove any '+'
if (linestate == LINESTATE_REMOVEPLUS) {
linestate = LINESTATE_NOTHINGSPECIAL;
}
}
}
IO_put_byte(byte);
}
if (hibit)
IO_put_string(REV_END);
// and add newline
IO_put_byte('\n');
// now check second length byte
length2 = IO_get_byte();
if (length1 != length2)
fprintf(stderr, "Error: Length bytes differ (%d != %d)\n", length1, length2);
}
}

View File

@ -0,0 +1,46 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// Converting CBM screen code to ISO 8859/1
#include "scr2iso.h"
// constants
// conversion table
const char SCR2ISO_table[256] = {
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};

View File

@ -0,0 +1,17 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// Converting CBM screen code to ISO 8859/1
#ifndef scr2iso_H
#define scr2iso_H
#include "config.h"
// constants
extern const char SCR2ISO_table[256]; // Conversion table
#define SCR2ISO(v) (SCR2ISO_table[(unsigned char) v])
#endif

View File

@ -0,0 +1,99 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2019 Marco Baye
// Have a look at "main.c" for further info
//
// Version
#define RELEASE_NUMBER "0.15" // change before release (FIXME)
#define CHANGE_DATE "25 Apr" // change before release
#define CHANGE_YEAR "2019" // change before release
#define HOME_PAGE "http://sourceforge.net/projects/acme-crossass/"
// "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define FILE_TAG ";ACME 0.96.4" // check before release
#include <stdio.h>
#include <string.h>
#include "io.h"
#include "platform.h"
// variables
void (*client_main)(void) = NULL;
// functions
// show version info and usage
void version_show_info(const char program_name[]) {
printf(
"\n"
"ToACME - converts other assemblers' source codes to ACME format.\n"
"Release " RELEASE_NUMBER " (" CHANGE_DATE " " CHANGE_YEAR "), Copyright (C) 1999-" CHANGE_YEAR " Marco Baye.\n"
PLATFORM_VERSION "\n"
"Thanks to Stefan Hübner for fixing the AssBlaster macro conversion code.\n"
"Thanks to Andreas Paul for helping with the Giga-Assembler mode.\n"
"Thanks to Arndt Dettke for helping with the Hypra-Assembler mode.\n"
"Thanks to Hoogo for helping with the Professional Assembler mode.\n"
"\n"
"The newest version can be found at the ACME homepage:\n"
HOME_PAGE "\n"
"\n"
"ToACME comes with ABSOLUTELY NO WARRANTY; for details read the help file.\n"
"This is free software, and you are welcome to redistribute it under\n"
"certain conditions; as outlined in the GNU General Public License.\n"
"\n"
"Syntax: %s FORMAT_ID INPUT_FILE OUTPUT_FILE\n"
"\n"
"Format ID: source file format quality\n"
"--------------------------------------------------\n"
"object object code files poor\n"
"hypra C64: Hypra-Assembler ok\n"
"giga C64: Giga-Assembler ok\n"
"vis C64: VisAss untested\n"
"ab3 C64: AssBlaster 3.0 to 3.2 good\n"
"f8ab C64: Flash8-AssBlaster ok\n"
"prof C64: Professional Assembler poor (work in progress)\n"
"\n"
, program_name);
}
extern void visass_main(void);
extern void ab3_main(void);
extern void f8ab_main(void);
extern void giga_main(void);
extern void hypra_main(void);
extern void obj_main(void);
extern void prof_main(void);
// check id string. returns whether illegal.
int version_parse_id(const char id[])
{
if (strcmp(id, "vis") == 0)
client_main = visass_main;
else if (strcmp(id, "ab3") == 0)
client_main = ab3_main;
else if (strcmp(id, "f8ab") == 0)
client_main = f8ab_main;
else if (strcmp(id, "giga") == 0)
client_main = giga_main;
else if (strcmp(id, "hypra") == 0)
client_main = hypra_main;
else if (strcmp(id, "object") == 0)
client_main = obj_main;
else if (strcmp(id, "prof") == 0)
client_main = prof_main;
return client_main ? 0 : 1;
}
// do the actual work
void version_main(void)
{
IO_put_string(
FILE_TAG "\n"
"; ToACME: Converted by ToACME, release " RELEASE_NUMBER ".\n"
);
client_main();
}

View File

@ -0,0 +1,16 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2006 Marco Baye
// Have a look at "main.c" for further info
//
// version
#ifndef version_H
#define version_H
// prototypes
extern void version_show_info(const char[]);
extern int version_parse_id(const char[]);
extern void version_main(void);
#endif

49
contrib/toacme/src/vis.c Normal file
View File

@ -0,0 +1,49 @@
// ToACME - converts other source codes to ACME format.
// Copyright (C) 1999-2015 Marco Baye
// Have a look at "main.c" for further info
//
// VisAss stuff
#include "ab.h"
#include "acme.h"
#include "io.h"
static int number_parser(void)
{
return 0;
}
// config struct for shared VisAss/AB code
struct vab visass_conf = {
VABFLAG_HASLENGTHBYTE,
number_parser,
visass_ab3_pseudo_opcode_table,
visass_ab3_mnemonic_table,
2, // we fake absolute addressing because VisAss does not encode the addr mode
// meaning of input bytes (0x80-0xec differ between VisAss, AB3 and F8AB)
0, // first mnemonic
0x48, // count
0x48, // first pseudo opcode
14, // count
0x100, // first unused value (dummy)
1 // count (dummy)
};
// main
void visass_main(void)
{
IO_set_input_padding(AB_ENDOFLINE);
visass_ab3_illegals();
IO_process_load_address();
// first byte after load address should be AB_ENDOFLINE in VisAss sources
if (IO_get_byte() == AB_ENDOFLINE) {
IO_get_byte(); // skip it and pre-read first valid byte
fputs("Input has VisAss header.\n", stderr);
} else {
fputs("Input does not have any known VisAss header.\n", stderr);
}
AB_main(&visass_conf);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

View File

@ -0,0 +1,58 @@
#/bin/bash
#
# Get release and create RC-File
#
function DEBUG()
{
[ "$_DEBUG" == "on" ] && $@
}
function pause()
{
read -p "Weiter mit Eingabe" $a
}
FILE="resource.rc"
RELEASE=`grep -m1 "define RELEASE" ../version.c | cut -f2 | tr -d '"'`
DEBUG echo $RELEASE
VERSION=${RELEASE//./,},0
DEBUG echo $VERSION
FILEVERSION=\""$RELEASE ${CODENAME//\"/}"\"
DEBUG echo $FILEVERSION
CHANGE_YEAR=`grep -m1 "define CHANGE_YEAR" ../version.c | cut -f2 | tr -d '"'`
DEBUG echo $CHANGE_YEAR
cat << EndOfFile > $FILE
// Iconfile (64/32/16)
ID ICON "Logo.ico"
// Infos for windows
1 VERSIONINFO
FILEVERSION $VERSION
PRODUCTVERSION $VERSION
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", "Smørbrød Software"
VALUE "FileDescription", "ToAcme Converter"
VALUE "FileVersion", $FILEVERSION
VALUE "InternalName", "ToACME Converter"
VALUE "LegalCopyright", "Copyright © $CHANGE_YEAR Marco Baye"
VALUE "OriginalFilename", "toacme.exe"
VALUE "ProductName", "ToACME Converter"
VALUE "ProductVersion", $FILEVERSION
VALUE "PorductLicence","GNU General Public License"
VALUE "WindowsPort","Dirk Höpfner hoeppie@gmx.de"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
EndOfFile

View File

@ -12,10 +12,10 @@ ACME.
----------------------------------------------------------------------
Section: Command aliases for "long" JMPs and JSRs
Section: Aliases for "long" JMPs and JSRs
----------------------------------------------------------------------
In addition to the commands JMP and JSR, the 65816 processor also
In addition to the mnemonics JMP and JSR, the 65816 processor also
knows JML and JSL, which are JMP and JSR using new (long) addressing
modes. ACME also accepts the new addressing modes when using the old
mnemonics JMP and JSR, but the old addressing modes cannot be used
@ -30,12 +30,13 @@ According to WDC's official syntax for 65816 assembly language, the
argument order of the MVN and MVP instructions differs between
assembly language and machine code.
To copy bytes from bank $ab to bank $cd, use the following statement:
mvn $ab, $cd ; source bank $ab, destination bank $cd
mvn $ab, $cd ; source bank $ab, destination bank $cd
or
mvn #$ab, #$cd ; source bank $ab, destination bank $cd
ACME will then produce the following machine code:
$54 $cd $ab ; opcode mvn, destination bank $cd, source bank $ab
$54 $cd $ab ; opcode mvn, destination bank $cd, source bank $ab
ACME 0.05 and earlier did it the wrong way. Several other assemblers
still do. Make sure your sources are correct.
ACME 0.05 and earlier did it the wrong way.
----------------------------------------------------------------------
@ -54,13 +55,13 @@ this at any time using the following pseudo opcodes:
!rs ; switch to short index registers
Please note that ACME, unlike some other assemblers, does *not* track
SEP/REP commands: I don't like that method - it fails when
SEP/REP instructions: I don't like that method - it fails when
encountering PLPs, for example. So if it doesn't work reliably in the
first place, why use it? :)
If you don't like that you always have to use a pseudo opcode
alongside SEP/REP commands, then have a look at the file <65816/std.a>
(in the library). There are some predefined macros that you can use.
alongside SEP/REP instructions, then have a look at the library file
<65816/std.a> which has some predefined macros you can use.
----------------------------------------------------------------------

View File

@ -7,12 +7,12 @@
--- addressing modes ---
If a command can be used with different addressing modes, ACME has to
decide which one to use. Several commands of the 6502 CPU can be used
with either "absolute" addressing or "zeropage-absolute" addressing.
The former one means there's a 16-bit argument, the latter one means
there's an 8-bit argument.
And the 65816 CPU even knows some commands with 24-bit addressing...
If an instruction can be used with different addressing modes, ACME
has to decide which one to use. Several instructions of the 6502 CPU
can be used with either "absolute" addressing or "zeropage-absolute"
addressing. The former one means there's a 16-bit argument, the latter
one means there's an 8-bit argument.
And the 65816 CPU even has some instructions with 24-bit addressing...
So how does ACME know which addressing mode to use?
The simple approach is to always use the smallest possible argument,
@ -29,11 +29,10 @@ The two exceptions are:
*** 1) Symbols are defined too late
If ACME cannot figure out the argument value in the first pass, it
assumes that the command uses 16-bit addressing.
assumes that the instruction uses 16-bit addressing.
If it later finds out that the argument only needs 8 bits, ACME gives
a warning ("using oversized addressing mode") and continues. However,
@ -43,8 +42,7 @@ These problems can be solved by defining the symbols *before* using
them, so that the value can be figured out in the first pass. If this
is not possible, you can use the postfix method, effectively exactly
defining what addressing mode to use. The postfix method is described
in a separate paragraph below.
in a separate section below.
@ -85,10 +83,12 @@ will be assembled to
ad fd 00 ; lda $00fd
8f ff 00 00 ; sta $0000ff
The other possibility is to use the postfix method (described in the
next paragraph).
This feature can be disabled using the "--ignore-zeroes" CLI switch.
The other possibility is to use the postfix method (described in the
next section).
*** The postfix method
@ -129,7 +129,7 @@ will be assembled to
8c fd 00 ; sty $00fd
8f ff 00 00 ; sta $0000ff
Postfixes given directly after the command have higher priority than
Postfixes added directly to the mnemonic have higher priority than
those given to the argument. As you can see, you can add the postfix
to the symbol definition as well (equivalent to leading zeros).
@ -138,8 +138,7 @@ gives the high byte and "^" gives the bank byte of a value) to any
value will clear the argument's Force Bits 2 and 3 and set Force
Bit 1 instead. So "lda <symbol" will use 8-bit addressing, regardless
of the symbol's Force Bits. Of course, you can change this by
postfixing the command again... :)
postfixing the instruction again... :)
@ -149,7 +148,7 @@ You don't need to read this paragraph just to use ACME, I only
included it for completeness' sake. This is a description of ACME's
strategy for finding the addressing mode to use:
First, ACME checks whether the command has any postfix. If it has,
First, ACME checks whether the instruction has any postfix. If it has,
ACME acts upon it. So postfixes have the highest priority.
Otherwise, ACME checks whether the argument has any Force Bits set
@ -169,4 +168,4 @@ I admit that this algorithm sounds complicated, but it hasn't failed
yet. :) And in everyday usage, it does exactly what one expects.
If you want to take a closer look at the algorithm, examine the
"calc_arg_size" function in the "sources/mnemo.c" file.
"calc_arg_size" function in the "src/mnemo.c" file.

View File

@ -22,34 +22,108 @@ Purpose: Insert 8-bit values.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: "!08", "!by", "!byte"
Examples: !08 127, symbol, -128 ; output some values
!by 14, $3d, %0110, &304, <*, "c"
!by 14, $3d, %0110, &304, <*, 'c'
!byte 3 - 4, symbol1 XOR symbol2, 2 ^ tz, (3+4)*7
Call: !16 EXPRESSION [, EXPRESSION]*
Purpose: Insert 16-bit values.
Purpose: Insert 16-bit values in chosen CPU's byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: "!wo", "!word"
Aliases: "!wo", "!word" (and because all currently supported
CPUs are little-endian, "!le16" is in fact another
alias)
Examples: !16 65535, symbol, -32768 ; output some values
!wo 14, $4f35, %100101010010110, &36304, *, "c"
!wo 14, $4f35, %100101010010110, &36304, *, 'c'
!word 3000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !le16 EXPRESSION [, EXPRESSION]*
Purpose: Insert 16-bit values in little-endian byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None (but because all currently supported CPUs are
little-endian, "!16/!wo/!word" are in fact aliases)
Examples: !le16 65535, symbol, -32768 ; output some values
!le16 14, $4f35, %100101010010110, &36304, *, 'c'
!le16 3000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !be16 EXPRESSION [, EXPRESSION]*
Purpose: Insert 16-bit values in big-endian byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None
Examples: !be16 65535, symbol, -32768 ; output some values
!be16 14, $4f35, %100101010010110, &36304, *, 'c'
!be16 3000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !24 EXPRESSION [, EXPRESSION]*
Purpose: Insert 24-bit values.
Purpose: Insert 24-bit values in chosen CPU's byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None (but because all currently supported CPUs are
little-endian, "!le24" is in fact an alias)
Examples: !24 16777215, symbol, -8388608, 14, $6a4f35
!24 %10010110100101010010110, &47336304, *, "c"
!24 %10010110100101010010110, &47336304, *, 'c'
!24 300000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !le24 EXPRESSION [, EXPRESSION]*
Purpose: Insert 24-bit values in little-endian byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None (but because all currently supported CPUs are
little-endian, "!24" is in fact an alias)
Examples: !le24 16777215, symbol, -8388608, 14, $6a4f35
!le24 %10010110100101010010110, &47336304, *, 'c'
!le24 300000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !be24 EXPRESSION [, EXPRESSION]*
Purpose: Insert 24-bit values in big-endian byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None
Examples: !be24 16777215, symbol, -8388608, 14, $6a4f35
!be24 %10010110100101010010110, &47336304, *, 'c'
!be24 300000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !32 EXPRESSION [, EXPRESSION]*
Purpose: Insert 32-bit values.
Purpose: Insert 32-bit values in chosen CPU's byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None (but because all currently supported CPUs are
little-endian, "!le32" is in fact an alias)
Examples: !32 $7fffffff, symbol, -$80000000, 14, $46a4f35
!32 %1001011010010101001011010010, &4733630435, *, "c"
!32 %1001011010010101001011010010, &4733630435, *, 'c'
!32 300000 - 4, a AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !le32 EXPRESSION [, EXPRESSION]*
Purpose: Insert 32-bit values in little-endian byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None (but because all currently supported CPUs are
little-endian, "!32" is in fact an alias)
Examples: !le32 $7fffffff, symbol, -$80000000, 14, $46a4f35
!le32 %1001011010010101001011010010, &4733630435, *, 'c'
!le32 300000 - 4, a AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !be32 EXPRESSION [, EXPRESSION]*
Purpose: Insert 32-bit values in big-endian byte order.
Parameters: EXPRESSION: Any formula the value parser accepts.
Aliases: None
Examples: !be32 $7fffffff, symbol, -$80000000, 14, $46a4f35
!be32 %1001011010010101001011010010, &4733630435, *, 'c'
!be32 300000 - 4, a AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
Call: !hex PAIRS_OF_HEX_DIGITS
Purpose: Insert byte values with a minimum of additional
syntax. This pseudo opcode was added for easier
writing of external source code generator tools.
Parameters: PAIRS_OF_HEX_DIGITS: Just hexadecimal digits, without
any "0x" or "$" prefix. Spaces and TABs are allowed,
but not needed to separate the byte values.
Aliases: "!h"
Examples: !h f0 f1 f2 f3 f4 f5 f6 f7 ; insert values 0xf0..0xf7
!h f0f1f2f3 f4f5f6f7 ; insert values 0xf0..0xf7
!h f0f1f2f3f4f5f6f7 ; insert values 0xf0..0xf7
!h f0f 1f2 ; ERROR: space inside pair!
!h 0x00, $00 ; ERROR: "0x", "," and "$" are forbidden!
!h SOME_SYMBOL ; ERROR: symbols are forbidden!
!h ABCD ; insert value 0xAB, then 0xCD (CAUTION, big-endian)
Call: !fill AMOUNT [, VALUE]
Purpose: Fill amount of memory with value.
@ -62,6 +136,18 @@ Examples: !fi 256, $ff ; reserve 256 bytes
!fill 2 ; reserve two bytes
Call: !skip AMOUNT
Purpose: Advance in output buffer without starting a new
segment.
Parameters: AMOUNT: Any formula the value parser accepts, but it
must be solvable even in the first pass (this
limitation will hopefully be lifted in a future
release).
Aliases: None
Examples: !skip BUFSIZE ; reserve some bytes
!skip 5 ; reserve five bytes
Call: !align ANDVALUE, EQUALVALUE [, FILLVALUE]
Purpose: Fill memory until a matching address is reached. ACME
outputs FILLVALUE until "program counter AND ANDVALUE"
@ -72,7 +158,7 @@ Parameters: ANDVALUE: Any formula the value parser accepts, but it
it must be solvable even in the first pass.
FILLVALUE: Any formula the value parser accepts. If it
is omitted, a default value is used (currently 234,
that's the 6502 CPU's NOP command).
that's the opcode of the 6502 CPU's NOP instruction).
Examples: !align 255, 0 ; align to page (256 bytes)
!align 63, 0 ; align to C64 sprite block (64 bytes)
@ -295,23 +381,25 @@ Section: Flow control
Call: !if CONDITION { BLOCK } [ else { BLOCK } ]
Purpose: Conditional assembly. If the given condition is true,
the first block of statements will be parsed;
if it isn't, the second block will be parsed instead
(if present).
the matching block of statements will be parsed;
if no condition is true, the ELSE block (if present)
will be parsed.
Parameters: CONDITION: Any formula the value parser accepts, but
it must be solvable even in the first pass.
BLOCK: A block of assembler statements.
Examples: !text "Black", 0 ; Choose wording according to
!if country = uk { ; content of "country" symbol.
Examples: ; Choose word according to "country" symbol:
!if country = uk {
!text "Grey"
} else if country = fr {
!text "Gris"
} else if country = de {
!text "Grau"
} else {
!text "Gray"
}
!byte 0
!text "White", 0
; Insert debug commands if symbol "debug" is not zero:
!if debug { lda #"z":jsr char_output }
; Insert debug code depending on symbol "debug":
!if debug { lda #'z':jsr char_output }
Call: !ifdef SYMBOL { BLOCK } [ else { BLOCK } ]
@ -354,12 +442,26 @@ Examples: ; this was taken from <6502/std.a>:
; further instances will be skipped.
}
; include at most one driver source code:
!ifdef RAM_REU {
!src "driver_reu.a"
} else ifdef RAM_GEORAM {
!src "driver_georam.a"
} else ifdef RAM_VDCRAM {
!src "driver_vdcram.a"
} else ifdef RAM_SUPERRAM {
!src "driver_superram.a"
} else {
!src "driver_noram.a"
}
Call: !for SYMBOL, START, END { BLOCK }
Purpose: Looping assembly. The block of statements will be
parsed a fixed number of times, as specified by the
values of START and END. For a more flexible
possibility, have a look at "!do" below.
values of START and END. For more flexible
possibilities, have a look at "!do" and "!while"
below.
Parameters: SYMBOL: Any valid symbol name.
START: Any formula the value parser accepts, but it
must be solvable even in the first pass. SYMBOL will
@ -409,12 +511,13 @@ Examples:
Miscellaneous: The old syntax ("!for SYMBOL, END { BLOCK }" where
START was always implied to be 1) is still fully
supported, but gives a warning to get people to change
to the new syntax. You can disable this warning using
the "-Wno-old-for" switch, but then you will get
to the new syntax.
You can disable this warning using the "--dialect" or
the "-Wno-old-for" switches, but then you will get
warnings for using the *new* syntax.
When migrating your sources, bear in mind that it is
no longer possible to skip the block completely by
specifying a loop count of zero.
When migrating your sources to the current syntax,
bear in mind that it is no longer possible to skip the
block completely by specifying a loop count of zero.
Also note that with the new algorithm, SYMBOL has a
different value after the block than during the last
loop cycle, while the old algorithm kept that last
@ -424,9 +527,9 @@ Miscellaneous: The old syntax ("!for SYMBOL, END { BLOCK }" where
Call: !set SYMBOL = VALUE
Purpose: Assign given value to symbol even if the symbol
already has a different value. Needed for loop
counters when using "!do", for example. Only use this
opcode for something else if you're sure you *really*
know what you are doing... :)
counters when using "!do"or "!while", for example.
Only use this opcode for something else if you're sure
you *really* know what you are doing... :)
Parameters: SYMBOL: Any valid symbol name.
VALUE: Any formula the value parser accepts.
Example: see "!do" below
@ -466,6 +569,34 @@ Examples: ; a loop with conditions at both start and end
!do until 3 = 4 { } while 3 < 4
Call: !while [CONDITION] { BLOCK }
Purpose: Looping assembly. The block of statements can be
parsed several times, depending on the given
condition.
The condition is parsed in every repetition before the
actual block. If it isn't met when first checked, the
block will be skipped.
Parameters: CONDITION: Any formula the value parser accepts, but
it must be solvable even in the first pass.
BLOCK: A block of assembler statements.
Examples: ; a loop with a counter
!set a = 0 ; init loop counter
!while a < 6 {
lda #a
sta label + a
!set a = a + 1
}
; a loop depending on program counter
!while * < $c000 { nop }
; a never ending loop - this will cause an error
!while 3 < 4 { nop }
; an empty loop - this will hang ACME
!while 3 != 4 { }
Call: !endoffile
Purpose: Stop processing the current source file. Using this
pseudo opcode you can add explanatory text inside your
@ -480,22 +611,24 @@ Example: rts ; some assembler mnemonic
"!eof" is reached.
Call: !warn STRING_VALUE [, STRING_VALUE]*
Call: !warn VALUE [, VALUE]*
Purpose: Show a warning during assembly.
Parameters: STRING_VALUE: Can be either a string given in double
quotes or any formula the value parser accepts.
Numbers will be output in decimal _and_ hex format.
Parameters: VALUE: Can be either a string given in double quotes
or any formula the value parser accepts.
Integer numbers will be output in both decimal _and_
hex formats.
Example: !if * > $a000 {
!warn "Program reached ROM: ", * - $a000, " bytes overlap."
}
Call: !error STRING_VALUE [, STRING_VALUE]*
Call: !error VALUE [, VALUE]*
Purpose: Generate an error during assembly (therefore, no
output file will be generated).
Parameters: STRING_VALUE: Can be either a string given in double
quotes or any formula the value parser accepts.
Numbers will be output in decimal _and_ hex format.
Parameters: VALUE: Can be either a string given in double quotes
or any formula the value parser accepts.
Integer numbers will be output in both decimal _and_
hex formats.
Example: rts ; end of some function
start !source "colors.a"
end !if end - start > 256 {
@ -503,12 +636,13 @@ Example: rts ; end of some function
}
Call: !serious STRING_VALUE [, STRING_VALUE]*
Call: !serious VALUE [, VALUE]*
Purpose: Generate a serious error, immediately stopping
assembly.
Parameters: STRING_VALUE: Can be either a string given in double
quotes or any formula the value parser accepts.
Numbers will be output in decimal _and_ hex format.
Parameters: VALUE: Can be either a string given in double quotes
or any formula the value parser accepts.
Integer numbers will be output in both decimal _and_
hex formats.
Example: !source "part1.a" ; sets part1_version
!source "part2.a" ; sets part2_version
!if part1_version != part2_version {
@ -528,9 +662,9 @@ Parameters: TITLE: The macro's desired name (same rules as for
could want this is beyond me).
SYMBOL: The desired name for the parameter value at
call time. Normally, these parameter symbols should be
local (first character a dot), as different macro
calls will almost for sure have different parameter
values.
local (first character a '.' or a '@'), as different
macro calls will almost for sure have different
parameter values.
If you prefix SYMBOL with a '~' character, it will be
called by reference, not by value: Changing the value
inside the macro will result in the "outer" symbol to
@ -657,8 +791,10 @@ Purpose: Set program counter to given value and start new
issued. Because some people do this overlapping
on purpose, the warnings can be suppressed using
modifier keywords.
Future versions of ACME may issue errors instead of
warnings.
Using the "--strict-segments" CLI switch, these
warnings can be turned onto errors. Future versions of
ACME may do that by default - so if needed, use the
modifier keywords.
Parameters: EXPRESSION: Any formula the value parser accepts, but
it must be solvable even in the first pass.
MODIFIER: "overlay" or "invisible" (without quotes):
@ -715,6 +851,24 @@ Examples: !to "TinyDemo", cbm ; define output file + format
; Useful if you want to store your code in an EPROM.
Call: !xor EXPRESSION [ { BLOCK } ]
Purpose: Change the value to XOR all output bytes with (the
value defaults to zero on startup). This "encryption"
facility was added to compensate for the shortcomings
of the "!scrxor" pseudo opcode, which only XORs
strings and characters, but not numbers.
When used with block syntax, the previously chosen
value is restored afterwards.
Parameters: EXPRESSION: Any formula the value parser accepts.
BLOCK: A block of assembler statements.
Examples: ; first as normal screencodes:
!scr "Hello everybody...", GROUPLOGOCHAR
; and now as inverted screencodes:
!xor $80 {
!scr "Hello everybody...", GROUPLOGOCHAR
}
----------------------------------------------------------------------
Section: Offset assembly
----------------------------------------------------------------------
@ -746,6 +900,13 @@ Examples: ldx #.shifted_end - .shifted_start
}
.shifted_end
Miscellaneous: If you need to convert a label or the program counter
from its "pseudopc" to its "real" value, you can do
that using the "&" operator. Given the example above,
the symbol ".target" will evaluate to the value $0400,
but "&.target" will evaluate to the same value as
".shifted_start" will.
----------------------------------------------------------------------
Section: CPU support pseudo opcodes (especially 65816 support)
@ -755,19 +916,25 @@ Call: !cpu KEYWORD [ { BLOCK } ]
Purpose: Select the processor to produce code for. If this PO
isn't used, ACME defaults to the 6502 CPU (or to the
one selected by the "--cpu" command line option).
ACME will give errors if you try to assemble commands
the chosen CPU does not have. You can change the
chosen CPU at any time. When used with block syntax,
the previously chosen CPU value is restored
afterwards.
ACME will give errors if you try to assemble
instructions the chosen CPU does not support. You can
change the chosen CPU at any time. When used with
block syntax, the previously chosen CPU value is
restored afterwards.
Parameters: KEYWORD: Currently valid keywords are:
6502 mnemonics and addressing modes of 6502 cpu
65c02 superset of 6502, adds 65c02 extensions
65816 superset of 65c02, adds 65816 extensions
6510 superset of 6502, adds mnemonics for
undocumented opcodes
c64dtv2 superset of 6510, adds mnemonics for DTV2
extensions (BRA/SAC/SIR)
6502 for the original MOS 6502
nmos6502 6502 plus undocumented opcodes
6510 (alias for "nmos6502")
65c02 6502 plus BRA,PHX/Y,PLX/Y,STZ,TRB/TSB
r65c02 65c02 plus BBRx, BBSx, RMBx, SMBx
w65c02 r65c02 plus STP/WAI
65816 65c02 plus 16/24-bit extensions
65ce02 r65c02 plus Z reg, long branches, ...
4502 65ce02 with MAP instead of AUG
m65 4502 plus 32-bit extensions
c64dtv2 6502 plus BRA/SAC/SIR plus some of the
undocumented opcodes
See "docs/cputypes/all.txt" for more info.
BLOCK: A block of assembler statements.
Examples: !if cputype = $65c02 {
!cpu 65c02 { ; temporarily allow 65c02 stuff
@ -780,7 +947,7 @@ Examples: !if cputype = $65c02 {
pla
}
rts
!cpu 65816 ; allow 65816 commands from here on
!cpu 65816 ; now allow instructions of 65816 cpu
Call: !al [ { BLOCK } ]
@ -828,6 +995,8 @@ Parameters: BLOCK: A block of assembler statements
If no block is given, only the current statement will
be affected, which should then be an explicit symbol
definition.
To make use of this feature, you need to use the
"-Wtype-mismatch" CLI switch.
Aliases: "!addr"
Examples: !addr k_chrout = $ffd2 ; this is an address
CLEAR = 147 ; but this is not
@ -853,6 +1022,10 @@ Purpose: Use PetSCII as the text conversion table. Now
superseded by the "!convtab" pseudo opcode.
Old usage: !cbm ; gives "use !ct pet instead" error
Now use: !convtab pet ; does the same without error
If you just want to assemble an old source code
without touching it, use the "--dialect" CLI switch:
Using "--dialect 0.94.6" or earlier will assemble this
pseudo opcode without throwing an error.
Call: !subzone [TITLE] { BLOCK }
@ -867,6 +1040,10 @@ Old usage: !subzone graphics {
Now use: !zone graphics {
!source "graphics.a"
}
If you just want to assemble an old source code
without touching it, use the "--dialect" CLI switch:
Using "--dialect 0.94.6" or earlier will assemble this
pseudo opcode without throwing an error.
Call: !realpc
@ -880,3 +1057,8 @@ Old usage: !pseudopc $0400
Now use: !pseudopc $0400 {
; imagine some code here...
}
If you just want to assemble an old source code
without touching it, use the "--dialect" CLI switch:
Using "--dialect 0.94.6" or earlier will assemble this
pseudo opcode without throwing an error.
Using "--dialect 0.85", not even a warning is thrown.

View File

@ -12,6 +12,186 @@ platform used. There should be another help file in this archive
outlining the platform specific changes.
----------------------------------------------------------------------
Section: New in release 0.97
----------------------------------------------------------------------
FINALLY strings can be assigned to symbols!
"anything in double quotes" is a string, while characters in
single quotes are, just as before, immediately converted to their
character code. Go and read "docs/Upgrade.txt" to learn about
compatibility issues.
Added backslash escaping in all string literals:
\0 is a null byte, \t is a TAB, \n is a line feed, \r is a
carriage return, \" is a double quote, \' is a single quote and
\\ is a backslash. Go and read "docs/Upgrade.txt" to learn about
compatibility issues.
Added "--dialect" CLI switch:
Because string symbols and backslash escaping introduce a few
incompatibilities to older versions, ACME can now be told to mimic
the behavior of older versions. So it's still possible to assemble
older sources.
Added lists:
Lists can be used to pass an arbitrary number of arguments to
macros, or to store any number of items (including other lists) in
a single symbol. Example: my_list = [1, 2, label, "string", 9]
Added "len()" operator:
This returns the number of elements in a string or list.
Added "[]" operator (for indexing):
This returns a single element from a string or list. Negative
indices are supported as well, they access the string/list from
the other end. Examples: a = my_list[2] b = my_string[-1]
Added "&" operator:
This operator converts labels or the program counter from its
value inside a "!pseudopc" block to the value outside of that
block. Thanks to markusC64 for the suggestion!
Added "!while {}" pseudo opcode.
Added "else if", "else ifdef" and "else ifndef" possibilities.
Added "M65" cpu:
This instruction set includes the MEGA65 extensions, namely 32-bit
pointers and 32-bit data operations using prefix bytes.
Added "NMOS6502" as an alias for "6510" cpu.
Improved NMOS6502/6510 mode:
DOP and TOP can now also be written as NOP.
Improved 65816 mode:
MVN and MVP can now also be written with '#' before arguments.
Added "--test" CLI switch:
This is for people who want to help test experimental features.
Improved error messages:
"Garbage data at end of statement" now includes the unexpected
character.
"Symbol not defined" is only output once per symbol.
Added warning:
ACME complains about binary literals with an "unusual" number of
digits. Thanks to groepaz for the suggestion!
The warning can be disabled using the "-Wno-bin-len" CLI switch.
Added warning:
All mnemonics without indirect addressing now complain about
unneeded parentheses.
Fix: Characters are now unsigned (had been architecture-dependent).
Improved error handling of "--cpu" and "--format" switches.
Added opcode table for NMOS6502 cpu to docs.
Added some test sources.
Added support for "hashbang" lines (if file starts with a '#'
character, the first line is ignored)
Fixed some minor bugs no-one ever seems to have encountered.
Rewritten "docs/Upgrade.txt".
----------------------------------------------------------------------
Section: New in release 0.96.5
----------------------------------------------------------------------
Allowed C++-style comments via "//". Thanks to awsm for the
suggestion (and please accept my apologies for taking so long to
release this)
Added "--ignore-zeroes" CLI switch. This disables the "leading zeroes
determine number size" algorithm. Thanks to groepaz for the
suggestion.
Added "--strict-segments" CLI switch. This changes warnings about
overlapping memory segments into errors. Thanks to groepaz for the
suggestion.
Added 6502 family tree to docs/cpu_types/all.txt
----------------------------------------------------------------------
Section: New in release 0.96.4
----------------------------------------------------------------------
Bugfix: Removed warnings about zero page wrap-around for the 65816's
24-bit pointers (because wrap-around does not actually happen).
Thanks to Johann Klasek for reporting this.
Added "!xor" pseudo opcode to compensate for the shortcomings of the
"!scrxor" pseudo opcode. Thanks to spider-j for the initial bug
report.
Added "-I" CLI switch to add search paths for input files. Thanks to
peiselulli for the suggestion.
----------------------------------------------------------------------
Section: New in release 0.96.3
----------------------------------------------------------------------
Added "!h"/"!hex" pseudo opcode: Now external source code generator
tools can easily put data in sources with minimal syntax overhead.
Added "!skip" pseudo opcode: "!skip N" works like "*=*+N" without
starting a new segment.
Added "cheap locals": Labels with '@' prefix have automatic scoping,
bounded by the preceding and the following global labels.
Added "--fullstop" CLI switch to change pseudo opcode prefix from '!'
to '.' (so other assemblers' sources need less conversion work)
Fixed a bug where expressions like "1)+1" crashed ACME. Thanks to
Bitbreaker for reporting this.
Added warning when using zp-indirect addressing modes where argument
is $ff because pointer wraps around to $00. Thanks to Gerrit for
the suggestion.
----------------------------------------------------------------------
Section: New in release 0.96.2
----------------------------------------------------------------------
Added "--color" CLI switch to enable colored error output using ANSI
escape codes. Thanks to Clifford Carnmo for submitting this patch.
----------------------------------------------------------------------
Section: New in release 0.96.1
----------------------------------------------------------------------
Fixed bug where 65ce02's "(zp),z" addressing mode could be used in
65816 mode.
----------------------------------------------------------------------
Section: New in release 0.96
----------------------------------------------------------------------
Added experimental support for instruction sets of Rockwell 65C02,
WDC 65C02(S), CSG 65CE02 and CSG 4502.
Stack indexing can now be given either as ",s" or as ",sp" (only
relevant for 65816 and 65CE02).
----------------------------------------------------------------------
Section: New in release 0.95.8
----------------------------------------------------------------------
Warnings and errors inside macros now cause the call stack to be
displayed as well (does not yet work for serious errors, though).
----------------------------------------------------------------------
Section: New in release 0.95.7
----------------------------------------------------------------------
New pseudo opcodes:
"!be16", "!be24" and "!be32" for big-endian byte order output.
"!le16", "!le24" and "!le32" for little-endian byte order output.
The old pseudo opcodes ("!16", "!24", "!32") will now use the
correct byte order for the chosen CPU (which is always little-
endian, because there is no support for any big-endian CPU yet.;))
----------------------------------------------------------------------
Section: New in release 0.95.6
----------------------------------------------------------------------
Fixed a bug: The "C64 DTV2" does not support the undocumented
("illegal") opcodes 0x0b and 0x2b, therefore the "ANC #8"
mnemonic was removed from the "!cpu c64dtv2" mode. Thanks to
peiselulli for testing and reporting this.
"Value not defined" error message now includes the name of the
undefined symbol. Thanks to Thomas Woinke for suggesting this
improvement.
Fixed a bug in type system: "!for" loop counters were not correctly
flagged as "address" or "non-address".
The "addr()" function can now also be written as "address()".
Fixed a bug in report listing generator: CR characters in input caused
additional blank lines in output. Thanks to Johann Klasek for
submitting this patch.
----------------------------------------------------------------------
Section: New in release 0.95.5
----------------------------------------------------------------------
@ -35,8 +215,9 @@ Section: New in release 0.95.3
Added "c64dtv2" cpu type so you can use its SIR, SAC and BRA opcodes;
along with the undocumented ("illegal") opcodes of the 6510.
Added Martin Piper's "--msvc" patch so error output can be configured
to be in Visual Studio format.
Added "--msvc" CLI switch so error output can be configured to be in
Visual Studio format. Thanks to Martin Piper for writing this
patch!
Merged third-party patch (who wrote it?) to output label dump in VICE
format. Still needs work to be configurable about the types of
symbols actually output.
@ -183,8 +364,8 @@ Added "apple" output format.
Section: New in release 0.94.3
----------------------------------------------------------------------
"Target out of range" error now includes info on how much the range was
exceeded. Thanks to Bitbreaker/VOZ for the suggestion.
"Target out of range" error now includes info on how much the range
was exceeded. Thanks to Bitbreaker/VOZ for the suggestion.
----------------------------------------------------------------------
@ -192,12 +373,12 @@ Section: New in release 0.94.2
----------------------------------------------------------------------
Added missing newline after "no output file specified" message.
Fixed bug in "!to" and "!sl" (colon in filename is interpreted as command
separator in later passes).
Fixed bug in "!to" and "!sl" (colon in filename is interpreted as
command separator in later passes).
Changed verbose output hex prefix from $ to 0x.
Changed --help output
Changed EOR to XOR in docs and comments (the ACME operator, not the 6502
opcode)
Changed EOR to XOR in docs and comments (the ACME operator, not the
6502 opcode)
----------------------------------------------------------------------

View File

@ -38,15 +38,29 @@ Assembling buggy JMP($xxff) instruction
location ARGUMENT + 1, but from ARGUMENT - 255. Therefore ACME
issues this warning if you are about to generate such an
instruction.
Note that this warning is only given for CPU types 6502 and 6510,
because 65c02 and 65816 have been fixed in this respect.
Note that this warning is only given for some CPU types (6502,
nmos6502/6510, c64dtv2) because later ones like 65c02 and 65816
have been fixed in this regard.
Assembling unstable ANE #NONZERO instruction
Assembling unstable LXA #NONZERO instruction
This warning is only ever given for CPU type 6510. LXA is one of
the undocumented ("illegal") opcodes of this CPU (opcode 0xab),
and it only works reliably if its argument is zero. Therefore ACME
issues this warning if you are about to generate this instruction
with a non-zero argument.
These warnings are only ever given for CPU type nmos6502 (6510).
ANE and LXA are undocumented ("illegal") opcodes of this CPU, and
they only work reliably if the argument is zero or the accumulator
contains 0xff.
Therefore ACME issues these warnings if it is about to generate
these instructions with a non-zero argument.
Binary literal without any digits.
Hex literal without any digits.
A special literal was started, but then no digits followed. Expect
this to become an error in future!
Binary literal with strange number of digits.
This warning is given if the number of digits in a binary literal
is not a multiple of four. This is useful when you meant to write
%#....... but actually wrote %#........ by mistake. See? :P
You can disable this warning using the CLI switch "-Wno-bin-len".
Bug in ACME, code follows
A situation has been encountered implying there is a bug in ACME.
@ -57,7 +71,7 @@ C-style "==" comparison detected.
Converted to integer for binary logic operator.
Applying binary logic to float values does not make much sense,
therefore floats will be converted to integer in this case.
therefore floats will be converted to integer in such cases.
"EOR" is deprecated; use "XOR" instead.
This means the operator, not the mnemonic.
@ -65,12 +79,20 @@ Converted to integer for binary logic operator.
Found old "!for" syntax.
Please update your sources to use the new "!for" syntax. See
AllPOs.txt for details.
You can suppress this warning using the "-Wno-old-for" switch.
You can suppress this warning using the "--dialect" or the
"-Wno-old-for" CLI switch.
("-Wno-old-for" does _exactly_ the same as "--dialect 0.94.8")
Found new "!for" syntax.
When using the "-Wno-old-for" switch to disable the warning about
the older syntax, the new syntax will trigger this warning.
Found SED instruction for CPU with known decimal SBC bug.
This warning is only ever given for CPU types 65ce02 and 4502,
because they are known to be buggy in decimal mode.
Pavel Zima and Eric Smith found an example where $41 minus $08
gave $39 instead of $33.
Label name not in leftmost column.
A label definition has blanks before the label name.
Imagine this source code:
@ -90,33 +112,35 @@ Label name starts with a shift-space character.
warning is issued.
Memory already initialised.
The "!initmem" command was given more than once (or in addition to
the "--initmem" command line option). Only use it once.
The "!initmem" pseudo opcode was given more than once, or in
addition to the "--initmem" command line option. Only use it once.
Output file already chosen.
The "!to" command was given more than once (or in addition to the
"--outfile" command line option). Only use it once.
The "!to" pseudo opcode was given more than once, or in addition
to the "--outfile" command line option. Only use it once.
Segment reached another one, overwriting it.
The program counter has just reached the start of another segment.
Because some people might want to assemble "onto" a binary file
that was loaded before, this warning can be switched off using
modifier keywords when changing the program counter via "* =".
Future versions of ACME might throw an error instead of a warning
in this case.
that was loaded before, this warning can be inhibited using
modifier keywords when changing the program counter via "*=".
For extra safety you can also turn this warning into an error
using the "--strict-segments" CLI switch. In future versions of
ACME this might become the default.
Segment starts inside another one, overwriting it.
The given value in a "* =" command is located inside another
The given value in a "*=" assignment is located inside another
segment. Because some people might want to assemble "onto" a
binary file that was loaded before, this warning can be switched
off using modifier keywords when changing the program counter via
"* =".
Future versions of ACME might throw an error instead of a warning
in this case.
binary file that was loaded before, this warning can be inhibited
using modifier keywords when changing the program counter via
"*=".
For extra safety you can also turn this warning into an error
using the "--strict-segments" CLI switch. In future versions of
ACME this might become the default.
Symbol list file name already chosen.
The "!sl" command was given more than once (or in addition to the
"--symbollist" command line option). Only use it once.
The "!sl" pseudo opcode was given more than once, or in addition
to the "--symbollist" command line option. Only use it once.
Used "!to" without file format indicator. Defaulting to "cbm".
Now that "!to" can be given a file format keyword (either "plain"
@ -124,27 +148,40 @@ Used "!to" without file format indicator. Defaulting to "cbm".
works though.
Using oversized addressing mode.
ACME just assembled a command using an addressing mode that was
larger than needed. This only happens if ACME could not work out
the argument's value in the first pass, therefore assuming a 16-
bit addressing mode. If, in a later pass, ACME finds out that the
argument is small enough to fit in 8 bits, then this warning is
shown. If you define all your zeropage symbols *before* they are
first used, this shouldn't happen. If you know that a specific
ACME just assembled an instruction using an addressing mode that
was larger than needed. This only happens if ACME could not work
out the argument's value in the first pass, therefore assuming a
16-bit addressing mode. If, in a later pass, ACME finds out that
the argument is small enough to fit in 8 bits, then this warning
is shown. If you define all your zeropage symbols *before* they
are first used, this shouldn't happen. If you know that a specific
argument fits in 8 bits, you can force ACME to use 8 bits
addressing by postfixing the command with "+1". Example:
addressing by postfixing the mnemonic with "+1". Example:
lda+1 label
ACME will then use an 8-bit addressing mode, regardless of whether
the label is known or not. If the label value happens to be too
large to fit in 8 bits, ACME will show an error of course (To
large to fit in 8 bits, ACME will show an error of course (to
always truncate a value to 8 bits, use the '<' operator).
More about the postfixing method can be found in "AddrModes.txt".
Wrong type - expected address.
Wrong type - expected integer.
Wrong type for loop's END value - must match type of START value.
These warnings are only given when type checking has been enabled
using the "-Wtype-mismatch" switch. Make sure the argument type
matches the instruction's addressing mode.
In "!for" loops, START and END must have the same type, which then
gets used for the loop counter.
Zeropage pointer wraps around from $ff to $00
A zeropage-indirect addressing mode uses $ff as the argument. The
6502 will then fetch the second pointer byte from $00 instead of
$0100, therefore this warning is issued.
...called from here.
If warnings and/or errors are output during a macro call, messages
with this text are added to display the call stack (because you
might need to fix the call instead of the macro itself).
----------------------------------------------------------------------
@ -159,19 +196,35 @@ Section: Errors during assembly
"!cbm" is obsolete; use "!ct pet" instead.
This is given when the now obsolete "!cbm" pseudo opcode is
encountered.
If you want to assemble an old source code without first updating
it, you can use the "--dialect" CLI switch to make ACME mimic an
older version.
"!pseudopc/!realpc" is obsolete; use "!pseudopc {}" instead.
This is given when one of the now obsolete !pseudopc/!realpc
pseudo opcodes is encountered.
If you want to assemble an old source code without first updating
it, you can use the "--dialect" CLI switch to make ACME mimic an
older version.
"!subzone {}" is obsolete; use "!zone {}" instead.
This is given when the now obsolete "!subzone" pseudo opcode is
encountered.
If you want to assemble an old source code without first updating
it, you can use the "--dialect" CLI switch to make ACME mimic an
older version.
!error: ...
This is given when the pseudo opcode "!error" is executed. The
actual message varies according to the pseudo opcode's arguments.
After ELSE, expected block or IF/IFDEF/IFNDEF.
There is something strange after ELSE: It must be "if", "ifdef",
"ifndef" or an opening brace.
Argument out of range.
You called arcsin/arccos with something not in the [-1, 1] range.
Cannot open input file.
ACME had problems opening an input file ("!bin", "!convtab" or
"!src"). Maybe you mistyped its name.
@ -180,35 +233,62 @@ Conversion table incomplete.
The conversion table file is too small. It needs to be exactly 256
bytes in size.
CPU does not support this addressing mode for this mnemonic.
The given mnemonic cannot be combined with the given addressing
mode on the CPU you have chosen.
CPU does not support this postfix for this mnemonic.
The given mnemonic cannot be combined with the addressing mode
indicated by the given postfix, at least not on the CPU you have
chosen.
Division by zero.
Guess what - you attempted to divide by zero.
Expected ELSE or end-of-statement.
There is something after the closing brace of an IF block that is
not an ELSE.
Expected end-of-statement after ELSE block.
There is something after the closing brace of an ELSE block.
Exponent is negative.
Using negative exponents only give sensible results when using
floating point maths.
Expression did not return a number.
An expression returned a string or a list but a number (integer or
float) was expected.
File name quotes not found ("" or <>).
File names have to be given in quotes. Either "" quoting for files
located in the current directory or <> quoting for library files.
Force bits can only be given to numbers.
You tried to give a force bit to a symbol and then assign a string
or list to it.
Found '}' instead of end-of-file.
ACME encountered a '}' character when it expected the file to end
instead (because no blocks were open).
Garbage data at end of statement.
There are still arguments when there should not be any more.
Garbage data at end of statement (unexpected 'CHAR').
There are still arguments when there should not be any more. The
given character is the one where end-of-line was expected.
Illegal combination of command and addressing mode.
The given command cannot be used with the given addressing mode on
the CPU you have chosen.
Illegal combination of command and postfix.
The given command cannot be used with the addressing mode
indicated by the given postfix.
Hex digits are not given in pairs.
The two digits of a hex byte are separated by another character,
or there is an odd number of digits.
Illegal postfix.
You used a postfix other than "+1", "+2" or "+3".
Index is undefined.
You attempted an indexing operation with some undefined symbol.
Index out of range.
The value for an indexing operation wasn't in the allowed range.
Macro already defined.
Macros can only be defined once. If you define a macro twice, ACME
will help you find the definitions by giving a warning for the
@ -225,6 +305,10 @@ Macro parameter twice.
The same symbol name is used two (or more) times in the same macro
parameter list.
Negative size argument.
The size argument of "!bin" or "!skip" must be zero or positive,
but cannot be negative.
Negative value - cannot choose addressing mode.
Because the argument is a negative value, ACME does not know what
addressing mode (8 bits, 16 bits, on a 65816 even 24 bits) to use.
@ -232,10 +316,18 @@ Negative value - cannot choose addressing mode.
your program to use positive addresses instead.
No string given.
ACME expects a string but doesn't find it.
ACME expects a string but doesn't find it, or the string is empty.
Number does not fit in N bits.
Number out of range.
A value is too high or too low.
A value is too high or too low to be stored in 8/16/24 bits.
This can also mean the desired addressing mode is not available,
as in "sty $e000, x".
Operation not supported: Cannot apply "OP" to "TYPE".
Operation not supported: Cannot apply "OP" to "TYPE" and "TYPE".
You tried to use an operator on the wrong type(s) of argument(s),
like indexing a float or negating a string.
Program counter is unset.
You didn't set the program counter, so ACME didn't know where to
@ -247,27 +339,35 @@ Quotes still open at end of line.
Source file contains illegal character.
Your source code file contained a null byte.
String length is not 1.
You tried something like LDA#"X" with an illegal string length.
Symbol already defined.
You defined a symbol that already had a different value. To change
a symbol's value, use the "!set" pseudo opcode.
You defined a symbol that already had a different type or value.
To change a symbol's type or value, use the "!set" pseudo opcode.
Syntax error.
Guess what - there's a syntax error.
Target not in bank (0xTARGET).
You tried to branch to an address not in the 0x0000..0xffff range.
Relative addressing (branch commands or PER) cannot leave the
Relative addressing (branch instructions or PER) cannot leave the
current code bank of 64 KiB.
Target out of range (N; M too far).
Branch commands use relative addressing, which only has a limited
range. You exceeded it. N is the attempted offset, M is the
difference to the limit - so if you succeed in optimizing M bytes
away, the code would assemble.
Branch instructions use relative addressing, which only has a
limited range. You exceeded it. N is the attempted offset, M is
the difference to the limit - so if you succeed in optimizing M
bytes away, the code would assemble.
The chosen CPU uses opcode 0xXY as a prefix code, do not use this mnemonic!
The mnemonic is valid, but should not be used on this CPU. If you
know better, you can get around this error like this:
!cpu ANY_OTHER_CPU { PROBLEMATIC_MNEMONIC }
There's more than one character.
You used a text string in an arithmetic expression, but the string
contained more than a single character.
You used a text string containing more than one character in a
situation where only a string with length one is allowed.
Too late for postfix.
You can only postfix symbols at the start, before they are used for
@ -276,28 +376,58 @@ Too late for postfix.
Too many '('.
A formula ends before all parentheses were closed.
Too many ')'.
There are more closing than opening parentheses in a formula.
Un-pseudopc operator '&' can only be applied to labels.
You tried to apply the operator '&' to something that is not a
label. This operator only works on labels and on '*' (the program
counter), it cannot be used on other objects.
Un-pseudopc operator '&' has no !pseudopc context.
You either tried to apply the operator '&' to something that is
not an implicitly defined label, but the result of an explicit
symbol assignment (like the result of a calculation).
Or you applied the operator to a label that was defined outside of
a !pseudopc block, or, more generally, the number of '&'
characters used was larger than the number of !pseudopc blocks
around the definition.
Unknown encoding.
You used the "!convtab" command with a keyword ACME does not know.
You used the "!convtab" pseudo opcode with a keyword ACME does not
know.
Unknown function.
You used a mathematical function ACME does not know.
Unknown operator.
You used an arithmetic/logical operator ACME does not know.
Unknown output format.
You used the "!to" command with a keyword ACME does not know.
You used the "!to" pseudo opcode with a format specifier ACME does
not know.
Unknown processor.
You used the "!cpu" command with a keyword ACME does not know.
You used the "!cpu" pseudo opcode with a cpu specifier ACME does
not know.
Unknown pseudo opcode.
You have mistyped a "!" command.
You have mistyped the keyword after "!".
Unknown "* =" segment modifier.
Unknown "*=" segment modifier.
You used a modifier keyword ACME does not know.
Value not yet defined.
Unsupported backslash sequence.
The character following the backslash was not one of the allowed
ones. Backslash escaping was added in release 0.97 of ACME.
If you want to assemble an old source code without first updating
it, you can use the "--dialect" CLI switch to make ACME mimic an
older version.
Unterminated index spec.
An index was started with '[' but did not end with ']'.
Unterminated list.
A list was started with '[' but did not end with ']'.
Value not defined (SYMBOL NAME).
A value could not be worked out. Maybe you mistyped a symbol name.
Whether this is given as a "normal" or as a serious error depends
on the currently parsed pseudo opcode.
@ -316,8 +446,9 @@ Found end-of-file instead of '}'.
(because there was at least one block left open).
Loop count is negative.
You used the "!for" command with a negative loop count (getting
this error is only possible when using the now deprecated syntax).
You used the "!for" pseudo opcode with a negative loop count
(getting this error is only possible when using the now deprecated
syntax).
Macro already defined.
Macros can only be defined once. If you define a macro twice, ACME
@ -327,7 +458,7 @@ Macro already defined.
Missing '{'.
ACME didn't find the expected '{' character. Remember that '{'
characters must be given on the same line as the command they
characters must be given on the same line as the keyword they
belong to.
Out of memory.
@ -345,14 +476,17 @@ Syntax error.
Too deeply nested. Recursive macro calls?
The only reason for ACME to have a limit on macro call nesting
at all is to find infinite recursions. Current limit is 64.
at all is to find infinite recursions.
The default limit is 64, this can be changed using the
"--maxdepth" CLI switch.
Too deeply nested. Recursive "!source"?
The only reason for ACME to still have a limit on "!source"
nesting at all is to find infinite recursions. Current limit is
64.
nesting at all is to find infinite recursions.
The default limit is 64, this can be changed using the
"--maxdepth" CLI switch.
Value not yet defined.
Value not defined.
A value could not be worked out. Maybe you mistyped a symbol name.
Whether this is given as a "normal" or as a serious error depends
on the currently parsed pseudo opcode.
@ -375,41 +509,89 @@ No output file specified (use the "-o" option or the "!to" pseudo opcode).
Section: Bugs in ACME
----------------------------------------------------------------------
The warning "Bug in ACME, code follows" is always followed by a
serious error message, stopping assembly. The second message
actually gives a hint about the bug's location in the source code.
If you ever get this combination of warning and serious error,
please send me an e-mail and tell me about it. If possible,
include a piece of source code that triggers it.
The warning "Bug in ACME, code follows" is always followed by a
serious error message, stopping assembly. The second message actually
gives a hint about the bug's location in the source code.
If you ever get this combination of warning and serious error, please
send me an e-mail and tell me about it. If possible, include a piece
of source code that triggers it.
Please don't get this wrong - there are no known bugs. I just left
some debugging code in place in case there is a bug I failed to notice
during testing. In practice, this warning is not expected to be given
at all. That's the reason why I want to be notified if it *does*
decide to show up.
Please don't get this wrong - there are no known bugs. I just left
some debugging code in place in case there is a bug I failed to
notice during testing. In practice, this warning is not expected
to be given at all. That's the reason why I want to be notified if
it *does* decide to show up.
The hint messages are of no real interest to the end user, but here
they are for completeness' sake:
The hint messages are of no real interest to the end user, but here
they are for completeness' sake.
IllegalGroupIndex
The mnemonic tree contains a group that I didn't add.
ArgStackEmpty
There was no data for a monadic operator to work on.
ArgStackNotEmpty
The expression parser has finished though there are still
arguments left to process.
ExtendingListWithItself
There were multiple references to the same list.
ForceBitZero
The function to handle force bits was called without a force bit.
IllegalBlockTerminator
A RAM block (macro or loop) was terminated incorrectly.
IllegalOperatorHandle
IllegalGroupIndex
The mnemonic tree contains a group that I didn't add.
IllegalIfMode
A sanity check in the if/ifdef/ifndef/else code failed.
IllegalImmediateMode
The mnemonic tree contains invalid info about the size of immediate
arguments.
IllegalInputSource
Input is taken neither from a file nor from a RAM block.
IllegalNumberTypeX
A number was neither INT nor FLOAT nor UNDEFINED.
IllegalObjectType
A symbol is used that is neither number nor list nor string.
IllegalOperatorId
IllegalOperatorGroup
The expression parser found an operator that does not exist.
OperandStackNotEmpty
The expression parser has finished though there are still operands
left to parse.
IllegalSymbolNameLength
A sanity check on string lengths failed.
NotEnoughArgs
There was not enough data for a dyadic operator to work on.
NullTypeObject
ObjectHasNullType
A symbol is used that does not have a type (number/list/string)
associated with it.
OperatorIsNotDyadic
OperatorIsNotMonadic
A function was passed the wrong type of operator.
OperatorStackNotEmpty
The expression parser has finished though there are still
operators left to parse.
operators left to process.
PartialEscapeSequence
Buffered data ended on a backslash, which shouldn't be possible.
SecondArgIsNotAnInt
A sanity check failed: An argument should have been converted to
integer but wasn't.
StrangeInputMode
The input state machine has reached a state that does not exist.
StrangeParenthesis
StrangeOperator
The expression parser found a non-existing operator.

View File

@ -30,4 +30,6 @@ Just in case you wonder:
Please *don't* look at it. :)
"trigono.o" is a simple example written to test the floating-point
capabilities.
capabilities. Because floats are prone to rounding errors, there
are two different "expected" outputs: these were generated on
different architectures, they only differ in one byte ($7f/$80).

View File

@ -17,7 +17,7 @@ with floats and returns a float. Applies to sin(), cos(), tan(),
arcsin(), arccos(), arctan() and float(): These are always computed in
float mode and always return floats.
b) if a maths operation is useles when done with floats, it is done
b) if a maths operation is useless when done with floats, it is done
with integers and returns an integer. Applies to NOT, AND, OR, XOR,
MOD, DIV, LSR, lowbyteof, highbyteof, bankbyteof and int(). These are
always computed in integer mode and always return integers.

View File

@ -6,15 +6,15 @@
- free software -
(C) 1998-2014 Marco Baye
(C) 1998-2020 Marco Baye
----------------------------------------------------------------------
Section: Copyright
----------------------------------------------------------------------
ACME - a crossassembler for producing 6502/6510/65c02/65816 code.
Copyright (C) 1998-2014 Marco Baye
ACME - a crossassembler for producing 6502/65c02/65816 code.
Copyright (C) 1998-2020 Marco Baye
The ACME icon was designed by Wanja "Brix" Gayk
This program is free software; you can redistribute it and/or modify
@ -39,9 +39,9 @@ Section: Introduction
ACME is a crossassembler for the 65xx range of processors. It knows
about the standard 6502, the 65c02 and the 65816. It also supports
the undocumented ("illegal") opcodes of the 6510 processor (a 6502-
variant that is used in the Commodore C=64), and the extensions added
in the C64DTV2.
the undocumented ("illegal") opcodes of the NMOS versions of the 6502,
like the 6510 variant that is used in the Commodore C=64, and it also
supports extensions to the intruction set done by other parties.
This text and the other files in the same directory only describe the
basic functions independent of the platform used. There should be
@ -61,13 +61,16 @@ The files in the docs directory and what they contain:
Help.txt ...is this text.
Illegals.txt Support for undocumented opcodes
Lib.txt Information about the library
QuickRef.txt All the basic stuff about ACME
QuickRef.txt All the basic stuff about ACME <- START HERE!
Source.txt How to compile ACME
Upgrade.txt Incompatibilities to earlier versions
cputypes/ Instruction sets of target CPUs
IMPORTANT: If you upgrade from ACME 0.05 or earlier, don't forget to
read the file "Upgrade.txt" - release 0.07 and all later ones are
slightly incompatible to 0.05 and earlier.
IMPORTANT: If you upgrade from an earlier version of ACME, don't
forget to read the files "Changes.txt" and "Upgrade.txt". Adding new
features can not always be done in a 100% compatible way, so newer
versions may behave slightly differently. To solve this problem, the
"--dialect" CLI switch can be used.
If you want to start using ACME right away, read the file
"QuickRef.txt", it contains the main help text.
@ -78,15 +81,14 @@ Section: What it can and does
----------------------------------------------------------------------
ACME is a crossassembler.
ACME can produce code for the 6502, 6510, 65c02 and 65816 processors.
ACME can produce code for the 6502, 65c02 and 65816 processors.
It does this *fast*.
It can produce at most 64 KBytes of code.
You can use global labels, local labels and anonymous labels.
It is fast.
You can use global and local macros.
You can use conditional assembly.
You can use looping assembly (There are two ways to do this; a very
simple and a very flexible one).
You can use looping assembly.
You can include other source files.
You can include binary files (either whole or parts) directly into the
output.
@ -99,6 +101,7 @@ ACME's maths parser has no problems concerning parentheses and
indirect addressing modes.
ACME's maths parser knows a shit load of different operations.
ACME supports both integer and floating point maths operations.
In addition to numbers, symbols can also hold strings or lists.
You can dump the global symbols into a file.
ACME supports a library of commonly used macros and symbols.
It always takes as many passes as are needed.

View File

@ -8,12 +8,13 @@
In release 0.87, support for some of the undocumented opcodes of the
6502 processor was added.
NMOS 6502 processor was added.
In release 0.89, some more were added.
In release 0.94.8, another one was added (lxa).
In release 0.95.3, C64DTV2 support was added, which includes these
opcodes as well.
In release 0.95.4, the remaining seven were added.
In release 0.95.6, "ANC" was removed from C64DTV2 mode.
Here are the new mnemonics, possible addressing modes and generated
opcodes (mnemonics in parentheses are used by other sources):
@ -22,15 +23,14 @@ opcodes (mnemonics in parentheses are used by other sources):
mnemonic | 8 8,x 8,y 16 16,x 16,y (8,x) (8),y | performs:
----------------+--------------------------------------+-----------
slo (aso) | 07 17 0f 1f 1b 03 13 | asl + ora
rla | 27 37 2f 3f 3b 23 33 | rol + and
rla (rln) | 27 37 2f 3f 3b 23 33 | rol + and
sre (lse) | 47 57 4f 5f 5b 43 53 | lsr + eor
rra | 67 77 6f 7f 7b 63 73 | ror + adc
rra (rrd) | 67 77 6f 7f 7b 63 73 | ror + adc
sax (axs, aax) | 87 97 8f 83 | stx + sta
lax | a7 b7 af bf a3 b3 | ldx + lda
dcp (dcm) | c7 d7 cf df db c3 d3 | dec + cmp
isc (isb, ins) | e7 f7 ef ff fb e3 f3 | inc + sbc
las (lar, lae) | bb | A,X,S = {addr} & S
These five are said to be unstable:
tas (shs, xas) | 9b | S = A & X {addr} = A&X& {H+1}
sha (axa, ahx) | 9f 93 | {addr} = A & X & {H+1}
shx (xas, sxa) | 9e | {addr} = X & {H+1}
@ -39,31 +39,37 @@ These five are said to be unstable:
| addressing mode |
mnemonic | implied #8 8 8,x 16 16,x | performs:
----------------+---------------------------------+-----------------------
anc | 0b* | A = A & arg, then C=N
asr (alr) | 4b | A = A & arg, then lsr
anc (ana, anb) | 0b* | A = A & arg, then C=N
alr/asr | 4b | A = A & arg, then lsr
arr | 6b | A = A & arg, then ror
sbx (axs, sax) | cb | X = (A & X) - arg
dop (nop, skb) | 80** 80 04 14 | skips next byte
top (nop, skw) | 0c** 0c 1c | skips next two bytes
nop (skb, skw) | ea 80 04 14 0c 1c | see the two lines above
jam (kil, hlt) | 02 | crash (wait for reset)
These two are somewhat unstable, because they involve an arbitrary value:
ane (xaa) | 8b*** | A = (A | ??) & X & arg
ane (xaa, axm) | 8b*** | A = (A | ??) & X & arg
lxa (lax, atx) | ab*** | A,X = (A | ??) & arg
Example:
!cpu 6510 ; activate additional mnemonics...
!cpu nmos6502 ; activate additional mnemonics...
lax (some_zp_label,x) ; ...and use them. No, this
dcp (other_zp_label),y ; example does not make sense.
*) Up until ACME version 0.95.1, anc#8 generated opcode 0x2b. Since
ACME version 0.95.2, anc#8 generates opcode 0x0b. Both opcodes work
the same way on a 6510. I am told 0x2b does not work on the C64DTV2.
the same way on a real NMOS 6502 CPU, but they do not work on the
C64DTV2.
Using the "--dialect" CLI switch does not change the generated opcode!
**) Note that DOP ("double nop") and TOP ("triple nop") can be used
with implied addressing, but the generated opcodes are those for
immediate and 16-bit absolute addressing, respectively. Using dop/top
with x-indexed addressing might have its uses when timing is critical
(crossing a page border adds a penalty cycle).
immediate and 16-bit absolute addressing, respectively, This way DOP
and TOP can be used to skip the following one- or two-byte
instruction.
Using DOP/TOP with x-indexed addressing might have its uses when
timing is critical (crossing a page border adds a penalty cycle).
Unless using implied addressing, DOP/TOP can also be written as NOP.
***) ANE and LXA first perform an ORA with an arbitrary(!) value and
then perform an AND with the given argument. So they are unstable and
@ -74,10 +80,8 @@ ACME will output a warning if these opcodes get assembled with a
nonzero argument.
There is no guarantee that these opcodes actually work on a given 6502
(or 6510, or 8500, or 8502) CPU. But as far as I know, nobody ever
found an unmodified C64/C128 where these illegals didn't work. That's
why I used "6510" as the CPU keyword instead of "6502illegal" or
something like that.
(or 6510, or 8500, or 8501, or 8502) CPU. But as far as I know, nobody
ever found an unmodified C64/C128 where these illegals didn't work.
These illegals will definitely *not* work on 65c02 and 65816 CPUs. But
I really should not have to tell you that ;)
@ -87,7 +91,7 @@ people use different names for them. I hope my choices are not too
exotic for your taste.
Just for the sake of completeness: Here are all the remaining opcodes
(the ones ACME won't generate even with "6510" cpu):
(the ones ACME won't generate even with "nmos6502" cpu chosen):
Opcode| Description C64DTV2
------+--------------------------------------------------------------
@ -132,4 +136,10 @@ For more information about what these opcodes do, see these documents:
Extra Instructions Of The 65XX Series CPU, Adam Vardy, 27 Sept. 1996
6502 Undocumented Opcodes, by Freddy Offenga, 5/17/1997
AAY64 (All About Your 64)
NMOS 6510 Unintended Opcodes
...but the most comprehensive work is:
"No More Secrets - NMOS 6510 Unintended Opcodes"
Download it from https://csdb.dk/release/?id=185341
or ask google for the latest version.

View File

@ -106,6 +106,10 @@ Then there are local symbols (their names starting with a '.'
character). These can only be accessed from inside the macro or zone
they were defined in (for more about macros and zones, see the file
"AllPOs.txt").
There are also "cheap locals": their names start with an '@'.
The area where these can be accessed is limited automatically by the
previous and the following global label (cheap locals are "cheap"
because you don't have to put in any extra work to limit their range).
And then there are anonymous labels (their names being sequences of
either '-' or '+' characters). They are also local (bound to their
macro/zone), but in addition to that, the "-" labels can only be used
@ -113,6 +117,7 @@ for backward references, while the "+" labels can only be used for
forward references.
In contrast to global and local labels, anonymous labels can not be
defined explicitly (as in SYMBOL = VALUE).
Each macro call automatically gets its own scope for local symbols.
Save the given example source code to a file called "tiny.a" and start
acme by typing
@ -149,7 +154,7 @@ found in the file "AllPOs.txt". Here's just a short overview:
!convtab !pet !raw !scr !scrxor !text
...for converting and outputting strings.
!do !endoffile !for !if !ifdef !ifndef !set
!do !endoffile !for !if !ifdef !ifndef !set !while
...for flow control; looping assembly and conditional assembly.
!binary !source !to
@ -170,7 +175,7 @@ found in the file "AllPOs.txt". Here's just a short overview:
!warn !error !serious
...for generating warnings, errors and serious errors.
!addr
!address
...to mark symbols as addresses, for the optional type check system.
@ -187,33 +192,57 @@ Available options are:
This is more or less useless, because the help is also shown
if ACME is run without any arguments at all.
-f, --format FORMAT set output file format ("plain", "cbm" or "apple")
-f, --format FORMAT set output file format
Use this with a bogus format type to get a list of all
supported ones (as of writing: "plain", "cbm" and "apple")
-o, --outfile FILE set output file name
Output file name and format can also be given using the "!to"
pseudo opcode. If the format is not specified, "!to" defaults
to "cbm", while the command line option defaults to "plain".
-r, --report set report file name
This creates a text listing containing the original line
number, the resulting memory address, the byte value(s) put
there and the original text line from the source file.
-l, --symbollist FILE set symbol list file name
This can also be given using the "!symbollist"/"!sl" pseudo
opcode. The switch was called "--labeldump" in older versions,
that name still works, too.
--setpc NUMBER set program counter
This can also be given in the source code using "* = NUMBER".
--vicelabels FILE set file name for label dump in VICE format
The resulting file uses a format suited for the VICE emulator.
--cpu CPU_TYPE set processor type
--setpc VALUE set program counter
This can also be given in the source code using "* = VALUE".
--cpu CPU_TYPE set target processor
This can be changed in the source code using the "!cpu" pseudo
opcode. Defaults to 6502.
Use this with a bogus cpu type to get a list of all supported
ones.
--initmem NUMBER define 'empty' memory
--initmem VALUE define 'empty' memory
This can also be given using the "!initmem" pseudo opcode.
Defaults to zero.
--maxerrors NUMBER set number of errors before exiting
If not given, defaults to 10.
--maxdepth NUMBER set recursion depth for macro calls and the
"!source" pseudo opcode. If not given, defaults to 64.
--maxdepth NUMBER set recursion depth for macro calls and !src
The default value for this is 64.
--ignore-zeroes do not determine number size by leading zeroes
Normally, using leading zeroes forces ACME to generate
oversized addressing modes, like 3-byte absolute instructions
instead of 2-byte zero page instructions.
Using this CLI switch disables this behavior.
--strict-segments turn segment overlap warnings into errors
When changing the program counter, segment overlap warnings may
be generated. Using this CLI switch turns those warnings into
errors (which is recommended).
This strict behavior may become the default in future releases!
-vDIGIT set verbosity level
Sets how much additional informational output is generated.
@ -239,6 +268,12 @@ Available options are:
"-DSYSTEM=128" could build the C128 version of the software
(using conditional assembly in your source code file).
-I PATH/TO/DIR add search path for input files
This option allows to add a directory to the search list for
input files. If an input file cannot be found in the current
working directory, all directories in the search list are
tried (the first match is used).
-W fine-tune amount and type of warnings
-Wno-label-indent
Disables warnings about labels not being in the leftmost
@ -246,6 +281,11 @@ Available options are:
-Wno-old-for
Disables warnings about the old "!for" syntax and at the
same time enables warnings about the _new_ "!for" syntax.
Internally, this does exactly the same as what happens
when the "--dialect 0.94.8" CLI switch is used...
-Wno-bin-len
Do not complain about unusual number of digits in a binary
literal.
-Wtype-mismatch
Enables type checking system (warns about wrong types).
@ -253,6 +293,28 @@ Available options are:
With this option, errors are written to the standard output
stream instead of to the standard error stream.
--msvc output errors in MS VS format
This changes the format of the error output to that used by
a certain commercial IDE.
--color uses ANSI color codes for error output
If your terminal emulation supports ANSI escape codes, use
this option to have warnings and errors displayed in color.
--fullstop use '.' as pseudo opcode prefix
This changes the prefix character used to mark pseudo opcodes
from '!' to '.' (so sources intended for other assemblers can
be converted with less effort).
--dialect VERSION behave like different version
This CLI switch tells ACME to mimic the behavior of an older
version. Use this with a bogus version to get a list of all
supported ones.
--test enable experimental features
This is for people who want to help test new features before
they are officially announced.
-V, --version show version and exit.
Platform-specific versions of ACME might offer more options.
@ -261,61 +323,119 @@ given on the command line.
----------------------------------------------------------------------
Section: The maths parser
Section: The expression parser
----------------------------------------------------------------------
ACME has a relatively powerful maths parser. This parser is used
whenever ACME expects to read a numerical value. Supported operations
include addition, subtraction, multiplication, divisions, comparisons,
shifts, negation, boolean operations and some assembler-specific stuff
like extracting the "low byte", the "high byte" or the "bank byte"
of a value.
Calculations are done using either signed 32-bit integer arithmetic or
floating point arithmetic using the C "double" data type. Symbol
values are stored the same way.
whenever ACME expects to read a value. Supported operations include
addition, subtraction, multiplication, divisions, comparisons, shifts,
negation, boolean operations and some assembler-specific stuff like
extracting the "low byte", the "high byte" or the "bank byte" of a
value.
Calculations are done using either signed (at least 32-bit) integer
arithmetic or floating point arithmetic using the C "double" data
type. Symbol values are stored the same way.
This is a list of the value formats currently known by ACME:
Examples Notes
---------------------------------------------------------------------
128 a decimal value, integer
128.5 a decimal value, floating point
$d011 hexadecimal values are indicated by either a
0xffd2 leading "$" or a leading "0x".
&1701 an octal value, indicated by "&"
%1010 binary values are indicated by either a leading "%"
%....#... or a leading "0b". In binary values, you can
0b01100110 substitute the characters "0" and "1" by "." and
"#" respectively. This way the values are much
more readable, especially when building bitmapped
objects (like C64 sprites or fonts) in your source
code.
'p' single characters in single quotes are converted to
their character code. The actual numeric value
depends on the current conversion table chosen
using the "!ct" pseudo opcode.
"player 2" double quotes indicate text strings. See below for
more information on single vs. double quotes.
[2, 3, 5, 7] brackets indicate lists. These are useful to group
[0, [x, y], 9] data, for example when passing an arbitrary number
of arguments to a macro.
poll_joy2 a global symbol
.fail a local symbol, indicated by leading "."
@loop a "cheap local", indicated by leading "@"
* the current program counter. During offset assembly,
"*" gives the value of the "Pseudo PC". Just to
make sure: The value of the program counter is
always the value that was valid at the start of
the current statement, so
!word *, *, *, *
will give the same value four times. I think most
assemblers do it this way.
In older versions of ACME, 'x' and "x" were the same thing, namely the
character code of the letter x using the currently selected encoding
table.
Since release 0.97, anything in single quotes gives the character code
(as before), while anything in double quotes is treated as a string
object. To be compatible to those older versions, ACME keeps accepting
one-char strings in a lot of places where actually single characters
are expected.
This is a list of the operators currently known by ACME:
Priority Example Meaning Alias
------------------------------------------------------------
14 sin(v) Trigonometric sine function
14 cos(v) Trigonometric cosine function
14 tan(v) Trigonometric tangent function
14 arcsin(v) Inverse of sin()
14 arccos(v) Inverse of cos()
14 arctan(v) Inverse of tan()
14 addr(v) Mark as address
14 int(v) Convert to integer
14 float(v) Convert to float
13 ! v Complement of NOT
12 v ^ w To the power of
11 - v Negate
10 v * w Multiply
10 v / w Divide
10 v DIV w Integer-Divide
10 v % w Remainder of DIV MOD
9 v + w Add
9 v - w Subtract
8 v << w Shift left ASL, LSL
8 v >> w Arithmetic shift right ASR
8 v >>> w Logical shift right LSR
7 < v Lowbyte of
7 > v Highbyte of
7 ^ v Bankbyte of
6 v <= w Lower or equal
6 v < w Lower than
6 v >= w Higher or equal
6 v > w Higher than
5 v != w Not equal <>, ><
4 v = w Equal
3 v & w Bit-wise AND AND
2 Bit-wise exclusive OR XOR
1 v | w Bit-wise OR OR
Priority Example Meaning Alias Note
----------------------------------------------------------------------
16 is_number(v) these three functions return 1 *3
16 is_list(v) if v is the correct symbol *3
16 is_string(v) type and 0 otherwise *3
16 len(v) length of list or string *2
16 sin(v) trigonometric sine function
16 cos(v) trigonometric cosine function
16 tan(v) trigonometric tangent function
16 arcsin(v) inverse of sin()
16 arccos(v) inverse of cos()
16 arctan(v) inverse of tan()
16 address(v) mark as address addr(v)
16 int(v) convert to integer
16 float(v) convert to float
15 &symbol "unpseudopc" symbol (see docs on "!pseudopc")
14 v[w] access v with index w *2
13 ! v bit-wise complement NOT
12 v ^ w to the power of
11 - v negate
10 v * w multiply
10 v / w divide
10 v DIV w integer divide
10 v % w remainder of DIV MOD
9 v + w add *3
9 v - w subtract
8 v << w shift left ASL, LSL
8 v >> w arithmetic shift right ASR
8 v >>> w logical shift right LSR
7 < v low byte of
7 > v high byte of
7 ^ v bank byte of
6 v <= w lower or equal
6 v < w lower than
6 v >= w higher or equal
6 v > w higher than
5 v != w not equal <>, >< *3
4 v = w equal *3
3 v & w bit-wise AND AND
2 bit-wise exclusive OR XOR
1 v | w bit-wise OR OR
Notes:
"*2" means this operator only works on lists and strings.
"*3" means this operator works on all three data types (numbers, lists
and strings).
All other operators only work on numbers.
Operations with higher priority are done first. Of course you can
change this using parentheses. If you prefer the aliases over the
shorthand characters, note that they must be written in capital
letters.
change this using parentheses.
Note that though there are operators to extract the "low byte", the
"high byte" and the "bank byte", there is no operator to extract the
fourth byte. If you want to access that, shift it down using ">>>" or
@ -332,41 +452,8 @@ Calculating 0^0 (zero to the power of zero) will give 1. If
you don't know why I'm telling you this, ask a mathematician. :)
This is a list of the value formats currently known by ACME:
Examples Notes
---------------------------------------------------------------------
128 a decimal value, integer
128.5 a decimal value, floating point
$d011 hexadecimal values are indicated by either a
0xffd2 leading "$" or a leading "0x".
&1701 an octal value, indicated by "&"
%010010 binary values are indicated by either a leading "%"
%....#... or a leading "0b". In binary values, you can
0b01100110 substitute the characters "0" and "1" by "." and
"#" respectively. This way the values are much
more readable, especially when building bitmapped
objects (like C64 sprites or fonts) in your source
code.
"p" character values are indicated by double or single
'q' quotes. The actual numeric value depends on the
current conversion table (none/petscii/screen),
chosen using the "!ct" pseudo opcode.
poll_joy2 a global symbol
.fail a local symbol, indicated by leading dot
* the current program counter. During offset assembly,
"*" gives the value of the "Pseudo PC". Just to
make sure: The value of the program counter is
always the value that was valid at the start of
the current statement, so
!word *, *, *, *
will give the same value four times. I think most
assemblers do it this way.
----------------------------------------------------------------------
Section: Almost, but not quite, entirely useless syntax
Section: Almost, but not quite, complete syntax
----------------------------------------------------------------------
Every ACME source code file consists of a non-negative number of
@ -376,7 +463,7 @@ or CRLF characters.
Every line consists of a non-negative number of "statements" and an
optional comment. Statements have to be separated from each other
using colon (":") characters, the comment has to be prefixed with a
semicolon (";") character.
semicolon (";") character or two slashes ("//").
Every statement consists of an optional "label" and an optional
"command". These are separated from each other using any number of
@ -386,15 +473,19 @@ issued (to spot typing errors - see Errors.txt for more info).
Every symbol name consists of these characters: "a" to "z", "A" to
"Z", "0" to "9", the underscore character "_" and all characters with
values beyond 127. The first character must not be a digit though. But
it can be a dot ("."), making the symbol a local one. Two other
possibilities for label names are "all-characters-are-minus" (then it
is an anonymous backward label) and "all-characters-are-plus" (then it
is an anonymous forward label).
it can be '.' or '@', making the symbol a local one.
Local symbols beginning with '.' are only valid inside the current
zone (marked using the "!zone" pseudo opcode) or the current macro.
Local symbols beginning with '@' are only valid between the enclosing
global labels (or inside the current macro).
Two other possibilities for label names are "all-characters-are-minus"
(then it is an anonymous backward label) and "all-characters-are-plus"
(then it is an anonymous forward label).
Every command is one of the following:
An assembler opcode
An assembler mnemonic with an optional argument
A pseudo opcode, beginning with a "!" character
A symbol definition (symbol=value)
An explicit symbol definition (SYMBOL = VALUE)
A pc definition, beginning with a "*" character
A macro call, beginning with a "+" character
...and the syntax of those things varies. :)

View File

@ -4,116 +4,197 @@
...the ACME Crossassembler for Multiple Environments
--- compatibility problems ---
--- upgrading from earlier versions ---
If you haven't used ACME before, you don't need to read this text.
It is only of use to people who upgraded from ACME 0.05 (or earlier)
to ACME 0.07 (or later).
You might encounter some slight incompatibilities: I have done a few
changes to ACME's workings.
Because backwards compatibility is the root of all evil (*g*), I did
not include any possibility to enforce the old behaviour. If one of
the following changes applies to your source files, assemble them with
this new release of ACME and then compare new and old output files.
Sorry for this inconvenience, but at least I think that there won't be
any further changes in the future.
----------------------------------------------------------------------
Section: Offset assembly / segment assembly
Upgrading from earlier releases to ACME release 0.97
----------------------------------------------------------------------
a) Single quotes vs. double quotes:
Since "anything in double quotes" is now considered to be a string,
problems can arise when trying to do a calculation with a character
code. Here are some examples:
lda #' ' ; loads 32 like before (ASCII code of space)
lda #' ' + 1 ; loads 33 like before (32 plus one)
lda #" " ; loads 32 like before (ASCII code of space)
lda #" " + 1 ; used to load 33, now fails with error!
The third example still works, because 1-char-strings are treated
just like single characters when returned by the expression parser as
an argument for a mnemonic.
However, the fourth example now fails because the expression parser
tries to add a string to an integer, which is an undefined operation.
Some examples for a related problem:
a = ' ' ; a is 32 (ASCII code of space)
b = ' ' + 1 ; b is 33 (32 plus one)
c = "!" ; c used to be 33, now it's a 1-char string
d = "!" + "!" ; d used to be 66, now it's a 2-char string
If you do not get any errors when compiling your old sources, you do
not need to worry about this problem.
If you _do_ get errors, just use single quotes instead of double
quotes. If you had to use double quotes because the quoted character
itself is a single quote, write '\'' instead (backslash escaping, see
below).
b) Backslash escaping:
Backslashes in single or double quotes are now used as escape
characters. You need to replace any backslash in older sources with a
sequence of two backslashes, so "some\string" becomes "some\\string",
and a single character '\' becomes '\\'.
If you have used backslashes as directory separators in path names (in
Windows/DOS environments), these also need changing - but instead of
using a double backslash, just use a single forward slash ('/')
instead. This has the added benefit of making the sources platform-
independent (*and* it's compatible to older ACME releases as well).
c) Character values are now unsigned:
When parsing a character in single quotes, ACME returns its character
code, according to the chosen encoding (raw/petscii/screencode). If
this resulted in a byte with its most significant bit set, the actual
number was architecture-dependent. Here's an example:
!ct pet ; choose PetSCII encoding
x = 'A' ; PetSCII 'A' is 0xc1, so MSB is set
Now x was either -63 or +193, depending on the host cpu architecture.
Since release 0.97, this example will give 193 on all architectures.
In most cases, this is not a problem, because the actual bit pattern
of the lower eight bits is the same. But if you have written any code
where the numerical value of a PetSCII character is used for
computations _in_the_source_code_, please check those computations.
Use the "--dialect 0.94.12" CLI switch to get the old behavior
concerning a) double quotes and b) backslashes. There is no way to get
the old behavior concerning c) character values, because, as explained
above, the old behavior was architecture-dependent, which is a bad
idea(tm).
----------------------------------------------------------------------
Upgrading from earlier releases to ACME release 0.95.2
----------------------------------------------------------------------
In 6510 mode, ACME now outputs 0x0b instead of 0x2b when assembling
the undocumented ("illegal") ANC #imm8 instruction. Both opcodes do
the same thing, this was only changed because all other mnemonics use
the lowest-numbered possible opcode as well.
Forcing the old behavior via the "--dialect" switch is not supported.
----------------------------------------------------------------------
Upgrading from earlier releases to ACME release 0.94.12
----------------------------------------------------------------------
The pseudo opcode "!for" has a new syntax. The old syntax still works,
but gives a warning.
You can use the "--dialect 0.94.8" CLI switch to get the old behavior.
----------------------------------------------------------------------
Upgrading from earlier releases to ACME release 0.94.8
----------------------------------------------------------------------
The pseudo opcodes "!cbm", "!subzone" and "!realpc" no longer give
warnings, but have now been disabled.
You can use the "--dialect 0.94.6" CLI switch to get the old behavior.
----------------------------------------------------------------------
Upgrading from earlier releases to ACME release 0.94.6
----------------------------------------------------------------------
The "to-the-power-of" operator ('^') is now right-associative, so
b^c^d will now give b^(c^d) instead of (b^c)^d
If you have never used the operator in this way, you don't need to
worry about it.
You can use the "--dialect 0.86" CLI switch to get the old behavior.
----------------------------------------------------------------------
Upgrading from earlier releases to ACME release 0.89
----------------------------------------------------------------------
The "logical shift right" operator has been changed. Note: This is
about ACME's expression parser and has nothing to do with the 6502
mnemonic called "LSR".
Older versions were supposed to work like this:
a = b >> c ; alias "LSR", do a logical shift right
But what they actually did depended on the compiler that was used to
create the ACME binary: many binaries did an "arithmetic shift right"
instead. This has now been fixed and changed to:
a = b >> c ; alias "ASR", do an arithmetic shift right
a = b >>> c ; alias "LSR", do a logical shift right
If you have never applied the old ">>"/"LSR" operator to a negative
value, you do not need to worry about this. If you have, please check
what you expected to happen in those instances (arithmetic or logical
shift) and update your source codes accordingly (use either ">>"/"ASR"
or ">>>"/"LSR").
Forcing the old behavior via the "--dialect" switch is not possible,
because as explained above, the old behavior was compiler-dependent
anyway.
----------------------------------------------------------------------
Upgrading from earlier releases to ACME release 0.07
----------------------------------------------------------------------
Re-defining the program counter via "* = NEW_VALUE" no longer starts
offset assembly. Instead, ACME will change its pointer into the output
buffer to the given value, so you can write your code in distinct
segments. These segments can be given in any order. After assembly,
ACME stores everything from the lowest address used to the highest
address used. Have a look at "AllPOs.txt" for an example on how to use
this facility.
Offset assembly is now done using a new pseudo opcode called
"!pseudopc". Have a look at "AllPOs.txt" for further information on
its syntax and usage.
The old way of just redefining the program counter by using more than
one "* = EXPRESSION" statements does something totally different now:
Whenever the program counter is redefined, ACME will actually change
its pointer into the output buffer, so you can write your code in
distinct segments. These segments can be given in any order. After
assembly, ACME stores everything from the lowest address used to the
highest address used. Have a look at "AllPOs.txt" for an example on
how to use this facility.
The pseudo opcode "!end" has been removed. Use "!eof" instead.
----------------------------------------------------------------------
Section: Argument order of MVP/MVN
----------------------------------------------------------------------
The mnemonic BIT can no longer be assembled without any argument. If
you want to insert the opcode only to mask the next instruction, use
!src <6502/std.a>
to get the definitions for these two macros:
+bit8 ; output $24 to mask following 1-byte instruction
+bit16 ; output $2c to mask following 2-byte instruction
The syntax of the 65816 opcodes MVN and MVP is usually given as
When using the 65816 cpu, ACME now uses the correct argument order for
the MVN and MVP mnemonics, which is:
mnemonic source_bank, destination_bank
MVN source_bank, destination_bank
All previous versions of ACME did it the other way round: First the
destination bank, then the source bank. This has been fixed, ACME now
uses the syntax given above.
----------------------------------------------------------------------
Section: Typecast
----------------------------------------------------------------------
You can use leading zeros to make ACME use a bigger addressing mode
than needed. Until now, this did not work when using labels. The
source code
label1 = $fa
Using leading zeroes in hexadecimal or binary values makes ACME use
bigger addressing modes than needed. This has now been extended to
symbols as well:
label2 = $00fa
lda $fa
lda $00fa
lda label1
lda label2
will be assembled to:
ad fa 00 lda $00fa
was assembled to:
Forcing the old behavior via the "--dialect" switch is not supported.
lda $fa
lda $00fa
lda $fa
lda $fa
Release 0.07 of ACME now correctly assembles the given source code to:
lda $fa
lda $00fa
lda $fa
lda $00fa
----------------------------------------------------------------------
Section: !endoffile
Upgrading from earlier releases to ACME release 0.04 beta
----------------------------------------------------------------------
Previous versions of ACME knew a pseudo opcode called "!end" that
marks the end of a source code file. Because the word "end" doesn't
actually specify *what* is about to end, I changed this to
"!endoffile". You can also use a short version, called "!eof". The old
PO "!end" no longer works.
The pseudo opcode "!module" has been removed. Use "!zone" instead.
Forcing the old behavior via the "--dialect" switch is not supported.
----------------------------------------------------------------------
Section: Using the BIT command without parameters
Upgrading from earlier releases to ACME release 0.03 beta
----------------------------------------------------------------------
Release 0.07 of ACME will complain if you try to assemble BIT without
any parameter. Previous versions did just output the byte $2c - a
commonly known trick to mask the following 2-byte command on the 6502
processor. If you still want to do this, use
It is no longer possible to have more than one label in a single line.
Forcing the old behavior via the "--dialect" switch is not supported.
!src <6502/std.a> ; parse library file
to include some standard macros. Then you can use
+bit8 ; output $24 to mask following 1-byte command
and
+bit16 ; output $2c to mask following 2-byte command
respectively.
That's all. Again, sorry for the inconvenience...

224
docs/cputypes/all.txt Normal file
View File

@ -0,0 +1,224 @@
ACME
...the ACME Crossassembler for Multiple Environments
--- cpu types ---
ACME supports the following cpu types (shown here as a sort of family
tree):
6502 standard
|
|\_nmos6502 (=6510) + undocumented opcodes
|
|\_c64dtv2 + BRA/SAC/SIR and some (not all!) undocumented
|
\_65c02 + BRA/PHX/PHY/PLX/PLY/STZ/TRB/TSB/...
|
|\_65816 16 bit regs, 24 bit address space, ...
|
\_r65c02 + bit manipulation instructions
|
|\_w65c02 + STP/WAI
|
\_65ce02 + Z reg, long branches, ...
|
\_4502 + MAP/EOM
|
\_m65 + 32-bit pointers, 32-bit 'Q' register
!cpu 6502
This is the official instruction set of the original NMOS 6502 CPU
designed by MOS (later CSG).
There are 151 documented opcodes.
ACME does not use "A" to indicate "accumulator addressing"; just write
the mnemonic without any argument: "LSR" will work, "LSR A" won't.
!cpu nmos6502
This instruction set includes the undocumented ("illegal") opcodes of
the NMOS 6502.
See "docs/Illegals.txt" for more info.
!cpu 6510
This is an alias for "nmos6502", because the 6510 cpu (as used in the
C64 computer) is a variant of this type.
!cpu c64dtv2
This is the cpu in version 2 of the C64DTV. It uses a superset of the
6502 instruction set. Features:
- new instructions:
BRA near_target branch always
SAC #$12 set accumulator mapping
SIR #$12 set index register mapping
- support for some (but not all!) of the undocumented opcodes.
!cpu 65c02
This is the CMOS re-design of the 6502. It seems to have also been
available from Rockwell, GTE/CMD and others. Features:
- new instructions:
BRA near_target branch always
PHX/PHY/PLX/PLY push/pull X/Y register
STZ $12 store zero in zp
STZ $12, x store zero in zp, x-indexed
STZ $1234 store zero absolute
STZ $1234, x store zero absolute, x-indexed
TRB $12 test and reset bits in zp
TRB $1234 test and reset bits absolute
TSB $12 test and set bits in zp
TSB $1234 test and set bits absolute
- new addressing modes for existing instructions:
LDA/STA/ADC/SBC ($12) zp indirect
AND/ORA/EOR/CMP ($12) zp indirect
BIT #$12 immediate
BIT $12, x zp, x-indexed
BIT $1234, x absolute, x-indexed
INC increment accumulator
DEC decrement accumulator
JMP ($1234, x) x-indexed indirect
- bugfix for flags in decimal mode
- bugfix for JMP($xxff) instruction
- undocumented opcodes are NOPs (although of different lengths)
There are 178 documented opcodes.
!cpu 65816
This is a superset of 65c02, originally designed by WDC (it seems to
have been available from GTE/CMD as well). Features:
- register sizes can be changed to 16-bit
- 24-bit address space
- several new instructions (including block transfers)
- several new addressing modes for existing instructions
There are 256 documented opcodes, but one of them ("WDM") is reserved
for future expansion.
See "docs/65816.txt" for more info.
!cpu r65c02
This is a superset of 65c02, probably originally by Rockwell. It adds
bit manipulation instructions:
BBR4 $12, near_target branch on bit reset in zp
BBS5 $12, near_target branch on bit set in zp
RMB6 $12 reset memory bit in zp
SMB7 $12 set memory bit in zp
The digit in the mnemonic is the bit number, therefore it must be in
the 0..7 range.
Chips with this instruction set seem to have been available from
Rockwell, GTE/CMD and others.
There are 210 documented opcodes.
!cpu w65c02
This is a superset of r65c02, originating at WDC. It adds two new
instructions:
STP stop (wait for reset)
WAI wait for interrupt
There are 212 documented opcodes.
!cpu 65ce02
This is a superset of r65c02, originating at CSG. Features:
- Z register
- 16-bit stack pointer
- 16-bit branches
- new instructions (including a few 16-bit operations)
- new addressing modes for existing instructions
There is a known bug: SBC does not work correctly in decimal mode.
There are 256 documented opcodes, but one of them ("AUG") is reserved
for future expansion.
ACME uses different mnemonics for old and new (long) branch
instructions:
BEQ near_target old, 8-bit offset
LBEQ far_target new, 16-bit offset
The original datasheet called BRA ("branch always") BRU ("branch
unconditional") instead. ACME accepts both mnemonics.
!cpu 4502
This is basically the same as 65ce02, but
- MAP replaces AUG
- EOM is synonymous to NOP
This cpu core can be found in the CSG4510 chip in the C65.
There are 256 documented opcodes.
!cpu m65
This is a superset of 4502 specified by the MEGA65 project. It uses
NEG:NEG and NOP as prefix bytes to extend the instruction set.
Features:
- "quad mode" (32-bit data operations on virtual register 'Q')
- "long mode" (32-bit pointer addressing for existing mnemonics)
- "quad" and "long" modes can be combined
quad mode introduces several new mnemonics:
LDQ/STQ/CPQ like LDA/STA/CMP
ADCQ/SBCQ like ADC/SBC
ANDQ/EORQ/ORQ like AND/EOR/ORA
ASLQ/LSRQ/ROLQ/RORQ like ASL/LSR/ROL/ROR
INQ/DEQ like INC/DEC
BITQ like BIT
ASRQ like ASR
The new mnemonics support most of the addressing modes of the
original mnemonics with these exceptions:
- there is no immediate addressing
- indirect-Z-indexed addressing becomes indirect addressing
- all other indexed addressing modes can only really be used
with read-modify-write instructions or LDQ, because otherwise
a part of the 'Q' value would be used as the index.
CAUTION: The STQ instruction clobbers the N and Z flags!
There is no "real" Q register, instead A/X/Y/Z are combined to form
the Q register (A holds lsb, Z holds msb), except for read-modify-
write instructions, where the 32-bit operation is performed without
using A/X/Y/Z.
To load a 32-bit immediate constant into the Q register, use the
+movq macro from the <m65/std.a> library file.
long mode brings a single new addressing mode for eight mnemonics:
LDA [$12], z contents of $12/$13/$14/$15
STA [$12], z plus z form the address
CMP [$12], z
ADC [$12], z
SBC [$12], z
AND [$12], z
EOR [$12], z
ORA [$12], z
quad and long modes combined result in another addressing mode for
eight of the new mnemonics:
LDQ [$12] contents of $12/$13/$14/$15
STQ [$12] form the address
CPQ [$12]
ADCQ [$12]
SBCQ [$12]
ANDQ [$12]
EORQ [$12]
ORQ [$12]
The NOP mnemonic is disabled for this instruction set because its
opcode is re-used internally as a prefix byte.
CAUTION: The !align pseudo opcode still inserts NOPs.

View File

@ -0,0 +1,98 @@
4502 opcode table
There are no more undocumented opcodes.
All differences to the 65ce02 are marked using '!' signs (only
opcodes 5c and ea anyway)
00 brk 01 ora (zp, x) 02 cle 03 see
04 tsb zp 05 ora zp 06 asl zp 07 rmb0 zp
08 php 09 ora #imm8 0a asl 0b tsy
0c tsb abs16 0d ora abs16 0e asl abs16 0f bbr0 zp, rel8
10 bpl rel8 11 ora (zp), y 12 ora (zp), z 13 bpl rel16
14 trb zp 15 ora zp, x 16 asl zp, x 17 rmb1 zp
18 clc 19 ora abs16, y 1a inc 1b inz
1c trb abs16 1d ora abs16, x 1e asl abs16, x 1f bbr1 zp, rel8
20 jsr abs16 21 and (zp, x) 22 jsr (abs16) 23 jsr (abs16, x)
24 bit zp 25 and zp 26 rol zp 27 rmb2 zp
28 plp 29 and #imm8 2a rol 2b tys
2c bit abs16 2d and abs16 2e rol abs16 2f bbr2 zp, rel8
30 bmi rel8 31 and (zp), y 32 and (zp), z 33 bmi rel16
34 bit zp, x 35 and zp, x 36 rol zp, x 37 rmb3 zp
38 sec 39 and abs16, y 3a dec 3b dez
3c bit abs16, x 3d and abs16, x 3e rol abs16, x 3f bbr3 zp, rel8
40 rti 41 eor (zp, x) 42 neg 43 asr
44 asr zp 45 eor zp 46 lsr zp 47 rmb4 zp
48 pha 49 eor #imm8 4a lsr 4b taz
4c jmp abs16 4d eor abs16 4e lsr abs16 4f bbr4 zp, rel8
50 bvc rel8 51 eor (zp), y 52 eor (zp), z 53 bvc rel16
54 asr zp, x 55 eor zp, x 56 lsr zp, x 57 rmb5 zp
58 cli 59 eor abs16, y 5a phy 5b tab
5c! map 5d eor abs16, x 5e lsr abs16, x 5f bbr5 zp, rel8
60 rts 61 adc (zp, x) 62 rtn #imm8 63 bsr rel16
64 stz zp 65 adc zp 66 ror zp 67 rmb6 zp
68 pla 69 adc #imm8 6a ror 6b tza
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f bbr6 zp, rel8
70 bvs rel8 71 adc (zp), y 72 adc (zp), z 73 bvs rel16
74 stz zp, x 75 adc zp, x 76 ror zp, x 77 rmb7 zp
78 sei 79 adc abs16, y 7a ply 7b tba
7c jmp (abs16, x) 7d adc abs16, x 7e ror abs16, x 7f bbr7 zp, rel8
80 bra rel8 81 sta (zp, x) 82 sta (o8, s), y 83 bra rel16
84 sty zp 85 sta zp 86 stx zp 87 smb0 zp
88 dey 89 bit #imm8 8a txa 8b sty abs16, x
8c sty abs16 8d sta abs16 8e stx abs16 8f bbs0 zp, rel8
90 bcc rel8 91 sta (zp), y 92 sta (zp), z 93 bcc rel16
94 sty zp, x 95 sta zp, x 96 stx zp, y 97 smb1 zp
98 tya 99 sta abs16, y 9a txs 9b stx abs16, y
9c stz abs16 9d sta abs16, x 9e stz abs16, x 9f bbs1 zp, rel8
a0 ldy #imm8 a1 lda (zp, x) a2 ldx #imm8 a3 ldz #imm8
a4 ldy zp a5 lda zp a6 ldx zp a7 smb2 zp
a8 tay a9 lda #imm8 aa tax ab ldz abs16
ac ldy abs16 ad lda abs16 ae ldx abs16 af bbs2 zp, rel8
b0 bcs rel8 b1 lda (zp), y b2 lda (zp), z b3 bcs rel16
b4 ldy zp, x b5 lda zp, x b6 ldx zp, y b7 smb3 zp
b8 clv b9 lda abs16, y ba tsx bb ldz abs16, x
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf bbs3 zp, rel8
c0 cpy #imm8 c1 cmp (zp, x) c2 cpz #imm8 c3 dew zp
c4 cpy zp c5 cmp zp c6 dec zp c7 smb4 zp
c8 iny c9 cmp #imm8 ca dex cb asw abs16
cc cpy abs16 cd cmp abs16 ce dec abs16 cf bbs4 zp, rel8
d0 bne rel8 d1 cmp (zp), y d2 cmp (zp), z d3 bne rel16
d4 cpz zp d5 cmp zp, x d6 dec zp, x d7 smb5 zp
d8 cld d9 cmp abs16, y da phx db phz
dc cpz abs16 dd cmp abs16, x de dec abs16, x df bbs5 zp, rel8
e0 cpx #imm8 e1 sbc (zp, x) e2 lda (o8, s), y e3 inw zp
e4 cpx zp e5 sbc zp e6 inc zp e7 smb6 zp
e8 inx e9 sbc #imm8 ea! nop/eom eb row abs16
ec cpx abs16 ed sbc abs16 ee inc abs16 ef bbs6 zp, rel8
f0 beq rel8 f1 sbc (zp), y f2 sbc (zp), z f3 beq rel16
f4 phw #imm16 f5 sbc zp, x f6 inc zp, x f7 smb7 zp
f8 sed f9 sbc abs16, y fa plx fb plz
fc phw abs16 fd sbc abs16, x fe inc abs16, x ff bbs7 zp, rel8
#imm8: 8-bit immediate value
#imm16: 16-bit immediate value (only for opcode f4)
zp: 8-bit zeropage address
abs16: 16-bit absolute address
rel8: 8-bit relative address offset
rel16: 16-bit relative address offset
o8: 8-bit offset (for stack-relative addressing, see opcodes 82 and e2)
The 4502 is a superset of the 65ce02. Opcode 5c (originally a "4-byte NOP
reserved for future expansion") has been changed to the "map" instruction,
now using implied addressing.
"map" uses the contents of the A/X/Y/Z registers to alter the memory map.
Because this might also change the current stack memory, all interrupts are
then implicitly disabled until an "eom" instruction gets executed.
"eom" stands for "end of mapping", but this is actually just a new alias for
opcode ea, the 6502-standard NOP.

View File

@ -0,0 +1,84 @@
6502 opcode table
All empty entries are undocumented opcodes.
Notice there are no documented opcodes in the fourth column.
00 brk 01 ora (zp, x) 02 03
04 05 ora zp 06 asl zp 07
08 php 09 ora #imm8 0a asl 0b
0c 0d ora abs16 0e asl abs16 0f
10 bpl rel8 11 ora (zp), y 12 13
14 15 ora zp, x 16 asl zp, x 17
18 clc 19 ora abs16, y 1a 1b
1c 1d ora abs16, x 1e asl abs16, x 1f
20 jsr abs16 21 and (zp, x) 22 23
24 bit zp 25 and zp 26 rol zp 27
28 plp 29 and #imm8 2a rol 2b
2c bit abs16 2d and abs16 2e rol abs16 2f
30 bmi rel8 31 and (zp), y 32 33
34 35 and zp, x 36 rol zp, x 37
38 sec 39 and abs16, y 3a 3b
3c 3d and abs16, x 3e rol abs16, x 3f
40 rti 41 eor (zp, x) 42 43
44 45 eor zp 46 lsr zp 47
48 pha 49 eor #imm8 4a lsr 4b
4c jmp abs16 4d eor abs16 4e lsr abs16 4f
50 bvc rel8 51 eor (zp), y 52 53
54 55 eor zp, x 56 lsr zp, x 57
58 cli 59 eor abs16, y 5a 5b
5c 5d eor abs16, x 5e lsr abs16, x 5f
60 rts 61 adc (zp, x) 62 63
64 65 adc zp 66 ror zp 67
68 pla 69 adc #imm8 6a ror 6b
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f
70 bvs rel8 71 adc (zp), y 72 73
74 75 adc zp, x 76 ror zp, x 77
78 sei 79 adc abs16, y 7a 7b
7c 7d adc abs16, x 7e ror abs16, x 7f
80 81 sta (zp, x) 82 83
84 sty zp 85 sta zp 86 stx zp 87
88 dey 89 8a txa 8b
8c sty abs16 8d sta abs16 8e stx abs16 8f
90 bcc rel8 91 sta (zp), y 92 93
94 sty zp, x 95 sta zp, x 96 stx zp, y 97
98 tya 99 sta abs16, y 9a txs 9b
9c 9d sta abs16, x 9e 9f
a0 ldy #imm8 a1 lda (zp, x) a2 ldx #imm8 a3
a4 ldy zp a5 lda zp a6 ldx zp a7
a8 tay a9 lda #imm8 aa tax ab
ac ldy abs16 ad lda abs16 ae ldx abs16 af
b0 bcs rel8 b1 lda (zp), y b2 b3
b4 ldy zp, x b5 lda zp, x b6 ldx zp, y b7
b8 clv b9 lda abs16, y ba tsx bb
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf
c0 cpy #imm8 c1 cmp (zp, x) c2 c3
c4 cpy zp c5 cmp zp c6 dec zp c7
c8 iny c9 cmp #imm8 ca dex cb
cc cpy abs16 cd cmp abs16 ce dec abs16 cf
d0 bne rel8 d1 cmp (zp), y d2 d3
d4 d5 cmp zp, x d6 dec zp, x d7
d8 cld d9 cmp abs16, y da db
dc dd cmp abs16, x de dec abs16, x df
e0 cpx #imm8 e1 sbc (zp, x) e2 e3
e4 cpx zp e5 sbc zp e6 inc zp e7
e8 inx e9 sbc #imm8 ea nop eb
ec cpx abs16 ed sbc abs16 ee inc abs16 ef
f0 beq rel8 f1 sbc (zp), y f2 f3
f4 f5 sbc zp, x f6 inc zp, x f7
f8 sed f9 sbc abs16, y fa fb
fc fd sbc abs16, x fe inc abs16, x ff
#imm8: 8-bit immediate value
zp: 8-bit zeropage address
abs16: 16-bit absolute address
rel8: 8-bit relative address offset

164
docs/cputypes/cpu 65816.txt Normal file
View File

@ -0,0 +1,164 @@
65816 opcode table
There are no more undocumented opcodes.
All differences to the 65c02 are marked using a '+' sign, except
for the #imm8 -> #imm change.
00 brk 01 ora (dp, x) 02+ cop imm8 03+ ora offs8, s
04 tsb dp 05 ora dp 06 asl dp 07+ ora [dp]
08 php 09 ora #imm 0a asl 0b+ phd
0c tsb abs16 0d ora abs16 0e asl abs16 0f+ ora abs24
10 bpl rel8 11 ora (dp), y 12 ora (dp) 13+ ora (offs8, s), y
14 trb dp 15 ora dp, x 16 asl dp, x 17+ ora [dp], y
18 clc 19 ora abs16, y 1a inc 1b+ tcs
1c trb abs16 1d ora abs16, x 1e asl abs16, x 1f+ ora abs24, x
20 jsr abs16 21 and (dp, x) 22+ jsr abs24 23+ and offs8, s
24 bit dp 25 and dp 26 rol dp 27+ and [dp]
28 plp 29 and #imm 2a rol 2b+ pld
2c bit abs16 2d and abs16 2e rol abs16 2f+ and abs24
30 bmi rel8 31 and (dp), y 32 and (dp) 33+ and (offs8, s), y
34 bit dp, x 35 and dp, x 36 rol dp, x 37+ and [dp], y
38 sec 39 and abs16, y 3a dec 3b+ tsc
3c bit abs16, x 3d and abs16, x 3e rol abs16, x 3f+ and abs24, x
40 rti 41 eor (dp, x) 42+ wdm 43+ eor offs8, s
44+ mvp src, dst 45 eor dp 46 lsr dp 47+ eor [dp]
48 pha 49 eor #imm 4a lsr 4b+ phk
4c jmp abs16 4d eor abs16 4e lsr abs16 4f+ eor abs24
50 bvc rel8 51 eor (dp), y 52 eor (dp) 53+ eor (offs8, s), y
54+ mvn src, dst 55 eor dp, x 56 lsr dp, x 57+ eor [dp], y
58 cli 59 eor abs16, y 5a phy 5b+ tcd
5c+ jmp abs24 5d eor abs16, x 5e lsr abs16, x 5f+ eor abs24, x
60 rts 61 adc (dp, x) 62+ per rel16 63+ adc offs8, s
64 stz dp 65 adc dp 66 ror dp 67+ adc [dp]
68 pla 69 adc #imm 6a ror 6b+ rtl
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f+ adc abs24
70 bvs rel8 71 adc (dp), y 72 adc (dp) 73+ adc (offs8, s), y
74 stz dp, x 75 adc dp, x 76 ror dp, x 77+ adc [dp], y
78 sei 79 adc abs16, y 7a ply 7b+ tdc
7c jmp (abs16, x) 7d adc abs16, x 7e ror abs16, x 7f+ adc abs24, x
80 bra rel8 81 sta (dp, x) 82+ brl rel16 83+ sta offs8, s
84 sty dp 85 sta dp 86 stx dp 87+ sta [dp]
88 dey 89 bit #imm 8a txa 8b+ phb
8c sty abs16 8d sta abs16 8e stx abs16 8f+ sta abs24
90 bcc rel8 91 sta (dp), y 92 sta (dp) 93+ sta (offs8, s), y
94 sty dp, x 95 sta dp, x 96 stx dp, y 97+ sta [dp], y
98 tya 99 sta abs16, y 9a txs 9b+ txy
9c stz abs16 9d sta abs16, x 9e stz abs16, x 9f+ sta abs24, x
a0 ldy #imm a1 lda (dp, x) a2 ldx #imm a3+ lda offs8, s
a4 ldy dp a5 lda dp a6 ldx dp a7+ lda [dp]
a8 tay a9 lda #imm aa tax ab+ plb
ac ldy abs16 ad lda abs16 ae ldx abs16 af+ lda abs24
b0 bcs rel8 b1 lda (dp), y b2 lda (dp) b3+ lda (offs8, s), y
b4 ldy dp, x b5 lda dp, x b6 ldx dp, y b7+ lda [dp], y
b8 clv b9 lda abs16, y ba tsx bb+ tyx
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf+ lda abs24, x
c0 cpy #imm c1 cmp (dp, x) c2+ rep #imm8 c3+ cmp offs8, s
c4 cpy dp c5 cmp dp c6 dec dp c7+ cmp [dp]
c8 iny c9 cmp #imm ca dex cb+ wai
cc cpy abs16 cd cmp abs16 ce dec abs16 cf+ cmp abs24
d0 bne rel8 d1 cmp (dp), y d2 cmp (dp) d3+ cmp (offs8, s), y
d4+ pei (dp) d5 cmp dp, x d6 dec dp, x d7+ cmp [dp], y
d8 cld d9 cmp abs16, y da phx db+ stp
dc+ jmp [abs16] dd cmp abs16, x de dec abs16, x df+ cmp abs24, x
e0 cpx #imm e1 sbc (dp, x) e2+ sep #imm8 e3+ sbc offs8, s
e4 cpx dp e5 sbc dp e6 inc dp e7+ sbc [dp]
e8 inx e9 sbc #imm ea nop eb+ xba
ec cpx abs16 ed sbc abs16 ee inc abs16 ef+ sbc abs24
f0 beq rel8 f1 sbc (dp), y f2 sbc (dp) f3+ sbc (offs8, s), y
f4+ pea abs16 f5 sbc dp, x f6 inc dp, x f7+ sbc [dp], y
f8 sed f9 sbc abs16, y fa plx fb+ xce
fc+ jsr (abs16, x) fd sbc abs16, x fe inc abs16, x ff+ sbc abs24, x
#imm: immediate value (8 or 16 bits, depends on processor status)
#imm8: 8-bit immediate value
dp: 8-bit direct page address
offs8: 8-bit offset (for stack-relative addressing)
abs16: 16-bit absolute address
abs24: 24-bit absolute address
rel8: 8-bit relative address offset
rel16: 16-bit relative address offset
src, dst: two 8-bit bank values
(CAUTION: assembler expects "mnemonic src, dst" syntax,
but machine language order is actually "opcode dst src")
The instruction set of the 65816 is a much extended superset of that
of the 65c02. Among the improvements are:
- the register widths can be switched to 16 bits
- addresses can now be 24 bits wide
- zero page is now called direct page, with an arbitrary base address
- lots of new addressing modes
- block transfer instructions
New mnemonics
-------------
02 cop imm8 coprocessor operation
6b rtl return long (fetches 24-bit address from stack)
82 brl rel16 branch long (16-bit offset)
0b phd push direct page register
4b phk push program bank register
8b phb push data bank register
62 per rel16 push effective relative address
d4 pei (dp) push effective indirect address
f4 pea abs16 push effective absolute address
2b pld pull direct page register
ab plb pull data bank register
1b tcs transfer C to stack pointer
3b tsc transfer stack pointer to C
5b tcd transfer C to direct page register
7b tdc transfer direct page register to C
('C' means the whole 16-bit accumulator, even in 8-bit mode)
9b txy transfer X to Y
bb tyx transfer Y to X
eb xba exchange high and low bytes of accumulator
fb xce exchange Carry and Emulation bits
c2 rep #imm8 clear bits in status register
e2 sep #imm8 set bits in status register
cb wai wait for interrupt
db stp wait for reset
42 wdm (reserved for future expansion)
block transfers:
44 mvp src, dst move previous (decrementing addresses)
54 mvn src, dst move next (incrementing addresses)
the arguments are bank numbers. block size minus one must be in 16-bit
accumulator. X holds source address, Y holds target address.
after these instructions, data bank register is set to "dst".
if blocks overlap:
when moving a block to a higher address, use mvp and put the highest
addresses in X/Y.
when moving a block to a lower address, use mvn and put the lowest
adresses in X/Y.
New addressing modes for existing mnemonics
-------------------------------------------
22 jsr abs24
5c jmp abs24
dc jmp [abs16]
fc jsr (abs16, x)
ora and eor adc sta lda cmp sbc
-------------------------------
03 23 43 63 83 a3 c3 e3 offs8, s
07 27 47 67 87 a7 c7 e7 [dp]
0f 2f 4f 6f 8f af cf ef abs24
13 33 53 73 93 b3 d3 f3 (offs8, s), y
17 37 57 77 97 b7 d7 f7 [dp], y
1f 3f 5f 7f 9f bf df ff abs24, x

130
docs/cputypes/cpu 65c02.txt Normal file
View File

@ -0,0 +1,130 @@
65c02 opcode table
All empty entries are undocumented opcodes.
Notice there are still no documented opcodes in the fourth column.
All differences to the original 6502 are marked using a '+' sign.
00 brk 01 ora (zp, x) 02 03
04+ tsb zp 05 ora zp 06 asl zp 07
08 php 09 ora #imm8 0a asl 0b
0c+ tsb abs16 0d ora abs16 0e asl abs16 0f
10 bpl rel8 11 ora (zp), y 12+ ora (zp) 13
14+ trb zp 15 ora zp, x 16 asl zp, x 17
18 clc 19 ora abs16, y 1a+ inc 1b
1c+ trb abs16 1d ora abs16, x 1e asl abs16, x 1f
20 jsr abs16 21 and (zp, x) 22 23
24 bit zp 25 and zp 26 rol zp 27
28 plp 29 and #imm8 2a rol 2b
2c bit abs16 2d and abs16 2e rol abs16 2f
30 bmi rel8 31 and (zp), y 32+ and (zp) 33
34+ bit zp, x 35 and zp, x 36 rol zp, x 37
38 sec 39 and abs16, y 3a+ dec 3b
3c+ bit abs16, x 3d and abs16, x 3e rol abs16, x 3f
40 rti 41 eor (zp, x) 42 43
44 45 eor zp 46 lsr zp 47
48 pha 49 eor #imm8 4a lsr 4b
4c jmp abs16 4d eor abs16 4e lsr abs16 4f
50 bvc rel8 51 eor (zp), y 52+ eor (zp) 53
54 55 eor zp, x 56 lsr zp, x 57
58 cli 59 eor abs16, y 5a+ phy 5b
5c 5d eor abs16, x 5e lsr abs16, x 5f
60 rts 61 adc (zp, x) 62 63
64+ stz zp 65 adc zp 66 ror zp 67
68 pla 69 adc #imm8 6a ror 6b
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f
70 bvs rel8 71 adc (zp), y 72+ adc (zp) 73
74+ stz zp, x 75 adc zp, x 76 ror zp, x 77
78 sei 79 adc abs16, y 7a+ ply 7b
7c+ jmp (abs16, x) 7d adc abs16, x 7e ror abs16, x 7f
80+ bra rel8 81 sta (zp, x) 82 83
84 sty zp 85 sta zp 86 stx zp 87
88 dey 89+ bit #imm8 8a txa 8b
8c sty abs16 8d sta abs16 8e stx abs16 8f
90 bcc rel8 91 sta (zp), y 92+ sta (zp) 93
94 sty zp, x 95 sta zp, x 96 stx zp, y 97
98 tya 99 sta abs16, y 9a txs 9b
9c+ stz abs16 9d sta abs16, x 9e+ stz abs16, x 9f
a0 ldy #imm8 a1 lda (zp, x) a2 ldx #imm8 a3
a4 ldy zp a5 lda zp a6 ldx zp a7
a8 tay a9 lda #imm8 aa tax ab
ac ldy abs16 ad lda abs16 ae ldx abs16 af
b0 bcs rel8 b1 lda (zp), y b2+ lda (zp) b3
b4 ldy zp, x b5 lda zp, x b6 ldx zp, y b7
b8 clv b9 lda abs16, y ba tsx bb
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf
c0 cpy #imm8 c1 cmp (zp, x) c2 c3
c4 cpy zp c5 cmp zp c6 dec zp c7
c8 iny c9 cmp #imm8 ca dex cb
cc cpy abs16 cd cmp abs16 ce dec abs16 cf
d0 bne rel8 d1 cmp (zp), y d2+ cmp (zp) d3
d4 d5 cmp zp, x d6 dec zp, x d7
d8 cld d9 cmp abs16, y da+ phx db
dc dd cmp abs16, x de dec abs16, x df
e0 cpx #imm8 e1 sbc (zp, x) e2 e3
e4 cpx zp e5 sbc zp e6 inc zp e7
e8 inx e9 sbc #imm8 ea nop eb
ec cpx abs16 ed sbc abs16 ee inc abs16 ef
f0 beq rel8 f1 sbc (zp), y f2+ sbc (zp) f3
f4 f5 sbc zp, x f6 inc zp, x f7
f8 sed f9 sbc abs16, y fa+ plx fb
fc fd sbc abs16, x fe inc abs16, x ff
#imm8: 8-bit immediate value
zp: 8-bit zeropage address
abs16: 16-bit absolute address
rel8: 8-bit relative address offset
The 65c02 is the CMOS re-design of the 6502. It has a few
improvements:
New mnemonics
-------------
test and (re-)set bits against accumulator:
04 tsb zp
0c tsb abs16
14 trb zp
1c trb abs16
push/pull x/y:
5a phy
7a ply
da phx
fa plx
store zero:
64 stz zp
74 stz zp, x
9c stz abs16
9e stz abs16, x
branch always:
80 bra rel8
New addressing modes for existing mnemonics
-------------------------------------------
zp indirect addressing without indexing:
12 ora (zp)
32 and (zp)
52 eor (zp)
72 adc (zp)
92 sta (zp)
b2 lda (zp)
d2 cmp (zp)
f2 sbc (zp)
implied ("accumulator") addressing:
1a inc
3a dec
x-indexed indirect addressing:
7c jmp (abs16, x)
three more addressing modes for BIT:
34 bit zp, x
3c bit abs16, x
89 bit #imm8

View File

@ -0,0 +1,162 @@
65ce02 opcode table
There are no more undocumented opcodes.
All differences to the r65c02 are marked using '+' or '!' signs:
'!' marks (backward-compatible) changes to existing instructions.
'+' marks new instructions.
00 brk 01 ora (zp, x) 02+ cle 03+ see
04 tsb zp 05 ora zp 06 asl zp 07 rmb0 zp
08 php 09 ora #imm8 0a asl 0b+ tsy
0c tsb abs16 0d ora abs16 0e asl abs16 0f bbr0 zp, rel8
10 bpl rel8 11 ora (zp), y 12! ora (zp), z 13+ bpl rel16
14 trb zp 15 ora zp, x 16 asl zp, x 17 rmb1 zp
18 clc 19 ora abs16, y 1a inc 1b+ inz
1c trb abs16 1d ora abs16, x 1e asl abs16, x 1f bbr1 zp, rel8
20 jsr abs16 21 and (zp, x) 22+ jsr (abs16) 23+ jsr (abs16, x)
24 bit zp 25 and zp 26 rol zp 27 rmb2 zp
28 plp 29 and #imm8 2a rol 2b+ tys
2c bit abs16 2d and abs16 2e rol abs16 2f bbr2 zp, rel8
30 bmi rel8 31 and (zp), y 32! and (zp), z 33+ bmi rel16
34 bit zp, x 35 and zp, x 36 rol zp, x 37 rmb3 zp
38 sec 39 and abs16, y 3a dec 3b+ dez
3c bit abs16, x 3d and abs16, x 3e rol abs16, x 3f bbr3 zp, rel8
40 rti 41 eor (zp, x) 42+ neg 43+ asr
44+ asr zp 45 eor zp 46 lsr zp 47 rmb4 zp
48 pha 49 eor #imm8 4a lsr 4b+ taz
4c jmp abs16 4d eor abs16 4e lsr abs16 4f bbr4 zp, rel8
50 bvc rel8 51 eor (zp), y 52! eor (zp), z 53+ bvc rel16
54+ asr zp, x 55 eor zp, x 56 lsr zp, x 57 rmb5 zp
58 cli 59 eor abs16, y 5a phy 5b+ tab
5c+ aug 5d eor abs16, x 5e lsr abs16, x 5f bbr5 zp, rel8
60 rts 61 adc (zp, x) 62+ rtn #imm8 63+ bsr rel16
64! stz zp 65 adc zp 66 ror zp 67 rmb6 zp
68 pla 69 adc #imm8 6a ror 6b+ tza
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f bbr6 zp, rel8
70 bvs rel8 71 adc (zp), y 72! adc (zp), z 73+ bvs rel16
74! stz zp, x 75 adc zp, x 76 ror zp, x 77 rmb7 zp
78 sei 79 adc abs16, y 7a ply 7b+ tba
7c jmp (abs16, x) 7d adc abs16, x 7e ror abs16, x 7f bbr7 zp, rel8
80 bra rel8 81 sta (zp, x) 82+ sta (o8, s), y 83+ bra rel16
84 sty zp 85 sta zp 86 stx zp 87 smb0 zp
88 dey 89 bit #imm8 8a txa 8b+ sty abs16, x
8c sty abs16 8d sta abs16 8e stx abs16 8f bbs0 zp, rel8
90 bcc rel8 91 sta (zp), y 92! sta (zp), z 93+ bcc rel16
94 sty zp, x 95 sta zp, x 96 stx zp, y 97 smb1 zp
98 tya 99 sta abs16, y 9a txs 9b+ stx abs16, y
9c! stz abs16 9d sta abs16, x 9e! stz abs16, x 9f bbs1 zp, rel8
a0 ldy #imm8 a1 lda (zp, x) a2 ldx #imm8 a3+ ldz #imm8
a4 ldy zp a5 lda zp a6 ldx zp a7 smb2 zp
a8 tay a9 lda #imm8 aa tax ab+ ldz abs16
ac ldy abs16 ad lda abs16 ae ldx abs16 af bbs2 zp, rel8
b0 bcs rel8 b1 lda (zp), y b2! lda (zp), z b3+ bcs rel16
b4 ldy zp, x b5 lda zp, x b6 ldx zp, y b7 smb3 zp
b8 clv b9 lda abs16, y ba tsx bb+ ldz abs16, x
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf bbs3 zp, rel8
c0 cpy #imm8 c1 cmp (zp, x) c2+ cpz #imm8 c3+ dew zp
c4 cpy zp c5 cmp zp c6 dec zp c7 smb4 zp
c8 iny c9 cmp #imm8 ca dex cb+ asw abs16
cc cpy abs16 cd cmp abs16 ce dec abs16 cf bbs4 zp, rel8
d0 bne rel8 d1 cmp (zp), y d2! cmp (zp), z d3+ bne rel16
d4+ cpz zp d5 cmp zp, x d6 dec zp, x d7 smb5 zp
d8 cld d9 cmp abs16, y da phx db+ phz
dc+ cpz abs16 dd cmp abs16, x de dec abs16, x df bbs5 zp, rel8
e0 cpx #imm8 e1 sbc (zp, x) e2+ lda (o8, s), y e3+ inw zp
e4 cpx zp e5 sbc zp e6 inc zp e7 smb6 zp
e8 inx e9 sbc #imm8 ea nop eb+ row abs16
ec cpx abs16 ed sbc abs16 ee inc abs16 ef bbs6 zp, rel8
f0 beq rel8 f1 sbc (zp), y f2! sbc (zp), z f3+ beq rel16
f4+ phw #imm16 f5 sbc zp, x f6 inc zp, x f7 smb7 zp
f8 sed f9 sbc abs16, y fa plx fb+ plz
fc+ phw abs16 fd sbc abs16, x fe inc abs16, x ff bbs7 zp, rel8
#imm8: 8-bit immediate value
#imm16: 16-bit immediate value (only for opcode f4)
zp: 8-bit zeropage address
abs16: 16-bit absolute address
rel8: 8-bit relative address offset
rel16: 16-bit relative address offset
o8: 8-bit offset (for stack-relative addressing, see opcodes 82 and e2)
The 65ce02 is a superset of the r65c02. It has several improvements:
new Z register
--------------
The "stz" mnemonic no longer means "store zero", but "store Z register"
(see opcodes 64, 74, 9c, 9e)
The "(zp)" addressing mode now becomes "(zp), z"
(see opcodes 12, 32, 52, 72, 92, b2, d2, f2)
Z defaults to zero after reset, so these changes are backward compatible
until Z is loaded with a non-zero value.
New instructions for this register:
1b inz increment Z
3b dez decrement Z
4b taz transfer A to Z
6b tza transfer Z to A
a3 ldz #imm8
ab ldz abs16
bb ldz abs16, x
c2 cpz #imm8
d4 cpz zp
db phz push Z
dc cpz abs16
fb plz pull Z
16-bit stack pointer
--------------------
02 cle clear stack extend disable
03 see set stack extend disable
0b tsy transfer stack_ptr_high to Y
2b tys transfer Y to stack_ptr_high
16-bit branches
---------------
13 bpl rel16
33 bmi rel16
53 bvc rel16
63 bsr rel16 relative jsr, "branch to subroutine"
73 bvs rel16
83 bra rel16 relative jmp
93 bcc rel16
b3 bcs rel16
d3 bne rel16
f3 beq rel16
To use these in ACME, use the mnemonics lbpl, lbmi, lbvc, ...
(except for "bsr", because there is no 8-bit version of it anyway)
new addressing modes for existing instructions
----------------------------------------------
22 jsr (abs16)
23 jsr (abs16, x)
82 sta (offset8, s), y
8b sty abs16, x
9b stx abs16, y
e2 lda (offset8, s), y
new instructions
----------------
42 neg negate A
43 asr
44 asr zp
54 asr zp, x
5b tab
5c aug "4-byte NOP reserved for future expansion"
62 rtn #imm8
7b tba
c3 dew zp
cb asw abs16
e3 inw zp
eb row abs16
f4 phw #imm16
fc phw abs16

120
docs/cputypes/cpu m65.txt Normal file
View File

@ -0,0 +1,120 @@
m65 opcode table(s)
The m65 instruction set extends the 4502 instruction set using prefix bytes.
Therefore, the "normal" opcode table is the same as for the 4502 cpu (see that
file), so this file only contains information about the extensions.
"quad mode" allows 32-bit data operations using a virtual register called 'Q'.
The mnemonics aslq/lsrq/rolq/rorq/inq/deq have five addressing modes.
The mnemonic ldq has eight addressing modes in quad mode, and a ninth when
combined with long mode.
The mnemonics stq/cpq/adcq/sbcq/andq/eorq/orq have three addressing modes in
quad mode, and a fourth when combined with long mode.
The mnemonic bitq has two addressing modes.
The mnemonic asrq has three addressing modes.
This mode is entered after a NEG:NEG (42 42) prefix, the following opcode is
then taken from this table:
00 01 02 03
04 05 orq zp 06 aslq zp 07
08 09 0a aslq 0b
0c 0d orq abs16 0e aslq abs16 0f
10 11 12 orq (zp) 13
14 15 16 aslq zp, x 17
18 19 1a inq 1b
1c 1d 1e aslq abs16, x 1f
20 21 22 23
24 bitq zp 25 andq zp 26 rolq zp 27
28 29 2a rolq 2b
2c bitq abs16 2d andq abs16 2e rolq abs16 2f
30 31 32 andq (zp) 33
34 35 36 rolq zp, x 37
38 39 3a deq 3b
3c 3d 3e rolq abs16, x 3f
40 41 42 43 asrq
44 asrq zp 45 eorq zp 46 lsrq zp 47
48 49 4a lsrq 4b
4c 4d eorq abs16 4e lsrq abs16 4f
50 51 52 eorq (zp) 53
54 asrq zp, x 55 56 lsrq zp, x 57
58 59 5a 5b
5c 5d 5e lsrq abs16, x 5f
60 61 62 63
64 65 adcq zp 66 rorq zp 67
68 69 6a rorq 6b
6c 6d adcq abs16 6e rorq abs16 6f
70 71 72 adcq (zp) 73
74 75 76 rorq zp, x 77
78 79 7a 7b
7c 7d 7e rorq abs16, x 7f
80 81 82 83
84 85 stq zp 86 87
88 89 8a 8b
8c 8d stq abs16 8e 8f
90 91 92 stq (zp) 93
94 95 96 97
98 99 9a 9b
9c 9d 9e 9f
a0 a1 a2 a3
a4 a5 ldq zp a6 a7
a8 a9 aa ab
ac ad ldq abs16 ae af
b0 b1 ldq (zp), y b2 ldq (zp) b3
b4 b5 ldq zp, x b6 b7
b8 b9 ldq abs16, y ba bb
bc bd ldq abs16, x be bf
c0 c1 c2 c3
c4 c5 cpq zp c6 deq zp c7
c8 c9 ca cb
cc cd cpq abs16 ce deq abs16 cf
d0 d1 d2 cpq (zp) d3
d4 d5 d6 deq zp, x d7
d8 d9 da db
dc dd de deq abs16, x df
e0 e1 e2 ldq (zp, s), y e3
e4 e5 sbcq zp e6 inq zp e7
e8 e9 ea eb
ec ed sbcq abs16 ee inq abs16 ef
f0 f1 f2 sbcq (zp) f3
f4 f5 f6 inq zp, x f7
f8 f9 fa fb
fc fd fe inq abs16, x ff
zp: 8-bit zeropage address
abs16: 16-bit absolute address
"long mode" adds an addressing mode using 32-bit pointers for eight existing
mnemonics. This mode is entered after a NOP (ea) prefix, the following opcode
should then be one of these:
12 ora [zp], z 32 and [zp], z 52 eor [zp], z 72 adc [zp], z
92 sta [zp], z b2 lda [zp], z d2 cmp [zp], z f2 sbc [zp], z
"quad" and "long" modes can be combined to have 32-bit data access using a
32-bit pointer. This adds another addressing mode for eight of the new
mnemonics. This mode is entered after a NEG:NEG:NOP (42 42 ea) prefix, the
following opcode should then be one of these:
12 orq [zp] 32 andq [zp] 52 eorq [zp] 72 adcq [zp]
92 stq [zp] b2 ldq [zp] d2 cpq [zp] f2 sbcq [zp]
Because the addressing modes are changed a bit by the prefix codes, here are
some of the unsupported combinations just for comparison (these result in
"Illegal combination of command and addressing mode"):
lda (zp) ; 65c02 knew this, but 65ce02 added z index!
lda [zp] ; long mode also expects z index!
ldq #imm ; quad mode has no immediate addressing!
ldq (zp), z ; quad mode does not use z index!
ldq [zp], z ; quad and long modes combined do not use z index!

View File

@ -0,0 +1,86 @@
nmos6502 opcode table
This table includes all of the unintended ("illegal") opcodes. These are
marked using '+' or '!' signs:
'+' means the instruction is supported by ACME,
'!' means ACME will use a different (but functionally equivalent) opcode.
00 brk 01 ora (zp, x) 02+ jam 03+ slo (zp, x)
04+ nop zp 05 ora zp 06 asl zp 07+ slo zp
08 php 09 ora #imm8 0a asl 0b+ anc #imm8
0c+ nop abs16 0d ora abs16 0e asl abs16 0f+ slo abs16
10 bpl rel8 11 ora (zp), y 12! jam 13+ slo (zp), y
14+ nop zp, x 15 ora zp, x 16 asl zp, x 17+ slo zp, x
18 clc 19 ora abs16, y 1a! nop 1b+ slo abs16, y
1c+ nop abs16, x 1d ora abs16, x 1e asl abs16, x 1f+ slo abs16, x
20 jsr abs16 21 and (zp, x) 22! jam 23+ rla (zp, x)
24 bit zp 25 and zp 26 rol zp 27+ rla zp
28 plp 29 and #imm8 2a rol 2b! anc #imm8
2c bit abs16 2d and abs16 2e rol abs16 2f+ rla abs16
30 bmi rel8 31 and (zp), y 32! jam 33+ rla (zp), y
34! nop zp, x 35 and zp, x 36 rol zp, x 37+ rla zp, x
38 sec 39 and abs16, y 3a! nop 3b+ rla abs16, y
3c! nop abs16, x 3d and abs16, x 3e rol abs16, x 3f+ rla abs16, x
40 rti 41 eor (zp, x) 42! jam 43+ sre (zp, x)
44! nop zp 45 eor zp 46 lsr zp 47+ sre zp
48 pha 49 eor #imm8 4a lsr 4b+ alr #imm8
4c jmp abs16 4d eor abs16 4e lsr abs16 4f+ sre abs16
50 bvc rel8 51 eor (zp), y 52! jam 53+ sre (zp), y
54! nop zp, x 55 eor zp, x 56 lsr zp, x 57+ sre zp, x
58 cli 59 eor abs16, y 5a! nop 5b+ sre abs16, y
5c! nop abs16, x 5d eor abs16, x 5e lsr abs16, x 5f+ sre abs16, x
60 rts 61 adc (zp, x) 62! jam 63+ rra (zp, x)
64! nop zp 65 adc zp 66 ror zp 67+ rra zp
68 pla 69 adc #imm8 6a ror 6b+ arr #imm8
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f+ rra abs16
70 bvs rel8 71 adc (zp), y 72! jam 73+ rra (zp), y
74! nop zp, x 75 adc zp, x 76 ror zp, x 77+ rra zp, x
78 sei 79 adc abs16, y 7a! nop 7b+ rra abs16, y
7c! nop abs16, x 7d adc abs16, x 7e ror abs16, x 7f+ rra abs16, x
80+ nop #imm8 81 sta (zp, x) 82! nop #imm8 83+ sax (zp, x)
84 sty zp 85 sta zp 86 stx zp 87+ sax zp
88 dey 89! nop #imm8 8a txa 8b+ ane #imm8
8c sty abs16 8d sta abs16 8e stx abs16 8f+ sax abs16
90 bcc rel8 91 sta (zp), y 92! jam 93+ sha (zp), y
94 sty zp, x 95 sta zp, x 96 stx zp, y 97+ sax zp, y
98 tya 99 sta abs16, y 9a txs 9b+ tas abs16, y
9c+ shy abs16, x 9d sta abs16, x 9e+ shx abs16, y 9f+ sha abs16, y
a0 ldy #imm8 a1 lda (zp, x) a2 ldx #imm8 a3+ lax (zp, x)
a4 ldy zp a5 lda zp a6 ldx zp a7+ lax zp
a8 tay a9 lda #imm8 aa tax ab+ lxa #imm8
ac ldy abs16 ad lda abs16 ae ldx abs16 af+ lax abs16
b0 bcs rel8 b1 lda (zp), y b2! jam b3+ lax (zp), y
b4 ldy zp, x b5 lda zp, x b6 ldx zp, y b7+ lax zp, y
b8 clv b9 lda abs16, y ba tsx bb+ las abs16, y
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf+ lax abs16, y
c0 cpy #imm8 c1 cmp (zp, x) c2! nop #imm8 c3+ dcp (zp, x)
c4 cpy zp c5 cmp zp c6 dec zp c7+ dcp zp
c8 iny c9 cmp #imm8 ca dex cb+ sbx #imm8
cc cpy abs16 cd cmp abs16 ce dec abs16 cf+ dcp abs16
d0 bne rel8 d1 cmp (zp), y d2! jam d3+ dcp (zp), y
d4! nop zp, x d5 cmp zp, x d6 dec zp, x d7+ dcp zp, x
d8 cld d9 cmp abs16, y da! nop db+ dcp abs16, y
dc! nop abs16, x dd cmp abs16, x de dec abs16, x df+ dcp abs16, x
e0 cpx #imm8 e1 sbc (zp, x) e2! nop #imm8 e3+ isc (zp, x)
e4 cpx zp e5 sbc zp e6 inc zp e7+ isc zp
e8 inx e9 sbc #imm8 ea nop eb! sbc #imm8
ec cpx abs16 ed sbc abs16 ee inc abs16 ef+ isc abs16
f0 beq rel8 f1 sbc (zp), y f2! jam f3+ isc (zp), y
f4! nop zp, x f5 sbc zp, x f6 inc zp, x f7+ isc zp, x
f8 sed f9 sbc abs16, y fa! nop fb+ isc abs16, y
fc! nop abs16, x fd sbc abs16, x fe inc abs16, x ff+ isc abs16, x
#imm8: 8-bit immediate value
zp: 8-bit zeropage address
abs16: 16-bit absolute address
rel8: 8-bit relative address offset

View File

@ -0,0 +1,94 @@
r65c02 opcode table
All empty entries are undocumented opcodes.
All differences to the 65c02 (all in the fourth column) are marked
using a '+' sign.
00 brk 01 ora (zp, x) 02 03
04 tsb zp 05 ora zp 06 asl zp 07+ rmb0 zp
08 php 09 ora #imm8 0a asl 0b
0c tsb abs16 0d ora abs16 0e asl abs16 0f+ bbr0 zp, rel8
10 bpl rel8 11 ora (zp), y 12 ora (zp) 13
14 trb zp 15 ora zp, x 16 asl zp, x 17+ rmb1 zp
18 clc 19 ora abs16, y 1a inc 1b
1c trb abs16 1d ora abs16, x 1e asl abs16, x 1f+ bbr1 zp, rel8
20 jsr abs16 21 and (zp, x) 22 23
24 bit zp 25 and zp 26 rol zp 27+ rmb2 zp
28 plp 29 and #imm8 2a rol 2b
2c bit abs16 2d and abs16 2e rol abs16 2f+ bbr2 zp, rel8
30 bmi rel8 31 and (zp), y 32 and (zp) 33
34 bit zp, x 35 and zp, x 36 rol zp, x 37+ rmb3 zp
38 sec 39 and abs16, y 3a dec 3b
3c bit abs16, x 3d and abs16, x 3e rol abs16, x 3f+ bbr3 zp, rel8
40 rti 41 eor (zp, x) 42 43
44 45 eor zp 46 lsr zp 47+ rmb4 zp
48 pha 49 eor #imm8 4a lsr 4b
4c jmp abs16 4d eor abs16 4e lsr abs16 4f+ bbr4 zp, rel8
50 bvc rel8 51 eor (zp), y 52 eor (zp) 53
54 55 eor zp, x 56 lsr zp, x 57+ rmb5 zp
58 cli 59 eor abs16, y 5a phy 5b
5c 5d eor abs16, x 5e lsr abs16, x 5f+ bbr5 zp, rel8
60 rts 61 adc (zp, x) 62 63
64 stz zp 65 adc zp 66 ror zp 67+ rmb6 zp
68 pla 69 adc #imm8 6a ror 6b
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f+ bbr6 zp, rel8
70 bvs rel8 71 adc (zp), y 72 adc (zp) 73
74 stz zp, x 75 adc zp, x 76 ror zp, x 77+ rmb7 zp
78 sei 79 adc abs16, y 7a ply 7b
7c jmp (abs16, x) 7d adc abs16, x 7e ror abs16, x 7f+ bbr7 zp, rel8
80 bra rel8 81 sta (zp, x) 82 83
84 sty zp 85 sta zp 86 stx zp 87+ smb0 zp
88 dey 89 bit #imm8 8a txa 8b
8c sty abs16 8d sta abs16 8e stx abs16 8f+ bbs0 zp, rel8
90 bcc rel8 91 sta (zp), y 92 sta (zp) 93
94 sty zp, x 95 sta zp, x 96 stx zp, y 97+ smb1 zp
98 tya 99 sta abs16, y 9a txs 9b
9c stz abs16 9d sta abs16, x 9e stz abs16, x 9f+ bbs1 zp, rel8
a0 ldy #imm8 a1 lda (zp, x) a2 ldx #imm8 a3
a4 ldy zp a5 lda zp a6 ldx zp a7+ smb2 zp
a8 tay a9 lda #imm8 aa tax ab
ac ldy abs16 ad lda abs16 ae ldx abs16 af+ bbs2 zp, rel8
b0 bcs rel8 b1 lda (zp), y b2 lda (zp) b3
b4 ldy zp, x b5 lda zp, x b6 ldx zp, y b7+ smb3 zp
b8 clv b9 lda abs16, y ba tsx bb
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf+ bbs3 zp, rel8
c0 cpy #imm8 c1 cmp (zp, x) c2 c3
c4 cpy zp c5 cmp zp c6 dec zp c7+ smb4 zp
c8 iny c9 cmp #imm8 ca dex cb
cc cpy abs16 cd cmp abs16 ce dec abs16 cf+ bbs4 zp, rel8
d0 bne rel8 d1 cmp (zp), y d2 cmp (zp) d3
d4 d5 cmp zp, x d6 dec zp, x d7+ smb5 zp
d8 cld d9 cmp abs16, y da phx db
dc dd cmp abs16, x de dec abs16, x df+ bbs5 zp, rel8
e0 cpx #imm8 e1 sbc (zp, x) e2 e3
e4 cpx zp e5 sbc zp e6 inc zp e7+ smb6 zp
e8 inx e9 sbc #imm8 ea nop eb
ec cpx abs16 ed sbc abs16 ee inc abs16 ef+ bbs6 zp, rel8
f0 beq rel8 f1 sbc (zp), y f2 sbc (zp) f3
f4 f5 sbc zp, x f6 inc zp, x f7+ smb7 zp
f8 sed f9 sbc abs16, y fa plx fb
fc fd sbc abs16, x fe inc abs16, x ff+ bbs7 zp, rel8
#imm8: 8-bit immediate value
zp: 8-bit zeropage address
abs16: 16-bit absolute address
rel8: 8-bit relative address offset
The r65c02 is a superset of the 65c02. It adds bit manipulation instructions:
smbB zp set bit in zp location
rmbB zp reset bit in zp location
bbsB zp, rel8 branch if bit is set in zp location
bbrB zp, rel8 branch if bit is reset in zp location
The 'B' in the mnemonic is the bit number, therefore it must be in
the 0..7 range.

View File

@ -0,0 +1,90 @@
w65c02 opcode table
All empty entries are undocumented opcodes.
All differences to the r65c02 are marked using a '+' sign (only two
opcodes anyway: cb and db)
00 brk 01 ora (zp, x) 02 03
04 tsb zp 05 ora zp 06 asl zp 07 rmb0 zp
08 php 09 ora #imm8 0a asl 0b
0c tsb abs16 0d ora abs16 0e asl abs16 0f bbr0 zp, rel8
10 bpl rel8 11 ora (zp), y 12 ora (zp) 13
14 trb zp 15 ora zp, x 16 asl zp, x 17 rmb1 zp
18 clc 19 ora abs16, y 1a inc 1b
1c trb abs16 1d ora abs16, x 1e asl abs16, x 1f bbr1 zp, rel8
20 jsr abs16 21 and (zp, x) 22 23
24 bit zp 25 and zp 26 rol zp 27 rmb2 zp
28 plp 29 and #imm8 2a rol 2b
2c bit abs16 2d and abs16 2e rol abs16 2f bbr2 zp, rel8
30 bmi rel8 31 and (zp), y 32 and (zp) 33
34 bit zp, x 35 and zp, x 36 rol zp, x 37 rmb3 zp
38 sec 39 and abs16, y 3a dec 3b
3c bit abs16, x 3d and abs16, x 3e rol abs16, x 3f bbr3 zp, rel8
40 rti 41 eor (zp, x) 42 43
44 45 eor zp 46 lsr zp 47 rmb4 zp
48 pha 49 eor #imm8 4a lsr 4b
4c jmp abs16 4d eor abs16 4e lsr abs16 4f bbr4 zp, rel8
50 bvc rel8 51 eor (zp), y 52 eor (zp) 53
54 55 eor zp, x 56 lsr zp, x 57 rmb5 zp
58 cli 59 eor abs16, y 5a phy 5b
5c 5d eor abs16, x 5e lsr abs16, x 5f bbr5 zp, rel8
60 rts 61 adc (zp, x) 62 63
64 stz zp 65 adc zp 66 ror zp 67 rmb6 zp
68 pla 69 adc #imm8 6a ror 6b
6c jmp (abs16) 6d adc abs16 6e ror abs16 6f bbr6 zp, rel8
70 bvs rel8 71 adc (zp), y 72 adc (zp) 73
74 stz zp, x 75 adc zp, x 76 ror zp, x 77 rmb7 zp
78 sei 79 adc abs16, y 7a ply 7b
7c jmp (abs16, x) 7d adc abs16, x 7e ror abs16, x 7f bbr7 zp, rel8
80 bra rel8 81 sta (zp, x) 82 83
84 sty zp 85 sta zp 86 stx zp 87 smb0 zp
88 dey 89 bit #imm8 8a txa 8b
8c sty abs16 8d sta abs16 8e stx abs16 8f bbs0 zp, rel8
90 bcc rel8 91 sta (zp), y 92 sta (zp) 93
94 sty zp, x 95 sta zp, x 96 stx zp, y 97 smb1 zp
98 tya 99 sta abs16, y 9a txs 9b
9c stz abs16 9d sta abs16, x 9e stz abs16, x 9f bbs1 zp, rel8
a0 ldy #imm8 a1 lda (zp, x) a2 ldx #imm8 a3
a4 ldy zp a5 lda zp a6 ldx zp a7 smb2 zp
a8 tay a9 lda #imm8 aa tax ab
ac ldy abs16 ad lda abs16 ae ldx abs16 af bbs2 zp, rel8
b0 bcs rel8 b1 lda (zp), y b2 lda (zp) b3
b4 ldy zp, x b5 lda zp, x b6 ldx zp, y b7 smb3 zp
b8 clv b9 lda abs16, y ba tsx bb
bc ldy abs16, x bd lda abs16, x be ldx abs16, y bf bbs3 zp, rel8
c0 cpy #imm8 c1 cmp (zp, x) c2 c3
c4 cpy zp c5 cmp zp c6 dec zp c7 smb4 zp
c8 iny c9 cmp #imm8 ca dex cb+ wai
cc cpy abs16 cd cmp abs16 ce dec abs16 cf bbs4 zp, rel8
d0 bne rel8 d1 cmp (zp), y d2 cmp (zp) d3
d4 d5 cmp zp, x d6 dec zp, x d7 smb5 zp
d8 cld d9 cmp abs16, y da phx db+ stp
dc dd cmp abs16, x de dec abs16, x df bbs5 zp, rel8
e0 cpx #imm8 e1 sbc (zp, x) e2 e3
e4 cpx zp e5 sbc zp e6 inc zp e7 smb6 zp
e8 inx e9 sbc #imm8 ea nop eb
ec cpx abs16 ed sbc abs16 ee inc abs16 ef bbs6 zp, rel8
f0 beq rel8 f1 sbc (zp), y f2 sbc (zp) f3
f4 f5 sbc zp, x f6 inc zp, x f7 smb7 zp
f8 sed f9 sbc abs16, y fa plx fb
fc fd sbc abs16, x fe inc abs16, x ff bbs7 zp, rel8
#imm8: 8-bit immediate value
zp: 8-bit zeropage address
abs16: 16-bit absolute address
rel8: 8-bit relative address offset
The w65c02 is a superset of the r65c02. It only adds two instructions:
cb wai wait for interrupt
db stp wait for reset

22
examples/Makefile Normal file
View File

@ -0,0 +1,22 @@
ASSEMBLER6502 = acme
AS_FLAGS = -v9 -Wtype-mismatch
RM = rm
PROGS = ddrv128.prg ddrv64.prg macedit.o trigono.o
all: $(PROGS)
ddrv128.prg: ddrv.a
$(ASSEMBLER6502) $(AS_FLAGS) --outfile ddrv128.prg --format cbm -DSYSTEM=128 ddrv.a
ddrv64.prg: ddrv.a
$(ASSEMBLER6502) $(AS_FLAGS) --outfile ddrv64.prg --format cbm -DSYSTEM=64 ddrv.a
macedit.o: macedit.a
$(ASSEMBLER6502) $(AS_FLAGS) --outfile macedit.o --format cbm macedit.a
trigono.o: trigono.a
$(ASSEMBLER6502) $(AS_FLAGS) --outfile trigono.o --format plain trigono.a
clean:
-$(RM) -f *.o *.tmp $(PROGS) *~ core

View File

@ -76,10 +76,12 @@
Sprite_HotspotX = 1
Sprite_HotspotY = 1
; address definitions
!addr {
; Locations to store button states, $ff = pressed, $00 = not pressed.
; Mouse uses both buttons, joystick only uses "LeftButton".
; Location to store pointer's current character coordinates.
!addr {
!if SYSTEM = 64 {
LeftButton = $a4
RightButton = $a5
@ -111,6 +113,10 @@
cia1_prb = $dc01
cia1_ddrb = $dc03
mmu_cr = $ff00 ; c128 only
; dummy value for self mod
MODIFIED16 = $ffff
};addr
; --- Label definitions
@ -422,7 +428,7 @@ StoreOF sta Sprites_OF ; set x overflow
; The initialisation routine sets the argument to the address of the
; previous IRQ routine.
mod16 = * + 1: jmp addr($ffff) ; (self-modifying)
mod16 = * + 1: jmp MODIFIED16 ; (self-modifying)
; This table is for part 8.
;OrTable !byte 0, 32, 64 ; VDC only

BIN
examples/trigono.exp2 Normal file

Binary file not shown.

View File

@ -1,4 +1,5 @@
CFLAGS = -O3 -Wall -Wstrict-prototypes
#CFLAGS = -O3 -Wall -Wextra -Wstrict-prototypes
LIBS = -lm
CC = gcc
RM = rm
@ -17,7 +18,7 @@ acme: $(OBJS)
strip acme
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h version.h acme.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
@ -31,9 +32,9 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
global.o: config.h platform.h acme.h cpu.h dynabuf.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c
macro.o: config.h acme.h alu.h dynabuf.h global.h input.h section.h symbol.h tree.h macro.h macro.c
@ -43,9 +44,9 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h macro.h output.h pseudoopcodes.h pseudoopcodes.c
pseudoopcodes.o: acme.h alu.h global.h input.h macro.h output.h symbol.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
section.o: config.h dynabuf.h global.h symbol.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c

View File

@ -18,7 +18,7 @@ acme: $(OBJS)
djp acme.exe
djp acmepmod.exe
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h version.h acme.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
@ -32,9 +32,9 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
global.o: config.h platform.h acme.h cpu.h dynabuf.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c
macro.o: config.h acme.h alu.h dynabuf.h global.h input.h section.h symbol.h tree.h macro.h macro.c
@ -44,9 +44,9 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h macro.h output.h pseudoopcodes.h pseudoopcodes.c
pseudoopcodes.o: acme.h alu.h global.h input.h macro.h output.h symbol.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
section.o: config.h dynabuf.h global.h symbol.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c

View File

@ -21,7 +21,7 @@ acme.exe: acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o inpu
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h _dos.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h version.h acme.h _dos.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
@ -35,9 +35,9 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
global.o: config.h platform.h acme.h cpu.h dynabuf.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c
macro.o: config.h acme.h alu.h dynabuf.h global.h input.h section.h symbol.h tree.h macro.h macro.c
@ -47,9 +47,9 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h macro.h output.h pseudoopcodes.h pseudoopcodes.c
pseudoopcodes.o: acme.h alu.h global.h input.h macro.h output.h symbol.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
section.o: config.h dynabuf.h global.h symbol.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c

View File

@ -1,4 +1,5 @@
CFLAGS = -O3 -mthrowback -mlibscl -Wall -Wstrict-prototypes
LINKFLAGS = -mlibscl -Wall
LIBS = -lm
CC = gcc
RM = rm
@ -13,10 +14,10 @@ OBJS = acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.
all: $(PROGS)
acme: $(OBJS)
$(CC) $(CFLAGS) -o !Unsqueezed $(OBJS) $(LIBS)
$(CC) $(LINKFLAGS) -o !Unsqueezed $(OBJS) $(LIBS)
Squeeze -f -v !Unsqueezed !ACME.!RunImage
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h acme.h acme.c
acme.o: config.h platform.h acme.h alu.h cpu.h dynabuf.h encoding.h flow.h global.h input.h macro.h mnemo.h output.h pseudoopcodes.h section.h symbol.h version.h acme.h acme.c
alu.o: config.h platform.h cpu.h dynabuf.h encoding.h global.h input.h section.h symbol.h tree.h alu.h alu.c
@ -30,9 +31,9 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc
flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c
global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
global.o: config.h platform.h acme.h cpu.h dynabuf.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c
input.o: config.h alu.h dynabuf.h global.h section.h tree.h input.h input.c
input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c
macro.o: config.h acme.h alu.h dynabuf.h global.h input.h section.h symbol.h tree.h macro.h macro.c
@ -42,9 +43,9 @@ output.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h tree.h output.h
platform.o: config.h platform.h platform.c
pseudoopcodes.o: acme.h alu.h input.h macro.h output.h pseudoopcodes.h pseudoopcodes.c
pseudoopcodes.o: acme.h alu.h global.h input.h macro.h output.h symbol.h pseudoopcodes.h pseudoopcodes.c
section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c
section.o: config.h dynabuf.h global.h symbol.h tree.h section.h section.c
symbol.o: config.h acme.h alu.h cpu.h dynabuf.h global.h input.h section.h tree.h symbol.h symbol.c

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816 code.
// Copyright (C) 1998-2009 Marco Baye
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for AmigaOS)
@ -13,7 +13,10 @@
#define PLATFORM_INIT
// convert UNIX-style pathname to Amiga-style pathname (no change)
#define PLATFORM_CONVERTPATHCHAR(a) (a)
//#define PLATFORM_CONVERTPATH(p)
// directory separator for include paths
#define DIRECTORY_SEPARATOR '\0' // actually '/', but paths ending on ':' are ok, so auto-adding '/' is bad)
// string containing the prefix for accessing files from the library tree
#define PLATFORM_LIBPREFIX "progdir:acme_lib/"

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816 code.
// Copyright (C) 1998-2009 Marco Baye
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for DOS, OS/2 and Windows)
@ -34,14 +34,17 @@ void DOS_entry(void)
}
// convert UNIX-style pathname character to DOS-style pathname character
char DOS_convert_path_char(char byte)
// convert UNIX-style pathname to DOS-style pathname
void DOS_convert_path(char *p)
{
if (byte == '/')
return '\\';
if (byte == '\\')
return '/';
return byte;
while (*p) {
if (*p == '/') {
*p = '\\';
} else if (*p == '\\') {
*p = '/';
}
++p;
}
}

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816 code.
// Copyright (C) 1998-2009 Marco Baye
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for DOS, OS/2 and Windows)
@ -16,7 +16,10 @@
#define PLATFORM_INIT DOS_entry()
// convert UNIX-style pathname to DOS-style pathname
#define PLATFORM_CONVERTPATHCHAR(a) DOS_convert_path_char(a)
#define PLATFORM_CONVERTPATH(p) DOS_convert_path(p)
// directory separator for include paths
#define DIRECTORY_SEPARATOR '\\'
// string containing the prefix for accessing files from the library tree
#define PLATFORM_LIBPREFIX DOS_lib_prefix
@ -54,8 +57,8 @@ extern char *DOS_lib_prefix; // header string of library tree
// used as PLATFORM_INIT: reads "ACME" environment variable
extern void DOS_entry(void);
// Convert UNIX-style pathname character to DOS-style pathname character
extern char DOS_convert_path_char(char);
// Convert UNIX-style pathname to DOS-style pathname
extern void DOS_convert_path(char *p);
#endif

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816 code.
// Copyright (C) 1998-2009 Marco Baye
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for RISC OS)
@ -23,7 +23,7 @@
// variables
int RISCOS_flags = 0; // used to store platform-specific flags
bits RISCOS_flags = 0; // used to store platform-specific flags
// exit handler: if throwback was used, de-register now
@ -46,17 +46,20 @@ void RISCOS_entry(void)
// convert UNIX-style pathname to RISC OS-style pathname
char RISCOS_convert_path_char(char byte)
void RISCOS_convert_path(char *p)
{
if (byte == '.')
return '/';
if (byte == '/')
return '.';
if (byte == '?')
return '#';
if (byte == '#')
return '?';
return byte;
while (*p) {
if (*p == '.') {
*p = '/';
} else if (*p == '/') {
*p = '.';
} else if (*p == '?') {
*p = '#';
} else if (*p == '#') {
*p = '?';
}
++p;
}
}

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