mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-06-01 13:41:29 +00:00
Compare commits
242 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a5bc7a48bd | ||
|
4901f44fdd | ||
|
d59b45036d | ||
|
88cc8cd886 | ||
|
5b1fabc1f5 | ||
|
beb1e178cd | ||
|
2be25080aa | ||
|
aa8d766e6c | ||
|
b2b14cb176 | ||
|
b03b217979 | ||
|
3db33bafb5 | ||
|
26168e6752 | ||
|
2acece9c60 | ||
|
6dd15f7116 | ||
|
f87ddbb5e6 | ||
|
32d59eafa3 | ||
|
a3d36ca156 | ||
|
78390cb632 | ||
|
465da8c139 | ||
|
62dd48ab9f | ||
|
b8f9bb9d36 | ||
|
ca08a1d150 | ||
|
eb138ae785 | ||
|
70b9ee222d | ||
|
a7dd713d93 | ||
|
a534d9c28a | ||
|
94f36db2e5 | ||
|
21cc635bc8 | ||
|
ecca1552d0 | ||
|
d0c824c60a | ||
|
d2683cc64d | ||
|
ca6b6d8771 | ||
|
7038cecfec | ||
|
8f432f6aa7 | ||
|
9d637eee25 | ||
|
c85081cbe4 | ||
|
296ecefa6c | ||
|
a5851cd51a | ||
|
6c869568cd | ||
|
aa51fde056 | ||
|
9f5ac5b212 | ||
|
1441da12ac | ||
|
cf167a34e4 | ||
|
be72f71faa | ||
|
89344d34ee | ||
|
1261960cad | ||
|
7f736ceccb | ||
|
3039db71e6 | ||
|
b8679e7f06 | ||
|
ceabdfb4a0 | ||
|
85f0c32ff4 | ||
|
5b37c4d24e | ||
|
beb875ff2b | ||
|
562ce98f75 | ||
|
fc913eefb6 | ||
|
28e196caab | ||
|
c3e651f4ca | ||
|
eca73fb335 | ||
|
64aa52da35 | ||
|
326f36fd4f | ||
|
c2978f7e15 | ||
|
f9a2f5f698 | ||
|
929fefe0e6 | ||
|
b32320d5f3 | ||
|
430b225208 | ||
|
f64780a3bd | ||
|
2671eef384 | ||
|
1199c75025 | ||
|
4643e841f9 | ||
|
395dcf55f3 | ||
|
8bf6bcd6eb | ||
|
ec2b7515ca | ||
|
7c82984075 | ||
|
da12925408 | ||
|
0588f0fffe | ||
|
1f74a6b8fd | ||
|
a165279e88 | ||
|
93cea56d88 | ||
|
b17203faa7 | ||
|
77e945ce88 | ||
|
02a35ac468 | ||
|
61d5144faa | ||
|
00d0462f74 | ||
|
72fc28e84c | ||
|
9db5ad6fdb | ||
|
7a0f9f9528 | ||
|
5ea2a03174 | ||
|
f164b737ad | ||
|
8c751f3552 | ||
|
8a3bdb265f | ||
|
8e4857de4c | ||
|
c03d1145f6 | ||
|
64a29e4504 | ||
|
47b1fab4fe | ||
|
9bbac556d3 | ||
|
af4a918f18 | ||
|
5bcb80ac47 | ||
|
8169cf6e06 | ||
|
8c8f425559 | ||
|
2ad075911b | ||
|
dddf3f3d10 | ||
|
636080ce25 | ||
|
3c9f21cebd | ||
|
a6eae58032 | ||
|
78e7c32507 | ||
|
bc0cd5b8ea | ||
|
98ae73381d | ||
|
64a4b336b0 | ||
|
d407faab1c | ||
|
486febcef4 | ||
|
0173eaf777 | ||
|
dfca72688b | ||
|
8eddb4f4bc | ||
|
c1d8f90fae | ||
|
f5e7f23311 | ||
|
cd09855098 | ||
|
ba168a3ea5 | ||
|
916bf9cbc8 | ||
|
5b0989ac31 | ||
|
768c80219b | ||
|
101c04e413 | ||
|
beaf86da5b | ||
|
3448cda3df | ||
|
2fbbc0324e | ||
|
c64ffcfced | ||
|
688c00f31b | ||
|
4eb3ffa149 | ||
|
c07f373b53 | ||
|
665c579470 | ||
|
5ba17ccfc4 | ||
|
4e0d82ac69 | ||
|
ccaf576e8a | ||
|
ff11dec18c | ||
|
7c732fca59 | ||
|
c055688355 | ||
|
a7ec38bff5 | ||
|
fd2ac55392 | ||
|
365306428b | ||
|
40afd3311a | ||
|
3300c9d468 | ||
|
dac11ba8c7 | ||
|
16fb63deda | ||
|
20e04e22bc | ||
|
4c938480fc | ||
|
abdea30e33 | ||
|
e908284773 | ||
|
f7c52d747c | ||
|
75bd395f2f | ||
|
440dc697ad | ||
|
4cad44f3ec | ||
|
2b1c9d06bd | ||
|
55f303c05e | ||
|
c1f62fdef5 | ||
|
4b81e40c63 | ||
|
38952534f4 | ||
|
7d4200faa4 | ||
|
60603c7350 | ||
|
a4943e1f40 | ||
|
bc0efebb3e | ||
|
2c104118eb | ||
|
5c459cad56 | ||
|
4565070849 | ||
|
ef3cbbe340 | ||
|
d1ac849272 | ||
|
54defa1add | ||
|
e3e68af762 | ||
|
7286e00855 | ||
|
bf074b830d | ||
|
669f95c238 | ||
|
0a4c13bb2e | ||
|
c4a88fa738 | ||
|
68b4409b1c | ||
|
41f9534b99 | ||
|
a4afd81f42 | ||
|
c6f443d581 | ||
|
2ad798bef2 | ||
|
63d26a9c82 | ||
|
f22907849c | ||
|
06e2612a5b | ||
|
07a7a00b1a | ||
|
c68cefcab0 | ||
|
a57a7b6c68 | ||
|
81f2d3f683 | ||
|
8fc1d4c738 | ||
|
e1744c0008 | ||
|
238eb5d626 | ||
|
cefa89c138 | ||
|
c4487b9239 | ||
|
c262cbe7b4 | ||
|
6604877b54 | ||
|
aa611df8b7 | ||
|
75d52177cc | ||
|
99d866e2e8 | ||
|
fb81d868d6 | ||
|
b31e6c4e70 | ||
|
6ff2e95da8 | ||
|
a123239d2d | ||
|
b3d818da39 | ||
|
bc68e36127 | ||
|
9628f69f4e | ||
|
f23a38de8c | ||
|
3867147615 | ||
|
7cb100c480 | ||
|
e1683b1e28 | ||
|
47f09e9804 | ||
|
a6daa92e63 | ||
|
071778e2c1 | ||
|
a5e984f158 | ||
|
53a8e9ab79 | ||
|
bb484d683e | ||
|
a915eef8e9 | ||
|
2e0c8fc9f0 | ||
|
899f8c3b0c | ||
|
a21ff667a8 | ||
|
5120d12af4 | ||
|
9603d13031 | ||
|
4979302d0d | ||
|
90dd2e0a36 | ||
|
294fe25c36 | ||
|
681cbda33e | ||
|
c0a78ccec6 | ||
|
222f06c905 | ||
|
7fd4bc6539 | ||
|
a63007c0f9 | ||
|
d53d0992aa | ||
|
a8d89e373a | ||
|
f1e5dff122 | ||
|
a6ca824eb7 | ||
|
5240b5eff4 | ||
|
9dcb622b3d | ||
|
fcbebf8343 | ||
|
651b059e67 | ||
|
ba348db03e | ||
|
8d2719db8a | ||
|
9c3d91adfa | ||
|
c3e12f91db | ||
|
b2afe0d5f4 | ||
|
b451573f00 | ||
|
b11d8771e6 | ||
|
8689aac860 | ||
|
6cd245dc76 | ||
|
56ee1d304e |
45
ACME_Lib/6502/split.a
Normal file
45
ACME_Lib/6502/split.a
Normal 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
|
|
@ -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
|
||||
+
|
||||
}
|
||||
|
|
|
@ -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
6
ACME_Lib/cbm/264/basic.a
Normal 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>
|
46
ACME_Lib/cbm/264/petscii.a
Normal file
46
ACME_Lib/cbm/264/petscii.a
Normal 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
215
ACME_Lib/cbm/264/ted.a
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
33
ACME_Lib/cbm/c64/memcopy.a
Normal file
33
ACME_Lib/cbm/c64/memcopy.a
Normal 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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
109
ACME_Lib/cbm/cia.a
Normal 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
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
20
ACME_Lib/cbm/msbstring.a
Normal 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
94
ACME_Lib/cbm/multicolor.a
Normal 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
13
ACME_Lib/m65/std.a
Normal 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
12
README.md
Normal 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
|
|
@ -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":
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
58
contrib/toacme/docs/CHANGES
Normal file
58
contrib/toacme/docs/CHANGES
Normal 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
340
contrib/toacme/docs/COPYING
Normal 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.
|
23
contrib/toacme/docs/INSTALL
Normal file
23
contrib/toacme/docs/INSTALL
Normal 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.
|
86
contrib/toacme/docs/Known problems.txt
Normal file
86
contrib/toacme/docs/Known problems.txt
Normal 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 } }
|
93
contrib/toacme/docs/README
Normal file
93
contrib/toacme/docs/README
Normal 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.
|
61
contrib/toacme/src/Makefile
Normal file
61
contrib/toacme/src/Makefile
Normal 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
|
62
contrib/toacme/src/Makefile.dos
Normal file
62
contrib/toacme/src/Makefile.dos
Normal 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
|
59
contrib/toacme/src/Makefile.mingw
Normal file
59
contrib/toacme/src/Makefile.mingw
Normal 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
|
59
contrib/toacme/src/Makefile.riscos
Normal file
59
contrib/toacme/src/Makefile.riscos
Normal 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
524
contrib/toacme/src/ab.c
Normal 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
51
contrib/toacme/src/ab.h
Normal 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
114
contrib/toacme/src/ab3.c
Normal 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
47
contrib/toacme/src/acme.c
Normal 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
41
contrib/toacme/src/acme.h
Normal 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
|
22
contrib/toacme/src/config.h
Normal file
22
contrib/toacme/src/config.h
Normal 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
265
contrib/toacme/src/f8ab.c
Normal 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
198
contrib/toacme/src/giga.c
Normal 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
158
contrib/toacme/src/gighyp.c
Normal 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;
|
||||
}
|
33
contrib/toacme/src/gighyp.h
Normal file
33
contrib/toacme/src/gighyp.h
Normal 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
219
contrib/toacme/src/hypra.c
Normal 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
118
contrib/toacme/src/io.c
Normal 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
33
contrib/toacme/src/io.h
Normal 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
77
contrib/toacme/src/main.c
Normal 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
122
contrib/toacme/src/mnemo.c
Normal 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";
|
74
contrib/toacme/src/mnemo.h
Normal file
74
contrib/toacme/src/mnemo.h
Normal 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
277
contrib/toacme/src/obj.c
Normal 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");
|
||||
}
|
46
contrib/toacme/src/pet2iso.c
Normal file
46
contrib/toacme/src/pet2iso.c
Normal 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,
|
||||
};
|
18
contrib/toacme/src/pet2iso.h
Normal file
18
contrib/toacme/src/pet2iso.h
Normal 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
|
34
contrib/toacme/src/platform.c
Normal file
34
contrib/toacme/src/platform.c
Normal 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, ®ister_set, ®ister_set);
|
||||
}
|
||||
|
||||
#else
|
||||
//
|
||||
// other OS (not that much here)
|
||||
//
|
||||
|
||||
|
||||
#endif
|
24
contrib/toacme/src/platform.h
Normal file
24
contrib/toacme/src/platform.h
Normal 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
120
contrib/toacme/src/prof.c
Normal 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);
|
||||
}
|
||||
}
|
46
contrib/toacme/src/scr2iso.c
Normal file
46
contrib/toacme/src/scr2iso.c
Normal 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,
|
||||
};
|
17
contrib/toacme/src/scr2iso.h
Normal file
17
contrib/toacme/src/scr2iso.h
Normal 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
|
99
contrib/toacme/src/version.c
Normal file
99
contrib/toacme/src/version.c
Normal 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();
|
||||
}
|
16
contrib/toacme/src/version.h
Normal file
16
contrib/toacme/src/version.h
Normal 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
49
contrib/toacme/src/vis.c
Normal 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);
|
||||
}
|
BIN
contrib/toacme/src/win/logo.ico
Normal file
BIN
contrib/toacme/src/win/logo.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
58
contrib/toacme/src/win/setRelease.sh
Normal file
58
contrib/toacme/src/win/setRelease.sh
Normal 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
|
|
@ -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.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
|
|
@ -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.
|
||||
|
|
298
docs/AllPOs.txt
298
docs/AllPOs.txt
|
@ -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.
|
||||
|
|
197
docs/Changes.txt
197
docs/Changes.txt
|
@ -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)
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
|
362
docs/Errors.txt
362
docs/Errors.txt
|
@ -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.
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. :)
|
||||
|
|
245
docs/Upgrade.txt
245
docs/Upgrade.txt
|
@ -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
224
docs/cputypes/all.txt
Normal 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.
|
98
docs/cputypes/cpu 4502.txt
Normal file
98
docs/cputypes/cpu 4502.txt
Normal 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.
|
84
docs/cputypes/cpu 6502.txt
Normal file
84
docs/cputypes/cpu 6502.txt
Normal 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
164
docs/cputypes/cpu 65816.txt
Normal 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
130
docs/cputypes/cpu 65c02.txt
Normal 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
|
162
docs/cputypes/cpu 65ce02.txt
Normal file
162
docs/cputypes/cpu 65ce02.txt
Normal 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
120
docs/cputypes/cpu m65.txt
Normal 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!
|
86
docs/cputypes/cpu nmos6502.txt
Normal file
86
docs/cputypes/cpu nmos6502.txt
Normal 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
|
94
docs/cputypes/cpu r65c02.txt
Normal file
94
docs/cputypes/cpu r65c02.txt
Normal 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.
|
90
docs/cputypes/cpu w65c02.txt
Normal file
90
docs/cputypes/cpu w65c02.txt
Normal 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
22
examples/Makefile
Normal 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
|
|
@ -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
BIN
examples/trigono.exp2
Normal file
Binary file not shown.
11
src/Makefile
11
src/Makefile
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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/"
|
||||
|
|
21
src/_dos.c
21
src/_dos.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
13
src/_dos.h
13
src/_dos.h
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user