From d152f60acd14a6cd4f52ea0967012e4031ecfbea Mon Sep 17 00:00:00 2001 From: marcobaye Date: Mon, 2 Jun 2014 00:47:46 +0000 Subject: [PATCH] Release 0.95: Added experimental type checking system (still missing docs, however). Made warning about old "!for" syntax configurable. git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@34 4df02467-bbd4-4a76-a152-e7ce94205b78 --- ACME_Lib/6502/std.a | 10 +- ACME_Lib/65816/std.a | 35 +- ACME_Lib/cbm/c128/kernel.a | 48 +- ACME_Lib/cbm/c128/mmu.a | 245 +++---- ACME_Lib/cbm/c128/vdc.a | 39 +- ACME_Lib/cbm/c128/vic.a | 22 +- ACME_Lib/cbm/c128/zeropage.a | 1172 +++++++++++++++++----------------- ACME_Lib/cbm/c64/cia1.a | 36 +- ACME_Lib/cbm/c64/cia2.a | 36 +- ACME_Lib/cbm/c64/float.a | 140 ++-- ACME_Lib/cbm/c64/georam.a | 15 +- ACME_Lib/cbm/c64/reu.a | 90 +-- ACME_Lib/cbm/c64/sid.a | 95 +-- ACME_Lib/cbm/c64/vic.a | 106 +-- ACME_Lib/cbm/kernel.a | 82 +-- docs/AllPOs.txt | 40 +- docs/Changes.txt | 13 + docs/Errors.txt | 13 +- docs/Help.txt | 2 + docs/QuickRef.txt | 52 +- examples/ddrv.a | 21 +- examples/macedit.a | 4 +- examples/me/const.a | 6 +- examples/me/out.a | 12 +- src/Makefile | 4 +- src/Makefile.dos | 4 +- src/Makefile.mingw | 6 +- src/Makefile.riscos | 4 +- src/acme.c | 16 +- src/alu.c | 126 ++-- src/alu.h | 10 +- src/basics.c | 16 + src/config.h | 6 +- src/cpu.c | 8 +- src/flow.c | 5 +- src/global.c | 9 +- src/global.h | 6 +- src/label.c | 16 +- src/mnemo.c | 72 ++- src/output.c | 11 +- src/output.h | 4 +- src/typesystem.c | 53 ++ src/typesystem.h | 25 + 43 files changed, 1516 insertions(+), 1219 deletions(-) create mode 100644 src/typesystem.c create mode 100644 src/typesystem.h diff --git a/ACME_Lib/6502/std.a b/ACME_Lib/6502/std.a index d5a8d8f..d296c4a 100644 --- a/ACME_Lib/6502/std.a +++ b/ACME_Lib/6502/std.a @@ -1,13 +1,15 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_6502_std_a !eof lib_6502_std_a = 1 ; labels and macros for plain 6502 processor -cpu_nmi = $fffa -cpu_reset = $fffc -cpu_irq = $fffe +!address { + cpu_nmi = $fffa + cpu_reset = $fffc + cpu_irq = $fffe +} ; skip byte !macro bit8 { diff --git a/ACME_Lib/65816/std.a b/ACME_Lib/65816/std.a index f7c22ea..2630419 100644 --- a/ACME_Lib/65816/std.a +++ b/ACME_Lib/65816/std.a @@ -1,21 +1,23 @@ -;ACME 0.07 +;ACME 0.95 -!ifdef Lib_65816_std_a !eof -Lib_65816_std_a = 1 +!ifdef lib_65816_std_a !eof +lib_65816_std_a = 1 ; Labels and macros for Western Digital's 65c816 processor -cpu_e_cop = $fff4 -cpu_e_abort = $fff8 -cpu_e_nmi = $fffa -cpu_e_reset = $fffc -cpu_e_irq = $fffe +!address { + cpu_e_cop = $fff4 + cpu_e_abort = $fff8 + cpu_e_nmi = $fffa + 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 = $fff4 + cpu_n_brk = $fff6 + cpu_n_abort = $fff8 + cpu_n_nmi = $fffa + cpu_n_irq = $fffe +} !macro cpu_emu {; switch to emulation mode sec @@ -71,10 +73,9 @@ cpu_n_irq = $fffe !macro inc24 .t {; increase 24-bit counter inc .t - bne .j; "*" syntax not used here because size of ".t" is unknown + bne + inc .t + 1 - bne .j + bne + inc .t + 2 -.j ++ } - diff --git a/ACME_Lib/cbm/c128/kernel.a b/ACME_Lib/cbm/c128/kernel.a index 04503ff..ad33461 100644 --- a/ACME_Lib/cbm/c128/kernel.a +++ b/ACME_Lib/cbm/c128/kernel.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c128_kernel_a !eof lib_cbm_c128_kernel_a = 1 @@ -6,27 +6,31 @@ lib_cbm_c128_kernel_a = 1 ; Taken from the web. ; Sorry, I can't give credit because I don't have the URL anymore. -k_spin_spout = $ff47 -k_close_all = $ff4a -k_c64mode = $ff4d -k_dma_call = $ff50 -k_boot_call = $ff53 -k_phoenix = $ff56 -k_lkupla = $ff59 -k_lkupsa = $ff5c -k_swapper = $ff5f -k_dlchr = $ff62 -k_pfkey = $ff65 -k_setbnk = $ff68 -k_getcfg = $ff6b -k_jsrfar = $ff6e -k_jmpfar = $ff71 -k_indfet = $ff74 -k_indsta = $ff77 -k_indcmp = $ff7a -k_primm = $ff7d -k_release_number = $ff80 +!address { + k_spin_spout = $ff47 + k_close_all = $ff4a + k_c64mode = $ff4d + k_dma_call = $ff50 + k_boot_call = $ff53 + k_phoenix = $ff56 + k_lkupla = $ff59 + k_lkupsa = $ff5c + k_swapper = $ff5f + k_dlchr = $ff62 + k_pfkey = $ff65 + k_setbnk = $ff68 + k_getcfg = $ff6b + k_jsrfar = $ff6e + k_jmpfar = $ff71 + k_indfet = $ff74 + k_indsta = $ff77 + k_indcmp = $ff7a + k_primm = $ff7d + k_release_number = $ff80 +} !source ; $ff81-$fff5 is backward compatible to older machines ; $fff6/$fff7 are unused (ff ff) -k_indirect128mode = $fff8 ; indirect vector, without JMP command! +!address { + k_indirect128mode = $fff8 ; indirect vector, without JMP command! +} ; $fffa through $ffff are cpu hardware vectors (see <6502/std.a>) diff --git a/ACME_Lib/cbm/c128/mmu.a b/ACME_Lib/cbm/c128/mmu.a index dc4363e..416fb5a 100644 --- a/ACME_Lib/cbm/c128/mmu.a +++ b/ACME_Lib/cbm/c128/mmu.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c128_mmu_a !eof lib_cbm_c128_mmu_a = 1 @@ -8,138 +8,151 @@ lib_cbm_c128_mmu_a = 1 ; registers in i/o area (i/o needs to be enabled to access these): -; 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) - ; contents of cr and all four pcr: - mmu_CR_RAMBANK_MASK = %##...... ; this controls which RAM bank is used in areas where RAM is enabled -; mmu_CR_RAMBANK_0 = %........ - mmu_CR_RAMBANK_1 = %.#...... - mmu_CR_RAMBANK_2 = %#....... ; on an unmodified c128, there is no ram bank 2 (0 will be used instead) - mmu_CR_RAMBANK_3 = %##...... ; on an unmodified c128, there is no ram bank 3 (1 will be used instead) +!address { + ; 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) +} +; contents of cr and all four pcr: +mmu_CR_RAMBANK_MASK = %##...... ; this controls which RAM bank is used in areas where RAM is enabled +;mmu_CR_RAMBANK_0 = %........ +mmu_CR_RAMBANK_1 = %.#...... +mmu_CR_RAMBANK_2 = %#....... ; on an unmodified c128, there is no ram bank 2 (0 will be used instead) +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_INTFUNCROM = %...#.... - mmu_CR_HIGH_EXTFUNCROM = %..#..... - mmu_CR_HIGH_RAM = %..##.... +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_INTFUNCROM = %...#.... +mmu_CR_HIGH_EXTFUNCROM = %..#..... +mmu_CR_HIGH_RAM = %..##.... - mmu_CR_MID_MASK = %....##.. ; this controls the "middle area" (8000..bfff) -; mmu_CR_MID_SYSROM = %........ ; this is the upper half of basic - mmu_CR_MID_INTFUNCROM = %.....#.. - mmu_CR_MID_EXTFUNCROM = %....#... - mmu_CR_MID_RAM = %....##.. +mmu_CR_MID_MASK = %....##.. ; this controls the "middle area" (8000..bfff) +;mmu_CR_MID_SYSROM = %........ ; this is the upper half of basic +mmu_CR_MID_INTFUNCROM = %.....#.. +mmu_CR_MID_EXTFUNCROM = %....#... +mmu_CR_MID_RAM = %....##.. - mmu_CR_LOW_MASK = %......#. ; this controls the "low area" (4000..7fff) -; mmu_CR_LOW_SYSROM = %........ ; this is the lower half of basic - mmu_CR_LOW_RAM = %......#. +mmu_CR_LOW_MASK = %......#. ; this controls the "low area" (4000..7fff) +;mmu_CR_LOW_SYSROM = %........ ; this is the lower half of basic +mmu_CR_LOW_RAM = %......#. - mmu_CR_IO_MASK = %.......# ; this controls i/o space (d000..dfff) -; mmu_CR_IO_ON = %........ - mmu_CR_IO_OFF = %.......# ; if i/o is off, contents depend on "high area" +mmu_CR_IO_MASK = %.......# ; this controls i/o space (d000..dfff) +;mmu_CR_IO_ON = %........ +mmu_CR_IO_OFF = %.......# ; if i/o is off, contents depend on "high area" - ; configuration register values used by C128 firmware (lookup table at $f7f0, see end of file): - mmu_CR_BANK0 = $3f ; full 64 KiB ram bank 0 - mmu_CR_BANK1 = $7f ; full 64 KiB ram bank 1 - mmu_CR_BANK2 = $bf ; full 64 KiB ram bank 2 - mmu_CR_BANK3 = $ff ; full 64 KiB ram bank 3 - mmu_CR_BANK4 = $16 ; 32 KiB bank 0; 32 KiB IFROM with i/o overlay - mmu_CR_BANK5 = $56 ; 32 KiB bank 1; 32 KiB IFROM with i/o overlay - mmu_CR_BANK6 = $96 ; 32 KiB bank 2; 32 KiB IFROM with i/o overlay - mmu_CR_BANK7 = $d6 ; 32 KiB bank 3; 32 KiB IFROM with i/o overlay - 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 - ; 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) - ; EFROM means external function ROM (socket in a REU, for example) +; configuration register values used by C128 firmware (lookup table at $f7f0, see end of file): +mmu_CR_BANK0 = $3f ; full 64 KiB ram bank 0 +mmu_CR_BANK1 = $7f ; full 64 KiB ram bank 1 +mmu_CR_BANK2 = $bf ; full 64 KiB ram bank 2 +mmu_CR_BANK3 = $ff ; full 64 KiB ram bank 3 +mmu_CR_BANK4 = $16 ; 32 KiB bank 0; 32 KiB IFROM with i/o overlay +mmu_CR_BANK5 = $56 ; 32 KiB bank 1; 32 KiB IFROM with i/o overlay +mmu_CR_BANK6 = $96 ; 32 KiB bank 2; 32 KiB IFROM with i/o overlay +mmu_CR_BANK7 = $d6 ; 32 KiB bank 3; 32 KiB IFROM with i/o overlay +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 +; 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) +; EFROM means external function ROM (socket in a REU, for example) -; mode configuration register -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_UNUSED = %.....##. ; always set - mmu_MCR_8502MODE = %.......# ; setting this to zero switches to Z80 cpu +!address { + ; mode configuration register + 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_UNUSED = %.....##. ; always set +mmu_MCR_8502MODE = %.......# ; setting this to zero switches to Z80 cpu -; ram configuration register -mmu_rcr = $d506 - ; contents: - mmu_RCR_VICBANK_MASK = %##...... ; this controls which RAM bank is "seen" by VIC -; mmu_RCR_VICBANK_0 = %........ - mmu_RCR_VICBANK_1 = %.#...... - mmu_RCR_VICBANK_2 = %#....... ; on an unmodified c128, there is no ram bank 2 (0 will be used instead) - mmu_RCR_VICBANK_3 = %##...... ; on an unmodified c128, there is no ram bank 3 (1 will be used instead) +!address { + ; ram configuration register + mmu_rcr = $d506 +} +; contents: +mmu_RCR_VICBANK_MASK = %##...... ; this controls which RAM bank is "seen" by VIC +;mmu_RCR_VICBANK_0 = %........ +mmu_RCR_VICBANK_1 = %.#...... +mmu_RCR_VICBANK_2 = %#....... ; on an unmodified c128, there is no ram bank 2 (0 will be used instead) +mmu_RCR_VICBANK_3 = %##...... ; on an unmodified c128, there is no ram bank 3 (1 will be used instead) - mmu_RCR_RAMBLOCK_MASK = %..##.... ; on an unmodified c128, these bits are irrelevant (they select 256 KiB of 1 MiB of memory) -; mmu_RCR_RAMBLOCK_0 = %........ - mmu_RCR_RAMBLOCK_1 = %...#.... ; on an unmodified c128, there is only ram block 0 - mmu_RCR_RAMBLOCK_2 = %..#..... ; on an unmodified c128, there is only ram block 0 - mmu_RCR_RAMBLOCK_3 = %..##.... ; on an unmodified c128, there is only ram block 0 +mmu_RCR_RAMBLOCK_MASK = %..##.... ; on an unmodified c128, these bits are irrelevant (they select 256 KiB of 1 MiB of memory) +;mmu_RCR_RAMBLOCK_0 = %........ +mmu_RCR_RAMBLOCK_1 = %...#.... ; on an unmodified c128, there is only ram block 0 +mmu_RCR_RAMBLOCK_2 = %..#..... ; on an unmodified c128, there is only ram block 0 +mmu_RCR_RAMBLOCK_3 = %..##.... ; on an unmodified c128, there is only ram block 0 - mmu_RCR_SHARE_MASK = %....##.. -; mmu_RCR_SHARE_NONE = %........ - mmu_RCR_SHARE_BOTTOM = %.....#.. ; system default - mmu_RCR_SHARE_TOP = %....#... +mmu_RCR_SHARE_MASK = %....##.. +;mmu_RCR_SHARE_NONE = %........ +mmu_RCR_SHARE_BOTTOM = %.....#.. ; system default +mmu_RCR_SHARE_TOP = %....#... - mmu_RCR_SHARESIZE_MASK = %......## -; mmu_RCR_SHARESIZE_1K = %........ ; system default - mmu_RCR_SHARESIZE_4K = %.......# - mmu_RCR_SHARESIZE_8K = %......#. - mmu_RCR_SHARESIZE_16K = %......## +mmu_RCR_SHARESIZE_MASK = %......## +;mmu_RCR_SHARESIZE_1K = %........ ; system default +mmu_RCR_SHARESIZE_4K = %.......# +mmu_RCR_SHARESIZE_8K = %......#. +mmu_RCR_SHARESIZE_16K = %......## -; 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) - mmu_PxH_UNUSED = %####.... ; always set +!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) +} +mmu_PxH_UNUSED = %####.... ; always set - mmu_PxH_RAMBLOCK_MASK = %....##.. -; mmu_PxH_RAMBLOCK_0 = %........ - mmu_PxH_RAMBLOCK_1 = %.....#.. ; on an unmodified c128, there is only ram block 0 - mmu_PxH_RAMBLOCK_2 = %....#... ; on an unmodified c128, there is only ram block 0 - mmu_PxH_RAMBLOCK_3 = %....##.. ; on an unmodified c128, there is only ram block 0 +mmu_PxH_RAMBLOCK_MASK = %....##.. +;mmu_PxH_RAMBLOCK_0 = %........ +mmu_PxH_RAMBLOCK_1 = %.....#.. ; on an unmodified c128, there is only ram block 0 +mmu_PxH_RAMBLOCK_2 = %....#... ; on an unmodified c128, there is only ram block 0 +mmu_PxH_RAMBLOCK_3 = %....##.. ; on an unmodified c128, there is only ram block 0 - mmu_PxH_RAMBANK_MASK = %......## -; mmu_PxH_RAMBANK_0 = %........ - mmu_PxH_RAMBANK_1 = %.......# - mmu_PxH_RAMBANK_2 = %......#. ; on an unmodified c128, there is no ram bank 2 (0 will be used instead) - mmu_PxH_RAMBANK_3 = %......## ; on an unmodified c128, there is no ram bank 3 (1 will be used instead) +mmu_PxH_RAMBANK_MASK = %......## +;mmu_PxH_RAMBANK_0 = %........ +mmu_PxH_RAMBANK_1 = %.......# +mmu_PxH_RAMBANK_2 = %......#. ; on an unmodified c128, there is no ram bank 2 (0 will be used instead) +mmu_PxH_RAMBANK_3 = %......## ; on an unmodified c128, there is no ram bank 3 (1 will be used instead) + +!address { + ; version register + mmu_vr = $d50b ; read-only, value is $20 +} +mmu_VR_BANKS_MASK = %####.... ; 2 ram banks +mmu_VR_VERSION_MASK = %....#### ; mmu version 0 -; version register -mmu_vr = $d50b ; read-only, value is $20 - mmu_VR_BANKS_MASK = %####.... ; 2 ram banks - mmu_VR_VERSION_MASK = %....#### ; mmu version 0 ; reading addresses up until $d5ff returns $ff ; these registers are always available (in *every* memory configuration) unless C64 mode is entered: -; configuration register -mmu_cr = $ff00 ; always use this instead of $d500 -; 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) +!address { + ; configuration register + mmu_cr = $ff00 ; always use this instead of $d500 + ; 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) -; the c128 ROMs contain a look-up table to convert bank numbers to their -; corresponding configuration register values: -; romc_* needs "high rom area" enabled ($c000..$ffff) -romc_bank_to_cr_table = $f7f0 ; 3f 7f bf ff 16 56 96 d6 2a 6a aa ea 06 0a 01 00 + ; the c128 ROMs contain a look-up table to convert bank numbers to their + ; corresponding configuration register values: + ; romc_* needs "high rom area" enabled ($c000..$ffff) + romc_bank_to_cr_table = $f7f0 ; 3f 7f bf ff 16 56 96 d6 2a 6a aa ea 06 0a 01 00 +} diff --git a/ACME_Lib/cbm/c128/vdc.a b/ACME_Lib/cbm/c128/vdc.a index faf90f7..b0741af 100644 --- a/ACME_Lib/cbm/c128/vdc.a +++ b/ACME_Lib/cbm/c128/vdc.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c128_vdc_a !eof lib_cbm_c128_vdc_a = 1 @@ -135,14 +135,17 @@ vdcattr_B = %......#. ; blue vdcattr_I = %.......# ; intensity -; direct registers -vdc_state = $d600 ; READING this location yields status flags: - vdcstate_READY = %#....... ; RAM access is finished - vdcstate_LIGHTPEN = %.#...... ; light pen has been activated - vdcstate_IN_BORDER = %..#..... ; electron beam is in upper or lower border - vdcstate_VERSIONMASK = %...##### ; vdc version (0, 1 or 2) -vdc_reg = $d600 ; WRITING this location selects an indirect register -vdc_data = $d601 ; data of selected indirect register +!address { + ; direct registers + vdc_state = $d600 ; READING this location yields status flags, see below + vdc_reg = $d600 ; WRITING this location selects an indirect register + vdc_data = $d601 ; data of selected indirect register +} +; status flags in vdc_state: +vdcstate_READY = %#....... ; RAM access is finished +vdcstate_LIGHTPEN = %.#...... ; light pen has been activated +vdcstate_IN_BORDER = %..#..... ; electron beam is in upper or lower border +vdcstate_VERSIONMASK = %...##### ; vdc version (0, 1 or 2) ; indirect registers (default value, see $e179 in C128 kernal) @@ -219,11 +222,13 @@ vdcr_sync_polarity = $25 ; -- only in VDC 8568 vdcr_HSYNC_POLARITY = %#....... vdcr_VSYNC_POLARITY = %.#...... -; the c128 ROMs contain look-up tables to convert vic color values to vdc color -; values and vice-versa: -; rom4_* needs "low rom area" enabled ($4000..$7fff) -; rom8_* needs "middle rom area" enabled ($8000..$bfff) -; romc_* needs "high rom area" enabled ($c000..$ffff) -rom4_vic_to_vdc_color_table = $6a4c ; 00 0f 08 07 0b 04 02 0d 0a 0c 09 06 01 05 03 0e -rom8_vdc_to_vic_color_table = $81f3 ; 00 0c 06 0e 05 0d 0b 03 02 0a 08 04 09 07 0f 01 -romc_vic_to_vdc_color_table = $ce5c ; 00 0f 08 07 0b 04 02 0d 0a 0c 09 06 01 05 03 0e +!address { + ; the c128 ROMs contain look-up tables to convert vic color values to vdc color + ; values and vice-versa: + ; rom4_* needs "low rom area" enabled ($4000..$7fff) + ; rom8_* needs "middle rom area" enabled ($8000..$bfff) + ; romc_* needs "high rom area" enabled ($c000..$ffff) + rom4_vic_to_vdc_color_table = $6a4c ; 00 0f 08 07 0b 04 02 0d 0a 0c 09 06 01 05 03 0e + rom8_vdc_to_vic_color_table = $81f3 ; 00 0c 06 0e 05 0d 0b 03 02 0a 08 04 09 07 0f 01 + romc_vic_to_vdc_color_table = $ce5c ; 00 0f 08 07 0b 04 02 0d 0a 0c 09 06 01 05 03 0e +} diff --git a/ACME_Lib/cbm/c128/vic.a b/ACME_Lib/cbm/c128/vic.a index 4353abf..812a2f4 100644 --- a/ACME_Lib/cbm/c128/vic.a +++ b/ACME_Lib/cbm/c128/vic.a @@ -1,17 +1,19 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c128_vic_a !eof lib_cbm_c128_vic_a = 1 !source ; registers 0..2e -; registers only present in the C128 variant of this chip: -vic_keyboard = $d02f -vic_clock = $d030 +!address { + ; registers only present in the C128 variant of this chip: + vic_keyboard = $d02f + vic_clock = $d030 -; 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 + ; 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 +} diff --git a/ACME_Lib/cbm/c128/zeropage.a b/ACME_Lib/cbm/c128/zeropage.a index cb21565..84c0f47 100644 --- a/ACME_Lib/cbm/c128/zeropage.a +++ b/ACME_Lib/cbm/c128/zeropage.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c128_zeropage_a !eof lib_cbm_c128_zeropage_a = 1 @@ -17,592 +17,594 @@ lib_cbm_c128_zeropage_a = 1 ; z_bitmsk, given as $da and $116d ; z_dejavu, given as $0a02 and $1221 -z_d8502 = $00 -z_d6510 = $00 -z_r8502 = $01 -z_r6510 = $01 -z_bank = $02 -z_pc_hi = $03 -z_pc_lo = $04 -z_s_reg = $05 -z_a_reg = $06 -z_x_reg = $07 -z_y_reg = $08 -z_stkptr = $09 -z_integr = $09 -z_charac = $09 - ; labels from MONITOR - z_pcb = $02 - z_pch = $03 - z_pcl = $04 - z_flgs = $05 - z_acc = $06 - z_xr = $07 - z_yr = $08 - z_sp = $09 -z_endchr = $0a -z_trmpos = $0b -z_verck = $0c -z_count = $0d -z_dimflg = $0e -z_valtyp = $0f -z_intflg = $10 -z_garbfl = $11 -z_dores = $11 -z_subflg = $12 -z_inpflg = $13 -z_domask = $14 -z_tansgn = $14 -z_channl = $15 -z_poker = $15 -z_linnum = $16 -z_temppt = $18 -z_lastpt = $19 -z_tempst = $1b -z_index = $24 -z_index1 = $24 -z_index2 = $26 ; given as $24 in german manual, which is probably wrong -z_resho = $28 -z_resmoh = $29 -z_addend = $2a -z_resmo = $2a -z_reslo = $2b -z_txttab = $2d -z_vartab = $2f -z_arytab = $31 -z_strend = $33 -z_fretop = $35 -z_frespc = $37 -z_max_mem_1 = $39 -z_curlin = $3b -z_txtptr = $3d -z_form = $3f -z_fndpnt = $3f -z_datlin = $41 -z_datptr = $43 -z_inpptr = $45 -z_varnam = $47 -z_fdecpt = $49 -z_varpnt = $49 -z_lstpnt = $4b -z_andmsk = $4b -z_forpnt = $4b -z_eormsk = $4c -z_vartxt = $4d -z_opptr = $4d -z_opmask = $4f -z_grbpnt = $50 -z_tempf3 = $50 -z_defpnt = $50 -z_dscpnt = $52 -z_helper = $55 -z_jmper = $56 -z_oldov = $58 -z_tempf1 = $59 -z_arypnt = $5a -z_highds = $5a -z_hightr = $5c -z_tempf2 = $5e -z_deccnt = $5f -z_grbtop = $61 -z_dptflg = $61 -z_lowtr = $61 -z_expsgn = $62 -z_fac1 = $63 -z_degree = $69 -z_sgnflg = $69 -z_argexp = $6a -z_strng1 = $70 -z_arisgn = $70 -z_facov = $71 -z_strng2 = $72 -z_polypt = $72 -z_curtol = $72 -z_fbufpt = $72 -z_autinc = $74 -z_mvdflg = $76 -z_noze = $77 -z_sprnum = $77 -z_keynum = $77 -z_hulp = $78 -z_keysiz = $78 -z_syntmp = $79 -z_dsdesc = $7a -z_tos = $7d -z_runmod = $7f -z_parsts = $80 -z_point = $80 -z_parstx = $81 -z_oldstk = $82 -z_colsel = $83 -z_multicolor_1 = $84 -z_multicolor_2 = $85 -z_foreground = $86 -z_scale_x = $87 -z_scale_y = $89 -z_stopnb = $8b -z_grapnt = $8c -z_vtemp1 = $8e -z_vtemp2 = $8f -z_status = $90 -z_stkey = $91 -z_svxt = $92 -; z_verck = $93 ; already given as $0c ! -z_c3po = $94 -z_bsour = $95 -z_syno = $96 -z_xsav = $97 -z_ldtnd = $98 -z_dfltn = $99 -z_dflto = $9a -z_prty = $9b -z_dpsw = $9c -z_msgflg = $9d -z_ptr1 = $9e -z_t1 = $9e -z_ptr2 = $9f -z_t2 = $9f -z_time = $a0 -z_r2d2 = $a3 -z_pcntr = $a3 -z_bsour1 = $a4 -; z_count = $a5 ; already given as $0d ! -z_cntdn = $a5 -z_bufpt = $a6 -z_inbit = $a7 -z_bitci = $a8 -z_rinone = $a9 -z_ridata = $aa -z_riprty = $ab -z_sal = $ac -z_sah = $ad -z_eal = $ae -z_eah = $af -z_cmpo = $b0 -z_tape1 = $b2 -z_bitts = $b4 -z_nxtbit = $b5 -z_rodata = $b6 -z_fnlen = $b7 -z_la = $b8 -z_sa = $b9 -z_fa = $ba -z_fnadr = $bb -z_roprty = $bd -z_fsblk = $be -z_drive = $bf -z_cas1 = $c0 -z_stal = $c1 -z_stah = $c2 -z_memuss = $c3 -z_data = $c5 -z_ba = $c6 -z_fnbank = $c7 -z_ribuf = $c8 -z_robuf = $ca -z_keytab = $cc -z_imparm = $ce -z_ndx = $d0 -z_kyndx = $d1 -z_keyidx = $d2 -z_shflag = $d3 -z_sfdx = $d4 -z_lstx = $d5 -z_crsw = $d6 -z_mode = $d7 -z_graphm = $d8 -z_charen = $d9 -z_sedsal = $da -z_sedeal = $dc -z_sedt1 = $de -z_sedt2 = $df +!address { + z_d8502 = $00 + z_d6510 = $00 + z_r8502 = $01 + z_r6510 = $01 + z_bank = $02 + z_pc_hi = $03 + z_pc_lo = $04 + z_s_reg = $05 + z_a_reg = $06 + z_x_reg = $07 + z_y_reg = $08 + z_stkptr = $09 + z_integr = $09 + z_charac = $09 + ; labels from MONITOR + z_pcb = $02 + z_pch = $03 + z_pcl = $04 + z_flgs = $05 + z_acc = $06 + z_xr = $07 + z_yr = $08 + z_sp = $09 + z_endchr = $0a + z_trmpos = $0b + z_verck = $0c + z_count = $0d + z_dimflg = $0e + z_valtyp = $0f + z_intflg = $10 + z_garbfl = $11 + z_dores = $11 + z_subflg = $12 + z_inpflg = $13 + z_domask = $14 + z_tansgn = $14 + z_channl = $15 + z_poker = $15 + z_linnum = $16 + z_temppt = $18 + z_lastpt = $19 + z_tempst = $1b + z_index = $24 + z_index1 = $24 + z_index2 = $26 ; given as $24 in german manual, which is probably wrong + z_resho = $28 + z_resmoh = $29 + z_addend = $2a + z_resmo = $2a + z_reslo = $2b + z_txttab = $2d + z_vartab = $2f + z_arytab = $31 + z_strend = $33 + z_fretop = $35 + z_frespc = $37 + z_max_mem_1 = $39 + z_curlin = $3b + z_txtptr = $3d + z_form = $3f + z_fndpnt = $3f + z_datlin = $41 + z_datptr = $43 + z_inpptr = $45 + z_varnam = $47 + z_fdecpt = $49 + z_varpnt = $49 + z_lstpnt = $4b + z_andmsk = $4b + z_forpnt = $4b + z_eormsk = $4c + z_vartxt = $4d + z_opptr = $4d + z_opmask = $4f + z_grbpnt = $50 + z_tempf3 = $50 + z_defpnt = $50 + z_dscpnt = $52 + z_helper = $55 + z_jmper = $56 + z_oldov = $58 + z_tempf1 = $59 + z_arypnt = $5a + z_highds = $5a + z_hightr = $5c + z_tempf2 = $5e + z_deccnt = $5f + z_grbtop = $61 + z_dptflg = $61 + z_lowtr = $61 + z_expsgn = $62 + z_fac1 = $63 + z_degree = $69 + z_sgnflg = $69 + z_argexp = $6a + z_strng1 = $70 + z_arisgn = $70 + z_facov = $71 + z_strng2 = $72 + z_polypt = $72 + z_curtol = $72 + z_fbufpt = $72 + z_autinc = $74 + z_mvdflg = $76 + z_noze = $77 + z_sprnum = $77 + z_keynum = $77 + z_hulp = $78 + z_keysiz = $78 + z_syntmp = $79 + z_dsdesc = $7a + z_tos = $7d + z_runmod = $7f + z_parsts = $80 + z_point = $80 + z_parstx = $81 + z_oldstk = $82 + z_colsel = $83 + z_multicolor_1 = $84 + z_multicolor_2 = $85 + z_foreground = $86 + z_scale_x = $87 + z_scale_y = $89 + z_stopnb = $8b + z_grapnt = $8c + z_vtemp1 = $8e + z_vtemp2 = $8f + z_status = $90 + z_stkey = $91 + z_svxt = $92 + ; z_verck = $93 ; already given as $0c ! + z_c3po = $94 + z_bsour = $95 + z_syno = $96 + z_xsav = $97 + z_ldtnd = $98 + z_dfltn = $99 + z_dflto = $9a + z_prty = $9b + z_dpsw = $9c + z_msgflg = $9d + z_ptr1 = $9e + z_t1 = $9e + z_ptr2 = $9f + z_t2 = $9f + z_time = $a0 + z_r2d2 = $a3 + z_pcntr = $a3 + z_bsour1 = $a4 + ; z_count = $a5 ; already given as $0d ! + z_cntdn = $a5 + z_bufpt = $a6 + z_inbit = $a7 + z_bitci = $a8 + z_rinone = $a9 + z_ridata = $aa + z_riprty = $ab + z_sal = $ac + z_sah = $ad + z_eal = $ae + z_eah = $af + z_cmpo = $b0 + z_tape1 = $b2 + z_bitts = $b4 + z_nxtbit = $b5 + z_rodata = $b6 + z_fnlen = $b7 + z_la = $b8 + z_sa = $b9 + z_fa = $ba + z_fnadr = $bb + z_roprty = $bd + z_fsblk = $be + z_drive = $bf + z_cas1 = $c0 + z_stal = $c1 + z_stah = $c2 + z_memuss = $c3 + z_data = $c5 + z_ba = $c6 + z_fnbank = $c7 + z_ribuf = $c8 + z_robuf = $ca + z_keytab = $cc + z_imparm = $ce + z_ndx = $d0 + z_kyndx = $d1 + z_keyidx = $d2 + z_shflag = $d3 + z_sfdx = $d4 + z_lstx = $d5 + z_crsw = $d6 + z_mode = $d7 + z_graphm = $d8 + z_charen = $d9 + z_sedsal = $da + z_sedeal = $dc + z_sedt1 = $de + z_sedt2 = $df -; z_keysiz = $da ; already given as $78 ! -z_keylen = $db -; z_keynum = $dc ; already given as $77 ! -z_keynxt = $dd -z_keybnk = $de -z_keytmp = $df + ; z_keysiz = $da ; already given as $78 ! + z_keylen = $db + ; z_keynum = $dc ; already given as $77 ! + z_keynxt = $dd + z_keybnk = $de + z_keytmp = $df -z_bitmsk = $da -z_saver = $db + z_bitmsk = $da + z_saver = $db -z_pnt = $e0 -z_user = $e2 -z_scbot = $e4 -z_sctop = $e5 -z_sclf = $e6 -z_scrt = $e7 -z_lsxp = $e8 -z_lstp = $e9 -z_indx = $ea -z_tblx = $eb -z_pntr = $ec -z_lines = $ed -z_columns = $ee -z_datax = $ef -z_lstchr = $f0 -z_color = $f1 -z_tcolor = $f2 -z_rvs = $f3 -z_qtsw = $f4 -z_insrt = $f5 -z_insflg = $f6 -z_locks = $f7 -z_scroll = $f8 -z_beeper = $f9 -z_lofbuf = $ff -z_fbuffr = $0100 -z_xcnt = $0110 -z_dosf1l = $0111 -z_dosds1 = $0112 -z_dosf2l = $0113 -z_dosds2 = $0114 -z_dosf2a = $0115 -z_dosofl = $0117 -z_dosofh = $0119 -z_dosla = $011b -z_dosfa = $011c -z_dossa = $011d -z_dosrcl = $011e -z_dosbnk = $011f -z_dosdid = $0120 -z_didchk = $0122 -z_bnr = $0123 -z_enr = $0124 -z_dolr = $0125 -z_flag = $0126 -z_swe = $0127 -z_usgn = $0128 -z_uexp = $0129 -z_vn = $012a -z_chsn = $012b -z_vf = $012c -z_nf = $012d -z_posp = $012e -z_fesp = $012f -z_etof = $0130 -z_cform = $0131 -z_sno = $0132 -z_blfd = $0133 -z_begfd = $0134 -z_lfor = $0135 -z_endfd = $0136 -z_sysstk = $0137 -z_buf = $0200 - ; the following block is omitted in the german C128 manual - z_fetch = $02a2 - z_fetchvec = $02aa - z_stash = $02af - z_stavec = $02b9 - z_cmpare = $02c8 - z_cmpvec = $02c8 - z_jsrfar = $02cd - z_jmpfar = $02e3 -z_esc_fn_vec = $02fc -z_bnkvec = $02fe -z_ierror = $0300 -z_icrnch = $0304 -z_iqplop = $0306 -z_igone = $0308 -z_ieval = $030a -z_iesclk = $030c -z_iescpr = $030e -z_iescex = $0310 -z_itime = $0312 -z_iirq = $0314 -z_ibrk = $0316 -z_inmi = $0318 -z_iopen = $031a -z_iclose = $031c -z_ichkin = $031e -z_ichkout = $0320 -z_iclrch = $0322 -z_ibasin = $0324 -z_ibasout = $0326 -z_istop = $0328 -z_igetin = $032a -z_iclall = $032c -z_exmon = $032e -z_iload = $0330 -z_isave = $0332 - ; the following block is omitted in the german C128 manual - z_ctlvec = $0334 - z_shfvec = $0336 - z_escvec = $0338 - z_keyvec = $033a - z_keychk = $033c - z_decode = $033e - z_decode_shift = $0340 - z_decode_cbm = $0342 - z_decode_ctrl = $0344 - z_decode_alt = $0346 - z_decode_caps = $0348 - z_keyd = $034a - z_tabmap = $0354 - z_bitabl = $035e - z_lat = $0362 - z_fat = $036c - z_sat = $0376 - z_chrget = $0380 - z_chrgot = $0386 - z_qnum = $0390 -z_ind_sub_ram0 = $039f -z_ind_sub_ram1 = $03ab -z_indin1_ram1 = $03b7 -z_indin2 = $03c0 -z_indtxt = $03c9 -z_zero = $03d2 -z_current_bank = $03d5 -z_tmpdes = $03d6 -z_fin_bank = $03da -z_savsiz = $03db -z_bits = $03df -z_sprtmp_1 = $03e0 -z_sprtmp_2 = $03e1 -z_fg_bg = $03e2 -z_fg_mc1 = $03e3 -z_vicscn = $0400 -z_system = $0a00 -z_dejavu = $0a02 -z_palnts = $0a03 -z_init_status = $0a04 -z_memstr = $0a05 -z_memsiz = $0a07 -z_irqtmp = $0a09 -z_caston = $0a0b -z_kika26 = $0a0c -z_stupid = $0a0d -z_timout = $0a0e -z_enabl = $0a0f -z_m51ctr = $0a10 -z_m51cdr = $0a11 -z_m51ajb = $0a12 -z_rsstat = $0a14 -z_bitnum = $0a15 -z_baudof = $0a16 -z_ridbe = $0a18 -z_ridbs = $0a19 -z_rodbs = $0a1a -z_rodbe = $0a1b -z_serial = $0a1c -z_timer = $0a1d -z_xmax = $0a20 -z_pause = $0a21 -z_rptflg = $0a22 -z_kount = $0a23 -z_delay = $0a24 -z_lstshf = $0a25 -z_blnon = $0a26 -z_blnsw = $0a27 -z_blnct = $0a28 -z_gdbln = $0a29 -z_gdcol = $0a2a + z_pnt = $e0 + z_user = $e2 + z_scbot = $e4 + z_sctop = $e5 + z_sclf = $e6 + z_scrt = $e7 + z_lsxp = $e8 + z_lstp = $e9 + z_indx = $ea + z_tblx = $eb + z_pntr = $ec + z_lines = $ed + z_columns = $ee + z_datax = $ef + z_lstchr = $f0 + z_color = $f1 + z_tcolor = $f2 + z_rvs = $f3 + z_qtsw = $f4 + z_insrt = $f5 + z_insflg = $f6 + z_locks = $f7 + z_scroll = $f8 + z_beeper = $f9 + z_lofbuf = $ff + z_fbuffr = $0100 + z_xcnt = $0110 + z_dosf1l = $0111 + z_dosds1 = $0112 + z_dosf2l = $0113 + z_dosds2 = $0114 + z_dosf2a = $0115 + z_dosofl = $0117 + z_dosofh = $0119 + z_dosla = $011b + z_dosfa = $011c + z_dossa = $011d + z_dosrcl = $011e + z_dosbnk = $011f + z_dosdid = $0120 + z_didchk = $0122 + z_bnr = $0123 + z_enr = $0124 + z_dolr = $0125 + z_flag = $0126 + z_swe = $0127 + z_usgn = $0128 + z_uexp = $0129 + z_vn = $012a + z_chsn = $012b + z_vf = $012c + z_nf = $012d + z_posp = $012e + z_fesp = $012f + z_etof = $0130 + z_cform = $0131 + z_sno = $0132 + z_blfd = $0133 + z_begfd = $0134 + z_lfor = $0135 + z_endfd = $0136 + z_sysstk = $0137 + z_buf = $0200 + ; this block is not in the german C128 manual: + z_fetch = $02a2 + z_fetchvec = $02aa + z_stash = $02af + z_stavec = $02b9 + z_cmpare = $02c8 + z_cmpvec = $02c8 + z_jsrfar = $02cd + z_jmpfar = $02e3 + z_esc_fn_vec = $02fc + z_bnkvec = $02fe + z_ierror = $0300 + z_icrnch = $0304 + z_iqplop = $0306 + z_igone = $0308 + z_ieval = $030a + z_iesclk = $030c + z_iescpr = $030e + z_iescex = $0310 + z_itime = $0312 + z_iirq = $0314 + z_ibrk = $0316 + z_inmi = $0318 + z_iopen = $031a + z_iclose = $031c + z_ichkin = $031e + z_ichkout = $0320 + z_iclrch = $0322 + z_ibasin = $0324 + z_ibasout = $0326 + z_istop = $0328 + z_igetin = $032a + z_iclall = $032c + z_exmon = $032e + z_iload = $0330 + z_isave = $0332 + ; this block is not in the german C128 manual: + z_ctlvec = $0334 + z_shfvec = $0336 + z_escvec = $0338 + z_keyvec = $033a + z_keychk = $033c + z_decode = $033e + z_decode_shift = $0340 + z_decode_cbm = $0342 + z_decode_ctrl = $0344 + z_decode_alt = $0346 + z_decode_caps = $0348 + z_keyd = $034a + z_tabmap = $0354 + z_bitabl = $035e + z_lat = $0362 + z_fat = $036c + z_sat = $0376 + z_chrget = $0380 + z_chrgot = $0386 + z_qnum = $0390 + z_ind_sub_ram0 = $039f + z_ind_sub_ram1 = $03ab + z_indin1_ram1 = $03b7 + z_indin2 = $03c0 + z_indtxt = $03c9 + z_zero = $03d2 + z_current_bank = $03d5 + z_tmpdes = $03d6 + z_fin_bank = $03da + z_savsiz = $03db + z_bits = $03df + z_sprtmp_1 = $03e0 + z_sprtmp_2 = $03e1 + z_fg_bg = $03e2 + z_fg_mc1 = $03e3 + z_vicscn = $0400 + z_system = $0a00 + z_dejavu = $0a02 + z_palnts = $0a03 + z_init_status = $0a04 + z_memstr = $0a05 + z_memsiz = $0a07 + z_irqtmp = $0a09 + z_caston = $0a0b + z_kika26 = $0a0c + z_stupid = $0a0d + z_timout = $0a0e + z_enabl = $0a0f + z_m51ctr = $0a10 + z_m51cdr = $0a11 + z_m51ajb = $0a12 + z_rsstat = $0a14 + z_bitnum = $0a15 + z_baudof = $0a16 + z_ridbe = $0a18 + z_ridbs = $0a19 + z_rodbs = $0a1a + z_rodbe = $0a1b + z_serial = $0a1c + z_timer = $0a1d + z_xmax = $0a20 + z_pause = $0a21 + z_rptflg = $0a22 + z_kount = $0a23 + z_delay = $0a24 + z_lstshf = $0a25 + z_blnon = $0a26 + z_blnsw = $0a27 + z_blnct = $0a28 + z_gdbln = $0a29 + z_gdcol = $0a2a -z_curmod = $0a2b -z_vm1 = $0a2c -z_vm2 = $0a2d -z_vm3 = $0a2e -z_vm4 = $0a2f -z_lintmp = $0a30 -z_sav80a = $0a31 -z_sav80b = $0a32 -z_curcol = $0a33 -z_split = $0a34 -z_fnadrx = $0a35 -z_palcnt = $0a36 -z_speed = $0a37 -z_sprites = $0a38 -z_blanking = $0a39 - ; the following block is omitted in the german C128 manual - z_hold_off = $0a3a - z_ldtbi_sa = $0a3b - z_clr_ea_lo = $0a3c - z_clr_ea_hi = $0a3d -; $a40 - $a5f: copy of data at $e0 - $ff of currently inactive screen -; $a60 - $a7f: ? -; z_xcnt = $0a80 ; already given as $0110 ! -; z_hulp = $0aa0 ; already given as $78 ! -z_format = $0aaa -z_length = $0aab -z_msal = $0aac -z_sxreg = $0aaf -z_syreg = $0ab0 -z_wrap = $0ab1 -z_xsave = $0ab2 -z_direction = $0ab3 -z_temps = $0ab4 -z_curbnk = $0ac0 -z_pat = $0ac1 -z_tbuffr = $0b00 -z_rs232i = $0c00 -z_rs232o = $0d00 + z_curmod = $0a2b + z_vm1 = $0a2c + z_vm2 = $0a2d + z_vm3 = $0a2e + z_vm4 = $0a2f + z_lintmp = $0a30 + z_sav80a = $0a31 + z_sav80b = $0a32 + z_curcol = $0a33 + z_split = $0a34 + z_fnadrx = $0a35 + z_palcnt = $0a36 + z_speed = $0a37 + z_sprites = $0a38 + z_blanking = $0a39 + ; this block is not in the german C128 manual: + z_hold_off = $0a3a + z_ldtbi_sa = $0a3b + z_clr_ea_lo = $0a3c + z_clr_ea_hi = $0a3d + ; $a40 - $a5f: copy of data at $e0 - $ff of currently inactive screen + ; $a60 - $a7f: ? + ; z_xcnt = $0a80 ; already given as $0110 ! + ; z_hulp = $0aa0 ; already given as $78 ! + z_format = $0aaa + z_length = $0aab + z_msal = $0aac + z_sxreg = $0aaf + z_syreg = $0ab0 + z_wrap = $0ab1 + z_xsave = $0ab2 + z_direction = $0ab3 + z_temps = $0ab4 + z_curbnk = $0ac0 + z_pat = $0ac1 + z_tbuffr = $0b00 + z_rs232i = $0c00 + z_rs232o = $0d00 -z_pkybuf = $1000 -z_pkydef = $100a -z_dosstr = $1100 -z_vwork = $1131 -z_xypos = $1131 -z_xpos = $1131 -z_ypos = $1133 -z_xdest = $1135 -z_ydest = $1137 -z_xyabs = $1139 -z_xabs = $1139 -z_yabs = $113b -z_xysgn = $113d -z_xsgn = $113d -z_ysgn = $113f -z_fct = $1141 -z_errval = $1145 -z_lesser = $1147 -z_greatr = $1148 -z_angsgn = $1149 -z_sinval = $114a -z_cosval = $114c -z_angcnt = $114e -z_xcircl = $1150 -z_ycircl = $1152 -z_xradus = $1154 -z_yradus = $1156 -z_rotang = $1158 -z_angbeg = $115c -z_angend = $115e -z_xrcos = $1160 -z_yrsin = $1162 -z_xrsin = $1164 -z_yrcos = $1166 -z_xcentr = $1150 -z_ycentr = $1152 -z_xdist1 = $1154 -z_ydist1 = $1156 -z_xdist2 = $1158 -z_ydist2 = $115a -z_disend = $115c -z_colcnt = $115e -z_rowcnt = $115f -z_strcnt = $1160 -z_xcord1 = $1150 -z_ycord1 = $1152 -z_boxang = $1154 -z_xcount = $1156 -z_ycount = $1158 -z_bxleng = $115a -z_xcord2 = $115c -z_ycord2 = $115e -z_leylen = $1151 -; z_keynxt = $1152 ; already given as $dd ! -z_strsz = $1153 -z_gettyp = $1154 -z_strptr = $1155 -z_oldbyt = $1156 -z_newbyt = $1157 -z_xsize = $1159 -z_ysize = $115b -; z_xsave = $115d ; already given as $0ab2 ! -z_stradr = $115f -z_bitidx = $1161 -z_chrpag = $1168 -z_bitcnt = $1169 -z_scalem = $116a -z_width = $116b -z_filflg = $116c -; z_bitmsk = $116d ; already given as $da ! -z_numcnt = $116e -z_trcflg = $116f -z_renum_tmp_1 = $1170 -z_renum_tmp_2 = $1172 -z_t3 = $1174 -z_t4 = $1175 -z_vtemp3 = $1177 -z_vtemp4 = $1178 -z_vtemp5 = $1179 -z_adray1 = $117a -z_adray2 = $117c -z_sprite_data = $117e -z_vic_save = $11d6 - ; the following block is omitted in the german C128 manual - z_upper_lower = $11eb - z_upper_graphic = $11ec -z_oldlin = $1200 -z_oldtxt = $1202 -z_puchrs = $1204 -z_pufill = $1204 -z_pucoma = $1205 -z_pudot = $1206 -z_pumony = $1207 -z_errnum = $1208 -z_errlin = $1209 -z_trapno = $120b -z_tmptrp = $120d -z_errtxt = $120e -z_text_top = $1210 -z_max_mem_0 = $1212 -z_tmptxt = $1214 -z_tmplin = $1216 -z_usrpok = $1218 -z_rndx = $121b -z_circle_segment = $1220 -; z_dejavu = $1221 ; already given as $0a02 ! -z_tempo_rate = $1222 -z_voices = $1223 -z_ntime = $1229 -z_octave = $122b -z_sharp = $122c -z_pitch = $122d -z_voice = $122f -z_wave0 = $1230 -z_dnote = $1233 -z_fltsav = $1234 -z_fltflg = $1238 -z_nibble = $1239 -z_tonnum = $123a -z_tonval = $123b -z_parcnt = $123e -z_atktab = $123f -z_sustab = $1249 -z_wavtab = $1253 -z_pulslw = $125d -z_pulshi = $1267 -z_filters = $1271 -z_int_trip_flag = $1276 -z_int_adr_lo = $1279 -z_int_adr_hi = $127c -z_intval = $127f -z_coltyp = $1280 -z_sound_voice = $1281 -z_sound_time_lo = $1282 -z_sound_time_hi = $1285 -z_sound_max_lo = $1288 -z_sound_max_hi = $128b -z_sound_min_lo = $128e -z_sound_min_hi = $1291 -z_sound_direction = $1294 -z_sound_step_lo = $1297 -z_sound_step_hi = $129a -z_sound_freq_lo = $129d -z_sound_freq_hi = $12a0 -z_temp_time_lo = $12a3 -z_temp_time_hi = $12a4 -z_temp_max_lo = $12a5 -z_temp_max_hi = $12a6 -z_temp_min_lo = $12a7 -z_temp_min_hi = $12a8 -z_temp_direction = $12a9 -z_temp_step_lo = $12aa -z_temp_step_hi = $12ab -z_temp_freq_lo = $12ac -z_temp_freq_hi = $12ad -z_temp_pulse_lo = $12ae -z_temp_pulse_hi = $12af -z_temp_waveform = $12b0 -z_pot_temp_1 = $12b1 -z_pot_temp_2 = $12b2 -z_window_temp = $12b3 -z_savram = $12b7 -z_defmod = $12fa -z_lincnt = $12fb -z_sprite_number = $12fc - ; the following block is omitted in the german C128 manual - z_irq_wrap_flag = $12fd - z_rambot = $1c00 + z_pkybuf = $1000 + z_pkydef = $100a + z_dosstr = $1100 + z_vwork = $1131 + z_xypos = $1131 + z_xpos = $1131 + z_ypos = $1133 + z_xdest = $1135 + z_ydest = $1137 + z_xyabs = $1139 + z_xabs = $1139 + z_yabs = $113b + z_xysgn = $113d + z_xsgn = $113d + z_ysgn = $113f + z_fct = $1141 + z_errval = $1145 + z_lesser = $1147 + z_greatr = $1148 + z_angsgn = $1149 + z_sinval = $114a + z_cosval = $114c + z_angcnt = $114e + z_xcircl = $1150 + z_ycircl = $1152 + z_xradus = $1154 + z_yradus = $1156 + z_rotang = $1158 + z_angbeg = $115c + z_angend = $115e + z_xrcos = $1160 + z_yrsin = $1162 + z_xrsin = $1164 + z_yrcos = $1166 + z_xcentr = $1150 + z_ycentr = $1152 + z_xdist1 = $1154 + z_ydist1 = $1156 + z_xdist2 = $1158 + z_ydist2 = $115a + z_disend = $115c + z_colcnt = $115e + z_rowcnt = $115f + z_strcnt = $1160 + z_xcord1 = $1150 + z_ycord1 = $1152 + z_boxang = $1154 + z_xcount = $1156 + z_ycount = $1158 + z_bxleng = $115a + z_xcord2 = $115c + z_ycord2 = $115e + z_leylen = $1151 + ; z_keynxt = $1152 ; already given as $dd ! + z_strsz = $1153 + z_gettyp = $1154 + z_strptr = $1155 + z_oldbyt = $1156 + z_newbyt = $1157 + z_xsize = $1159 + z_ysize = $115b + ; z_xsave = $115d ; already given as $0ab2 ! + z_stradr = $115f + z_bitidx = $1161 + z_chrpag = $1168 + z_bitcnt = $1169 + z_scalem = $116a + z_width = $116b + z_filflg = $116c + ; z_bitmsk = $116d ; already given as $da ! + z_numcnt = $116e + z_trcflg = $116f + z_renum_tmp_1 = $1170 + z_renum_tmp_2 = $1172 + z_t3 = $1174 + z_t4 = $1175 + z_vtemp3 = $1177 + z_vtemp4 = $1178 + z_vtemp5 = $1179 + z_adray1 = $117a + z_adray2 = $117c + z_sprite_data = $117e + z_vic_save = $11d6 + ; this block is not in the german C128 manual: + z_upper_lower = $11eb + z_upper_graphic = $11ec + z_oldlin = $1200 + z_oldtxt = $1202 + z_puchrs = $1204 + z_pufill = $1204 + z_pucoma = $1205 + z_pudot = $1206 + z_pumony = $1207 + z_errnum = $1208 + z_errlin = $1209 + z_trapno = $120b + z_tmptrp = $120d + z_errtxt = $120e + z_text_top = $1210 + z_max_mem_0 = $1212 + z_tmptxt = $1214 + z_tmplin = $1216 + z_usrpok = $1218 + z_rndx = $121b + z_circle_segment = $1220 + ; z_dejavu = $1221 ; already given as $0a02 ! + z_tempo_rate = $1222 + z_voices = $1223 + z_ntime = $1229 + z_octave = $122b + z_sharp = $122c + z_pitch = $122d + z_voice = $122f + z_wave0 = $1230 + z_dnote = $1233 + z_fltsav = $1234 + z_fltflg = $1238 + z_nibble = $1239 + z_tonnum = $123a + z_tonval = $123b + z_parcnt = $123e + z_atktab = $123f + z_sustab = $1249 + z_wavtab = $1253 + z_pulslw = $125d + z_pulshi = $1267 + z_filters = $1271 + z_int_trip_flag = $1276 + z_int_adr_lo = $1279 + z_int_adr_hi = $127c + z_intval = $127f + z_coltyp = $1280 + z_sound_voice = $1281 + z_sound_time_lo = $1282 + z_sound_time_hi = $1285 + z_sound_max_lo = $1288 + z_sound_max_hi = $128b + z_sound_min_lo = $128e + z_sound_min_hi = $1291 + z_sound_direction = $1294 + z_sound_step_lo = $1297 + z_sound_step_hi = $129a + z_sound_freq_lo = $129d + z_sound_freq_hi = $12a0 + z_temp_time_lo = $12a3 + z_temp_time_hi = $12a4 + z_temp_max_lo = $12a5 + z_temp_max_hi = $12a6 + z_temp_min_lo = $12a7 + z_temp_min_hi = $12a8 + z_temp_direction = $12a9 + z_temp_step_lo = $12aa + z_temp_step_hi = $12ab + z_temp_freq_lo = $12ac + z_temp_freq_hi = $12ad + z_temp_pulse_lo = $12ae + z_temp_pulse_hi = $12af + z_temp_waveform = $12b0 + z_pot_temp_1 = $12b1 + z_pot_temp_2 = $12b2 + z_window_temp = $12b3 + z_savram = $12b7 + z_defmod = $12fa + z_lincnt = $12fb + z_sprite_number = $12fc + ; this block is not in the german C128 manual: + z_irq_wrap_flag = $12fd + z_rambot = $1c00 +} diff --git a/ACME_Lib/cbm/c64/cia1.a b/ACME_Lib/cbm/c64/cia1.a index 438281b..920bacd 100644 --- a/ACME_Lib/cbm/c64/cia1.a +++ b/ACME_Lib/cbm/c64/cia1.a @@ -1,21 +1,23 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c64_cia1_a !eof lib_cbm_c64_cia1_a = 1 -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 +!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 +} diff --git a/ACME_Lib/cbm/c64/cia2.a b/ACME_Lib/cbm/c64/cia2.a index 8fa4390..c1c8877 100644 --- a/ACME_Lib/cbm/c64/cia2.a +++ b/ACME_Lib/cbm/c64/cia2.a @@ -1,21 +1,23 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c64_cia2_a !eof lib_cbm_c64_cia2_a = 1 -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 +!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 +} diff --git a/ACME_Lib/cbm/c64/float.a b/ACME_Lib/cbm/c64/float.a index 70fbb9d..5962e0a 100644 --- a/ACME_Lib/cbm/c64/float.a +++ b/ACME_Lib/cbm/c64/float.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c64_float_a !eof lib_cbm_c64_float_a = 1 @@ -6,8 +6,10 @@ lib_cbm_c64_float_a = 1 ; 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 ; structures in zero page: -fac1_base = $61 ; base address of floating-point accumulator 1 -fac2_base = $69 ; base address of floating-point accumulator 2 +!address { + fac1_base = $61 ; base address of floating-point accumulator 1 + fac2_base = $69 ; base address of floating-point accumulator 2 +} ; There is really no need to use these addresses directly when calling the ROM ; functions. You'd only need the addresses when using . @@ -45,69 +47,71 @@ fac2_base = $69 ; base address of floating-point accumulator 2 lda .adr + 1 } -; constants in five-byte "mflpt" format -mflpt_pi = $aea8 ; 3.1415926... -mflpt_minus32768 = $b1a5 ; -32768 -mflpt_1 = $b9bc ; 1 -mflpt_half_sqr2 = $b9d6 ; SQR(2) / 2 -mflpt_sqr2 = $b9db ; SQR(2) -mflpt_minus_point5 = $b9e0 ; -.5 -mflpt_log_2 = $b9e5 ; LOG(2) -mflpt_10 = $baf9 ; 10 -mflpt_99999999 = $bdb3 ; 99 999 999 -mflpt_999999999 = $bdb8 ; 999 999 999 -mflpt_1000000000 = $bdbd ; 1 000 000 000 -mflpt_point5 = $bf11 ; .5, also known as 1 / 2 -mflpt_log_2_reciprocal = $bfbf ; 1 / LOG(2) -mflpt_half_pi = $e2e0 ; PI / 2 -mflpt_double_pi = $e2e5 ; 2 * PI (also see $e309) -mflpt_point25 = $e2ea ; .25, also known as 1 / 4 -mflpt_2_pi = $e309 ; 2 * PI (also see $e2e5) +!address { + ; constants in five-byte "mflpt" format + mflpt_pi = $aea8 ; 3.1415926... + mflpt_minus32768 = $b1a5 ; -32768 + mflpt_1 = $b9bc ; 1 + mflpt_half_sqr2 = $b9d6 ; SQR(2) / 2 + mflpt_sqr2 = $b9db ; SQR(2) + mflpt_minus_point5 = $b9e0 ; -.5 + mflpt_log_2 = $b9e5 ; LOG(2) + mflpt_10 = $baf9 ; 10 + mflpt_99999999 = $bdb3 ; 99 999 999 + mflpt_999999999 = $bdb8 ; 999 999 999 + mflpt_1000000000 = $bdbd ; 1 000 000 000 + mflpt_point5 = $bf11 ; .5, also known as 1 / 2 + mflpt_log_2_reciprocal = $bfbf ; 1 / LOG(2) + mflpt_half_pi = $e2e0 ; PI / 2 + mflpt_double_pi = $e2e5 ; 2 * PI (also see $e309) + mflpt_point25 = $e2ea ; .25, also known as 1 / 4 + mflpt_2_pi = $e309 ; 2 * PI (also see $e2e5) -; 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 -; 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_signed16 = $b1bf ; might throw ILLEGAL QUANTITY -fac1_read_signedYA = $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_add_point5 = $b849 ; for rounding, call this before fac1_int -fac1_memAY_minus_fac1 = $b850 ; subtract fac1 from mflpt value -fac1_fac2_minus_fac1 = $b853 -fac1_add_memAY = $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 -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_read_mem_via0x22ptr = $bba6 ; load mflpt value from memory into fac1 -fac1_to_memXY = $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_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_sqr = $bf71 ; SQR() -fac1_fac2_to_the_power_of_memAY = $bf78 -fac1_negate = $bfb4 -fac1_exp = $bfed ; EXP() -; end of basic rom jumps to start of kernel rom! -fac1_rnd = $e097 ; RND() -fac1_cos = $e264 ; COS() -fac1_sin = $e26b ; SIN() -fac1_tan = $e2b4 ; TAN() -fac1_atn = $e30e ; ATN() + ; 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 + ; 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_signed16 = $b1bf ; might throw ILLEGAL QUANTITY + fac1_read_signedYA = $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_add_point5 = $b849 ; for rounding, call this before fac1_int + fac1_memAY_minus_fac1 = $b850 ; subtract fac1 from mflpt value + fac1_fac2_minus_fac1 = $b853 + fac1_add_memAY = $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 + 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_read_mem_via0x22ptr = $bba6 ; load mflpt value from memory into fac1 + fac1_to_memXY = $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_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_sqr = $bf71 ; SQR() + fac1_fac2_to_the_power_of_memAY = $bf78 + fac1_negate = $bfb4 + fac1_exp = $bfed ; EXP() + ; end of basic rom jumps to start of kernel rom! + fac1_rnd = $e097 ; RND() + fac1_cos = $e264 ; COS() + fac1_sin = $e26b ; SIN() + fac1_tan = $e2b4 ; TAN() + fac1_atn = $e30e ; ATN() +} diff --git a/ACME_Lib/cbm/c64/georam.a b/ACME_Lib/cbm/c64/georam.a index 4068fba..20490fb 100644 --- a/ACME_Lib/cbm/c64/georam.a +++ b/ACME_Lib/cbm/c64/georam.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c64_georam_a !eof lib_cbm_c64_georam_a = 1 @@ -9,12 +9,13 @@ lib_cbm_c64_georam_a = 1 ; address $de00 in i/o space. Writing to registers allows to change which ; memory page is visible at that location. -; memory page -georam_page = $de00 - -; control registers (write-only, these registers can not be read) -georam_track = $dffe ; 0..63, i.e. the lower six bits are significant -georam_sector = $dfff ; 0..31, i.e. the lower five bits are significant +!address { + ; memory page + georam_page = $de00 + ; control registers (write-only, these registers can not be read) + georam_track = $dffe ; 0..63, i.e. the lower six bits are significant + georam_sector = $dfff ; 0..31, i.e. the lower five bits are significant +} ; these are the official addresses - actually the registers are accessible ; *everywhere* at $dfxx, but using these locations does not clash with the ; registers of a Commodore REU. diff --git a/ACME_Lib/cbm/c64/reu.a b/ACME_Lib/cbm/c64/reu.a index c86261c..befa4e5 100644 --- a/ACME_Lib/cbm/c64/reu.a +++ b/ACME_Lib/cbm/c64/reu.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c64_reu_a !eof lib_cbm_c64_reu_a = 1 @@ -8,48 +8,56 @@ lib_cbm_c64_reu_a = 1 ; (RAM Expansion Controller) capable of direct memory access (DMA). ; Standard base address of control registers is $df00 in i/o space. -; status register -rec_status = $df00 ; reading will clear IRQ, END and ERROR bits - rec_STATUS_IRQ = %#....... - rec_STATUS_END = %.#...... - rec_STATUS_ERROR = %..#..... ; for verify command - rec_STATUS_TYPE = %...#.... ; chip type (do not use to determine unit size!) - rec_STATUS_VERSION = %....#### -; command register -rec_command = $df01 - rec_COMMAND_EXECUTE = %#....... - ;reserved = %.#...... - rec_COMMAND_RELOAD = %..#..... - rec_COMMAND_IMMEDIATELY = %...#.... ; do not wait for $ff00 write - ;reserved = %....##.. - rec_COMMAND_MODE_MASK = %......## ; bit mask for the four modes - rec_COMMAND_MODE_STASH = %........ ; computer-to-REU - rec_COMMAND_MODE_FETCH = %.......# ; REU-to-computer - rec_COMMAND_MODE_SWAP = %......#. ; exchange - rec_COMMAND_MODE_VERIFY = %......## ; compare - rec_COMMAND_STASH = %#.#..... ; these wait for $ff00 before - rec_COMMAND_FETCH = %#.#....# ; starting and then reload values. -; internal address (computer RAM) -rec_int_low = $df02 -rec_int_high = $df03 -; external address (expansion RAM) -rec_ext_low = $df04 -rec_ext_high = $df05 -rec_ext_bank = $df06 +!address { + ; status register + rec_status = $df00 ; reading will clear IRQ, END and ERROR bits +} +rec_STATUS_IRQ = %#....... +rec_STATUS_END = %.#...... +rec_STATUS_ERROR = %..#..... ; for verify command +rec_STATUS_TYPE = %...#.... ; chip type (do not use to determine unit size!) +rec_STATUS_VERSION = %....#### +!address { + ; command register + rec_command = $df01 +} +rec_COMMAND_EXECUTE = %#....... +;reserved = %.#...... +rec_COMMAND_RELOAD = %..#..... +rec_COMMAND_IMMEDIATELY = %...#.... ; do not wait for $ff00 write +;reserved = %....##.. +rec_COMMAND_MODE_MASK = %......## ; bit mask for the four modes +rec_COMMAND_MODE_STASH = %........ ; computer-to-REU +rec_COMMAND_MODE_FETCH = %.......# ; REU-to-computer +rec_COMMAND_MODE_SWAP = %......#. ; exchange +rec_COMMAND_MODE_VERIFY = %......## ; compare +rec_COMMAND_STASH = %#.#..... ; these wait for $ff00 before +rec_COMMAND_FETCH = %#.#....# ; starting and then reload values. +!address { + ; internal address (computer RAM) + rec_int_low = $df02 + rec_int_high = $df03 + ; external address (expansion RAM) + rec_ext_low = $df04 + rec_ext_high = $df05 + rec_ext_bank = $df06 ; A stock 1700 unit has two banks (128 KiB). ; A stock 1764 unit has four banks (256 KiB). ; A stock 1750 unit has eight banks (512 KiB). ; 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 -; when to request interrupts -rec_irqctrl = $df09 - rec_IRQCTRL_ENABLE = %#....... - rec_IRQCTRL_ON_END = %.#...... - rec_IRQCTRL_ON_ERROR = %..#..... ; for verify errors -; address control (set to zero for normal operation) -rec_addrctrl = $df0a - rec_ADDRCTRL_FIX_INT = %#....... - rec_ADDRCTRL_FIX_EXT = %.#...... + ; amount of bytes to process + rec_amount_low = $df07 + rec_amount_high = $df08 + ; when to request interrupts + rec_irqctrl = $df09 +} +rec_IRQCTRL_ENABLE = %#....... +rec_IRQCTRL_ON_END = %.#...... +rec_IRQCTRL_ON_ERROR = %..#..... ; for verify errors +!address { + ; address control (set to zero for normal operation) + rec_addrctrl = $df0a +} +rec_ADDRCTRL_FIX_INT = %#....... +rec_ADDRCTRL_FIX_EXT = %.#...... diff --git a/ACME_Lib/cbm/c64/sid.a b/ACME_Lib/cbm/c64/sid.a index 09406c1..50efe98 100644 --- a/ACME_Lib/cbm/c64/sid.a +++ b/ACME_Lib/cbm/c64/sid.a @@ -1,52 +1,55 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c64_sid_a !eof lib_cbm_c64_sid_a = 1 -; write-only registers: -; voice 1: -sid_v1_freq_lo = $d400 -sid_v1_freq_hi = $d401 -sid_v1_width_lo = $d402 -sid_v1_width_hi = $d403 -sid_v1_control = $d404 ; see below for bits -sid_v1_attack_decay = $d405 ; hi-nibble: attack length, low-nibble: decay length -sid_v1_sustain_release = $d406 ; hi-nibble: sustain volumne, low-nibble: release length -; voice 2: -sid_v2_freq_lo = $d407 -sid_v2_freq_hi = $d408 -sid_v2_width_lo = $d409 -sid_v2_width_hi = $d40a -sid_v2_control = $d40b ; see below for bits -sid_v2_attack_decay = $d40c ; hi-nibble: attack length, low-nibble: decay length -sid_v2_sustain_release = $d40d ; hi-nibble: sustain volumne, low-nibble: release length -; voice 3: -sid_v3_freq_lo = $d40e -sid_v3_freq_hi = $d40f -sid_v3_width_lo = $d410 -sid_v3_width_hi = $d411 -sid_v3_control = $d412 ; see below for bits -sid_v3_attack_decay = $d413 ; hi-nibble: attack length, low-nibble: decay length -sid_v3_sustain_release = $d414 ; hi-nibble: sustain volumne, low-nibble: release length +!address { + ; write-only registers: + ; voice 1: + sid_v1_freq_lo = $d400 + sid_v1_freq_hi = $d401 + sid_v1_width_lo = $d402 + sid_v1_width_hi = $d403 + sid_v1_control = $d404 ; see below for bits + sid_v1_attack_decay = $d405 ; hi-nibble: attack length, low-nibble: decay length + sid_v1_sustain_release = $d406 ; hi-nibble: sustain volumne, low-nibble: release length + ; voice 2: + sid_v2_freq_lo = $d407 + sid_v2_freq_hi = $d408 + sid_v2_width_lo = $d409 + sid_v2_width_hi = $d40a + sid_v2_control = $d40b ; see below for bits + sid_v2_attack_decay = $d40c ; hi-nibble: attack length, low-nibble: decay length + sid_v2_sustain_release = $d40d ; hi-nibble: sustain volumne, low-nibble: release length + ; voice 3: + sid_v3_freq_lo = $d40e + sid_v3_freq_hi = $d40f + sid_v3_width_lo = $d410 + sid_v3_width_hi = $d411 + sid_v3_control = $d412 ; see below for bits + sid_v3_attack_decay = $d413 ; hi-nibble: attack length, low-nibble: decay length + sid_v3_sustain_release = $d414 ; hi-nibble: sustain volumne, low-nibble: release length +} ; voice control bits: - sid_VOICECONTROL_NOISE = %#....... - sid_VOICECONTROL_RECTANGLE = %.#...... - sid_VOICECONTROL_SAWTOOTH = %..#..... - sid_VOICECONTROL_TRIANGLE = %...#.... - sid_VOICECONTROL_DISABLE_RESET = %....#... ; 1 = disable voice, reset noise generator - sid_VOICECONTROL_RINGMODULATION = %.....#.. - sid_VOICECONTROL_SYNC = %......#. - sid_VOICECONTROL_ON = %.......# ; 0 = release, 1 = attack/sustain/decay -; registers shared by all voices: -sid_filter_cutoff_lo = $d415 ; only bits 0/1/2! -sid_filter_cutoff_hi = $d416 -sid_filter_control = $d417 ; hi-nibble: resonance, lo-nibble: filter ext/v3/v2/v1 -sid_filter_volume = $d418 ; hi-nibble: filter mode (disable v3, high, band, low), lo-nibble: volume -; read-only registers: -sid_potx = $d419 -sid_poty = $d41a -sid_v3_waveform_output = $d41b -sid_v3_adsr_output = $d41c - -; Do not use the shadow copies of these registers at $d500, $d600 or $d700, +sid_VOICECONTROL_NOISE = %#....... +sid_VOICECONTROL_RECTANGLE = %.#...... +sid_VOICECONTROL_SAWTOOTH = %..#..... +sid_VOICECONTROL_TRIANGLE = %...#.... +sid_VOICECONTROL_DISABLE_RESET = %....#... ; 1 = disable voice, reset noise generator +sid_VOICECONTROL_RINGMODULATION = %.....#.. +sid_VOICECONTROL_SYNC = %......#. +sid_VOICECONTROL_ON = %.......# ; 0 = release, 1 = attack/sustain/decay +!address { + ; registers shared by all voices: + sid_filter_cutoff_lo = $d415 ; only bits 0/1/2! + sid_filter_cutoff_hi = $d416 + sid_filter_control = $d417 ; hi-nibble: resonance, lo-nibble: filter ext/v3/v2/v1 + sid_filter_volume = $d418 ; hi-nibble: filter mode (disable v3, high, band, low), lo-nibble: volume + ; read-only registers: + sid_potx = $d419 + sid_poty = $d41a + sid_v3_waveform_output = $d41b + sid_v3_adsr_output = $d41c +} +; Do not use the shadow copies of these registers at $d5xx, $d6xx or $d7xx: ; on a C128 they do not exist! diff --git a/ACME_Lib/cbm/c64/vic.a b/ACME_Lib/cbm/c64/vic.a index 9b60e40..9c6802e 100644 --- a/ACME_Lib/cbm/c64/vic.a +++ b/ACME_Lib/cbm/c64/vic.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_c64_vic_a !eof lib_cbm_c64_vic_a = 1 @@ -21,58 +21,58 @@ viccolor_LGREEN = $d viccolor_LBLUE = $e viccolor_GRAY3 = $f -; 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 - +!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 +} ; See 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! diff --git a/ACME_Lib/cbm/kernel.a b/ACME_Lib/cbm/kernel.a index 4134a09..71a4928 100644 --- a/ACME_Lib/cbm/kernel.a +++ b/ACME_Lib/cbm/kernel.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !ifdef lib_cbm_kernel_a !eof lib_cbm_kernel_a = 1 @@ -7,42 +7,44 @@ lib_cbm_kernel_a = 1 ; Sorry, I can't give credit because I don't have the URL anymore. ; There are alternative names for some calls. -k_cint = $ff81 -k_ioinit = $ff84 -k_ramtas = $ff87 -k_restor = $ff8a -k_vector = $ff8d -k_setmsg = $ff90 -k_secnd = $ff93 -k_tksa = $ff96 -k_memtop = $ff99 -k_membot = $ff9c -k_key = $ff9f -k_settmo = $ffa2 -k_iecin = $ffa5:k_acptr = $ffa5 -k_iecout = $ffa8:k_ciout = $ffa8 -k_untalk = $ffab:k_untlk = $ffab -k_unlisten = $ffae:k_unlsn = $ffae -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_clall = $ffe7 -k_udtim = $ffea -k_scrorg = $ffed -k_plot = $fff0 ; get/set cursor (to set, clear carry) -k_iobase = $fff3 +!address { + k_cint = $ff81 + k_ioinit = $ff84 + k_ramtas = $ff87 + k_restor = $ff8a + k_vector = $ff8d + k_setmsg = $ff90 + k_secnd = $ff93 + k_tksa = $ff96 + k_memtop = $ff99 + k_membot = $ff9c + k_key = $ff9f + k_settmo = $ffa2 + k_iecin = $ffa5:k_acptr = $ffa5 + k_iecout = $ffa8:k_ciout = $ffa8 + k_untalk = $ffab:k_untlk = $ffab + k_unlisten = $ffae:k_unlsn = $ffae + 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_clall = $ffe7 + k_udtim = $ffea + k_scrorg = $ffed + k_plot = $fff0 ; get/set cursor (to set, clear carry) + k_iobase = $fff3 +} diff --git a/docs/AllPOs.txt b/docs/AllPOs.txt index 1d0d64e..a7c56df 100644 --- a/docs/AllPOs.txt +++ b/docs/AllPOs.txt @@ -412,9 +412,12 @@ Examples: Miscellaneous: The old syntax ("!for LABEL, 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. 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. + to the new syntax. You can disable this warning using + the "-Wno-old-for" switch, 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. Also note that with the new algorithm, LABEL has a different value after the block than during the last loop cycle, while the old algorithm kept that last @@ -811,6 +814,37 @@ Purpose: Assume short (8 bits) index registers. Only needed pass. +---------------------------------------------------------------------- +Section: Type system +---------------------------------------------------------------------- + +Call: !address [ { BLOCK } ] +or: !address LABEL = VALUE +Purpose: Mark a block or a statement as "explicitly defined + labels are holding addresses". +Parameters: BLOCK: A block of assembler statements + Everything inside the block will be parsed as usual, + but labels getting explicitly defined will be marked + as referencing memory. + If no block is given, only the current statement will + be affected, which should then be an explicit label + definition. +Aliases: "!addr" +Examples: !addr k_chrout = $ffd2 ; this is an address + CLEAR = 147 ; but this is not + !addr { + ; these are addresses: + sid_v1_control = $d404 + sid_v2_control = $d40b + sid_v3_control = $d412 + } + ; these are not: + sid_VOICECONTROL_NOISE = %#....... + sid_VOICECONTROL_RECTANGLE = %.#...... + sid_VOICECONTROL_SAWTOOTH = %..#..... + sid_VOICECONTROL_TRIANGLE = %...#.... + + ---------------------------------------------------------------------- Section: Obsolete pseudo opcodes (they will throw errors if used) ---------------------------------------------------------------------- diff --git a/docs/Changes.txt b/docs/Changes.txt index 4d0b7a6..5323811 100644 --- a/docs/Changes.txt +++ b/docs/Changes.txt @@ -12,6 +12,19 @@ platform used. There should be another help file in this archive outlining the platform specific changes. +---------------------------------------------------------------------- +Section: New in release 0.95 +---------------------------------------------------------------------- + +Added an experimental type system to tell addresses and non-addresses + apart (per default disabled; must be activated using the + "-Wtype-mismatch" CLI switch). The new "!address" pseudo opcode is + used to mark label definitions as setting address values. +Added "-Wno-old-for" switch to disable warning about old "!for" + syntax. However, this will in turn enable warnings about using the + *new* syntax. + + ---------------------------------------------------------------------- Section: New in release 0.94.12 ---------------------------------------------------------------------- diff --git a/docs/Errors.txt b/docs/Errors.txt index 35f8023..d722ccb 100644 --- a/docs/Errors.txt +++ b/docs/Errors.txt @@ -55,9 +55,14 @@ Bug in ACME, code follows C-style "==" comparison detected. To check for equality, use a single '=' character instead. -Found deprecated "!for" syntax. +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. + +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. Implicit label definition not in leftmost column. An implicit label definition has blanks before the label name. @@ -128,6 +133,12 @@ Using oversized addressing mode. 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. + 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. + ---------------------------------------------------------------------- Section: Errors during assembly diff --git a/docs/Help.txt b/docs/Help.txt index 8fcd5e3..ef614e8 100644 --- a/docs/Help.txt +++ b/docs/Help.txt @@ -105,6 +105,8 @@ ACME exists on several platforms, meaning you can easily exchange your sources with other people (preferring other OSes). ACME can convert its strings to PetSCII and screen code (Okay, this is C64-specific). +ACME has a rudimentary type checking system to catch errors like + missing '#' characters. Did I mention that it is fast? diff --git a/docs/QuickRef.txt b/docs/QuickRef.txt index 4d21661..fe4b4bb 100644 --- a/docs/QuickRef.txt +++ b/docs/QuickRef.txt @@ -21,7 +21,9 @@ Section: Example of what an ACME source code file looks like !to "tiny.o", cbm ; set output file and format * = $c000 ; set program counter - basout = $ffd2 ; explicit global label def. + CLEAR = 147 ; a global label definition +!addr basout = $ffd2 ; another one, marked as an address + ; a string output loop: ldx #0 beq + ; enter loop @@ -46,8 +48,19 @@ Here's the same fragment again, now with some additional info: ; respectively. * = $c000 ; set program counter ; This can also be done using the command line option "--setpc". - basout = $ffd2 ; explicit global label def. -; Now "basout" is defined as a global label having the value $ffd2. + + ; some global label definitions + CLEAR = 147 ; this is a simple constant +; Now "CLEAR" is defined as a global label having the value 147. +!addr basout = $ffd2 ; this gets marked as an address +; Now "basout" is defined as a global "address" type label having the +; value $ffd2. + ; The distinction between addresses and non-addresses only + ; matters when the type check system gets activated using + ; the "-Wtype-mismatch" switch. Then, a line like + ; "lda CLEAR" would trigger a type mismatch warning because + ; of the missing '#' character. + ; a string output loop: ldx #0 beq + ; enter loop @@ -157,6 +170,9 @@ found in the file "AllPOs.txt". Here's just a short overview: !warn !error !serious ...for generating warnings, errors and serious errors. +!addr +...to mark labels as addresses, for the optional type check system. + ---------------------------------------------------------------------- Section: Command line arguments @@ -180,13 +196,13 @@ Available options are: -l, --labeldump FILE select label dump file This can also be given using the "!sl" pseudo opcode. + --setpc NUMBER set program counter + This can also be given in the source code using "* = NUMBER". + --cpu CPU_TYPE set processor type This can be changed in the source code using the "!cpu" pseudo opcode. Defaults to 6502. - --setpc NUMBER set program counter - This can also be given in the source code using "* = NUMBER". - --initmem NUMBER define 'empty' memory This can also be given using the "!initmem" pseudo opcode. Defaults to zero. @@ -200,22 +216,18 @@ Available options are: -vDIGIT set verbosity level Sets how much additional informational output is generated. Higher values mean more output: - - acme -v0 source.a + acme -v0 source.a This is the default: No additional output is generated, ACME will only display warnings and errors. - - acme -v1 source.a + acme -v1 source.a Now the start and end addresses of the generated output file are displayed, along with its size (a CBM-style "load address" is *not* counted). - - acme -v2 source.a + acme -v2 source.a In addition to the "-v1" output, ACME will announce each pass, will show amount and offset of "!binary" loads, and show start and end addresses and size of each segment. - - acme -v3 source.a + acme -v3 source.a In addition to the "-v2" output, ACME will now announce each source file. @@ -226,9 +238,14 @@ Available options are: (using conditional assembly in your source code file). -W fine-tune amount and type of warnings - Currently only sub-option is supported: "-Wno-label-indent" - will switch off warnings about implicit label definitions not - being in the leftmost column. + -Wno-label-indent + Disables warnings about implicit label definitions not + being in the leftmost column. + -Wno-old-for + Disables warnings about the old "!for" syntax and at the + same time enables warnings about the _new_ "!for" syntax. + -Wtype-mismatch + Enables type checking system (warns about wrong types). --use-stdout fix for 'Relaunch64' IDE With this option, errors are written to the standard output @@ -265,6 +282,7 @@ This is a list of the operators currently known by ACME: 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 diff --git a/examples/ddrv.a b/examples/ddrv.a index f5f42b8..abd40f4 100644 --- a/examples/ddrv.a +++ b/examples/ddrv.a @@ -1,4 +1,4 @@ -;ACME 0.94 +;ACME 0.95 ;!sl "ddrv.l" ; Name DuoDriver ; Purpose Input driver for mouse and joystick @@ -26,6 +26,7 @@ ; 26 Mar 2006 Release 4.03. Adjusted source to ACME 0.91 capabilities. ; 25 Nov 2007 Release 4.04. Adjusted source to ACME 0.94 capabilities. ; 7 Apr 2013 Slightly reformatted. +; 1 Jun 2014 Adjusted to experimental type system of ACME 0.95 ; This source code file uses conditional assembly ; to decide which version to produce (C64 or C128). @@ -47,12 +48,12 @@ !if SYSTEM = 64 { * = $c000 !to "ddrv64.prg", cbm - VIC_Base = $d000 +!addr VIC_Base = $d000 } !if SYSTEM = 128 { * = $0c00 !to "ddrv128.prg", cbm - VIC_Base = $11d6 ; Location of mirror registers +!addr VIC_Base = $11d6 ; Location of mirror registers } ; Pointer's maximum coordinates @@ -78,11 +79,14 @@ ; 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 CharX = $b3 CharY = $b4 + tapebuf = $0340 + spr_ptrs = 2040 } !if SYSTEM = 128 { LeftButton = $fa @@ -96,7 +100,6 @@ ; x low, x high, y low, y high Coordinates = $fb ; $fb..$fe - ; --- System constants ; Interrupt vector @@ -108,7 +111,7 @@ cia1_prb = $dc01 cia1_ddrb = $dc03 mmu_cr = $ff00 ; c128 only - +};addr ; --- Label definitions @@ -168,15 +171,15 @@ Init lda sys_iirq ; Copy sprites to tape buffer ldx #127 - lda Sprites, x - sta $0340, x + sta tapebuf, x dex bpl - lda #Sprites_Bitmask ; Set sprite block pointers ldx #$0d - stx 2040 + Sprite_A + stx spr_ptrs + Sprite_A inx - stx 2040 + Sprite_B + stx spr_ptrs + Sprite_B ; Activate pointer sprites ora VIC_Base + 21 sta VIC_Base + 21 @@ -419,7 +422,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 $ffff ; (self-modifying) +mod16 = * + 1: jmp addr($ffff) ; (self-modifying) ; This table is for part 8. ;OrTable !byte 0, 32, 64 ; VDC only diff --git a/examples/macedit.a b/examples/macedit.a index 8a67016..b479518 100644 --- a/examples/macedit.a +++ b/examples/macedit.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 ; ist der komplette Sourcecode von MacEdit ; (80-Zeichen-Version) ; Version 0.7 @@ -76,3 +76,5 @@ Spätere Änderungen am Source: Converted to UTF-8 27 Jun 2013: Adjusted to change in library. + 1 Jun 2014: + Adjusted to experimental type system of ACME 0.95 diff --git a/examples/me/const.a b/examples/me/const.a index e0478eb..4e9558c 100644 --- a/examples/me/const.a +++ b/examples/me/const.a @@ -1,10 +1,10 @@ -;ACME 0.94.4 +;ACME 0.95 ; Konstanten: FALSE = 0 ; Das Programm verläßt sich an etlichen Stellen TRUE = $ff ; darauf, daß genau diese Werte zugewiesen wurden. MODIFIED8 = $ff ; Defaultwerte für - MODIFIED16 = $ffff ; Selbstmodifikationen +!addr MODIFIED16 = $ffff ; Selbstmodifikationen Char_NUL = $00 Char_STOP = $03 @@ -46,6 +46,7 @@ lf = 8 ; Filenr. & Sek.-Addy ; Zeropage: +!addr { D8502 = $00 ; Direction R8502 = $01 ; Register vvek = $83 ; Vektor auf LineVektor @@ -91,3 +92,4 @@ clrchn = $ffcc basin = $ffcf basout = $ffd2 +} diff --git a/examples/me/out.a b/examples/me/out.a index a446690..b9fc46a 100644 --- a/examples/me/out.a +++ b/examples/me/out.a @@ -1,4 +1,4 @@ -;ACME 0.94.4 +;ACME 0.95 !zone F_info ldx #hWindow_InfoBox @@ -483,7 +483,7 @@ swin !byte 0 ; Auch fuer 'lwin' bckgrnd = 26 ; screencolor-register flnmpos = 87 ; filenameposition wsstart = $0fd0 ; windowstack-start - tcolor = $f2 ; attribute-buffer +!addr tcolor = $f2 ; attribute-buffer ; Subs: !zone @@ -505,11 +505,11 @@ init ldx repeatedtry ; first start ? stx fnbank ; filename-CR dex stx locks ; 'CBM-shift' off - stx $0ac5 ; 'ASC/DIN' off + stx addr($0ac5) ; 'ASC/DIN' off stx basic ; 'Basic-IRQ' off jsr crsrinit ; init crsr ldx #$0b ; VIC off - stx $11e7 + stx addr($11e7) lda mode ; which mode ? bmi + ; if 40 then jsr kernel_switchmode ; switch mode @@ -567,7 +567,7 @@ init ldx repeatedtry ; first start ? sta conreg + 1 ; full RAM ldx #$0b ; loop for new - lda keyb, x ; keyboard-tabs - sta $033e, x + sta addr($033e), x dex bpl - jsr handleid ; old ID ? @@ -747,7 +747,7 @@ F_gosys +bank15 jsr kernel_cls ; CLS lda #0 ; '0' for sta locks ; 'CBM-Shift' on - sta $0ac5 ; 'ASC/DIN' on + sta addr($0ac5) ; 'ASC/DIN' on sta basic ; 'Basic-IRQ' on lda nmibuf ; restore NMI ldx nmibuf + 1 diff --git a/src/Makefile b/src/Makefile index f2c2aef..3d3eeb0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,7 @@ RM = rm PROGS = acme BINDIR = /usr/local/bin USERBIN = $(HOME)/bin -OBJS = acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o +OBJS = acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o typesystem.o all: $(PROGS) @@ -49,6 +49,8 @@ section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c tree.o: config.h dynabuf.h global.h label.h tree.h tree.c +typesystem.o: config.h global.h typesystem.h typesystem.c + clean: -$(RM) -f *.o $(PROGS) *~ core diff --git a/src/Makefile.dos b/src/Makefile.dos index cb55c89..fae0ca1 100644 --- a/src/Makefile.dos +++ b/src/Makefile.dos @@ -8,7 +8,7 @@ RM = rm PROGS = acme #BINDIR = /usr/local/bin #USERBIN = $(HOME)/bin -OBJS = acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o +OBJS = acme.o alu.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o typesystem.o all: $(PROGS) @@ -50,6 +50,8 @@ section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c tree.o: config.h dynabuf.h global.h label.h tree.h tree.c +typesystem.o: config.h global.h typesystem.h typesystem.c + clean: del *.o # -$(RM) -f *.o $(PROGS) *~ core diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 80c9c79..408db4e 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -15,8 +15,8 @@ USERBIN = $(HOME)/bin all: $(PROGS) -acme.exe: acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o _dos.o resource.res - $(CC) $(LIBS) $(CFLAGS) -o acme acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o resource.res +acme.exe: acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o typesystem.o_dos.o resource.res + $(CC) $(LIBS) $(CFLAGS) -o acme acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o typesystem.o resource.res strip acme.exe @@ -53,6 +53,8 @@ section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c tree.o: config.h dynabuf.h global.h label.h tree.h tree.c +typesystem.o: config.h global.h typesystem.h typesystem.c + # _dos.o: _dos.h win/resource.rc: acme.c diff --git a/src/Makefile.riscos b/src/Makefile.riscos index be65a94..118b99d 100644 --- a/src/Makefile.riscos +++ b/src/Makefile.riscos @@ -8,7 +8,7 @@ RM = rm PROGS = acme #BINDIR = /usr/local/bin #USERBIN = $(HOME)/bin -OBJS = acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o +OBJS = acme.o alu.o basics.o cliargs.o cpu.o dynabuf.o encoding.o flow.o global.o input.o label.o macro.o mnemo.o output.o platform.o section.o tree.o typesystem.o all: $(PROGS) @@ -50,6 +50,8 @@ section.o: config.h dynabuf.h global.h section.h tree.h section.h section.c tree.o: config.h dynabuf.h global.h label.h tree.h tree.c +typesystem.o: config.h global.h typesystem.h typesystem.c + clean: wipe o.* ~c # -$(RM) -f *.o $(PROGS) *~ core diff --git a/src/acme.c b/src/acme.c index e489671..a7ce737 100644 --- a/src/acme.c +++ b/src/acme.c @@ -15,9 +15,9 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#define RELEASE "0.94.12" // update before release (FIXME) -#define CODENAME "Zarquon" // update before release -#define CHANGE_DATE "31 May" // update before release +#define RELEASE "0.95" // update before release (FIXME) +#define CODENAME "Fenchurch" // update before release +#define CHANGE_DATE "2 Jun" // update before release #define CHANGE_YEAR "2014" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME @@ -64,6 +64,8 @@ static const char name_dumpfile[] = "label dump filename"; #define OPTION_VERSION "version" // options for "-W" #define OPTIONWNO_LABEL_INDENT "no-label-indent" +#define OPTIONWNO_OLD_FOR "no-old-for" +#define OPTIONWTYPE_MISMATCH "type-mismatch" // variables @@ -126,6 +128,8 @@ static void show_help_and_exit(void) // as long as there is only one -W option: #define OPTIONWNO_LABEL_INDENT "no-label-indent" " -W" OPTIONWNO_LABEL_INDENT " suppress warnings about indented labels\n" +" -W" OPTIONWNO_OLD_FOR " suppress warnings about old \"!for\" syntax\n" +" -W" OPTIONWTYPE_MISMATCH " enable type checking (warn about type mismatch)\n" // when there are more, use next line and add a separate function: //" -W show warning level options\n" " --" OPTION_USE_STDOUT " fix for 'Relaunch64' IDE (see docs)\n" @@ -425,6 +429,12 @@ static char short_option(const char *argument) if (strcmp(argument + 1, OPTIONWNO_LABEL_INDENT) == 0) { warn_on_indented_labels = FALSE; goto done; + } else if (strcmp(argument + 1, OPTIONWNO_OLD_FOR) == 0) { + warn_on_old_for = FALSE; + goto done; + } else if (strcmp(argument + 1, OPTIONWTYPE_MISMATCH) == 0) { + warn_on_type_mismatch = TRUE; + goto done; } else { fprintf(stderr, "%sUnknown warning level.\n", cliargs_error); exit(EXIT_FAILURE); diff --git a/src/alu.c b/src/alu.c index 6c80fcd..07b2cfa 100644 --- a/src/alu.c +++ b/src/alu.c @@ -48,6 +48,7 @@ enum operator_handle { OPHANDLE_END, // "reached end of expression" OPHANDLE_RETURN, // "return value to caller" // functions + OPHANDLE_ADDR, // addr(v) OPHANDLE_INT, // int(v) OPHANDLE_FLOAT, // float(v) OPHANDLE_SIN, // sin(v) @@ -129,6 +130,7 @@ static struct operator ops_negate = {OPHANDLE_NEGATE, 28}; // monadic static struct operator ops_powerof = {OPHANDLE_POWEROF, 29}; // dyadic, right-associative static struct operator ops_not = {OPHANDLE_NOT, 30}; // monadic // function calls act as if they were monadic operators +static struct operator ops_addr = {OPHANDLE_ADDR, 32}; // function static struct operator ops_int = {OPHANDLE_INT, 32}; // function static struct operator ops_float = {OPHANDLE_FLOAT, 32}; // function static struct operator ops_sin = {OPHANDLE_SIN, 32}; // function @@ -176,6 +178,7 @@ static struct node_t operator_list[] = { }; static struct node_t *function_tree = NULL; // tree to hold functions static struct node_t function_list[] = { + PREDEFNODE("addr", &ops_addr), PREDEFNODE("int", &ops_int), PREDEFNODE("float", &ops_float), PREDEFNODE(s_arcsin, &ops_arcsin), @@ -193,18 +196,22 @@ static struct node_t function_list[] = { #define RIGHT_INTVAL (operand_stack[operand_sp-1].val.intval) #define LEFT_FPVAL (operand_stack[operand_sp-2].val.fpval) #define RIGHT_FPVAL (operand_stack[operand_sp-1].val.fpval) +#define LEFT_ADDRREFS (operand_stack[operand_sp-2].addr_refs) +#define RIGHT_ADDRREFS (operand_stack[operand_sp-1].addr_refs) #define PUSH_OPERATOR(x) operator_stack[operator_sp++] = (x) -#define PUSH_INTOPERAND(i, f) \ +#define PUSH_INTOPERAND(i, f, r) \ do { \ operand_stack[operand_sp].flags = (f); \ - operand_stack[operand_sp++].val.intval = (i); \ + operand_stack[operand_sp].val.intval = (i); \ + operand_stack[operand_sp++].addr_refs = (r); \ } while (0) #define PUSH_FPOPERAND(fp, f) \ do { \ operand_stack[operand_sp].flags = (f) | MVALUE_IS_FP; \ - operand_stack[operand_sp++].val.fpval = (fp); \ + operand_stack[operand_sp].val.fpval = (fp); \ + operand_stack[operand_sp++].addr_refs = 0; \ } while (0) @@ -353,7 +360,7 @@ static void parse_quoted_character(char closing_quote) Throw_error("There's more than one character."); Input_skip_remainder(); } - PUSH_INTOPERAND(value, MVALUE_GIVEN | MVALUE_ISBYTE); + PUSH_INTOPERAND(value, MVALUE_GIVEN | MVALUE_ISBYTE, 0); // Now GotByte = char following closing quote (or CHAR_EOS on error) } @@ -393,7 +400,7 @@ static void parse_binary_value(void) // Now GotByte = "%" or "b" flags |= MVALUE_FORCE16; } } - PUSH_INTOPERAND(value, flags); + PUSH_INTOPERAND(value, flags, 0); // Now GotByte = non-binary char } @@ -437,7 +444,7 @@ static void parse_hexadecimal_value(void) // Now GotByte = "$" or "x" flags |= MVALUE_FORCE16; } } - PUSH_INTOPERAND(value, flags); + PUSH_INTOPERAND(value, flags, 0); // Now GotByte = non-hexadecimal char } @@ -497,7 +504,7 @@ static void parse_decimal_value(void) // Now GotByte = first digit GetByte(); parse_frac_part(intval); } else { - PUSH_INTOPERAND(intval, MVALUE_GIVEN); + PUSH_INTOPERAND(intval, MVALUE_GIVEN, 0); } // Now GotByte = non-decimal char } @@ -527,7 +534,7 @@ static void parse_octal_value(void) // Now GotByte = "&" flags |= MVALUE_FORCE16; } } - PUSH_INTOPERAND(value, flags); + PUSH_INTOPERAND(value, flags, 0); // Now GotByte = non-octal char } @@ -535,11 +542,11 @@ static void parse_octal_value(void) // Now GotByte = "&" // Parse program counter ('*') static void parse_program_counter(void) // Now GotByte = "*" { - struct result_int_t pc; + struct result_t pc; GetByte(); vcpu_read_pc(&pc); - PUSH_INTOPERAND(pc.intval, pc.flags | MVALUE_EXISTS); + PUSH_INTOPERAND(pc.val.intval, pc.flags | MVALUE_EXISTS, pc.addr_refs); } @@ -698,7 +705,7 @@ static void expect_operand_or_monadic_operator(void) } } else { // illegal character read - so don't go on - PUSH_INTOPERAND(0, 0); + PUSH_INTOPERAND(0, 0, 0); // push dummy operand so stack is ok // push pseudo value, EXISTS flag is clear if (operator_stack[operator_sp-1] == &ops_return) { PUSH_OPERATOR(&ops_end); @@ -840,7 +847,7 @@ static void expect_dyadic_operator(void) //break; unreachable // end of expression or text version of dyadic operator default: - // check string version of operators + // check string versions of operators if (BYTEFLAGS(GotByte) & STARTS_KEYWORD) { Input_read_and_lower_keyword(); // Now GotByte = illegal char @@ -878,6 +885,7 @@ static void perform_fp(double (*fn)(double)) RIGHT_FLAGS |= MVALUE_IS_FP; } RIGHT_FPVAL = fn(RIGHT_FPVAL); + RIGHT_ADDRREFS = 0; // result now is a non-address } @@ -895,6 +903,7 @@ static void perform_ranged_fp(double (*fn)(double)) Throw_error("Argument out of range."); RIGHT_FPVAL = 0; } + RIGHT_ADDRREFS = 0; // result now is a non-address } @@ -918,7 +927,7 @@ static void both_ensure_int(int warn) RIGHT_INTVAL = RIGHT_FPVAL; RIGHT_FLAGS &= ~MVALUE_IS_FP; } - // FIXME - "warn" is not used + // FIXME - warning is never seen if both operands are undefined in first pass! Throw_first_pass_warning("Converted to integer for binary logic operator."); } @@ -993,9 +1002,14 @@ static void try_to_reduce_stacks(int *open_parentheses) goto remove_next_to_last_operator; // functions + case OPHANDLE_ADDR: + RIGHT_ADDRREFS = 1; // result now is an address + goto remove_next_to_last_operator; + case OPHANDLE_INT: if (RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); + RIGHT_ADDRREFS = 0; // result now is a non-address goto remove_next_to_last_operator; case OPHANDLE_FLOAT: @@ -1004,30 +1018,31 @@ static void try_to_reduce_stacks(int *open_parentheses) RIGHT_FPVAL = RIGHT_INTVAL; RIGHT_FLAGS |= MVALUE_IS_FP; } + RIGHT_ADDRREFS = 0; // result now is a non-address goto remove_next_to_last_operator; case OPHANDLE_SIN: - perform_fp(sin); + perform_fp(sin); // also zeroes addr_refs goto remove_next_to_last_operator; case OPHANDLE_COS: - perform_fp(cos); + perform_fp(cos); // also zeroes addr_refs goto remove_next_to_last_operator; case OPHANDLE_TAN: - perform_fp(tan); + perform_fp(tan); // also zeroes addr_refs goto remove_next_to_last_operator; case OPHANDLE_ARCSIN: - perform_ranged_fp(asin); + perform_ranged_fp(asin); // also zeroes addr_refs goto remove_next_to_last_operator; case OPHANDLE_ARCCOS: - perform_ranged_fp(acos); + perform_ranged_fp(acos); // also zeroes addr_refs goto remove_next_to_last_operator; case OPHANDLE_ARCTAN: - perform_fp(atan); + perform_fp(atan); // also zeroes addr_refs goto remove_next_to_last_operator; // monadic operators @@ -1055,6 +1070,7 @@ static void try_to_reduce_stacks(int *open_parentheses) RIGHT_INTVAL = (RIGHT_INTVAL) & 255; RIGHT_FLAGS |= MVALUE_ISBYTE; RIGHT_FLAGS &= ~MVALUE_FORCEBITS; + RIGHT_ADDRREFS = 0; // result now is a non-address goto remove_next_to_last_operator; case OPHANDLE_HIGHBYTEOF: @@ -1064,6 +1080,7 @@ static void try_to_reduce_stacks(int *open_parentheses) RIGHT_INTVAL = ((RIGHT_INTVAL) >> 8) & 255; RIGHT_FLAGS |= MVALUE_ISBYTE; RIGHT_FLAGS &= ~MVALUE_FORCEBITS; + RIGHT_ADDRREFS = 0; // result now is a non-address goto remove_next_to_last_operator; case OPHANDLE_BANKBYTEOF: @@ -1073,6 +1090,7 @@ static void try_to_reduce_stacks(int *open_parentheses) RIGHT_INTVAL = ((RIGHT_INTVAL) >> 16) & 255; RIGHT_FLAGS |= MVALUE_ISBYTE; RIGHT_FLAGS &= ~MVALUE_FORCEBITS; + RIGHT_ADDRREFS = 0; // result now is a non-address goto remove_next_to_last_operator; // dyadic operators @@ -1080,6 +1098,7 @@ static void try_to_reduce_stacks(int *open_parentheses) if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { both_ensure_fp(); LEFT_FPVAL = pow(LEFT_FPVAL, RIGHT_FPVAL); + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; } @@ -1090,6 +1109,7 @@ static void try_to_reduce_stacks(int *open_parentheses) Throw_error("Exponent is negative."); LEFT_INTVAL = 0; } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_MULTIPLY: @@ -1099,6 +1119,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL *= RIGHT_INTVAL; } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_DIVIDE: @@ -1120,6 +1141,7 @@ static void try_to_reduce_stacks(int *open_parentheses) LEFT_INTVAL = 0; } } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_INTDIV: @@ -1142,6 +1164,7 @@ static void try_to_reduce_stacks(int *open_parentheses) LEFT_INTVAL = 0; } } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_MODULO: @@ -1154,6 +1177,7 @@ static void try_to_reduce_stacks(int *open_parentheses) Throw_error(exception_div_by_zero); LEFT_INTVAL = 0; } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_ADD: @@ -1163,6 +1187,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL += RIGHT_INTVAL; } + LEFT_ADDRREFS += RIGHT_ADDRREFS; // add address references goto handle_flags_and_dec_stacks; case OPHANDLE_SUBTRACT: @@ -1172,6 +1197,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL -= RIGHT_INTVAL; } + LEFT_ADDRREFS -= RIGHT_ADDRREFS; // subtract address references goto handle_flags_and_dec_stacks; case OPHANDLE_SL: @@ -1181,6 +1207,7 @@ static void try_to_reduce_stacks(int *open_parentheses) LEFT_FPVAL *= pow(2.0, RIGHT_INTVAL); else LEFT_INTVAL <<= RIGHT_INTVAL; + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_ASR: @@ -1190,6 +1217,7 @@ static void try_to_reduce_stacks(int *open_parentheses) LEFT_FPVAL /= (1 << RIGHT_INTVAL); else LEFT_INTVAL = my_asr(LEFT_INTVAL, RIGHT_INTVAL); + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_LSR: @@ -1197,6 +1225,7 @@ static void try_to_reduce_stacks(int *open_parentheses) if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL = ((uintval_t) LEFT_INTVAL) >> RIGHT_INTVAL; + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_LE: @@ -1206,6 +1235,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL = (LEFT_INTVAL <= RIGHT_INTVAL); } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_LESSTHAN: @@ -1215,6 +1245,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL = (LEFT_INTVAL < RIGHT_INTVAL); } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_GE: @@ -1224,6 +1255,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL = (LEFT_INTVAL >= RIGHT_INTVAL); } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_GREATERTHAN: @@ -1233,6 +1265,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL = (LEFT_INTVAL > RIGHT_INTVAL); } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_NOTEQUAL: @@ -1242,6 +1275,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL = (LEFT_INTVAL != RIGHT_INTVAL); } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_EQUALS: @@ -1251,6 +1285,7 @@ static void try_to_reduce_stacks(int *open_parentheses) } else { LEFT_INTVAL = (LEFT_INTVAL == RIGHT_INTVAL); } + LEFT_ADDRREFS = 0; // result now is a non-address goto handle_flags_and_dec_stacks; case OPHANDLE_AND: @@ -1258,6 +1293,7 @@ static void try_to_reduce_stacks(int *open_parentheses) if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL &= RIGHT_INTVAL; + LEFT_ADDRREFS += RIGHT_ADDRREFS; // add address references goto handle_flags_and_dec_stacks; case OPHANDLE_EOR: @@ -1268,6 +1304,7 @@ static void try_to_reduce_stacks(int *open_parentheses) if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL ^= RIGHT_INTVAL; + LEFT_ADDRREFS += RIGHT_ADDRREFS; // add address references goto handle_flags_and_dec_stacks; case OPHANDLE_OR: @@ -1275,6 +1312,7 @@ static void try_to_reduce_stacks(int *open_parentheses) if ((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL |= RIGHT_INTVAL; + LEFT_ADDRREFS += RIGHT_ADDRREFS; // add address references goto handle_flags_and_dec_stacks; default: @@ -1389,8 +1427,7 @@ static int parse_expression(struct result_t *result) } -// These functions handle numerical expressions. There are operators for -// arithmetic, logic, shift and comparison operations. +// These functions handle numerical expressions. // There are several different ways to call the core function: // intval_t ALU_any_int(void); // returns int value (0 if result was undefined) @@ -1473,23 +1510,19 @@ int ALU_optional_defined_int(intval_t *target) // It the result's "exists" flag is clear (=empty expression), it throws an // error. // If the result's "defined" flag is clear, result_is_undefined() is called. -void ALU_int_result(struct result_int_t *intresult) +void ALU_int_result(struct result_t *intresult) { - struct result_t result; - - if (parse_expression(&result)) + if (parse_expression(intresult)) Throw_error(exception_paren_open); - if ((result.flags & MVALUE_EXISTS) == 0) - Throw_error(exception_no_value); - else if ((result.flags & MVALUE_DEFINED) == 0) - result_is_undefined(); - if (result.flags & MVALUE_IS_FP) { - intresult->intval = result.val.fpval; - intresult->flags = result.flags & ~MVALUE_IS_FP; - } else { - intresult->intval = result.val.intval; - intresult->flags = result.flags; + // make sure result is not float + if (intresult->flags & MVALUE_IS_FP) { + intresult->val.intval = intresult->val.fpval; + intresult->flags &= ~MVALUE_IS_FP; } + if ((intresult->flags & MVALUE_EXISTS) == 0) + Throw_error(exception_no_value); + else if ((intresult->flags & MVALUE_DEFINED) == 0) + result_is_undefined(); } @@ -1497,26 +1530,23 @@ void ALU_int_result(struct result_int_t *intresult) // This function allows for one '(' too many. Needed when parsing indirect // addressing modes where internal indices have to be possible. Returns number // of parentheses still open (either 0 or 1). -int ALU_liberal_int(struct result_int_t *intresult) +int ALU_liberal_int(struct result_t *intresult) { - struct result_t result; - int parentheses_still_open; + int parentheses_still_open; - parentheses_still_open = parse_expression(&result); + parentheses_still_open = parse_expression(intresult); + // make sure result is not float + if (intresult->flags & MVALUE_IS_FP) { + intresult->val.intval = intresult->val.fpval; + intresult->flags &= ~MVALUE_IS_FP; + } if (parentheses_still_open > 1) { parentheses_still_open = 0; Throw_error(exception_paren_open); } - if ((result.flags & MVALUE_EXISTS) - && ((result.flags & MVALUE_DEFINED) == 0)) + if ((intresult->flags & MVALUE_EXISTS) + && ((intresult->flags & MVALUE_DEFINED) == 0)) result_is_undefined(); - if (result.flags & MVALUE_IS_FP) { - intresult->intval = result.val.fpval; - intresult->flags = result.flags & ~MVALUE_IS_FP; - } else { - intresult->intval = result.val.intval; - intresult->flags = result.flags; - } return parentheses_still_open; } diff --git a/src/alu.h b/src/alu.h index 60e74c2..5129092 100644 --- a/src/alu.h +++ b/src/alu.h @@ -1,5 +1,5 @@ // ACME - a crossassembler for producing 6502/65c02/65816 code. -// Copyright (C) 1998-2009 Marco Baye +// Copyright (C) 1998-2014 Marco Baye // Have a look at "acme.c" for further info // // ALU stuff (the expression parser) @@ -12,9 +12,9 @@ // constants -// meaning of bits in "flags" of result_t and result_int_t structures: +// meaning of bits in "flags" of result_t structure: #define MVALUE_IS_FP (1u << 8) - // floating point value (never set in result_int_t) + // floating point value #define MVALUE_INDIRECT (1u << 7) // needless parentheses indicate use of indirect addressing modes #define MVALUE_EXISTS (1u << 6) @@ -50,9 +50,9 @@ extern intval_t ALU_defined_int(void); // stores int value if given. Returns whether stored. Throws error if undefined. extern int ALU_optional_defined_int(intval_t *); // stores int value and flags (floats are transformed to int) -extern void ALU_int_result(struct result_int_t *); +extern void ALU_int_result(struct result_t *); // stores int value and flags, allowing for one '(' too many (x-indirect addr) -extern int ALU_liberal_int(struct result_int_t *); +extern int ALU_liberal_int(struct result_t *); // stores value and flags (result may be either int or float) extern void ALU_any_result(struct result_t *); diff --git a/src/basics.c b/src/basics.c index 5c6f0a5..c59b306 100644 --- a/src/basics.c +++ b/src/basics.c @@ -14,6 +14,7 @@ #include "global.h" #include "output.h" #include "tree.h" +#include "typesystem.h" // constants @@ -139,6 +140,19 @@ static enum eos PO_fill(void) } +// force explicit label definitions to set "address" flag ("!addr"). Has to be re-entrant. +static enum eos PO_addr(void) // Now GotByte = illegal char +{ + SKIPSPACE(); + if (GotByte == CHAR_SOB) { + typesystem_force_address_block(); + return ENSURE_EOS; + } + typesystem_force_address_statement(TRUE); + return PARSE_REMAINDER; +} + + // show user-defined message static enum eos throw_string(const char prefix[], void (*fn)(const char *)) { @@ -240,6 +254,8 @@ static struct node_t pseudo_opcodes[] = { PREDEFNODE("binary", PO_binary), PREDEFNODE("fi", PO_fill), PREDEFNODE("fill", PO_fill), + PREDEFNODE("addr", PO_addr), + PREDEFNODE("address", PO_addr), // PREDEFNODE("debug", PO_debug), // PREDEFNODE("info", PO_info), // PREDEFNODE("print", PO_print), diff --git a/src/config.h b/src/config.h index 182f248..354307c 100644 --- a/src/config.h +++ b/src/config.h @@ -18,11 +18,7 @@ struct result_t { // either int or float intval_t intval; // integer value double fpval; // floating point value } val; // Expression value -}; -// result structure type definition for int -struct result_int_t { - int flags; // expression flags - intval_t intval; // expression value + int addr_refs; // address reference count (only look at this if value is DEFINED) }; diff --git a/src/cpu.c b/src/cpu.c index 803b34f..7f8d80b 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -75,7 +75,7 @@ static enum eos PO_align(void) intval_t and, equal, fill, - test = CPU_state.pc.intval; + test = CPU_state.pc.val.intval; // make sure PC is defined. if ((CPU_state.pc.flags & MVALUE_DEFINED) == 0) { @@ -152,13 +152,13 @@ static enum eos PO_pseudopc(void) // set new new_pc = ALU_defined_int(); // FIXME - allow for undefined! - new_offset = (new_pc - CPU_state.pc.intval) & 0xffff; - CPU_state.pc.intval = new_pc; + new_offset = (new_pc - CPU_state.pc.val.intval) & 0xffff; + CPU_state.pc.val.intval = new_pc; CPU_state.pc.flags |= MVALUE_DEFINED; // FIXME - remove when allowing undefined! // if there's a block, parse that and then restore old value! if (Parse_optional_block()) { // restore old - CPU_state.pc.intval = (CPU_state.pc.intval - new_offset) & 0xffff; + CPU_state.pc.val.intval = (CPU_state.pc.val.intval - new_offset) & 0xffff; CPU_state.pc.flags = outer_flags; } else { // not using a block is no longer allowed diff --git a/src/flow.c b/src/flow.c index 300db08..4da58f4 100644 --- a/src/flow.c +++ b/src/flow.c @@ -209,12 +209,15 @@ static enum eos PO_for(void) // Now GotByte = illegal char first_arg = ALU_defined_int(); if (Input_accept_comma()) { old_algo = FALSE; // new format - yay! + if (!warn_on_old_for) + Throw_first_pass_warning("Found new \"!for\" syntax."); counter_first = first_arg; // use given argument counter_last = ALU_defined_int(); // read second argument counter_increment = (counter_last < counter_first) ? -1 : 1; } else { old_algo = TRUE; // old format - booo! - Throw_first_pass_warning("Found deprecated \"!for\" syntax."); + if (warn_on_old_for) + Throw_first_pass_warning("Found old \"!for\" syntax."); if (first_arg < 0) Throw_serious_error("Loop count is negative."); counter_first = 0; // CAUTION - old algo pre-increments and therefore starts with 1! diff --git a/src/global.c b/src/global.c index 22435b7..8f70d47 100644 --- a/src/global.c +++ b/src/global.c @@ -5,6 +5,7 @@ // Global stuff - things that are needed by several modules // 4 Oct 2006 Fixed a typo in a comment // 22 Nov 2007 Added warn_on_indented_labels +// 2 Jun 2014 Added warn_on_old_for and warn_on_type_mismatch #include #include "platform.h" #include "acme.h" @@ -17,6 +18,7 @@ #include "output.h" #include "section.h" #include "tree.h" +#include "typesystem.h" // constants @@ -55,7 +57,7 @@ const char exception_syntax[] = "Syntax error."; // ...4.... special character for input syntax: 0x00 TAB LF CR SPC : ; } // ....3... preceding sequence of '-' characters is anonymous backward // label. Currently only set for ')', ',' and CHAR_EOS. -// .....210 unused +// .....210 currently unused const char Byte_flags[256] = { /*$00*/ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// control characters 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, @@ -98,6 +100,8 @@ int pass_count; // number of current pass (starts 0) char GotByte; // Last byte read (processed) int Process_verbosity = 0; // Level of additional output int warn_on_indented_labels = TRUE; // warn if indented label is encountered +int warn_on_old_for = TRUE; // warn if "!for" with old syntax is found +int warn_on_type_mismatch = FALSE; // use type-checking system // global counters int pass_undefined_count; // "NeedValue" type errors int pass_real_errors; // Errors yet @@ -256,9 +260,10 @@ void Parse_until_eob_or_eof(void) while ((GotByte != CHAR_EOB) && (GotByte != CHAR_EOF)) { // process one statement statement_flags = 0; // no "label = pc" definition yet + typesystem_force_address_statement(FALSE); // Parse until end of statement. Only loops if statement // contains "label = pc" definition and something else; or - // if "!ifdef" is true. + // if "!ifdef" is true, or if "!addr" is used without block. do { switch (GotByte) { case CHAR_EOS: // end of statement diff --git a/src/global.h b/src/global.h index f8e993b..ddf1ff4 100644 --- a/src/global.h +++ b/src/global.h @@ -1,5 +1,5 @@ // ACME - a crossassembler for producing 6502/65c02/65816 code. -// Copyright (C) 1998-2009 Marco Baye +// Copyright (C) 1998-2014 Marco Baye // Have a look at "acme.c" for further info // // Global stuff - things that are needed by several modules @@ -47,7 +47,7 @@ extern const char Byte_flags[]; // converted to lower case by OR-ing this bit(!) #define BYTEIS_SYNTAX (1u << 4) // special character for input syntax #define FOLLOWS_ANON (1u << 3) // preceding '-' are backward label -// bits 2, 1 and 0 are unused +// bits 2, 1 and 0 are currently unused // Variables @@ -64,6 +64,8 @@ enum eos { extern int pass_count; extern int Process_verbosity; // Level of additional output extern int warn_on_indented_labels; // warn if indented label is encountered +extern int warn_on_old_for; // warn if "!for" with old syntax is found +extern int warn_on_type_mismatch; // use type-checking system extern char GotByte; // Last byte read (processed) // Global counters extern int pass_undefined_count; // "NeedValue" type errors in current pass diff --git a/src/label.c b/src/label.c index f5d8574..4e45447 100644 --- a/src/label.c +++ b/src/label.c @@ -17,6 +17,7 @@ #include "platform.h" #include "section.h" #include "tree.h" +#include "typesystem.h" // constants @@ -62,7 +63,7 @@ static void dump_one_label(struct node_ra_t *node, FILE *fd) } -// Search for label. Create if nonexistant. If created, give it flags "Flags". +// Search for label. Create if nonexistant. If created, give it flags "flags". // The label name must be held in GlobalDynaBuf. struct label *Label_find(zone_t zone, int flags) { @@ -78,6 +79,7 @@ struct label *Label_find(zone_t zone, int flags) label = safe_malloc(sizeof(*label)); // Finish empty label item label->result.flags = flags; + label->result.addr_refs = 0; if (flags & MVALUE_IS_FP) label->result.val.fpval = 0; else @@ -206,9 +208,9 @@ static struct node_t pseudo_opcodes[] = { // GlobalDynaBuf holds the label name. void Label_implicit_definition(zone_t zone, int stat_flags, int force_bit, int change) { - struct result_int_t pc; - struct result_t result; - struct label *label; + struct result_t pc, + result; + struct label *label; label = Label_find(zone, force_bit); // implicit label definition (label) @@ -216,7 +218,8 @@ void Label_implicit_definition(zone_t zone, int stat_flags, int force_bit, int c Throw_first_pass_warning("Implicit label definition not in leftmost column."); vcpu_read_pc(&pc); result.flags = pc.flags & MVALUE_DEFINED; - result.val.intval = pc.intval; + result.val.intval = pc.val.intval; + result.addr_refs = pc.addr_refs; Label_set_value(label, &result, change); } @@ -236,6 +239,9 @@ void Label_parse_definition(zone_t zone, int stat_flags) // label = parsed value GetByte(); // skip '=' ALU_any_result(&result); + // if wanted, mark as address reference + if (typesystem_says_address()) + result.addr_refs = 1; Label_set_value(label, &result, FALSE); Input_ensure_EOS(); } else { diff --git a/src/mnemo.c b/src/mnemo.c index af64f95..1a963ea 100644 --- a/src/mnemo.c +++ b/src/mnemo.c @@ -11,6 +11,7 @@ #include "input.h" #include "output.h" #include "tree.h" +#include "typesystem.h" // Constants @@ -395,9 +396,9 @@ static int get_index(int next) return addressing_mode; } -// This function stores the command's argument in the given result_int_t +// This function stores the command's argument in the given result_t // structure (using the valueparser). The addressing mode is returned. -static int get_argument(struct result_int_t *result) +static int get_argument(struct result_t *result) { int open_paren, addressing_mode = HAM_ABS; @@ -407,6 +408,7 @@ static int get_argument(struct result_int_t *result) case '[': GetByte(); // proceed with next char ALU_int_result(result); + typesystem_want_addr(result); if (GotByte == ']') addressing_mode |= HAM_LIND | get_index(TRUE); else @@ -416,10 +418,12 @@ static int get_argument(struct result_int_t *result) GetByte(); // proceed with next char addressing_mode |= HAM_IMM; ALU_int_result(result); + typesystem_want_imm(result); break; default: // liberal, to allow for "(...," open_paren = ALU_liberal_int(result); + typesystem_want_addr(result); // check for implied addressing if ((result->flags & MVALUE_EXISTS) == 0) addressing_mode |= HAM_IMP; @@ -447,7 +451,7 @@ static int get_argument(struct result_int_t *result) // Helper function for calc_arg_size() // Only call with "size_bit = MVALUE_FORCE16" or "size_bit = MVALUE_FORCE24" -static int check_oversize(int size_bit, struct result_int_t *argument) +static int check_oversize(int size_bit, struct result_t *argument) { // only check if value is *defined* if ((argument->flags & MVALUE_DEFINED) == 0) @@ -456,11 +460,11 @@ static int check_oversize(int size_bit, struct result_int_t *argument) // value is defined, so check if (size_bit == MVALUE_FORCE16) { // check 16-bit argument for high byte zero - if ((argument->intval <= 255) && (argument->intval >= -128)) + if ((argument->val.intval <= 255) && (argument->val.intval >= -128)) Throw_warning(exception_highbyte_zero); } else { // check 24-bit argument for bank byte zero - if ((argument->intval <= 65535) && (argument->intval >= -32768)) + if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768)) Throw_warning(exception_highbyte_zero); } return size_bit; // pass on result @@ -474,7 +478,7 @@ static int check_oversize(int size_bit, struct result_int_t *argument) // argument value and flags of parameter // addressing_modes adressing modes (8b, 16b, 24b or any combination) // Return value = force bit for number of parameter bytes to send (0 = error) -static int calc_arg_size(int force_bit, struct result_int_t *argument, int addressing_modes) +static int calc_arg_size(int force_bit, struct result_t *argument, int addressing_modes) { // if there are no possible addressing modes, complain if (addressing_modes == MAYBE______) { @@ -541,18 +545,18 @@ static int calc_arg_size(int force_bit, struct result_int_t *argument, int addre // Value is sure, so use its own size // if value is negative, size cannot be chosen. Complain! - if (argument->intval < 0) { + if (argument->val.intval < 0) { Throw_error("Negative value - cannot choose addressing mode."); return 0; } // Value is positive or zero. Check size ranges // if there is an 8-bit addressing mode and value fits, use 8 bits - if ((addressing_modes & MVALUE_FORCE08) && (argument->intval < 256)) + if ((addressing_modes & MVALUE_FORCE08) && (argument->val.intval < 256)) return MVALUE_FORCE08; // if there is a 16-bit addressing mode and value fits, use 16 bits - if ((addressing_modes & MVALUE_FORCE16) && (argument->intval < 65536)) + if ((addressing_modes & MVALUE_FORCE16) && (argument->val.intval < 65536)) return MVALUE_FORCE16; // if there is a 24-bit addressing mode, use that. In case the @@ -584,16 +588,17 @@ static void not_in_bank(intval_t target) // Mnemonics using only 8bit relative addressing (short branch instructions). static void group_only_relative8_addressing(int opcode) { - struct result_int_t target; - intval_t offset = 0; // dummy value, to not throw more errors than necessary + struct result_t target; + intval_t offset = 0; // dummy value, to not throw more errors than necessary ALU_int_result(&target); + typesystem_want_addr(&target); // FIXME - read pc via function call instead! if (CPU_state.pc.flags & target.flags & MVALUE_DEFINED) { - if ((target.intval | 0xffff) != 0xffff) { - not_in_bank(target.intval); + if ((target.val.intval | 0xffff) != 0xffff) { + not_in_bank(target.val.intval); } else { - offset = (target.intval - (CPU_state.pc.intval + 2)) & 0xffff; // clip to 16 bit offset + offset = (target.val.intval - (CPU_state.pc.val.intval + 2)) & 0xffff; // clip to 16 bit offset // fix sign if (offset & 0x8000) offset -= 0x10000; @@ -618,16 +623,17 @@ static void group_only_relative8_addressing(int opcode) // Mnemonics using only 16bit relative addressing (BRL and PER). static void group_only_relative16_addressing(int opcode) { - struct result_int_t target; - intval_t offset = 0; // dummy value, to not throw more errors than necessary + struct result_t target; + intval_t offset = 0; // dummy value, to not throw more errors than necessary ALU_int_result(&target); + typesystem_want_addr(&target); // FIXME - read pc via function call instead! if (CPU_state.pc.flags & target.flags & MVALUE_DEFINED) { - if ((target.intval | 0xffff) != 0xffff) { - not_in_bank(target.intval); + if ((target.val.intval | 0xffff) != 0xffff) { + not_in_bank(target.val.intval); } else { - offset = (target.intval - (CPU_state.pc.intval + 3)) & 0xffff; + offset = (target.val.intval - (CPU_state.pc.val.intval + 3)) & 0xffff; // no further checks necessary, 16-bit branches can access whole bank } } @@ -638,7 +644,7 @@ static void group_only_relative16_addressing(int opcode) // set addressing mode bits depending on which opcodes exist, then calculate // argument size and output both opcode and argument -static void make_command(int force_bit, struct result_int_t *result, unsigned long opcodes) +static void make_command(int force_bit, struct result_t *result, unsigned long opcodes) { int addressing_modes = MAYBE______; @@ -651,15 +657,15 @@ static void make_command(int force_bit, struct result_int_t *result, unsigned lo switch (calc_arg_size(force_bit, result, addressing_modes)) { case MVALUE_FORCE08: Output_byte(opcodes & 255); - Output_8b(result->intval); + Output_8b(result->val.intval); break; case MVALUE_FORCE16: Output_byte((opcodes >> 8) & 255); - Output_16b(result->intval); + Output_16b(result->val.intval); break; case MVALUE_FORCE24: Output_byte((opcodes >> 16) & 255); - Output_24b(result->intval); + Output_24b(result->val.intval); } } @@ -688,9 +694,9 @@ static unsigned int imm_ops(int *force_bit, unsigned char opcode, int imm_flag) // plus PEI. static void group_main(int index, int imm_flag) { - unsigned long imm_opcodes; - struct result_int_t result; - int force_bit = Input_get_force_bit(); // skips spaces after + unsigned long imm_opcodes; + struct result_t result; + int force_bit = Input_get_force_bit(); // skips spaces after switch (get_argument(&result)) { case HAM_IMM: // #$ff or #$ffff (depending on accu length) @@ -737,9 +743,9 @@ static void group_main(int index, int imm_flag) // Various mnemonics with different addressing modes. static void group_misc(int index, int imm_flag) { - unsigned long imm_opcodes; - struct result_int_t result; - int force_bit = Input_get_force_bit(); // skips spaces after + unsigned long imm_opcodes; + struct result_t result; + int force_bit = Input_get_force_bit(); // skips spaces after switch (get_argument(&result)) { case HAM_IMP: // implied addressing @@ -755,7 +761,7 @@ static void group_misc(int index, int imm_flag) make_command(force_bit, &result, imm_opcodes); // check whether to warn about 6510's unstable LXA if ((imm_opcodes == 0xab) - && ((result.intval & 0xff) != 0x00) + && ((result.val.intval & 0xff) != 0x00) && (result.flags & MVALUE_DEFINED) && (CPU_state.type->flags & CPUFLAG_AB_NEEDS_0_ARG)) Throw_warning("Assembling unstable LXA #NONZERO instruction"); @@ -796,8 +802,8 @@ static void group_move(int opcode) // The jump instructions. static void group_jump(int index) { - struct result_int_t result; - int force_bit = Input_get_force_bit(); // skips spaces after + struct result_t result; + int force_bit = Input_get_force_bit(); // skips spaces after switch (get_argument(&result)) { case HAM_ABS: // absolute16 or absolute24 @@ -806,7 +812,7 @@ static void group_jump(int index) case HAM_IND: // ($ffff) make_command(force_bit, &result, jump_ind[index]); // check whether to warn about 6502's JMP() bug - if (((result.intval & 0xff) == 0xff) + if (((result.val.intval & 0xff) == 0xff) && (result.flags & MVALUE_DEFINED) && (CPU_state.type->flags & CPUFLAG_INDIRECTJMPBUGGY)) Throw_warning("Assembling buggy JMP($xxff) instruction"); diff --git a/src/output.c b/src/output.c index 09fc3c5..1df3ef8 100644 --- a/src/output.c +++ b/src/output.c @@ -485,7 +485,7 @@ void Output_passinit(void) //vcpu stuff: CPU_state.pc.flags = 0; // not defined yet - CPU_state.pc.intval = 0; // same as output's write_idx on pass init + CPU_state.pc.val.intval = 0; // same as output's write_idx on pass init CPU_state.add_to_pc = 0; // increase PC by this at end of statement CPU_state.a_is_long = FALSE; // short accu CPU_state.xy_are_long = FALSE; // short index regs @@ -554,9 +554,10 @@ void vcpu_set_pc(intval_t new_pc, int segment_flags) { intval_t new_offset; - new_offset = (new_pc - CPU_state.pc.intval) & 0xffff; - CPU_state.pc.intval = new_pc; + new_offset = (new_pc - CPU_state.pc.val.intval) & 0xffff; + CPU_state.pc.val.intval = new_pc; CPU_state.pc.flags |= MVALUE_DEFINED; // FIXME - remove when allowing undefined! + CPU_state.pc.addr_refs = 1; // yes, PC counts as address // now tell output buffer to start a new segment Output_start_segment(new_offset, segment_flags); } @@ -614,7 +615,7 @@ void PO_setpc(void) // get program counter -void vcpu_read_pc(struct result_int_t *target) +void vcpu_read_pc(struct result_t *target) { *target = CPU_state.pc; } @@ -630,6 +631,6 @@ int vcpu_get_statement_size(void) // adjust program counter (called at end of each statement) void vcpu_end_statement(void) { - CPU_state.pc.intval = (CPU_state.pc.intval + CPU_state.add_to_pc) & 0xffff; + CPU_state.pc.val.intval = (CPU_state.pc.val.intval + CPU_state.add_to_pc) & 0xffff; CPU_state.add_to_pc = 0; } diff --git a/src/output.h b/src/output.h index f5dd68e..d016da7 100644 --- a/src/output.h +++ b/src/output.h @@ -19,7 +19,7 @@ // FIXME - move struct definition to .c file and change other .c files' accesses to fn calls struct vcpu { const struct cpu_type *type; // current CPU type (default 6502) (FIXME - move out of struct again?) - struct result_int_t pc; // current program counter (pseudo value) + struct result_t pc; // current program counter (pseudo value) int add_to_pc; // add to PC after statement int a_is_long; int xy_are_long; @@ -65,7 +65,7 @@ extern void Output_end_segment(void); // set program counter to defined value (FIXME - allow undefined!) extern void vcpu_set_pc(intval_t new_pc, int flags); // get program counter -extern void vcpu_read_pc(struct result_int_t *target); +extern void vcpu_read_pc(struct result_t *target); // get size of current statement (until now) - needed for "!bin" verbose output extern int vcpu_get_statement_size(void); // adjust program counter (called at end of each statement) diff --git a/src/typesystem.c b/src/typesystem.c new file mode 100644 index 0000000..56df22b --- /dev/null +++ b/src/typesystem.c @@ -0,0 +1,53 @@ +// ACME - a crossassembler for producing 6502/65c02/65816 code. +// Copyright (C) 1998-2014 Marco Baye +// Have a look at "acme.c" for further info +// +// Type system stuff +#include "typesystem.h" +#include "config.h" +#include "alu.h" +#include "global.h" + + +static int in_address_block = FALSE; +static int in_address_statement = FALSE; + +// Functions + +int typesystem_says_address(void) +{ + return in_address_block | in_address_statement; +} + +void typesystem_force_address_block(void) +{ + int buffer = in_address_block; + + in_address_block = TRUE; + Parse_optional_block(); + in_address_block = buffer; +} + +void typesystem_force_address_statement(int value) +{ + in_address_statement = value; +} + +void typesystem_want_imm(struct result_t *result) +{ + if (!warn_on_type_mismatch) + return; + if (!(result->flags & MVALUE_DEFINED)) + return; + if (result->addr_refs != 0) + Throw_warning("Wrong type - expected integer."); +} +void typesystem_want_addr(struct result_t *result) +{ + if (!warn_on_type_mismatch) + return; + if (!(result->flags & MVALUE_DEFINED)) + return; + if (result->addr_refs != 1) + Throw_warning("Wrong type - expected address."); +} diff --git a/src/typesystem.h b/src/typesystem.h new file mode 100644 index 0000000..4333fc5 --- /dev/null +++ b/src/typesystem.h @@ -0,0 +1,25 @@ +// ACME - a crossassembler for producing 6502/65c02/65816 code. +// Copyright (C) 1998-2014 Marco Baye +// Have a look at "acme.c" for further info +// +// Type system stuff +#ifndef typesystem_H +#define typesystem_H + + +#include "config.h" + + +// return whether explicit label definitions should force "address" mode +extern int typesystem_says_address(void); +// parse a block while forcing address mode +extern void typesystem_force_address_block(void); +// force address mode on or off for the next statement +extern void typesystem_force_address_statement(int value); +// warn if result is address instead of integer +extern void typesystem_want_imm(struct result_t *result); +// warn if result is integer instead of address +extern void typesystem_want_addr(struct result_t *result); + + +#endif