diff --git a/asminc/apple2.inc b/asminc/apple2.inc index 5ebf73164..528c463a1 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -15,6 +15,7 @@ PROMPT := $33 ; Used by GETLN RNDL := $4E ; Random counter low RNDH := $4F ; Random counter high HIMEM := $73 ; Highest available memory address+1 +CURLIN := $75 ; Current line number being executed ;----------------------------------------------------------------------------- ; Vectors diff --git a/asminc/c128.inc b/asminc/c128.inc index 2852631f3..749b4168c 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -7,6 +7,7 @@ ; Zero page, Commodore stuff TXTPTR := $3D ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status TIME := $A0 ; 60HZ clock FNAM_LEN := $B7 ; Length of filename SECADR := $B9 ; Secondary address diff --git a/asminc/c64.inc b/asminc/c64.inc index 1d10f673d..2cfc50db4 100644 --- a/asminc/c64.inc +++ b/asminc/c64.inc @@ -9,6 +9,7 @@ VARTAB := $2D ; Pointer to start of BASIC variables MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) TXTPTR := $7A ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status TIME := $A0 ; 60 HZ clock FNAM_LEN := $B7 ; Length of filename SECADR := $B9 ; Secondary address diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 6b9cb9947..31170fbed 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -2,18 +2,20 @@ CPU_ISET_NONE = $0001 CPU_ISET_6502 = $0002 CPU_ISET_6502X = $0004 -CPU_ISET_65SC02 = $0008 -CPU_ISET_65C02 = $0010 -CPU_ISET_65816 = $0020 -CPU_ISET_SWEET16 = $0040 -CPU_ISET_HUC6280 = $0080 -;CPU_ISET_M740 = $0100 not actually implemented -CPU_ISET_4510 = $0200 +CPU_ISET_6502DTV = $0008 +CPU_ISET_65SC02 = $0010 +CPU_ISET_65C02 = $0020 +CPU_ISET_65816 = $0040 +CPU_ISET_SWEET16 = $0080 +CPU_ISET_HUC6280 = $0100 +;CPU_ISET_M740 = $0200 not actually implemented +CPU_ISET_4510 = $0400 ; CPU capabilities CPU_NONE = CPU_ISET_NONE CPU_6502 = CPU_ISET_6502 CPU_6502X = CPU_ISET_6502|CPU_ISET_6502X +CPU_6502DTV = CPU_ISET_6502|CPU_ISET_6502X|CPU_ISET_6502DTV CPU_65SC02 = CPU_ISET_6502|CPU_ISET_65SC02 CPU_65C02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02 CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816 diff --git a/asminc/opcodes.inc b/asminc/opcodes.inc index aa7a65f00..e6b7e73df 100644 --- a/asminc/opcodes.inc +++ b/asminc/opcodes.inc @@ -505,4 +505,12 @@ OPC_ISC_aby = $FB OPC_NOP_abx = $FC OPC_ISC_abx = $FF +.if (.cpu .bitand ::CPU_ISET_6502DTV) + +OPC_BRA = $12 +OPC_SAC_imm = $32 +OPC_SIR_imm = $42 + +.endif + .endif diff --git a/asminc/plus4.inc b/asminc/plus4.inc index 774722e93..6c6017a78 100644 --- a/asminc/plus4.inc +++ b/asminc/plus4.inc @@ -10,6 +10,7 @@ TMPPTR := $22 ; Temporary ptr used by BASIC VARTAB := $2D ; Pointer to start of BASIC variables MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) TXTPTR := $3B ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status TIME := $A3 ; 60HZ clock FNAM_LEN := $AB ; Length of filename LFN := $AC ; Logical file number diff --git a/asminc/vic20.inc b/asminc/vic20.inc index b82874f56..fa9fdfa8d 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -9,6 +9,7 @@ VARTAB := $2D ; Pointer to start of BASIC variables MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) TXTPTR := $7A ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status TIME := $A0 ; 60HZ clock FNAM_LEN := $B7 ; Length of filename SECADR := $B9 ; Secondary address diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg index 3ccf7b6f3..cfe577e00 100644 --- a/cfg/apple2-hgr.cfg +++ b/cfg/apple2-hgr.cfg @@ -23,8 +23,8 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - HGR: load = MAIN, type = rw, optional = yes, start = $2000; - CODE: load = MAIN, type = ro start = $4000; + HGR: load = MAIN, type = rw, start = $2000; + CODE: load = MAIN, type = ro start = $4000; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; INIT: load = MAIN, type = rw; diff --git a/cfg/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg index 3ccf7b6f3..cfe577e00 100644 --- a/cfg/apple2enh-hgr.cfg +++ b/cfg/apple2enh-hgr.cfg @@ -23,8 +23,8 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - HGR: load = MAIN, type = rw, optional = yes, start = $2000; - CODE: load = MAIN, type = ro start = $4000; + HGR: load = MAIN, type = rw, start = $2000; + CODE: load = MAIN, type = ro start = $4000; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; INIT: load = MAIN, type = rw; diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index 56d2af15b..38fb68db9 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -8,39 +8,40 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STACKSIZE__: type = weak, value = $0800; # 2k stack + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __CHARGENSIZE__: type = weak, value = $0400; __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # address of relocated character generator - CHARGEN: file = "", define = yes, start = $D800, size = $0400; + CHARGEN: file = "", define = yes, start = $D800, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $DC00, size = $FFFA - $DC00; + HIDDEN_RAM: file = "", define = yes, start = $D800 + __CHARGENSIZE__, size = $FFFA - $D800 - __CHARGENSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -53,7 +54,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; SRPREPHDR: load = SRPREPHDR, type = ro; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index 923436497..339228ea0 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -3,44 +3,45 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __CHARGENSIZE__: type = weak, value = $0400; + __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; + MAINHDR: file = %O, start = $0000, size = $0004; MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__ + - __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __OVERLAYSIZE__ - __LOWBSS_SIZE__; + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __OVERLAYSIZE__ - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E000 + __CHARGENSIZE__, size = $FFFA - $E000 - __CHARGENSIZE__; # overlays OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; @@ -64,7 +65,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; SRPREPHDR: load = SRPREPHDR, type = ro; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes; diff --git a/cfg/atarixl-xex.cfg b/cfg/atarixl-xex.cfg index 0b1fe9ca1..1b76855d0 100644 --- a/cfg/atarixl-xex.cfg +++ b/cfg/atarixl-xex.cfg @@ -4,35 +4,36 @@ FEATURES { STARTADDRESS: default = $2400; } SYMBOLS { - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __STACKSIZE__: type = weak, value = $0800; # 2k stack + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTADDRESS__: type = export, value = %S; + __CHARGENSIZE__: type = weak, value = $0400; __SYSCHKHDR__: type = export, value = 0; # Disable system check header __SYSCHKTRL__: type = export, value = 0; # Disable system check trailer } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # "system check" load chunk - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; # "shadow RAM preparation" load chunk - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned # "main program" load chunk - MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E000 + __CHARGENSIZE__, size = $FFFA - $E000 - __CHARGENSIZE__; # UNUSED - hide - UNUSED: file = "", start = $0, size = $10; + UNUSED: file = "", start = $0, size = $10; } FILES { %O: format = atari; @@ -47,7 +48,7 @@ SEGMENTS { EXTZP: load = ZP, type = zp, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes; diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index 197daace6..cece23555 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -6,39 +6,40 @@ SYMBOLS { __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk __AUTOSTART__: type = import; # force inclusion of autostart "trailer" __STACKSIZE__: type = weak, value = $0800; # 2k stack + __CHARGENSIZE__: type = weak, value = $0400; __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E000 + __CHARGENSIZE__, size = $FFFA - $E000 - __CHARGENSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -51,7 +52,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; SRPREPHDR: load = SRPREPHDR, type = ro; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes; diff --git a/cfg/cx16-asm.cfg b/cfg/cx16-asm.cfg index c3c08aec3..92c9d96f7 100644 --- a/cfg/cx16-asm.cfg +++ b/cfg/cx16-asm.cfg @@ -22,9 +22,11 @@ SEGMENTS { EXEHDR: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - BSS: load = MAIN, type = bss, define = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/cx16-bank.cfg b/cfg/cx16-bank.cfg index 36b0edb02..d3c2c02ae 100644 --- a/cfg/cx16-bank.cfg +++ b/cfg/cx16-bank.cfg @@ -16,8 +16,6 @@ MEMORY { HEADER: file = %O, define = yes, start = %S, size = $000D; MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__; -# BRAM00ADDR: file = "%O.00", start = __BANKRAMSTART__ - 2, size = $0002; -# BRAM00: file = "%O.00", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; BRAM01ADDR: file = "%O.01", start = __BANKRAMSTART__ - 2, size = $0002; BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $01; BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002; @@ -36,64 +34,62 @@ MEMORY { BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $08; BRAM09ADDR: file = "%O.09", start = __BANKRAMSTART__ - 2, size = $0002; BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $09; - BRAM0AADDR: file = "%O.0a", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0A: file = "%O.0a", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0A; - BRAM0BADDR: file = "%O.0b", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0B: file = "%O.0b", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0B; - BRAM0CADDR: file = "%O.0c", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0C: file = "%O.0c", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0C; - BRAM0DADDR: file = "%O.0d", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0D: file = "%O.0d", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0D; - BRAM0EADDR: file = "%O.0e", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0E: file = "%O.0e", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0E; - BRAM0FADDR: file = "%O.0f", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0F: file = "%O.0f", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0F; + BRAM0AADDR: file = "%O.0A", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0A: file = "%O.0A", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0A; + BRAM0BADDR: file = "%O.0B", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0B: file = "%O.0B", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0B; + BRAM0CADDR: file = "%O.0C", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0C: file = "%O.0C", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0C; + BRAM0DADDR: file = "%O.0D", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0D: file = "%O.0D", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0D; + BRAM0EADDR: file = "%O.0E", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0E: file = "%O.0E", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0E; + BRAM0FADDR: file = "%O.0F", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0F: file = "%O.0F", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0F; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; + STARTUP: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = rw; - ONCE: load = MAIN, type = ro, define = yes; - BSS: load = BSS, type = bss, define = yes; -# BRAM00ADDR: load = BRAM00ADDR, type = ro, optional = yes; -# BANKRAM00: load = BRAM00, type = rw, define = yes, optional = yes; - BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes; - BANKRAM01: load = BRAM01, type = rw, define = yes, optional = yes; - BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes; - BANKRAM02: load = BRAM02, type = rw, define = yes, optional = yes; - BRAM03ADDR: load = BRAM03ADDR, type = ro, optional = yes; - BANKRAM03: load = BRAM03, type = rw, define = yes, optional = yes; - BRAM04ADDR: load = BRAM04ADDR, type = ro, optional = yes; - BANKRAM04: load = BRAM04, type = rw, define = yes, optional = yes; - BRAM05ADDR: load = BRAM05ADDR, type = ro, optional = yes; - BANKRAM05: load = BRAM05, type = rw, define = yes, optional = yes; - BRAM06ADDR: load = BRAM06ADDR, type = ro, optional = yes; - BANKRAM06: load = BRAM06, type = rw, define = yes, optional = yes; - BRAM07ADDR: load = BRAM07ADDR, type = ro, optional = yes; - BANKRAM07: load = BRAM07, type = rw, define = yes, optional = yes; - BRAM08ADDR: load = BRAM08ADDR, type = ro, optional = yes; - BANKRAM08: load = BRAM08, type = rw, define = yes, optional = yes; - BRAM09ADDR: load = BRAM09ADDR, type = ro, optional = yes; - BANKRAM09: load = BRAM09, type = rw, define = yes, optional = yes; - BRAM0AADDR: load = BRAM0AADDR, type = ro, optional = yes; - BANKRAM0A: load = BRAM0A, type = rw, define = yes, optional = yes; - BRAM0BADDR: load = BRAM0BADDR, type = ro, optional = yes; - BANKRAM0B: load = BRAM0B, type = rw, define = yes, optional = yes; - BRAM0CADDR: load = BRAM0CADDR, type = ro, optional = yes; - BANKRAM0C: load = BRAM0C, type = rw, define = yes, optional = yes; - BRAM0DADDR: load = BRAM0DADDR, type = ro, optional = yes; - BANKRAM0D: load = BRAM0D, type = rw, define = yes, optional = yes; - BRAM0EADDR: load = BRAM0EADDR, type = ro, optional = yes; - BANKRAM0E: load = BRAM0E, type = rw, define = yes, optional = yes; - BRAM0FADDR: load = BRAM0FADDR, type = ro, optional = yes; - BANKRAM0F: load = BRAM0F, type = rw, define = yes, optional = yes; + INIT: load = MAIN, type = rw, optional = yes; + ONCE: load = MAIN, type = ro, define = yes; + BSS: load = BSS, type = bss, define = yes; + BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes; + BANKRAM01: load = BRAM01, type = rw, optional = yes, define = yes; + BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes; + BANKRAM02: load = BRAM02, type = rw, optional = yes, define = yes; + BRAM03ADDR: load = BRAM03ADDR, type = ro, optional = yes; + BANKRAM03: load = BRAM03, type = rw, optional = yes, define = yes; + BRAM04ADDR: load = BRAM04ADDR, type = ro, optional = yes; + BANKRAM04: load = BRAM04, type = rw, optional = yes, define = yes; + BRAM05ADDR: load = BRAM05ADDR, type = ro, optional = yes; + BANKRAM05: load = BRAM05, type = rw, optional = yes, define = yes; + BRAM06ADDR: load = BRAM06ADDR, type = ro, optional = yes; + BANKRAM06: load = BRAM06, type = rw, optional = yes, define = yes; + BRAM07ADDR: load = BRAM07ADDR, type = ro, optional = yes; + BANKRAM07: load = BRAM07, type = rw, optional = yes, define = yes; + BRAM08ADDR: load = BRAM08ADDR, type = ro, optional = yes; + BANKRAM08: load = BRAM08, type = rw, optional = yes, define = yes; + BRAM09ADDR: load = BRAM09ADDR, type = ro, optional = yes; + BANKRAM09: load = BRAM09, type = rw, optional = yes, define = yes; + BRAM0AADDR: load = BRAM0AADDR, type = ro, optional = yes; + BANKRAM0A: load = BRAM0A, type = rw, optional = yes, define = yes; + BRAM0BADDR: load = BRAM0BADDR, type = ro, optional = yes; + BANKRAM0B: load = BRAM0B, type = rw, optional = yes, define = yes; + BRAM0CADDR: load = BRAM0CADDR, type = ro, optional = yes; + BANKRAM0C: load = BRAM0C, type = rw, optional = yes, define = yes; + BRAM0DADDR: load = BRAM0DADDR, type = ro, optional = yes; + BANKRAM0D: load = BRAM0D, type = rw, optional = yes, define = yes; + BRAM0EADDR: load = BRAM0EADDR, type = ro, optional = yes; + BANKRAM0E: load = BRAM0E, type = rw, optional = yes, define = yes; + BRAM0FADDR: load = BRAM0FADDR, type = ro, optional = yes; + BANKRAM0F: load = BRAM0F, type = rw, optional = yes, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/cx16.cfg b/cfg/cx16.cfg index 72fc2fe91..4b6025fb6 100644 --- a/cfg/cx16.cfg +++ b/cfg/cx16.cfg @@ -16,17 +16,17 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; + STARTUP: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = rw; - ONCE: load = MAIN, type = ro, define = yes; - BSS: load = BSS, type = bss, define = yes; + INIT: load = MAIN, type = rw, optional = yes; + ONCE: load = MAIN, type = ro, define = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/supervision-128k.cfg b/cfg/supervision-128k.cfg index a03ab0e1b..c90367aa1 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -1,4 +1,4 @@ -# supervision 1284kbyte cartridge with bankswitching +# supervision 128kbyte cartridge with bankswitching # for assembler # ld65 config file @@ -30,8 +30,23 @@ SEGMENTS { BANK5: load = BANKROM5, type = ro; BANK6: load = BANKROM6, type = ro; BANK7: load = BANKROM7, type = ro; - ZEROPAGE: load = RAM, type = bss, define = yes; - DATA: load = RAM, type = bss, define = yes, offset = $0200; + ZEROPAGE: load = RAM, type = zp, define = yes; + DATA: load = RAM, type = rw, define = yes, offset = $0200; BSS: load = RAM, type = bss, define = yes; - VECTOR: load = ROM, type = ro, offset = $3FFA; + VECTORS: load = ROM, type = ro, start = $FFFA; +} +FEATURES { + CONDES: type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__, + segment = ONCE; + CONDES: type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__, + segment = RODATA; + CONDES: type = interruptor, + label = __INTERRUPTOR_TABLE__, + count = __INTERRUPTOR_COUNT__, + segment = RODATA, + import = __CALLIRQ__; } diff --git a/cfg/supervision-16k.cfg b/cfg/supervision-16k.cfg index e0b54be23..dc6130b33 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -20,8 +20,8 @@ SEGMENTS { CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $3FF0; - VECTOR: load = ROM, type = ro, offset = $3FFA; + FFF0: load = ROM, type = ro, start = $FFF0; + VECTORS: load = ROM, type = ro, start = $FFFA; BSS: load = RAM, type = bss, define = yes; } FEATURES { diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index 9d5f15e45..d252c5d25 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -23,8 +23,23 @@ SEGMENTS { BANK1: load = BANKROM1, type = ro; BANK2: load = BANKROM2, type = ro; BANK3: load = BANKROM3, type = ro; - ZEROPAGE: load = RAM, type = bss, define = yes; - DATA: load = RAM, type = bss, define = yes, offset = $0200; + ZEROPAGE: load = RAM, type = zp, define = yes; + DATA: load = RAM, type = rw, define = yes, offset = $0200; BSS: load = RAM, type = bss, define = yes; - VECTOR: load = ROM, type = ro, offset = $3FFA; + VECTORS: load = ROM, type = ro, start = $FFFA; +} +FEATURES { + CONDES: type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__, + segment = ONCE; + CONDES: type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__, + segment = RODATA; + CONDES: type = interruptor, + label = __INTERRUPTOR_TABLE__, + count = __INTERRUPTOR_COUNT__, + segment = RODATA, + import = __CALLIRQ__; } diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index d9f189f2b..1177660b8 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -19,8 +19,8 @@ SEGMENTS { CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $7FF0; - VECTOR: load = ROM, type = ro, offset = $7FFA; + FFF0: load = ROM, type = ro, start = $FFF0; + VECTORS: load = ROM, type = ro, start = $FFFA; BSS: load = RAM, type = bss, define = yes; } FEATURES { diff --git a/cfg/vic20.cfg b/cfg/vic20.cfg index ceaee3a87..8efeae229 100644 --- a/cfg/vic20.cfg +++ b/cfg/vic20.cfg @@ -1,7 +1,7 @@ SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; - __STACKSIZE__: type = weak, value = $0400; # 1k stack + __STACKSIZE__: type = weak, value = $0100; } MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; diff --git a/doc/atari.sgml b/doc/atari.sgml index eecd1b803..7fc929f42 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -332,6 +332,7 @@ See the for declaration and u _scroll _setcolor _setcolor_low +waitvsync diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index 00d3dfbd2..c7e5be73e 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -30,7 +30,7 @@ information. Binary format

-The standard binary output format generated by the linker for the Atari 5200 target +The binary output format generated by the linker for the Atari 5200 target is a cartridge image. It is of course possible to change this behaviour by using a modified startup file and linker config. @@ -73,11 +73,22 @@ Special locations: Programs containing Atari 5200 specific code may use the +... + OS.sdmctl = 0x00; // screen off + OS.color4 = 14; // white frame + tics = OS.rtclok[1] // get ticks +... + + Atari 5200 specific functions

-TBD. +waitvsync @@ -208,10 +219,58 @@ you cannot use any of the following functions (and a few others): Other hints

+CAR format

+ AtariROMMaker ( ) can be used to create a Changing the splash screen

+ +The 5200 ROM displays a splash screen at startup with the name of the +game and the copyright year. The year information has a 'Year-2000' +problem, the first two digits are fixed in the ROM and are always "19". + +Changing the game name

+ +The runtime library provides a default game name which is "cc65 +compiled". To change that, one has to link a file which puts data into +the " +.export __CART_NAME__: absolute = 1 +.macpack atari +.segment "CARTNAME" + scrcode " cc" + .byte '6' + 32, '5' + 32 ; use playfield 1 + scrcode " compiled" + + +'Changing the copyright year / changing the cartridge type

+ +The century is hard-coded to 1900 by the ROM. + +There are two digits which can be changed. For example "92" will give +"1992" on the screen. + +The default used by the runtime library is + + +.export __CART_YEAR__: absolute = 1 +.segment "CARTYEAR" + .byte '9' + 32,'8' + 32 ; "98", using playfield 1 + + +If the second byte of the year in the License

diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 8d97bddfd..cebdca12e 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -151,7 +151,7 @@ Here is a description of all the command line options: Set the default for the CPU type. The option takes a parameter, which may be one of - 6502, 6502X, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510 + 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510

+ + Conditional assembly: Check if the assembler is currently in 6502DTV mode + (see command). + + .IFPSC02

Conditional assembly: Check if the assembler is currently in 65SC02 mode @@ -3585,6 +3593,14 @@ Here's a list of all control commands and a description, what they do: +.PDTV

+ + Enable the 6502DTV instruction set. This is a superset of the 6502 + instruction set. + + See: + + .POPCPU

Pop the last CPU setting from the stack, and activate it. @@ -3848,10 +3864,11 @@ Here's a list of all control commands and a description, what they do: Switch the CPU instruction set. The command is followed by a string that specifies the CPU. Possible values are those that can also be supplied to the command line option, - namely: 6502, 6502X, 65SC02, 65C02, 65816, 4510 and HuC6280. + namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510 and HuC6280. See: , , + , , , , @@ -4586,6 +4603,7 @@ each supported CPU a constant similar to CPU_SWEET16 CPU_HUC6280 CPU_4510 + CPU_6502DTV is defined. These constants may be used to determine the exact type of the @@ -4600,6 +4618,7 @@ another constant is defined: CPU_ISET_SWEET16 CPU_ISET_HUC6280 CPU_ISET_4510 + CPU_ISET_6502DTV The value read from the / pseudo variable may diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 115f0a30c..24f4422f4 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -6,8 +6,9 @@ -cc65 is a C compiler for 6502 targets. It supports several 6502 based home -computers like the Commodore and Atari machines, but it is easily retargetable. +cc65 is a C compiler for 6502 targets. It supports several 6502-based home +computers such as the Commodore and Atari machines, but it easily is +retargetable. @@ -548,6 +549,8 @@ Here is a description of all the command line options: Warn about a / that changes a character's code number from/to 0x00. + + Warn about no return statement in function returning non-void. Warn when passing structs by value. @@ -706,12 +709,13 @@ This cc65 version has some extensions to the ISO C standard. places.

- There are two pseudo variables named There are three pseudo variables named @@ -1011,7 +1015,7 @@ The compiler defines several macros at startup: __TELESTRAT__ This macro is defined if the target is the Telestrat (-t telestrat). - + __TIME__ This macro expands to the time of translation of the preprocessing @@ -1045,26 +1049,39 @@ parameter with the #pragma bss-name ([push,] <name>)

+#pragma bss-name ([push, ]<name>[ ,<addrsize>])

- This pragma changes the name used for the BSS segment (the BSS segment - is used to store variables with static storage duration and no explicit - initializer). The argument is a string enclosed in double quotes. + This pragma changes the name used for the BSS segment (the BSS segment is + used to store variables with static storage duration and no explicit + initializers). The + "zp", "zeropage", "direct" + "abs", "absolute", "near", "default" + "far" + "long", "dword" + - Beware: The startup code will zero only the default BSS segment. If you - use another BSS segment, you have to do that yourself, otherwise - variables with static storage duration and no explicit initializer will - not have the value zero. + Note: The default linker configuration file maps only the standard segments. + If you use other segments, you must create a new linker configuration file. - The - #pragma bss-name ("MyBSS") + #pragma bss-name ("MyBSS") + #pragma bss-name (push, "MyBSS") + #pragma bss-name ("MyBSS", "zp") @@ -1120,21 +1137,33 @@ parameter with the #pragma code-name ([push,] <name>)

+#pragma code-name ([push, ]<name>[ ,<addrsize>])

- This pragma changes the name used for the CODE segment (the CODE segment - is used to store executable code). The argument is a string enclosed in - double quotes. + This pragma changes the name used for the CODE segment (the CODE segment is + used to store executable code). The + "zp", "zeropage", "direct" + "abs", "absolute", "near", "default" + "far" + "long", "dword" + - The - #pragma code-name ("MyCODE") + #pragma code-name ("MyCODE") + #pragma code-name (push, "MyCODE") + #pragma code-name (push, "MyCODE", "far") @@ -1148,21 +1177,33 @@ parameter with the #pragma data-name ([push,] <name>)

+#pragma data-name ([push, ]<name>[ ,<addrsize>])

- This pragma changes the name used for the DATA segment (the DATA segment - is used to store initialized data). The argument is a string enclosed in - double quotes. + This pragma changes the name used for the DATA segment (the DATA segment is + used to store initialized data). The + "zp", "zeropage", "direct" + "abs", "absolute", "near", "default" + "far" + "long", "dword" + - The - #pragma data-name ("MyDATA") + #pragma data-name ("MyDATA") + #pragma data-name (push, "MyDATA") + #pragma data-name ("MyDATA", "zeropage") @@ -1224,21 +1265,32 @@ parameter with the #pragma rodata-name ([push,] <name>)

+#pragma rodata-name ([push, ]<name>[ ,<addrsize>])

- This pragma changes the name used for the RODATA segment (the RODATA - segment is used to store readonly data). The argument is a string - enclosed in double quotes. + This pragma changes the name used for the RODATA segment (the RODATA segment + is used to store read-only data). The + "zp", "zeropage", "direct" + "abs", "absolute", "near", "default" + "far" + "long", "dword" + - The - #pragma rodata-name ("MyRODATA") + #pragma rodata-name ("MyRODATA") + #pragma rodata-name (push, "MyRODATA") diff --git a/doc/da65.sgml b/doc/da65.sgml index 466b41984..b46ee9dd3 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -112,15 +112,17 @@ Here is a description of all the command line options: 6502 6502x + 6502dtv 65sc02 65c02 huc6280 4510 - 6502x is for the NMOS 6502 with unofficial opcodes. huc6280 is the CPU of - the PC engine. 4510 is the CPU of the Commodore C65. Support for the 65816 - currently is not available. + 6502x is for the NMOS 6502 with unofficial opcodes. 6502dtv is for the + emulated CPU of the C64DTV device. huc6280 is the CPU of the PC engine. + 4510 is the CPU of the Commodore C65. Support for the 65816 currently + is not available.

-These two functions are best suited for scanning the whole directory for particular files. Note that -the returned filehandles describe all file slots in the directory - even those with deleted files. -The return value can be obtained by casting both sides to geos/gdisk.h). The current +directory track and sector numbers are in FindFile

-This function scans the whole directory for the given filename. It returns either 0 (success) or 5 -(FILE_NOT_FOUND, defined in geos/gdisk.h), or any other fatal disk read error. After a successful +FindFTypes

diff --git a/doc/ld65.sgml b/doc/ld65.sgml index cba06fef4..538948fc0 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -921,9 +921,8 @@ name="6502 binary relocation format specification">). It is defined like this: } -The other format available is the Atari (xex) segmented file format, this is -the standard format used by Atari DOS 2.0 and upward file managers in the Atari -8-bit computers, and it is defined like this: +The other format available is the Atari segmented file format (xex), this is +the standard format used by Atari DOS 2.0 and upwards, and it is defined like this: FILES { @@ -1010,7 +1009,8 @@ The segment This attribute tells the linker into which segment the table should be - placed. If the segment does not exist, it is created. + placed. If the segment does not exist in any object file, it is created + in the final object code. type @@ -1059,7 +1059,7 @@ The . @@ -1140,6 +1140,19 @@ The builtin config files do contain segments that have a special meaning for the compiler and the libraries that come with it. If you replace the builtin config files, you will need the following information. +INIT

+ +The INIT segment is some kind of 'bss' segment since it contains +uninitialized data. Unlike .bss itself, its contents aren't +initialized to zero at program startup . It's mostly used by +constructors in the startup code. An example for the use of the INIT +segment is saving/restoring the zero page area used by cc65. + +LOWCODE

+ +For the LOWCODE segment, it is guaranteed that it won't be banked out, so it +is reachable at any time by interrupt handlers or similar. + ONCE

The ONCE segment is used for initialization code run only once before @@ -1147,11 +1160,6 @@ execution reaches main() - provided that the program runs in RAM. You may for example add the ONCE segment to the heap in really memory constrained systems. -LOWCODE

- -For the LOWCODE segment, it is guaranteed that it won't be banked out, so it -is reachable at any time by interrupt handlers or similar. - STARTUP

This segment contains the startup code which initializes the C software stack diff --git a/doc/pet.sgml b/doc/pet.sgml index eb13d9fb9..6bedf6a0f 100644 --- a/doc/pet.sgml +++ b/doc/pet.sgml @@ -105,6 +105,7 @@ declaration and usage. cbm_save cbm_write get_tv +waitvsync diff --git a/include/_atari5200os.h b/include/_atari5200os.h new file mode 100644 index 000000000..db0f7f0c9 --- /dev/null +++ b/include/_atari5200os.h @@ -0,0 +1,80 @@ +/*****************************************************************************/ +/* */ +/* _atari5200os.h */ +/* */ +/* Internal include file, do not use directly */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + +#ifndef __ATARI5200OS_H +#define __ATARI5200OS_H + + +struct __os { + + /*Page zero*/ + unsigned char pokmsk; // = $00 System mask for POKEY IRQ enable + unsigned char rtclok[2]; // = $01,$02 Real time clock + unsigned char critic; // = $03 Critical section flag + unsigned char atract; // = $04 Attract mode counter + + union { + struct { + unsigned char sdlstl; // = $05 Save display list LO + unsigned char sdlsth; // = $06 Save display list HI + }; + void* sdlst; // = $05,$06 Display list shadow + }; + + unsigned char sdmctl; // = $07 DMACTL shadow + unsigned char pcolr0; // = $08 PM color 0 + unsigned char pcolr1; // = $09 PM color 1 + unsigned char pcolr2; // = $0A PM color 2 + unsigned char pcolr3; // = $0B PM color 3 + unsigned char color0; // = $0C PF color 0 + unsigned char color1; // = $0D PF color 1 + unsigned char color2; // = $0E PF color 2 + unsigned char color3; // = $0F PF color 3 + unsigned char color4; // = $10 PF color 4 + unsigned char _free_1[0xEF]; // = $11-$FF User space + + /*Stack*/ + unsigned char stack[0x100]; // = $100-$1FF Stack + + /*Page 2 OS variables*/ + void (*vinter)(void); // = $200 Immediate IRQ vector + void (*vvblki)(void); // = $202 Immediate VBI vector + void (*vvblkd)(void); // = $204 Deferred VBI vector + void (*vdslst)(void); // = $206 DLI vector + void (*vkeybd)(void); // = $208 Keyboard IRQ vector + void (*vkeypd)(void); // = $20A Keyboard continuation vector + void (*vbrkky)(void); // = $20C Break key interrupt vector + void (*vbreak)(void); // = $20E BRK instruction interrupt vector + void (*vserin)(void); // = $210 Serial input ready vector + void (*vseror)(void); // = $212 Serial output data needed vector + void (*vseroc)(void); // = $214 Serial output completed vector + void (*vtimr1)(void); // = $216 POKEY timer 1 IRQ vector + void (*vtimr2)(void); // = $218 POKEY timer 2 IRQ vector + void (*vtimr4)(void); // = $21A POKEY timer 4 IRQ vector + +}; + +#endif diff --git a/include/atari.h b/include/atari.h index 1a00a4c67..86c7b9706 100644 --- a/include/atari.h +++ b/include/atari.h @@ -6,10 +6,11 @@ /* */ /* */ /* */ -/* (C) 2000-2019 Mark Keates */ +/* (C) 2000-2021 Mark Keates */ /* Freddy Offenga */ /* Christian Groessler */ /* Bill Kendrick */ +/* et al. */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -219,7 +220,7 @@ /* Color register functions */ /*****************************************************************************/ -extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); +extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminance); extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); extern unsigned char __fastcall__ _getcolor (unsigned char color_reg); @@ -227,6 +228,7 @@ extern unsigned char __fastcall__ _getcolor (unsigned char color_reg); /* Other screen functions */ /*****************************************************************************/ +extern void waitvsync (void); /* wait for start of next frame */ extern int __fastcall__ _graphics (unsigned char mode); /* mode value same as in BASIC */ extern void __fastcall__ _scroll (signed char numlines); /* numlines > 0 scrolls up */ diff --git a/include/atari5200.h b/include/atari5200.h index d6c2561b2..ff176c15b 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -35,7 +35,7 @@ -/* Check for errors */ +/* check for errors */ #if !defined(__ATARI5200__) # error This module may only be used when compiling for the Atari 5200! #endif @@ -46,14 +46,14 @@ /* the addresses of the static drivers */ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ -/* Masks for joy_read */ +/* masks for joy_read */ #define JOY_UP_MASK 0x01 #define JOY_DOWN_MASK 0x02 #define JOY_LEFT_MASK 0x04 #define JOY_RIGHT_MASK 0x08 #define JOY_BTN_1_MASK 0x10 -/* Character codes */ +/* character codes */ #define CH_ULCORNER 0x0B /* '+' sign */ #define CH_URCORNER 0x0B #define CH_LLCORNER 0x0B @@ -65,7 +65,11 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define AT_NTSC 0 #define AT_PAL 1 -/* Define hardware */ +/* Define variables used by the OS*/ +#include <_atari5200os.h> +#define OS (*(struct __os*)0x0000) + +/* define hardware */ #include <_gtia.h> #define GTIA_READ (*(struct __gtia_read*)0xC000) #define GTIA_WRITE (*(struct __gtia_write*)0xC000) @@ -89,5 +93,8 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ */ #define _bordercolor(color) 0 -/* End of atari5200.h */ +/* wait for start of next frame */ +extern void waitvsync (void); + +/* end of atari5200.h */ #endif diff --git a/include/cbm.h b/include/cbm.h index ac3615c38..cceb76b1b 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -166,7 +166,7 @@ unsigned char get_tv (void); unsigned char __fastcall__ kbrepeat (unsigned char mode); /* Changes which keys have automatic repeat. */ -#if !defined(__CBM610__) && !defined(__PET__) +#if !defined(__CBM610__) void waitvsync (void); /* Wait for the start of the next video field. */ #endif @@ -191,6 +191,8 @@ unsigned char cbm_k_acptr (void); unsigned char cbm_k_basin (void); void __fastcall__ cbm_k_bsout (unsigned char C); unsigned char __fastcall__ cbm_k_chkin (unsigned char FN); +unsigned char cbm_k_chrin (void); +void __fastcall__ cbm_k_chrout (unsigned char C); void __fastcall__ cbm_k_ciout (unsigned char C); unsigned char __fastcall__ cbm_k_ckout (unsigned char FN); void cbm_k_clall (void); @@ -295,7 +297,15 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, /* Reads one directory line into cbm_dirent structure. ** Returns 0 if reading directory-line was successful. ** Returns non-zero if reading directory failed, or no more file-names to read. -** Returns 2 on last line. Then, l_dirent->size = the number of "blocks free." +** Returns 2 on last line. Then, l_dirent->size = the number of "blocks free", +** "blocks used", or "mb free". Return codes: +** 0 = read file-name +** 1 = couldn't read directory +** 2 = read "blocks free", "blocks used", or "mb free" +** 3 = couldn't find start of file-name +** 4 = couldn't find end of file-name +** 5 = couldn't read file-type +** 6 = premature end of file */ void __fastcall__ cbm_closedir (unsigned char lfn); diff --git a/include/time.h b/include/time.h index 4ee658da9..49d7e6870 100644 --- a/include/time.h +++ b/include/time.h @@ -83,46 +83,31 @@ extern struct _timezone { -#if defined(__ATARI__) -/* The clock depends on the video standard, so read it at runtime */ -unsigned _clocks_per_sec (void); -# define CLK_TCK _clocks_per_sec() -# define CLOCKS_PER_SEC _clocks_per_sec() -#elif defined(__ATARI5200__) -# define CLK_TCK 60 /* POSIX */ -# define CLOCKS_PER_SEC 60 /* ANSI */ +#if defined(__ATARI5200__) +# define CLOCKS_PER_SEC 60 #elif defined(__ATMOS__) -# define CLK_TCK 100 /* POSIX */ -# define CLOCKS_PER_SEC 100 /* ANSI */ +# define CLOCKS_PER_SEC 100 #elif defined(__CBM__) # if defined(__CBM510__) || defined(__CBM610__) /* The 510/610 gets its clock from the AC current */ -# define CLK_TCK 50 /* POSIX */ -# define CLOCKS_PER_SEC 50 /* ANSI */ +# define CLOCKS_PER_SEC 50 # else -# define CLK_TCK 60 /* POSIX */ -# define CLOCKS_PER_SEC 60 /* ANSI */ +# define CLOCKS_PER_SEC 60 # endif #elif defined(__NES__) -# define CLK_TCK 50 /* POSIX */ -# define CLOCKS_PER_SEC 50 /* ANSI */ +# define CLOCKS_PER_SEC 50 #elif defined(__PCE__) -# define CLK_TCK 60 /* POSIX */ -# define CLOCKS_PER_SEC 60 /* ANSI */ +# define CLOCKS_PER_SEC 60 #elif defined(__GAMATE__) -# define CLK_TCK 135 /* POSIX */ /* FIXME */ -# define CLOCKS_PER_SEC 135 /* ANSI */ /* FIXME */ +# define CLOCKS_PER_SEC 135 /* FIXME */ #elif defined(__GEOS__) -# define CLK_TCK 1 /* POSIX */ -# define CLOCKS_PER_SEC 1 /* ANSI */ -#elif defined(__LYNX__) -/* The clock-rate depends on the video scan-rate; -** so, read it at run-time. -*/ -extern clock_t _clk_tck (void); -# define CLK_TCK _clk_tck() -# define CLOCKS_PER_SEC _clk_tck() +# define CLOCKS_PER_SEC 1 +#else +/* Read the clock rate at runtime */ +clock_t _clocks_per_sec (void); +# define CLOCKS_PER_SEC _clocks_per_sec() #endif +#define CLK_TCK CLOCKS_PER_SEC #define CLOCK_REALTIME 0 @@ -149,6 +134,3 @@ int __fastcall__ clock_settime (clockid_t clock_id, const struct timespec *tp); /* End of time.h */ #endif - - - diff --git a/libsrc/Makefile b/libsrc/Makefile index d9ddb3ccd..3fac513af 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -133,8 +133,7 @@ MKINC = $(GEOS) \ TARGETUTIL = apple2 \ apple2enh \ - atari \ - geos-apple + atari GEOSDIRS = common \ conio \ diff --git a/libsrc/apple2/read.s b/libsrc/apple2/read.s index 14c80b7e2..99c189cbd 100644 --- a/libsrc/apple2/read.s +++ b/libsrc/apple2/read.s @@ -19,11 +19,14 @@ .segment "ONCE" initprompt: - ; Set prompt <> ']' to let DOS 3.3 know that we're - ; not in Applesoft immediate mode and thus keep it - ; from scanning our device I/O for DOS commands. + ; Set prompt <> ']' and currently executed Applesoft + ; line number hibyte <> $FF to let DOS 3.3 (at $A65E) + ; know that we're not in Applesoft immediate mode and + ; thus keep it from scanning our device I/O for DOS + ; commands. lda #$80 ; Same value used at $D52C sta PROMPT + sta CURLIN+1 ; Any value <> $FF will do rts .code diff --git a/libsrc/apple2/targetutil/Makefile.inc b/libsrc/apple2/targetutil/Makefile.inc index d9d727b0a..b53139a3d 100644 --- a/libsrc/apple2/targetutil/Makefile.inc +++ b/libsrc/apple2/targetutil/Makefile.inc @@ -1,9 +1,17 @@ -DEPS += ../libwrk/$(TARGET)/loader.d +DEPS += ../libwrk/$(TARGET)/convert.d \ + ../libwrk/$(TARGET)/loader.d + +../libwrk/$(TARGET)/convert.o: $(SRCDIR)/targetutil/convert.c | ../libwrk/$(TARGET) + $(COMPILE_recipe) ../libwrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../libwrk/$(TARGET) $(ASSEMBLE_recipe) +../target/$(TARGET)/util/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/$(TARGET).lib | ../target/$(TARGET)/util + $(LD65) -o $@ -C $(TARGET)-system.cfg $^ + ../target/$(TARGET)/util/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../target/$(TARGET)/util $(LD65) -o $@ -C $(filter %.cfg,$^) $(filter-out %.cfg,$^) -$(TARGET): ../target/$(TARGET)/util/loader.system +$(TARGET): ../target/$(TARGET)/util/convert.system \ + ../target/$(TARGET)/util/loader.system diff --git a/libsrc/geos-apple/targetutil/convert.c b/libsrc/apple2/targetutil/convert.c similarity index 100% rename from libsrc/geos-apple/targetutil/convert.c rename to libsrc/apple2/targetutil/convert.c diff --git a/libsrc/atari/clock.s b/libsrc/atari/clock.s index e04416c18..853870520 100644 --- a/libsrc/atari/clock.s +++ b/libsrc/atari/clock.s @@ -3,7 +3,7 @@ ; originally by Ullrich von Bassewitz and Sidney Cadot ; ; clock_t clock (void); -; unsigned _clocks_per_sec (void); +; clock_t _clocks_per_sec (void); ; .export _clock, __clocks_per_sec @@ -30,8 +30,10 @@ .proc __clocks_per_sec - ldx #$00 ; Clear high byte of return value - lda PAL ; use hw register, PALNTS is only supported on XL/XE ROM + ldx #$00 ; Clear byte 1 of return value + stx sreg ; Clear byte 2 of return value + stx sreg+1 ; Clear byte 3 of return value + lda PAL ; Use hw register, PALNTS is only supported on XL/XE ROM and #$0e bne @NTSC lda #50 diff --git a/libsrc/atari/doesclrscr.s b/libsrc/atari/doesclrscr.s index 2e19e4b98..f937f9ac5 100644 --- a/libsrc/atari/doesclrscr.s +++ b/libsrc/atari/doesclrscr.s @@ -1,7 +1,7 @@ ; ; Christian Groessler, June-2016 ; -; unsigned char doesclrscr(void); +; unsigned char doesclrscrafterexit (void); ; ; returns 0/1 if after program termination the screen isn't/is cleared ; diff --git a/libsrc/atari/shadow_ram_timerirq1.s b/libsrc/atari/shadow_ram_timerirq1.s index f8a3e9b4d..e1b7d831b 100644 --- a/libsrc/atari/shadow_ram_timerirq1.s +++ b/libsrc/atari/shadow_ram_timerirq1.s @@ -11,6 +11,7 @@ SHRAM_HANDLERS = 1 .include "atari.inc" .include "romswitch.inc" + .import __CHARGEN_START__ .export set_VTIMR1_handler diff --git a/libsrc/atari/shadow_ram_timerirq2.s b/libsrc/atari/shadow_ram_timerirq2.s index b2cdaecd2..d6d581937 100644 --- a/libsrc/atari/shadow_ram_timerirq2.s +++ b/libsrc/atari/shadow_ram_timerirq2.s @@ -11,6 +11,7 @@ SHRAM_HANDLERS = 1 .include "atari.inc" .include "romswitch.inc" + .import __CHARGEN_START__ .export set_VTIMR2_handler diff --git a/libsrc/atari/waitvsync.s b/libsrc/atari/waitvsync.s new file mode 100644 index 000000000..a19b2375d --- /dev/null +++ b/libsrc/atari/waitvsync.s @@ -0,0 +1,15 @@ +; +; Written by Christian Groessler +; +; void waitvsync (void); +; + + .include "atari.inc" + .export _waitvsync + +.proc _waitvsync + lda RTCLOK+2 +@lp: cmp RTCLOK+2 + beq @lp + rts +.endproc diff --git a/libsrc/atari5200/clock.s b/libsrc/atari5200/clock.s index f2ef85b0b..fff766093 100644 --- a/libsrc/atari5200/clock.s +++ b/libsrc/atari5200/clock.s @@ -2,7 +2,6 @@ ; from Atari computer version by Christian Groessler, 2014 ; ; clock_t clock (void); -; unsigned _clocks_per_sec (void); ; .export _clock diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index ee3d0de4f..9538d3bb4 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -13,7 +13,6 @@ .import zerobss, copydata .include "zeropage.inc" - .include "atari5200.inc" start: diff --git a/libsrc/atari5200/waitvsync.s b/libsrc/atari5200/waitvsync.s new file mode 100644 index 000000000..9a67c6429 --- /dev/null +++ b/libsrc/atari5200/waitvsync.s @@ -0,0 +1,15 @@ +; +; Written by Christian Groessler +; +; void waitvsync (void); +; + + .include "atari5200.inc" + .export _waitvsync + +.proc _waitvsync + lda RTCLOK+1 +@lp: cmp RTCLOK+1 + beq @lp + rts +.endproc diff --git a/libsrc/atmos/cputc.s b/libsrc/atmos/cputc.s index f1ce5f2b7..db3fa373d 100644 --- a/libsrc/atmos/cputc.s +++ b/libsrc/atmos/cputc.s @@ -7,7 +7,7 @@ ; .export _cputcxy, _cputc - .export setscrptr, putchar + .export setscrptr, cputdirect, putchar .constructor initcputc .import rvs .import popax @@ -32,13 +32,13 @@ _cputc: cmp #$0D ; CR? rts L1: cmp #$0A ; LF? - bne output + bne cputdirect inc CURS_Y ; Newline rts ; Output the character, then advance the cursor position -output: +cputdirect: jsr putchar advance: diff --git a/libsrc/atmos/read.s b/libsrc/atmos/read.s index 83aa8024e..3f22d8d0e 100644 --- a/libsrc/atmos/read.s +++ b/libsrc/atmos/read.s @@ -20,18 +20,19 @@ sta ptr3 stx ptr3+1 ; save count as result - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; Remember -count-1 + + inx + stx ptr2+1 + tax + inx + stx ptr2 ; save count with each byte incremented separately jsr popptr1 ; get buf jsr popax ; get fd and discard -L1: inc ptr2 +L1: dec ptr2 bnz L2 - inc ptr2+1 + dec ptr2+1 bze L9 ; no more room in buf ; If there are no more characters in BASIC's input buffer, then get a line from diff --git a/libsrc/atmos/write.s b/libsrc/atmos/write.s index 7865b5698..4a68994ec 100644 --- a/libsrc/atmos/write.s +++ b/libsrc/atmos/write.s @@ -17,17 +17,17 @@ sta ptr3 stx ptr3+1 ; save count as result - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; Remember -count-1 + inx + stx ptr2+1 + tax + inx + stx ptr2 ; save count with each byte incremented separately jsr popptr1 ; get buf jsr popax ; get fd and discard -L1: inc ptr2 +L1: dec ptr2 bne L2 - inc ptr2+1 + dec ptr2+1 beq L9 L2: ldy #0 lda (ptr1),y diff --git a/libsrc/c128/mcbdefault.s b/libsrc/c128/mcbdefault.s index eb521eb3a..a3ca3d0d1 100644 --- a/libsrc/c128/mcbdefault.s +++ b/libsrc/c128/mcbdefault.s @@ -19,12 +19,12 @@ ; Sprite definitions. The first value can be changed to adjust the number ; of the sprite used for the mouse. All others depend on this value. -MOUSE_SPR = 0 ; Sprite used for the mouse -MOUSE_SPR_MEM = $0E00 ; Memory location -MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask -MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask -VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register -VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register +MOUSE_SPR = 0 ; Sprite used for the mouse +MOUSE_SPR_MEM = $0E00 ; Memory location +MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask +MOUSE_SPR_NMASK = .lobyte(.bitnot MOUSE_SPR_MASK) ; Negative mask +VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register +VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index bee81a113..1df1e5c62 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "plus4.inc" ; ------------------------------------------------------------------------ ; Startup code diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index 7bd294ca7..4e5c7c9d4 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "c64.inc" ; ------------------------------------------------------------------------ diff --git a/libsrc/c64/mcbdefault.s b/libsrc/c64/mcbdefault.s index dd2f7cee7..79a8d93e5 100644 --- a/libsrc/c64/mcbdefault.s +++ b/libsrc/c64/mcbdefault.s @@ -21,11 +21,11 @@ ; Sprite definitions. The first value can be changed to adjust the number ; of the sprite used for the mouse. All others depend on this value. -MOUSE_SPR = 0 ; Sprite used for the mouse -MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask -MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask -VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register -VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register +MOUSE_SPR = 0 ; Sprite used for the mouse +MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask +MOUSE_SPR_NMASK = .lobyte(.bitnot MOUSE_SPR_MASK) ; Negative mask +VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register +VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. diff --git a/libsrc/cbm/c_basin.s b/libsrc/cbm/c_basin.s index da925a1a4..c2211e9ce 100644 --- a/libsrc/cbm/c_basin.s +++ b/libsrc/cbm/c_basin.s @@ -2,14 +2,16 @@ ; Ullrich von Bassewitz, 03.06.1999 ; ; unsigned char cbm_k_basin (void); +; unsigned char cbm_k_chrin (void); ; .include "cbm.inc" - .export _cbm_k_basin + .export _cbm_k_basin, _cbm_k_chrin _cbm_k_basin: +_cbm_k_chrin: jsr BASIN ldx #0 ; Clear high byte rts diff --git a/libsrc/cbm/c_bsout.s b/libsrc/cbm/c_bsout.s index 104878453..cec46bf90 100644 --- a/libsrc/cbm/c_bsout.s +++ b/libsrc/cbm/c_bsout.s @@ -2,10 +2,12 @@ ; Ullrich von Bassewitz, 03.06.1999 ; ; void __fastcall__ cbm_k_bsout (unsigned char C); +; void __fastcall__ cbm_k_chrout (unsigned char C); ; .include "cbm.inc" - .export _cbm_k_bsout + .export _cbm_k_bsout, _cbm_k_chrout -_cbm_k_bsout = BSOUT +_cbm_k_bsout := BSOUT +_cbm_k_chrout := CHROUT diff --git a/libsrc/cbm/cbm_dir.c b/libsrc/cbm/cbm_dir.c index 8f31c502a..4b8927f98 100644 --- a/libsrc/cbm/cbm_dir.c +++ b/libsrc/cbm/cbm_dir.c @@ -6,6 +6,7 @@ /* 2009-10-10 -- Version 0.3 */ /* 2011-04-07 -- Version 0.4, groepaz */ /* 2011-04-14 -- Version 0.5, Greg King */ +/* 2021-02-15 -- Version 0.6, Greg King */ /* Tested with floppy-drive and IDE64 devices. */ /* Not tested with messed (buggy) directory listings. */ @@ -29,7 +30,7 @@ unsigned char cbm_opendir (unsigned char lfn, unsigned char device, ...) va_list ap; const char* name = "$"; - /* The name used in cbm_open may optionally be passed */ + /* The name used in cbm_open() optionally may be passed */ if (__argsize__ == 4) { va_start (ap, device); name = va_arg (ap, const char*); @@ -76,9 +77,10 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d byte = cbm_k_basin(); switch (byte) { - - /* "B" BLOCKS FREE. */ + /* "B" BLOCKS FREE/USED. */ + /* "M" MB FREE. */ case 'b': + case 'm': /* Read until end; careless callers might call us again. */ while (!cbm_k_readst()) { cbm_k_basin(); @@ -168,7 +170,6 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d } rv = 0; - goto ret_val; } } diff --git a/libsrc/cbm/cbm_read.s b/libsrc/cbm/cbm_read.s index b010966a3..29e0e1f19 100644 --- a/libsrc/cbm/cbm_read.s +++ b/libsrc/cbm/cbm_read.s @@ -45,11 +45,11 @@ _cbm_read: - eor #$FF - sta ptr1 - txa - eor #$FF - sta ptr1+1 ; Save -size-1 + inx + stx ptr1+1 + tax + inx + stx ptr1 ; Save size with both bytes incremented separately. jsr popax sta ptr2 @@ -92,9 +92,9 @@ _cbm_read: bne @L3 inc ptr3+1 ; ++bytesread; -@L3: inc ptr1 +@L3: dec ptr1 bne @L1 - inc ptr1+1 + dec ptr1+1 bne @L1 @L4: jsr CLRCH diff --git a/libsrc/cbm/cbm_write.s b/libsrc/cbm/cbm_write.s index 2d932d04a..5ac07209c 100644 --- a/libsrc/cbm/cbm_write.s +++ b/libsrc/cbm/cbm_write.s @@ -39,11 +39,11 @@ _cbm_write: sta ptr3 stx ptr3+1 ; Save size - eor #$FF - sta ptr1 - txa - eor #$FF - sta ptr1+1 ; Save -size-1 + inx + stx ptr1+1 + tax + inx + stx ptr1 ; Save size with both bytes incremented separately jsr popax sta ptr2 @@ -69,9 +69,9 @@ _cbm_write: @L2: jsr BSOUT ; cbm_k_bsout (A); -@L3: inc ptr1 ; --size; +@L3: dec ptr1 ; --size; bne @L1 - inc ptr1+1 + dec ptr1+1 bne @L1 jsr CLRCH diff --git a/libsrc/cbm/read.s b/libsrc/cbm/read.s index ee01596aa..fb0bb3171 100644 --- a/libsrc/cbm/read.s +++ b/libsrc/cbm/read.s @@ -106,9 +106,9 @@ ; Decrement the count -@L3: inc ptr2 +@L3: dec ptr2 bne @L0 - inc ptr2+1 + dec ptr2+1 bne @L0 beq done ; Branch always diff --git a/libsrc/cbm/readdir.c b/libsrc/cbm/readdir.c index 8d6968977..1512edc4e 100644 --- a/libsrc/cbm/readdir.c +++ b/libsrc/cbm/readdir.c @@ -1,5 +1,7 @@ /* -** Ullrich von Bassewitz, 2012-05-30. Based on code by Groepaz. +** Based on code by Groepaz. +** 2012-05-30, Ullrich von Bassewitz +** 2021-02-15, Greg King */ @@ -52,12 +54,14 @@ struct dirent* __fastcall__ readdir (register DIR* dir) /* Bump the directory offset and include the bytes for line-link and size */ dir->off += count + 4; - /* End of directory is reached if the buffer contains "blocks free". It is - ** sufficient here to check for the leading 'b'. buffer will contain at - ** least one byte if we come here. + /* End of directory is reached if the buffer contains "blocks free/used" or + ** "mb free.". It is sufficient here to check for the leading 'b' and 'm'. + ** buffer will contain at least one byte if we come here. */ - if (buffer[0] == 'b') { - goto exitpoint; + switch (buffer[0]) { + case 'b': + case 'm': + goto exitpoint; } /* Parse the buffer for the filename and file type */ @@ -67,7 +71,6 @@ struct dirent* __fastcall__ readdir (register DIR* dir) b = buffer; while (i < count) { switch (s) { - case 0: /* Searching for start of file name */ if (*b == '"') { @@ -127,6 +130,3 @@ struct dirent* __fastcall__ readdir (register DIR* dir) exitpoint: return 0; } - - - diff --git a/libsrc/cbm/rwcommon.s b/libsrc/cbm/rwcommon.s index a1f92be8c..d13c478b5 100644 --- a/libsrc/cbm/rwcommon.s +++ b/libsrc/cbm/rwcommon.s @@ -21,11 +21,11 @@ .proc rwcommon - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; Remember -count-1 + inx + stx ptr2+1 + tax + inx + stx ptr2 ; Save count with each byte incremented separately jsr popptr1 ; Get buf to ptr1, Y=0 by call diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index 7a27f0044..ebc44a0ac 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -83,9 +83,9 @@ ; Decrement count -@L2: inc ptr2 +@L2: dec ptr2 bne @L0 - inc ptr2+1 + dec ptr2+1 bne @L0 ; Wrote all chars or disk full. Close the output channel diff --git a/libsrc/cbm510/mcbdefault.s b/libsrc/cbm510/mcbdefault.s index 700dcebb1..53eb804c0 100644 --- a/libsrc/cbm510/mcbdefault.s +++ b/libsrc/cbm510/mcbdefault.s @@ -21,12 +21,12 @@ ; Sprite definitions. The first value can be changed to adjust the number ; of the sprite used for the mouse. All others depend on that value. -MOUSE_SPR = 0 ; Sprite used for the mouse -MOUSE_SPR_MEM = $F400 ; Memory location -MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask -MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask -VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register -VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register +MOUSE_SPR = 0 ; Sprite used for the mouse +MOUSE_SPR_MEM = $F400 ; Memory location +MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask +MOUSE_SPR_NMASK = .lobyte(.bitnot MOUSE_SPR_MASK) ; Negative mask +VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register +VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. diff --git a/libsrc/common/getcwd.s b/libsrc/common/getcwd.s index 22b6ceded..4bfc0a5b6 100644 --- a/libsrc/common/getcwd.s +++ b/libsrc/common/getcwd.s @@ -17,22 +17,22 @@ .proc _getcwd -; Remember -size-1 because this simplifies the following loop +; Remember size with each byte incremented because this simplifies the following loop - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 + inx + stx ptr2+1 + tax + inx + stx ptr2 ; Save size with each byte incremented separately jsr popptr1 ; Get buf to ptr1 ; Copy __cwd to the given buffer checking the length ; ldy #$00 is guaranteed by popptr1 -loop: inc ptr2 +loop: dec ptr2 bne @L1 - inc ptr2+1 + dec ptr2+1 beq overflow ; Copy one character, end the loop if the zero terminator is reached. We diff --git a/libsrc/common/memcmp.s b/libsrc/common/memcmp.s index 93a2c28dc..d651a3cfc 100644 --- a/libsrc/common/memcmp.s +++ b/libsrc/common/memcmp.s @@ -10,14 +10,14 @@ _memcmp: -; Calculate (-count-1) and store it into ptr3. This is some overhead here but -; saves time in the compare loop +; Calculate a special count, and store it into ptr3. That is some overhead here, +; but saves time in the compare loop - eor #$FF - sta ptr3 - txa - eor #$FF - sta ptr3+1 + inx + stx ptr3+1 + tax + inx + stx ptr3 ; Save count with each byte incremented separately ; Get the pointer parameters @@ -29,12 +29,12 @@ _memcmp: ; Loop initialization ;ldy #$00 ; Initialize pointer (Y=0 guaranteed by popptr1) - ldx ptr3 ; Load low counter byte into X + ldx ptr3 ; Load inner counter byte into .X ; Head of compare loop: Test for the end condition -Loop: inx ; Bump low byte of (-count-1) - beq BumpHiCnt ; Jump on overflow +Loop: dex + beq BumpHiCnt ; Jump on end of inner count ; Do the compare @@ -50,10 +50,10 @@ Comp: lda (ptr1),y inc ptr2+1 bne Loop ; Branch always (pointer wrap is illegal) -; Entry on low counter byte overflow +; Entry on inner loop end BumpHiCnt: - inc ptr3+1 ; Bump high byte of (-count-1) + dec ptr3+1 bne Comp ; Jump if not done jmp return0 ; Count is zero, areas are identical @@ -67,4 +67,3 @@ NotEqual: Greater: ldx #$01 ; Make result positive rts - diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index caa6804fc..060378442 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -5,17 +5,17 @@ ; char* strncat (char* dest, const char* src, size_t n); ; - .export _strncat - .import popax, popptr1 - .importzp ptr1, ptr2, ptr3, tmp1, tmp2 - .macpack cpu +.export _strncat +.import popax, popptr1 +.importzp ptr1, ptr2, ptr3, tmp1, tmp2 +.macpack cpu _strncat: - eor #$FF ; one's complement to count upwards - sta tmp1 - txa - eor #$FF - sta tmp2 + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately jsr popptr1 ; get src @@ -49,9 +49,9 @@ L2: sty ptr2 L3: ldy #0 ldx tmp1 ; low counter byte -L4: inx +L4: dex bne L5 - inc tmp2 + dec tmp2 beq L6 ; jump if done L5: lda (ptr1),y sta (ptr2),y diff --git a/libsrc/common/strncpy.s b/libsrc/common/strncpy.s index 56387f880..138413ecb 100644 --- a/libsrc/common/strncpy.s +++ b/libsrc/common/strncpy.s @@ -10,11 +10,11 @@ .proc _strncpy - eor #$FF - sta tmp1 - txa - eor #$FF - sta tmp2 ; Store -size - 1 + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately jsr popptr1 ; get src jsr popax ; get dest @@ -24,11 +24,11 @@ ; Copy src -> dest up to size bytes - ldx tmp1 ; Load low byte of ones complement of size + ldx tmp1 ldy #$00 -L1: inx +L1: dex bne L2 - inc tmp2 + dec tmp2 beq L9 L2: lda (ptr1),y ; Copy one character @@ -42,8 +42,8 @@ L2: lda (ptr1),y ; Copy one character ; Fill the remaining bytes. -L3: inx ; Counter low byte - beq L6 ; Branch on overflow +L3: dex ; Counter low byte + beq L6 L4: sta (ptr2),y ; Clear one byte L5: iny ; Bump pointer bne L3 @@ -52,7 +52,7 @@ L5: iny ; Bump pointer ; Bump the counter high byte -L6: inc tmp2 +L6: dec tmp2 bne L4 ; Done, return dest diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s index 43d6d0d50..477aa3d66 100644 --- a/libsrc/common/strnicmp.s +++ b/libsrc/common/strnicmp.s @@ -15,17 +15,11 @@ _strnicmp: _strncasecmp: -; Convert the given counter value in a/x from a downward counter into an -; upward counter, so we can increment the counter in the loop below instead -; of decrementing it. This adds some overhead now, but is cheaper than -; executing a more complex test in each iteration of the loop. We do also -; correct the value by one, so we can do the test on top of the loop. - - eor #$FF - sta ptr3 - txa - eor #$FF - sta ptr3+1 + inx + stx ptr3+1 + tax + inx + stx ptr3 ; save count with each byte incremented separately ; Get the remaining arguments @@ -40,8 +34,8 @@ _strncasecmp: ; Start of compare loop. Check the counter. -Loop: inc ptr3 - beq IncHi ; increment high byte +Loop: dec ptr3 ; decrement high byte + beq IncHi ; Compare a byte from the strings @@ -79,7 +73,7 @@ L2: ldx tmp1 ; Increment hi byte -IncHi: inc ptr3+1 +IncHi: dec ptr3+1 bne Comp ; jump if counter not zero ; Exit code if strings are equal. a/x not set diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index 3a9ddf9d7..084efe089 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -47,12 +47,12 @@ outdesc: ; Static outdesc structure out: jsr popax ; count sta ptr2 - eor #$FF - sta outdesc+6 - txa - sta ptr2+1 - eor #$FF - sta outdesc+7 + stx ptr2+1 + inx + stx outdesc+7 + tax + inx + stx outdesc+6 jsr popptr1 ; buf @@ -74,7 +74,7 @@ out: jsr popax ; count ; Loop outputting characters -@L1: inc outdesc+6 +@L1: dec outdesc+6 beq @L4 @L2: ldy tmp1 lda (ptr1),y @@ -85,7 +85,7 @@ out: jsr popax ; count jsr _cputc jmp @L1 -@L4: inc outdesc+7 +@L4: dec outdesc+7 bne @L2 rts diff --git a/libsrc/cx16/getdevice.s b/libsrc/cx16/getdevice.s index 9b554900f..5f2e74af4 100644 --- a/libsrc/cx16/getdevice.s +++ b/libsrc/cx16/getdevice.s @@ -51,7 +51,7 @@ next: inx jsr closecmdchannel ldx tmp2 -; As we had to reference ST above anyway, we can do so, as well, +; As we had to reference STATUS above anyway, we can do so, as well, ; here too (instead of calling READST). lda STATUS diff --git a/libsrc/geos-apple/targetutil/Makefile.inc b/libsrc/geos-apple/targetutil/Makefile.inc deleted file mode 100644 index 3d366f913..000000000 --- a/libsrc/geos-apple/targetutil/Makefile.inc +++ /dev/null @@ -1,14 +0,0 @@ -DEPS += ../libwrk/$(TARGET)/convert.d - -../libwrk/$(TARGET)/convert.o: TARGET = apple2enh - -../libwrk/$(TARGET)/convert.o: $(SRCDIR)/targetutil/convert.c | ../libwrk/$(TARGET) - $(COMPILE_recipe) - -../lib/apple2enh.lib: - @$(MAKE) --no-print-directory apple2enh - -../target/$(TARGET)/util/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/apple2enh.lib | ../target/$(TARGET)/util - $(LD65) -o $@ -C apple2enh-system.cfg $^ - -$(TARGET): ../target/$(TARGET)/util/convert.system diff --git a/libsrc/geos-common/disk/calcblksfree.s b/libsrc/geos-common/disk/calcblksfree.s index 520c8ca61..5d7b98aba 100644 --- a/libsrc/geos-common/disk/calcblksfree.s +++ b/libsrc/geos-common/disk/calcblksfree.s @@ -13,6 +13,10 @@ .include "geossym.inc" _CalcBlksFree: + lda #curDirHead + sta r5L + stx r5H jsr CalcBlksFree stx __oserror lda r4L diff --git a/libsrc/geos-common/drivers/fio_module.s b/libsrc/geos-common/drivers/fio_module.s index 0be5015a7..937ef292e 100644 --- a/libsrc/geos-common/drivers/fio_module.s +++ b/libsrc/geos-common/drivers/fio_module.s @@ -94,11 +94,12 @@ _read: ; popax - fd, must be == to the above one ; return -1+__oserror or number of bytes read - eor #$ff - sta ptr1 - txa - eor #$ff - sta ptr1+1 ; -(# of bytes to read)-1 + inx + stx ptr1+1 + tax + inx + stx ptr1 ; save count with each byte incremented separately + jsr popax sta ptr2 stx ptr2+1 ; buffer ptr @@ -152,9 +153,9 @@ _read: beq @done ; yes, we're done jmp __mappederrno ; no, we're screwed -@L3: inc ptr1 ; decrement the count +@L3: dec ptr1 ; decrement the count bne @L0 - inc ptr1+1 + dec ptr1+1 bne @L0 @done: diff --git a/libsrc/geos-common/file/get1stdirentry.s b/libsrc/geos-common/file/get1stdirentry.s index 3b99554eb..f0ad59388 100644 --- a/libsrc/geos-common/file/get1stdirentry.s +++ b/libsrc/geos-common/file/get1stdirentry.s @@ -1,11 +1,11 @@ ; -; Maciej 'YTM/Alliance' Witkowiak +; 1999-10-26, Maciej 'YTM/Alliance' Witkowiak +; 2020-10-29, Greg King ; -; 26.10.99 ; struct filehandle* Get1stDirEntry (void); - .import __oserror + .import __oserror, return0 .export _Get1stDirEntry .include "diskdrv.inc" @@ -14,6 +14,10 @@ _Get1stDirEntry: jsr Get1stDirEntry stx __oserror + txa + bne L1 ; jump if disk error lda r5L ldx r5H rts + +L1: jmp return0 ; return NULL if not valid entry diff --git a/libsrc/geos-common/file/getnxtdirentry.s b/libsrc/geos-common/file/getnxtdirentry.s index 912f48ca4..e8ccbf3a2 100644 --- a/libsrc/geos-common/file/getnxtdirentry.s +++ b/libsrc/geos-common/file/getnxtdirentry.s @@ -1,11 +1,11 @@ ; -; Maciej 'YTM/Alliance' Witkowiak +; 1999-10-26, Maciej 'YTM/Alliance' Witkowiak +; 2020-10-29, Greg King ; -; 26.10.99 ; struct filehandle* GetNxtDirEntry (void); - .import __oserror + .import __oserror, return0 .export _GetNxtDirEntry .include "diskdrv.inc" @@ -14,6 +14,12 @@ _GetNxtDirEntry: jsr GetNxtDirEntry stx __oserror + txa + bne L1 ; jump if disk error + tya + bne L1 ; jump when no more entries lda r5L ldx r5H rts + +L1: jmp return0 ; return NULL if not valid entry diff --git a/libsrc/lynx/clock.s b/libsrc/lynx/clock.s index dbccb32cb..e29799df6 100644 --- a/libsrc/lynx/clock.s +++ b/libsrc/lynx/clock.s @@ -2,18 +2,14 @@ ; 2003-04-13, Ullrich von Bassewitz ; 2012-02-06, Greg King ; -; #include +; clock_t clock (void); +; clock_t _clocks_per_sec (void); ; -; typedef unsigned long int clock_t; -; clock_t _clk_tck(void); -; #define CLOCKS_PER_SEC _clk_tck() -; clock_t clock(void); -; -; clk_tck()'s test-values are based on the numbers in "set_tv.s". +; clocks_per_sec()'s test-values are based on the numbers in "set_tv.s". ; If you change the numbers there, then change them here, too. ; - .export _clock, __clk_tck, clock_count + .export _clock, __clocks_per_sec, clock_count .interruptor update_clock, 2 ; (low priority) .constructor init_clock @@ -42,7 +38,7 @@ ;----------------------------------------------------------------------------- ; Return the number of clock ticks in one second. ; -__clk_tck: +__clocks_per_sec: ldx #$00 ; >50, >60, >75 ldy PBKUP lda #<75 diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index ed2ade222..e88e257fd 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -50,16 +50,15 @@ LINEDIST = $20 ; Offset in video RAM between two lines ldx #>load_addr sta load stx load+1 - lda #load_size - eor #$FF - sta count+1 -L1: inc count ; pre-count one's-complement upwards + ldx #(load_size) + 1 + stx count+1 ; save size with each byte incremented separately + +L1: dec count bnz L2 - inc count+1 + dec count+1 bze L3 L2: jsr GETCHAR ; (doesn't change .Y) sta (load),y diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index 520a147f7..e56a7eca4 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -12,7 +12,6 @@ .include "zeropage.inc" .include "pet.inc" - .include "../cbm/cbm.inc" ; ------------------------------------------------------------------------ ; Startup code diff --git a/libsrc/pet/waitvsync.s b/libsrc/pet/waitvsync.s new file mode 100644 index 000000000..39b562e43 --- /dev/null +++ b/libsrc/pet/waitvsync.s @@ -0,0 +1,16 @@ +; +; Written by Robin Harbron, requires 12" monitor +; +; void waitvsync (void); +; + + .export _waitvsync + + .include "pet.inc" + +_waitvsync: +@l1: + lda VIA_PB + and #%00100000 + bne @l1 + rts diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 2262b4c42..6b44a2b7e 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -198,5 +198,3 @@ irqcount: .byte 0 .segment "INIT" zpsave: .res zpspace - - diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index ac61c8215..203c681b8 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -78,5 +78,3 @@ not_dma: .word nmi .word reset32kcode .word irq - - diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index a1ab145c2..d48c05f65 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -39,7 +39,7 @@ _cputcxy: ldx CHARCOLOR cpx OLD_CHARCOLOR beq do_not_change_color_foreground - + stx OLD_CHARCOLOR ; Store CHARCOLOR into OLD_CHARCOLOR @@ -93,9 +93,9 @@ do_not_change_color: CHARCOLOR: .res 1 OLD_CHARCOLOR: - .res 1 + .res 1 BGCOLOR: - .res 1 + .res 1 OLD_BGCOLOR: .res 1 diff --git a/libsrc/telestrat/crt0.s b/libsrc/telestrat/crt0.s index 59b1ea642..df75520ce 100644 --- a/libsrc/telestrat/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -12,7 +12,6 @@ .import __MAIN_START__, __MAIN_SIZE__ .include "zeropage.inc" - .include "telestrat.inc" ; ------------------------------------------------------------------------ ; Place the startup code in a special segment. diff --git a/libsrc/telestrat/kbhit.s b/libsrc/telestrat/kbhit.s new file mode 100644 index 000000000..54e4bf4d8 --- /dev/null +++ b/libsrc/telestrat/kbhit.s @@ -0,0 +1,17 @@ +; +; Jede, 2021-02-01 +; +; int kbhit (void); +; + + .export _kbhit + + .include "telestrat.inc" + +_kbhit: + BRK_TELEMON XRD0 + ldx #$00 + txa + rol + eor #$01 + rts diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 68aef42d6..215db3e52 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -13,11 +13,11 @@ sta ptr3 stx ptr3+1 ; save count as result - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; remember -count-1 + inx + stx ptr2+1 + tax + inx + stx ptr2 ; save count with each byte incremented separately jsr popptr1 ; get buf jsr popax ; get fd and discard @@ -51,9 +51,9 @@ next: rts -L1: inc ptr2 +L1: dec ptr2 bne L2 - inc ptr2+1 + dec ptr2+1 beq L9 L2: ldy #0 lda (ptr1),y diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index 68ab3ed12..c5486063b 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "vic20.inc" ; ------------------------------------------------------------------------ ; Startup code diff --git a/samples/mandelbrot.c b/samples/mandelbrot.c index 595bcfbbb..519f3d823 100644 --- a/samples/mandelbrot.c +++ b/samples/mandelbrot.c @@ -31,6 +31,7 @@ /* Workaround missing clock stuff */ #ifdef __APPLE2__ # define clock() 0 +# undef CLK_TCK # define CLK_TCK 1 #endif diff --git a/samples/plasma.c b/samples/plasma.c index ac17265f3..f48d6dc77 100644 --- a/samples/plasma.c +++ b/samples/plasma.c @@ -1,7 +1,7 @@ /*****************************************************************************\ ** plasma test program for cc65. ** ** ** -** (w)2001 by groepaz/hitmen ** +** (w)2001 by groepaz ** ** ** ** Cleanup and porting by Ullrich von Bassewitz. ** ** ** @@ -54,7 +54,6 @@ #pragma static-locals (1); - static const unsigned char sinustable[0x100] = { 0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a, 0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52, @@ -131,8 +130,6 @@ static void doplasma (register unsigned char* scrn) } } - - static void makechar (void) { static const unsigned char bittab[8] = { @@ -147,7 +144,7 @@ static void makechar (void) for (i = 0; i < 8; ++i){ b = 0; for (ii = 0; ii < 8; ++ii) { - if ((rand() & 0xFF) > s) { + if ((rand() & 0xFFu) > s) { b |= bittab[ii]; } } diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index b8bda4c7d..6198f4017 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -416,6 +416,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFPDTV: + D = AllocIf (".IFPDTV", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_6502DTV); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFPSC02: D = AllocIf (".IFPSC02", 1); NextTok (); @@ -470,6 +480,7 @@ int CheckConditionals (void) case TOK_IFP4510: case TOK_IFP816: case TOK_IFPC02: + case TOK_IFPDTV: case TOK_IFPSC02: case TOK_IFREF: DoConditionals (); diff --git a/src/ca65/instr.c b/src/ca65/instr.c index d71476799..faeff2026 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -303,6 +303,91 @@ static const struct { } }; +/* Instruction table for the 6502 with DTV extra opcodes (DTV) and +** those illegal instructions (X) which are supported by DTV. +** Note: illegals opcodes which contain more subinstructions +** (ASO, DCM, LSE, LXA, SBX and SHS) are not enlisted. +*/ +static const struct { + unsigned Count; + InsDesc Ins[71]; +} InsTab6502DTV = { + sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]), + { + { "ADC", 0x080A26C, 0x60, 0, PutAll }, + { "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */ + { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */ + { "AND", 0x080A26C, 0x20, 0, PutAll }, + { "ANE", 0x0800000, 0x8B, 0, PutAll }, /* X */ + { "ARR", 0x0800000, 0x6B, 0, PutAll }, /* X */ + { "ASL", 0x000006e, 0x02, 1, PutAll }, + { "AXS", 0x0800000, 0xCB, 0, PutAll }, /* X */ + { "BCC", 0x0020000, 0x90, 0, PutPCRel8 }, + { "BCS", 0x0020000, 0xb0, 0, PutPCRel8 }, + { "BEQ", 0x0020000, 0xf0, 0, PutPCRel8 }, + { "BIT", 0x000000C, 0x00, 2, PutAll }, + { "BMI", 0x0020000, 0x30, 0, PutPCRel8 }, + { "BNE", 0x0020000, 0xd0, 0, PutPCRel8 }, + { "BPL", 0x0020000, 0x10, 0, PutPCRel8 }, + { "BRA", 0x0020000, 0x12, 0, PutPCRel8 }, /* DTV */ + { "BRK", 0x0000001, 0x00, 0, PutAll }, + { "BVC", 0x0020000, 0x50, 0, PutPCRel8 }, + { "BVS", 0x0020000, 0x70, 0, PutPCRel8 }, + { "CLC", 0x0000001, 0x18, 0, PutAll }, + { "CLD", 0x0000001, 0xd8, 0, PutAll }, + { "CLI", 0x0000001, 0x58, 0, PutAll }, + { "CLV", 0x0000001, 0xb8, 0, PutAll }, + { "CMP", 0x080A26C, 0xc0, 0, PutAll }, + { "CPX", 0x080000C, 0xe0, 1, PutAll }, + { "CPY", 0x080000C, 0xc0, 1, PutAll }, + { "DEC", 0x000006C, 0x00, 3, PutAll }, + { "DEX", 0x0000001, 0xca, 0, PutAll }, + { "DEY", 0x0000001, 0x88, 0, PutAll }, + { "EOR", 0x080A26C, 0x40, 0, PutAll }, + { "INC", 0x000006c, 0x00, 4, PutAll }, + { "INX", 0x0000001, 0xe8, 0, PutAll }, + { "INY", 0x0000001, 0xc8, 0, PutAll }, + { "JMP", 0x0000808, 0x4c, 6, PutJMP }, + { "JSR", 0x0000008, 0x20, 7, PutAll }, + { "LAS", 0x0000200, 0xBB, 0, PutAll }, /* X */ + { "LAX", 0x080A30C, 0xA3, 11, PutAll }, /* X */ + { "LDA", 0x080A26C, 0xa0, 0, PutAll }, + { "LDX", 0x080030C, 0xa2, 1, PutAll }, + { "LDY", 0x080006C, 0xa0, 1, PutAll }, + { "LSR", 0x000006F, 0x42, 1, PutAll }, + { "NOP", 0x080006D, 0x00, 10, PutAll }, /* X */ + { "ORA", 0x080A26C, 0x00, 0, PutAll }, + { "PHA", 0x0000001, 0x48, 0, PutAll }, + { "PHP", 0x0000001, 0x08, 0, PutAll }, + { "PLA", 0x0000001, 0x68, 0, PutAll }, + { "PLP", 0x0000001, 0x28, 0, PutAll }, + { "RLA", 0x000A26C, 0x23, 0, PutAll }, /* X */ + { "ROL", 0x000006F, 0x22, 1, PutAll }, + { "ROR", 0x000006F, 0x62, 1, PutAll }, + { "RRA", 0x000A26C, 0x63, 0, PutAll }, /* X */ + { "RTI", 0x0000001, 0x40, 0, PutAll }, + { "RTS", 0x0000001, 0x60, 0, PutAll }, + { "SAC", 0x0800000, 0x32, 1, PutAll }, /* DTV */ + { "SBC", 0x080A26C, 0xe0, 0, PutAll }, + { "SEC", 0x0000001, 0x38, 0, PutAll }, + { "SED", 0x0000001, 0xf8, 0, PutAll }, + { "SEI", 0x0000001, 0x78, 0, PutAll }, + { "SHA", 0x0002200, 0x93, 1, PutAll }, /* X */ + { "SHX", 0x0000200, 0x9e, 1, PutAll }, /* X */ + { "SHY", 0x0000040, 0x9c, 1, PutAll }, /* X */ + { "SIR", 0x0800000, 0x42, 1, PutAll }, /* DTV */ + { "STA", 0x000A26C, 0x80, 0, PutAll }, + { "STX", 0x000010c, 0x82, 1, PutAll }, + { "STY", 0x000002c, 0x80, 1, PutAll }, + { "TAX", 0x0000001, 0xaa, 0, PutAll }, + { "TAY", 0x0000001, 0xa8, 0, PutAll }, + { "TSX", 0x0000001, 0xba, 0, PutAll }, + { "TXA", 0x0000001, 0x8a, 0, PutAll }, + { "TXS", 0x0000001, 0x9a, 0, PutAll }, + { "TYA", 0x0000001, 0x98, 0, PutAll } + } +}; + /* Instruction table for the 65SC02 */ static const struct { unsigned Count; @@ -930,6 +1015,7 @@ static const InsTable* InsTabs[CPU_COUNT] = { (const InsTable*) &InsTabNone, (const InsTable*) &InsTab6502, (const InsTable*) &InsTab6502X, + (const InsTable*) &InsTab6502DTV, (const InsTable*) &InsTab65SC02, (const InsTable*) &InsTab65C02, (const InsTable*) &InsTab65816, diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 5b2ef0573..26d01cbf1 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1552,6 +1552,14 @@ static void DoP4510 (void) +static void DoPDTV (void) +/* Switch to C64DTV CPU */ +{ + SetCPU (CPU_6502DTV); +} + + + static void DoPageLength (void) /* Set the page length for the listing */ { @@ -2058,6 +2066,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFP4510 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ + { ccKeepToken, DoConditionals }, /* .IFPDTV */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ { ccKeepToken, DoConditionals }, /* .IFREF */ { ccNone, DoImport }, @@ -2091,6 +2100,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoPageLength }, { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, + { ccNone, DoPDTV }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 361a817c1..fb9905809 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -219,6 +219,7 @@ struct DotKeyword { { ".IFP4510", TOK_IFP4510 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, + { ".IFPDTV", TOK_IFPDTV }, { ".IFPSC02", TOK_IFPSC02 }, { ".IFREF", TOK_IFREF }, { ".IMPORT", TOK_IMPORT }, @@ -258,6 +259,7 @@ struct DotKeyword { { ".PAGELENGTH", TOK_PAGELENGTH }, { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, + { ".PDTV", TOK_PDTV }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 8998cc162..ab36028fd 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -196,6 +196,7 @@ typedef enum token_t { TOK_IFP4510, TOK_IFP816, TOK_IFPC02, + TOK_IFPDTV, TOK_IFPSC02, TOK_IFREF, TOK_IMPORT, @@ -229,6 +230,7 @@ typedef enum token_t { TOK_PAGELENGTH, TOK_PARAMCOUNT, TOK_PC02, + TOK_PDTV, TOK_POPCPU, TOK_POPSEG, TOK_PROC, diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 539309283..3ca9d81e6 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -186,6 +186,7 @@ void g_preamble (void) switch (CPU) { case CPU_6502: AddTextLine ("\t.setcpu\t\t\"6502\""); break; case CPU_6502X: AddTextLine ("\t.setcpu\t\t\"6502X\""); break; + case CPU_6502DTV: AddTextLine ("\t.setcpu\t\t\"6502DTV\""); break; case CPU_65SC02: AddTextLine ("\t.setcpu\t\t\"65SC02\""); break; case CPU_65C02: AddTextLine ("\t.setcpu\t\t\"65C02\""); break; case CPU_65816: AddTextLine ("\t.setcpu\t\t\"65816\""); break; @@ -1432,6 +1433,22 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs) /* Note that this logic is largely duplicated by ArithmeticConvert. */ + /* Before we apply the integral promotions, we check if both types are the same character type. + ** If so, we return that type, rather than int, which would be returned by the standard + ** rules. This is only a performance optimization allowing the use of unsigned and/or char + ** operations; it does not affect correctness, as the flags are only used for code generation, + ** and not to determine types of other expressions containing this one. For codgen, CF_CHAR + ** means the operands are char and the result is int (unless CF_FORCECHAR is also set, in + ** which case the result is char). This special case part is not duplicated by + ** ArithmeticConvert. + */ + if ((lhs & CF_TYPEMASK) == CF_CHAR && (rhs & CF_TYPEMASK) == CF_CHAR && + (lhs & CF_UNSIGNED) == (rhs & CF_UNSIGNED)) { + /* Signedness flags are the same, so just use one of them. */ + const unsigned unsigned_flag = lhs & CF_UNSIGNED; + return const_flag | unsigned_flag | CF_CHAR; + } + /* Apply integral promotions for types char/short. */ lhs = g_intpromotion (lhs); rhs = g_intpromotion (rhs); @@ -2461,7 +2478,7 @@ void g_branch (unsigned Label) ** the label cannot be farther away from the branch than -128/+127 bytes. */ { - if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0) { + if ((CPUIsets[CPU] & (CPU_ISET_65SC02 | CPU_ISET_6502DTV)) != 0) { AddCodeLine ("bra %s", LocalLabelName (Label)); } else { g_jump (Label); @@ -3090,18 +3107,33 @@ void g_asr (unsigned flags, unsigned long val) "tosasrax", "tosshrax", "tosasreax", "tosshreax" }; - /* If the right hand side is const, the lhs is not on stack but still + /* If the right hand side is const, the lhs is not on stack, but still ** in the primary register. */ if (flags & CF_CONST) { - switch (flags & CF_TYPEMASK) { - case CF_CHAR: if (flags & CF_FORCECHAR) { - if ((flags & CF_UNSIGNED) != 0 && val <= 4) { - while (val--) { - AddCodeLine ("lsr a"); + val &= 7; + if ((flags & CF_UNSIGNED) != 0) { + /* Instead of `val` right shifts, we can also do `9 - val` left rotates + ** and a mask. This saves 3 bytes and 8 cycles for `val == 7` and + ** 1 byte and 4 cycles for `val == 6`. + */ + if (val < 6) { + while (val--) { + AddCodeLine ("lsr a"); /* 1 byte, 2 cycles */ + } + } else { + unsigned i; + /* The first ROL shifts in garbage and sets carry to the high bit. + ** The garbage is cleaned up by the mask. + */ + for (i = val; i < 9; ++i) { + AddCodeLine ("rol a"); /* 1 byte, 2 cycles */ + } + /* 2 bytes, 2 cycles */ + AddCodeLine ("and #$%02X", 0xFF >> val); } return; } else if (val <= 2) { @@ -3111,19 +3143,28 @@ void g_asr (unsigned flags, unsigned long val) } return; } + AddCodeLine ("ldx #$00"); + if ((flags & CF_UNSIGNED) == 0) { + unsigned L = GetLocalLabel (); + + AddCodeLine ("cmp #$80"); /* Sign bit into carry */ + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("dex"); /* Make $FF */ + g_defcodelabel (L); + } } /* FALLTHROUGH */ case CF_INT: val &= 0x0F; if (val >= 8) { + AddCodeLine ("txa"); if (flags & CF_UNSIGNED) { - AddCodeLine ("txa"); AddCodeLine ("ldx #$00"); } else { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("cpx #$80"); /* Sign bit into carry */ - AddCodeLine ("txa"); AddCodeLine ("ldx #$00"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("dex"); /* Make $FF */ @@ -3141,9 +3182,9 @@ void g_asr (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shrax%ld", val); + AddCodeLine ("jsr shrax%lu", val); } else { - AddCodeLine ("jsr asrax%ld", val); + AddCodeLine ("jsr asrax%lu", val); } } return; @@ -3154,7 +3195,8 @@ void g_asr (unsigned flags, unsigned long val) AddCodeLine ("ldx #$00"); AddCodeLine ("lda sreg+1"); if ((flags & CF_UNSIGNED) == 0) { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("bpl %s", LocalLabelName (L)); AddCodeLine ("dex"); g_defcodelabel (L); @@ -3167,7 +3209,8 @@ void g_asr (unsigned flags, unsigned long val) AddCodeLine ("ldy #$00"); AddCodeLine ("ldx sreg+1"); if ((flags & CF_UNSIGNED) == 0) { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("bpl %s", LocalLabelName (L)); AddCodeLine ("dey"); g_defcodelabel (L); @@ -3183,7 +3226,8 @@ void g_asr (unsigned flags, unsigned long val) AddCodeLine ("ldy sreg+1"); AddCodeLine ("sty sreg"); if ((flags & CF_UNSIGNED) == 0) { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("cpy #$80"); AddCodeLine ("ldy #$00"); AddCodeLine ("bcc %s", LocalLabelName (L)); @@ -3205,9 +3249,9 @@ void g_asr (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shreax%ld", val); + AddCodeLine ("jsr shreax%lu", val); } else { - AddCodeLine ("jsr asreax%ld", val); + AddCodeLine ("jsr asreax%lu", val); } } return; @@ -3237,17 +3281,27 @@ void g_asl (unsigned flags, unsigned long val) "tosaslax", "tosshlax", "tosasleax", "tosshleax" }; - /* If the right hand side is const, the lhs is not on stack but still + /* If the right hand side is const, the lhs is not on stack, but still ** in the primary register. */ if (flags & CF_CONST) { - switch (flags & CF_TYPEMASK) { - case CF_CHAR: - if ((flags & CF_FORCECHAR) != 0 && val <= 4) { - while (val--) { - AddCodeLine ("asl a"); + if ((flags & CF_FORCECHAR) != 0) { + val &= 7; + /* Large shifts are faster and smaller with ROR. See g_asr for detailed + ** byte and cycle counts. + */ + if (val < 6) { + while (val--) { + AddCodeLine ("asl a"); + } + } else { + unsigned i; + for (i = val; i < 9; ++i) { + AddCodeLine ("ror a"); + } + AddCodeLine ("and #$%02X", (~0U << val) & 0xFF); } return; } @@ -3270,9 +3324,9 @@ void g_asl (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shlax%ld", val); + AddCodeLine ("jsr shlax%lu", val); } else { - AddCodeLine ("jsr aslax%ld", val); + AddCodeLine ("jsr aslax%lu", val); } } return; @@ -3311,9 +3365,9 @@ void g_asl (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shleax%ld", val); + AddCodeLine ("jsr shleax%lu", val); } else { - AddCodeLine ("jsr asleax%ld", val); + AddCodeLine ("jsr asleax%lu", val); } } return; diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index e0cda84e9..90d4f4d68 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -493,22 +493,28 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) ** registers. */ *Use = REG_EAXY; - } else if (D->ParamCount > 0 && + } else if ((D->ParamCount > 0 || + (D->Flags & FD_EMPTY) != 0) && (AutoCDecl ? IsQualFastcall (E->Type) : !IsQualCDecl (E->Type))) { /* Will use registers depending on the last param. If the last - ** param has incomplete type, just assume __EAX__. + ** param has incomplete type, or if the function has not been + ** prototyped yet, just assume __EAX__. */ - switch (SizeOf (D->LastParam->Type)) { - case 1u: - *Use = REG_A; - break; - case 2u: - *Use = REG_AX; - break; - default: - *Use = REG_EAX; + if (D->LastParam != 0) { + switch (SizeOf(D->LastParam->Type)) { + case 1u: + *Use = REG_A; + break; + case 2u: + *Use = REG_AX; + break; + default: + *Use = REG_EAX; + } + } else { + *Use = REG_EAX; } } else { /* Will not use any registers */ diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 3df762eeb..375fdf541 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -1080,7 +1080,7 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) } else { - if ((LI->A.Flags & LI_CHECK_Y) == 0) { + if ((LI->X.Flags & LI_CHECK_Y) == 0) { /* ldy #const */ X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->X.Offs), 0, D->OpEntry->LI); } else { @@ -1094,7 +1094,7 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); } else { /* opc src,y */ - X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); + X = NewCodeEntry (OPC, LI->X.LoadEntry->AM, LI->X.LoadEntry->Arg, 0, D->OpEntry->LI); } InsertEntry (D, X, D->IP++); } diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index a4a8c6a9b..fda23ae0a 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -944,7 +944,9 @@ unsigned OptCmp9 (CodeSeg* S) if (L[0]->OPC == OP65_SBC && CS_GetEntries (S, L+1, I+1, 4) && (L[1]->OPC == OP65_BVC || - L[1]->OPC == OP65_BVS) && + L[1]->OPC == OP65_BVS || + L[1]->OPC == OP65_JVC || + L[1]->OPC == OP65_JVS) && L[1]->JumpTo != 0 && L[1]->JumpTo->Owner == L[3] && L[2]->OPC == OP65_EOR && diff --git a/src/cc65/coptjmp.c b/src/cc65/coptjmp.c index 693c7eb79..dd092a5ad 100644 --- a/src/cc65/coptjmp.c +++ b/src/cc65/coptjmp.c @@ -173,7 +173,7 @@ unsigned OptBranchDist (CodeSeg* S) } - } else if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && + } else if ((CPUIsets[CPU] & (CPU_ISET_65SC02 |CPU_ISET_6502DTV)) != 0 && (E->Info & OF_UBRA) != 0 && E->JumpTo != 0 && IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner))) { diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 0534a1fa2..046e65d79 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -988,7 +988,7 @@ unsigned OptPtrLoad12 (CodeSeg* S) L[4]->OPC == OP65_CLC && L[5]->OPC == OP65_ADC && CE_IsKnownImm (L[5], 1) && - L[6]->OPC == OP65_BCC && + (L[6]->OPC == OP65_BCC || L[6]->OPC == OP65_JCC) && L[6]->JumpTo != 0 && L[6]->JumpTo->Owner == L[8] && L[7]->OPC == OP65_INX && diff --git a/src/cc65/coptshift.c b/src/cc65/coptshift.c index 92210ebb5..aef3f64bc 100644 --- a/src/cc65/coptshift.c +++ b/src/cc65/coptshift.c @@ -341,7 +341,10 @@ unsigned OptShift2 (CodeSeg* S) L[0] = CS_GetEntry (S, I); /* Check for the sequence */ - if ((L[0]->OPC == OP65_BPL || L[0]->OPC == OP65_BCC) && + if ((L[0]->OPC == OP65_BPL || + L[0]->OPC == OP65_BCC || + L[0]->OPC == OP65_JPL || + L[0]->OPC == OP65_JCC) && L[0]->JumpTo != 0 && CS_GetEntries (S, L+1, I+1, 3) && L[1]->OPC == OP65_DEX && diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 41dfb5526..01d0b039c 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -287,7 +287,7 @@ static unsigned Opt_tosshift (StackOpData* D, const char* Name) /* ldx */ X = NewCodeEntry (OP65_LDX, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - + /* Lhs load entries can be removed if not used later */ D->Lhs.X.Flags |= LI_REMOVE; D->Lhs.A.Flags |= LI_REMOVE; @@ -453,6 +453,7 @@ static unsigned Opt_staxspidx (StackOpData* D) /* Optimize the staxspidx sequence */ { CodeEntry* X; + const char* Arg = 0; /* Check if we're using a register variable */ if (!IsRegVar (D)) { @@ -469,7 +470,7 @@ static unsigned Opt_staxspidx (StackOpData* D) if (RegValIsKnown (D->OpEntry->RI->In.RegY)) { /* Value of Y is known */ - const char* Arg = MakeHexArg (D->OpEntry->RI->In.RegY + 1); + Arg = MakeHexArg (D->OpEntry->RI->In.RegY + 1); X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI); } else { X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, D->OpEntry->LI); @@ -478,7 +479,7 @@ static unsigned Opt_staxspidx (StackOpData* D) if (RegValIsKnown (D->OpEntry->RI->In.RegX)) { /* Value of X is known */ - const char* Arg = MakeHexArg (D->OpEntry->RI->In.RegX); + Arg = MakeHexArg (D->OpEntry->RI->In.RegX); X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); } else { /* Value unknown */ @@ -493,7 +494,12 @@ static unsigned Opt_staxspidx (StackOpData* D) /* If we remove staxspidx, we must restore the Y register to what the ** function would return. */ - X = NewCodeEntry (OP65_LDY, AM65_IMM, "$00", 0, D->OpEntry->LI); + if (RegValIsKnown (D->OpEntry->RI->In.RegY)) { + Arg = MakeHexArg (D->OpEntry->RI->In.RegY); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI); + } else { + X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, D->OpEntry->LI); + } InsertEntry (D, X, D->OpIndex+5); /* Remove the push and the call to the staxspidx function */ @@ -1100,7 +1106,7 @@ static unsigned Opt_tosxorax (StackOpData* D) static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) -/* Optimize the tos compare sequence with a bool transformer */ +/* Optimize the TOS compare sequence with a bool transformer */ { CodeEntry* X; cmp_t Cond; @@ -1119,9 +1125,8 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) D->Rhs.A.Flags |= LI_REMOVE; } else if ((D->Lhs.A.Flags & LI_DIRECT) != 0) { - - /* If the lhs is direct (but not stack relative), encode compares with lhs - ** effectively reverting the order (which doesn't matter for ==). + /* If the lhs is direct (but not stack relative), encode compares with lhs, + ** effectively reversing the order (which doesn't matter for == and !=). */ Cond = FindBoolCmpCond (BoolTransformer); Cond = GetRevertedCond (Cond); @@ -1138,7 +1143,6 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) D->Lhs.A.Flags |= LI_REMOVE; } else { - /* We'll do reverse-compare */ Cond = FindBoolCmpCond (BoolTransformer); Cond = GetRevertedCond (Cond); @@ -1162,7 +1166,7 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) X = NewCodeEntry (OP65_JSR, AM65_ABS, BoolTransformer, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - /* Remove the push and the call to the tosgeax function */ + /* Remove the push and the call to the TOS function */ RemoveRemainders (D); /* We changed the sequence */ @@ -1179,22 +1183,6 @@ static unsigned Opt_a_toseq (StackOpData* D) -static unsigned Opt_a_tosge (StackOpData* D) -/* Optimize the tosgeax sequence */ -{ - return Opt_a_toscmpbool (D, "boolge"); -} - - - -static unsigned Opt_a_tosgt (StackOpData* D) -/* Optimize the tosgtax sequence */ -{ - return Opt_a_toscmpbool (D, "boolgt"); -} - - - static unsigned Opt_a_tosicmp (StackOpData* D) /* Replace tosicmp with CMP */ { @@ -1236,7 +1224,7 @@ static unsigned Opt_a_tosicmp (StackOpData* D) } InsertEntry (D, X, D->IP++); - /* cmp src,y OR cmp (sp),y*/ + /* cmp src,y OR cmp (sp),y */ if (D->Rhs.A.LoadEntry->OPC == OP65_JSR) { /* opc (sp),y */ X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); @@ -1268,18 +1256,18 @@ static unsigned Opt_a_tosicmp (StackOpData* D) InsertEntry (D, X, D->IP-3); } else { - /* Just clear A,Z,N and set C */ + /* Just clear A,Z,N; and set C */ + Arg = MakeHexArg (0); if ((RI = GetLastChangedRegInfo (D, &D->Lhs.A)) != 0 && RegValIsKnown (RI->Out.RegA) && (RI->Out.RegA & 0xFF) == 0) { - Arg = MakeHexArg (0); - X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); + + X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->OpIndex + 1); } else { - Arg = MakeHexArg (0); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->OpIndex + 1); - X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); + X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->OpIndex + 2); } } @@ -1292,24 +1280,8 @@ static unsigned Opt_a_tosicmp (StackOpData* D) -static unsigned Opt_a_tosle (StackOpData* D) -/* Optimize the tosleax sequence */ -{ - return Opt_a_toscmpbool (D, "boolle"); -} - - - -static unsigned Opt_a_toslt (StackOpData* D) -/* Optimize the tosltax sequence */ -{ - return Opt_a_toscmpbool (D, "boollt"); -} - - - static unsigned Opt_a_tosne (StackOpData* D) -/* Optimize the toseqax sequence */ +/* Optimize the tosneax sequence */ { return Opt_a_toscmpbool (D, "boolne"); } @@ -1317,7 +1289,7 @@ static unsigned Opt_a_tosne (StackOpData* D) static unsigned Opt_a_tosuge (StackOpData* D) -/* Optimize the tosugeax sequence */ +/* Optimize the tosgeax and tosugeax sequences */ { return Opt_a_toscmpbool (D, "booluge"); } @@ -1325,7 +1297,7 @@ static unsigned Opt_a_tosuge (StackOpData* D) static unsigned Opt_a_tosugt (StackOpData* D) -/* Optimize the tosugtax sequence */ +/* Optimize the tosgtax and tosugtax sequences */ { return Opt_a_toscmpbool (D, "boolugt"); } @@ -1333,7 +1305,7 @@ static unsigned Opt_a_tosugt (StackOpData* D) static unsigned Opt_a_tosule (StackOpData* D) -/* Optimize the tosuleax sequence */ +/* Optimize the tosleax and tosuleax sequences */ { return Opt_a_toscmpbool (D, "boolule"); } @@ -1341,7 +1313,7 @@ static unsigned Opt_a_tosule (StackOpData* D) static unsigned Opt_a_tosult (StackOpData* D) -/* Optimize the tosultax sequence */ +/* Optimize the tosltax and tosultax sequences */ { return Opt_a_toscmpbool (D, "boolult"); } @@ -1354,6 +1326,8 @@ static unsigned Opt_a_tosult (StackOpData* D) +/* The first column of these two tables must be sorted in lexical order */ + static const OptFuncDesc FuncTable[] = { { "__bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN }, { "staspidx", Opt_staspidx, REG_NONE, OP_NONE }, @@ -1379,11 +1353,11 @@ static const OptFuncDesc FuncTable[] = { static const OptFuncDesc FuncRegATable[] = { { "toseqax", Opt_a_toseq, REG_NONE, OP_NONE }, - { "tosgeax", Opt_a_tosge, REG_NONE, OP_NONE }, - { "tosgtax", Opt_a_tosgt, REG_NONE, OP_NONE }, + { "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE }, + { "tosgtax", Opt_a_tosugt, REG_NONE, OP_NONE }, { "tosicmp", Opt_a_tosicmp, REG_NONE, OP_NONE }, - { "tosleax", Opt_a_tosle, REG_NONE, OP_NONE }, - { "tosltax", Opt_a_toslt, REG_NONE, OP_NONE }, + { "tosleax", Opt_a_tosule, REG_NONE, OP_NONE }, + { "tosltax", Opt_a_tosult, REG_NONE, OP_NONE }, { "tosneax", Opt_a_tosne, REG_NONE, OP_NONE }, { "tosugeax", Opt_a_tosuge, REG_NONE, OP_NONE }, { "tosugtax", Opt_a_tosugt, REG_NONE, OP_NONE }, @@ -1732,7 +1706,7 @@ unsigned OptStackOps (CodeSeg* S) int I; int OldEntryCount; /* Old number of entries */ unsigned Used; /* What registers would be used */ - unsigned PushedRegs; /* Track if the same regs are used after the push */ + unsigned PushedRegs = 0; /* Track if the same regs are used after the push */ int RhsAChgIndex; /* Track if rhs is changed more than once */ int RhsXChgIndex; /* Track if rhs is changed more than once */ int IsRegAOptFunc = 0; /* Whether to use the RegA-only optimizations */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index e5e20ac1f..d78bfe116 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -124,7 +124,8 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu /* First argument */ SymEntry* Param = D->SymTab->SymHead; - for (unsigned I = 0; I < D->ParamCount; ++I) { + unsigned I; + for (I = 0; I < D->ParamCount; ++I) { CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); if (I > 0) { SB_AppendStr (&ParamList, ", "); @@ -461,7 +462,7 @@ Type* GetImplicitFuncType (void) Type* T = TypeAlloc (3); /* func/returns int/terminator */ /* Prepare the function descriptor */ - F->Flags = FD_EMPTY | FD_VARIADIC; + F->Flags = FD_EMPTY; F->SymTab = &EmptySymTab; F->TagTab = &EmptySymTab; @@ -602,7 +603,8 @@ void PrintFuncSig (FILE* F, const char* Name, Type* T) /* Get the parameter list string. Start from the first parameter */ SymEntry* Param = D->SymTab->SymHead; - for (unsigned I = 0; I < D->ParamCount; ++I) { + unsigned I; + for (I = 0; I < D->ParamCount; ++I) { CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); if (I > 0) { SB_AppendStr (&ParamList, ", "); diff --git a/src/cc65/error.c b/src/cc65/error.c index 132bf331d..feb43565d 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -74,6 +74,7 @@ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,6 +93,7 @@ static WarnMapEntry WarnMap[] = { { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, + { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a443aeff8..898793651 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -71,6 +71,7 @@ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 19572944e..09a7a1f39 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1,7 +1,7 @@ /* expr.c ** ** 1998-06-21, Ullrich von Bassewitz -** 2020-01-25, Greg King +** 2020-11-20, Greg King */ @@ -219,6 +219,13 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); + if (ED_IsConstAbsInt (lhs) && ltype == CF_INT && lhs->IVal >= 0 && lhs->IVal < 256) { + /* If the lhs is a int constant that fits in an unsigned char, use unsigned char. + ** g_typeadjust will either promote this to int or unsigned int as appropriate + ** based on the other operand. See comment in hie_internal. + */ + ltype = CF_CHAR | CF_UNSIGNED; + } if (ED_IsLocNone (lhs)) { ltype |= CF_CONST; } @@ -227,6 +234,9 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) ltype |= CF_PRIMARY; } rtype = TypeOf (rhst); + if (ED_IsConstAbsInt (rhs) && rtype == CF_INT && rhs->IVal >= 0 && rhs->IVal < 256) { + rtype = CF_CHAR | CF_UNSIGNED; + } if (ED_IsLocNone (rhs)) { rtype |= CF_CONST; } @@ -241,6 +251,42 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static void LimitExprValue (ExprDesc* Expr) +/* Limit the constant value of the expression to the range of its type */ +{ + switch (GetUnderlyingTypeCode (Expr->Type)) { + case T_INT: + case T_SHORT: + Expr->IVal = (int16_t)Expr->IVal; + break; + + case T_UINT: + case T_USHORT: + case T_PTR: + case T_ARRAY: + Expr->IVal = (uint16_t)Expr->IVal; + break; + + case T_LONG: + case T_ULONG: + /* No need to do anything */ + break; + + case T_SCHAR: + Expr->IVal = (int8_t)Expr->IVal; + break; + + case T_UCHAR: + Expr->IVal = (uint8_t)Expr->IVal; + break; + + default: + Internal ("hie_internal: constant result type %s\n", GetFullTypeName (Expr->Type)); + } +} + + + static const GenDesc* FindGen (token_t Tok, const GenDesc* Table) /* Find a token in a generator table */ { @@ -366,6 +412,9 @@ void DoneDeferredOps (void) static void DeferInc (const ExprDesc* Expr) /* Defer the post-inc and put it in a queue */ { + if (ED_IsUneval (Expr)) { + return; + } DeferredOp* Op = xmalloc (sizeof (DeferredOp)); memcpy (&Op->Expr, Expr, sizeof (ExprDesc)); Op->OpType = DOT_INC; @@ -377,6 +426,9 @@ static void DeferInc (const ExprDesc* Expr) static void DeferDec (const ExprDesc* Expr) /* Defer the post-dec and put it in a queue */ { + if (ED_IsUneval (Expr)) { + return; + } DeferredOp* Op = xmalloc (sizeof (DeferredOp)); memcpy (&Op->Expr, Expr, sizeof (ExprDesc)); Op->OpType = DOT_DEC; @@ -598,6 +650,8 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) ** The function returns the size of the arguments pushed in bytes. */ { + ExprDesc Expr; + /* Initialize variables */ SymEntry* Param = 0; /* Keep gcc silent */ unsigned PushedSize = 0; /* Size of arguments pushed */ @@ -624,7 +678,6 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) ** */ if (ParamComplete && IS_Get (&CodeSizeFactor) >= 200) { - /* Calculate the number and size of the parameters */ FrameParams = Func->ParamCount; FrameSize = Func->ParamSize; @@ -646,18 +699,13 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) } } - /* The info of the last argument could be needed out of the loop */ - ExprDesc Expr; - ED_Init (&Expr); - Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; - /* Parse the actual argument list */ while (CurTok.Tok != TOK_RPAREN) { - unsigned Flags; /* Code generator flags, not expression flags */ - - /* This way the info of the last parameter won't be cleared */ + ED_Init (&Expr); + + /* This way, the info of the last parameter won't be cleared */ Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; /* Count arguments */ @@ -771,18 +819,20 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) Error ("Argument expected after comma"); break; } + + DoDeferred (SQP_KEEP_NONE, &Expr); } + /* Append last deferred inc/dec before the function is called. + ** The last parameter needs to be preserved if it is passed in AX/EAX Regs. + */ + DoDeferred (IsFastcall ? SQP_KEEP_EAX : SQP_KEEP_NONE, &Expr); + /* Check if we had enough arguments */ if (PushedCount < Func->ParamCount) { Error ("Too few arguments in function call"); } - /* Append deferred inc/dec before the function is called. - ** The last parameter needs to be restored if it is passed with AX/EAX Regs. - */ - DoDeferred (IsFastcall ? SQP_KEEP_EAX : SQP_KEEP_NONE, &Expr); - /* The function returns the size of all arguments pushed onto the stack. ** However, if there are parameters missed (which is an error, and was ** flagged by the compiler), AND a stack frame was preallocated above, @@ -1163,16 +1213,16 @@ static void Primary (ExprDesc* E) /* IDENT is either an auto-declared function or an undefined variable. */ if (CurTok.Tok == TOK_LPAREN) { - /* C99 doesn't allow calls to undefined functions, so + /* C99 doesn't allow calls to undeclared functions, so ** generate an error and otherwise a warning. Declare a ** function returning int. For that purpose, prepare a ** function signature for a function having an empty param ** list and returning int. */ if (IS_Get (&Standard) >= STD_C99) { - Error ("Call to undefined function '%s'", Ident); + Error ("Call to undeclared function '%s'", Ident); } else { - Warning ("Call to undefined function '%s'", Ident); + Warning ("Call to undeclared function '%s'", Ident); } Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC); E->Type = Sym->Type; @@ -1385,7 +1435,7 @@ static void ArrayRef (ExprDesc* Expr) /* The array subscript is a constant. Since we can have the element ** address directly as base+offset, we can remove the array address ** push onto the stack before if loading subscript doesn't tamper that - ** address in the primary. + ** address in the primary. */ if (!ConstBaseAddr) { RemoveCode (&Mark2); @@ -1409,7 +1459,7 @@ static void ArrayRef (ExprDesc* Expr) ** remove the code that loaded the address into the primary. */ if (!IsTypeArray (Expr->Type)) { - + /* It's a pointer, so we do have to load it into the primary ** first (if it's not already there). */ @@ -2015,8 +2065,8 @@ static void PostInc (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* We are allowed by the C standard to defer the inc operation until - ** the this expression is used, so that we don't need to save and reload + /* We are allowed by the C standard to defer the inc operation until after + ** the expression is used, so that we don't need to save and reload ** the original value. */ @@ -2055,7 +2105,7 @@ static void PostInc (ExprDesc* Expr) /* Fetch the value and use it (since it's the result of the expression) */ LoadExpr (CF_NONE, Expr); - /* Defer the increment until the value of this expression is used */; + /* Defer the increment until after the value of this expression is used */ DeferInc (Expr); } } @@ -2122,7 +2172,7 @@ static void PostDec (ExprDesc* Expr) /* Fetch the value and save it (since it's the result of the expression) */ LoadExpr (CF_NONE, Expr); - /* Defer the decrement until the value of this expression is used */; + /* Defer the decrement until after the value of this expression is used */ DeferDec (Expr); } } @@ -2151,15 +2201,19 @@ static void UnaryOp (ExprDesc* Expr) ED_MakeConstAbsInt (Expr, 1); } - /* Check for a constant expression */ + /* Check for a constant numeric expression */ if (ED_IsConstAbs (Expr)) { - /* Value is constant */ + /* Value is numeric */ switch (Tok) { case TOK_MINUS: Expr->IVal = -Expr->IVal; break; case TOK_PLUS: break; case TOK_COMP: Expr->IVal = ~Expr->IVal; break; default: Internal ("Unexpected token: %d", Tok); } + + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); + } else { /* Value is not constant */ LoadExpr (CF_NONE, Expr); @@ -2210,7 +2264,7 @@ void hie10 (ExprDesc* Expr) NextToken (); BoolExpr (hie10, Expr); if (ED_IsConstAbs (Expr)) { - /* Constant expression */ + /* Constant numeric expression */ Expr->IVal = !Expr->IVal; } else if (ED_IsAddrExpr (Expr)) { /* Address != NULL, so !Address == 0 */ @@ -2501,7 +2555,19 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ } } + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); + } else if (lconst && (Gen->Flags & GEN_COMM) && !rconst) { + /* If the LHS constant is an int that fits into an unsigned char, change the + ** codegen type to unsigned char. If the RHS is also an unsigned char, then + ** g_typeadjust will return unsigned int (instead of int, which would be + ** returned without this modification). This allows more efficient operations, + ** but does not affect correctness for the same reasons explained in g_typeadjust. + */ + if (ltype == CF_INT && Expr->IVal >= 0 && Expr->IVal < 256) { + ltype = CF_CHAR | CF_UNSIGNED; + } /* The left side is constant, the right side is not, and the ** operator allows swapping the operands. We haven't pushed the @@ -2536,6 +2602,10 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ unsigned rtype = TypeOf (Expr2.Type); type = 0; if (rconst) { + /* As above, but for the RHS. */ + if (rtype == CF_INT && Expr2.IVal >= 0 && Expr2.IVal < 256) { + rtype = CF_CHAR | CF_UNSIGNED; + } /* Second value is constant - check for div */ type |= CF_CONST; rtype |= CF_CONST; @@ -2723,6 +2793,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } } + /* Get rid of unwanted flags */ + ED_MakeConstBool (Expr, Expr->IVal); + /* If the result is constant, this is suspicious when not in ** preprocessor mode. */ @@ -2775,7 +2848,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } /* Determine the type of the operation. */ - if (IsTypeChar (Expr->Type) && rconst) { + if (IsTypeChar (Expr->Type) && rconst && (!LeftSigned || RightSigned)) { /* Left side is unsigned char, right side is constant. ** Determine the minimum and maximum values @@ -2788,20 +2861,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ LeftMin = 0; LeftMax = 255; } - /* An integer value is always represented as a signed in the - ** ExprDesc structure. This may lead to false results below, - ** if it is actually unsigned, but interpreted as signed - ** because of the representation. Fortunately, in this case, - ** the actual value doesn't matter, since it's always greater - ** than what can be represented in a char. So correct the - ** value accordingly. - */ - if (!RightSigned && Expr2.IVal < 0) { - /* Correct the value so it is an unsigned. It will then - ** anyway match one of the cases below. - */ - Expr2.IVal = LeftMax + 1; - } /* Comparing a char against a constant may have a constant ** result. Please note: It is not possible to remove the code @@ -2867,7 +2926,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ ** since the right side constant is in a valid range. */ flags |= (CF_CHAR | CF_FORCECHAR); - if (!LeftSigned) { + if (!LeftSigned || !RightSigned) { flags |= CF_UNSIGNED; } @@ -2881,7 +2940,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ if (rconst) { flags |= CF_FORCECHAR; } - if (!LeftSigned) { + if (!LeftSigned || !RightSigned) { flags |= CF_UNSIGNED; } } else { @@ -2889,11 +2948,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ flags |= g_typeadjust (ltype, rtype); } - /* If the left side is an unsigned and the right is a constant, - ** we may be able to change the compares to something more + /* If the comparison is made as unsigned types and the right is a + ** constant, we may be able to change the compares to something more ** effective. */ - if (!LeftSigned && rconst) { + if ((!LeftSigned || !RightSigned) && rconst) { switch (Tok) { @@ -3021,6 +3080,9 @@ static void parseadd (ExprDesc* Expr) /* Integer addition */ Expr->IVal += Expr2.IVal; typeadjust (Expr, &Expr2, 1); + + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); } else { /* OOPS */ Error ("Invalid operands for binary operator '+'"); @@ -3109,6 +3171,9 @@ static void parseadd (ExprDesc* Expr) flags = CF_INT; } + /* Array and function types must be converted to pointer types */ + Expr->Type = PtrConversion (Expr->Type); + /* Result is an rvalue in primary register */ ED_FinalizeRValLoad (Expr); } @@ -3204,7 +3269,7 @@ static void parseadd (ExprDesc* Expr) ED_FinalizeRValLoad (Expr); } - /* Condition codes not set */ + /* Condition code not set */ ED_MarkAsUntested (Expr); } @@ -3280,7 +3345,7 @@ static void parsesub (ExprDesc* Expr) Error ("Incompatible pointer types"); } else { Expr->IVal = (Expr->IVal - Expr2.IVal) / - CheckedPSizeOf (lhst); + (long)CheckedPSizeOf (lhst); } /* Operate on pointers, result type is an integer */ Expr->Type = type_int; @@ -3288,14 +3353,14 @@ static void parsesub (ExprDesc* Expr) /* Integer subtraction */ typeadjust (Expr, &Expr2, 1); Expr->IVal -= Expr2.IVal; + + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); } else { /* OOPS */ Error ("Invalid operands for binary operator '-'"); } - /* Result is constant, condition codes not set */ - ED_MarkAsUntested (Expr); - } else { /* Left hand side is not constant, right hand side is. @@ -3337,8 +3402,6 @@ static void parsesub (ExprDesc* Expr) /* Result is an rvalue in the primary register */ ED_FinalizeRValLoad (Expr); - ED_MarkAsUntested (Expr); - } } else { @@ -3391,8 +3454,10 @@ static void parsesub (ExprDesc* Expr) /* Result is an rvalue in the primary register */ ED_FinalizeRValLoad (Expr); - ED_MarkAsUntested (Expr); } + + /* Condition code not set */ + ED_MarkAsUntested (Expr); } @@ -3715,7 +3780,7 @@ static void hieOr (ExprDesc *Expr) Error ("Scalar expression expected"); ED_MakeConstBool (Expr, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - + if (!ED_IsConstBool (Expr)) { /* Test the lhs if we haven't had && operators. If we had them, the ** jump is already in place and there's no need to do the test. @@ -3726,7 +3791,7 @@ static void hieOr (ExprDesc *Expr) /* Get first expr */ LoadExpr (CF_FORCECHAR, Expr); - + /* Append deferred inc/dec at sequence point */ DoDeferred (SQP_KEEP_TEST, Expr); @@ -3848,8 +3913,8 @@ static void hieOr (ExprDesc *Expr) static void hieQuest (ExprDesc* Expr) /* Parse the ternary operator */ { - int FalseLab; - int TrueLab; + int FalseLab = 0; + int TrueLab = 0; CodeMark SkippedBranch; CodeMark TrueCodeEnd; ExprDesc Expr2; /* Expression 2 */ diff --git a/src/cc65/expr.h b/src/cc65/expr.h index d0a9988af..71dbe8e0d 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -23,10 +23,10 @@ -#define SQP_KEEP_NONE 0x00 -#define SQP_KEEP_TEST 0x01U -#define SQP_KEEP_EAX 0x02U -#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ +#define SQP_KEEP_NONE 0x00 +#define SQP_KEEP_TEST 0x01U +#define SQP_KEEP_EAX 0x02U +#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index e82d0fafc..f5d8cd779 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -261,7 +261,7 @@ ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value) { Expr->Sym = 0; Expr->Type = type_bool; - Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); + Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE); Expr->Name = 0; Expr->IVal = Value; Expr->FVal = FP_D_Make (0.0); diff --git a/src/cc65/function.c b/src/cc65/function.c index 00755ae65..9269d4c62 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -654,8 +654,8 @@ void NewFunc (SymEntry* Func, FuncDesc* D) ** environment returning int, output a warning if we didn't see a return ** statement. */ - if (!F_HasVoidReturn (CurrentFunc) && !F_HasReturn (CurrentFunc) && !C99MainFunc) { - Warning ("Control reaches end of non-void function"); + if (!F_HasVoidReturn (CurrentFunc) && !F_HasReturn (CurrentFunc) && !C99MainFunc && IS_Get (&WarnReturnType)) { + Warning ("Control reaches end of non-void function [-Wreturn-type]"); } /* If this is the main function in a C99 environment returning an int, let diff --git a/src/cc65/main.c b/src/cc65/main.c index fabd71ef7..0b156fb74 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -463,7 +463,8 @@ static void OptCPU (const char* Opt, const char* Arg) /* Find the CPU from the given name */ CPU = FindCPU (Arg); if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 && - CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280) { + CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280 && + CPU != CPU_6502DTV) { AbEnd ("Invalid argument for %s: '%s'", Opt, Arg); } } diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index 86b904df9..aeea0297b 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -734,7 +734,7 @@ opc_t MakeShortBranch (opc_t OPC) case OP65_BVS: case OP65_JVS: return OP65_BVS; case OP65_BRA: - case OP65_JMP: return (CPUIsets[CPU] & CPU_ISET_65SC02)? OP65_BRA : OP65_JMP; + case OP65_JMP: return (CPUIsets[CPU] & (CPU_ISET_65SC02 | CPU_ISET_6502DTV)) ? OP65_BRA : OP65_JMP; default: Internal ("MakeShortBranch: Invalid opcode: %d", OPC); return 0; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index cf463a832..1ea86545d 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -677,7 +677,7 @@ static void WarnPragma (StrBuf* B) static void FlagPragma (StrBuf* B, IntStack* Stack) -/* Handle a pragma that expects a boolean paramater */ +/* Handle a pragma that expects a boolean parameter */ { StrBuf Ident = AUTO_STRBUF_INITIALIZER; long Val; @@ -727,7 +727,7 @@ ExitPoint: static void IntPragma (StrBuf* B, IntStack* Stack, long Low, long High) -/* Handle a pragma that expects an int paramater */ +/* Handle a pragma that expects an int parameter */ { long Val; int Push; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 56c868b2a..3c000f3a1 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1159,12 +1159,13 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Add an external or global symbol to the symbol table and return the entry */ { - /* Use the global symbol table */ + /* Start from the local symbol table */ SymTable* Tab = SymTab; /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTree (Tab, Name); if (Entry) { + /* We have a symbol with this name already */ if (HandleSymRedefinition (Entry, T, Flags)) { Entry = 0; @@ -1215,7 +1216,11 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Use the fail-safe table for fictitious symbols */ Tab = FailSafeTab; } - } + + } else if ((Flags & (SC_EXTERN | SC_FUNC)) != 0) { + /* Add the new declaration to the global symbol table instead */ + Tab = SymTab0; + } if (Entry == 0 || Entry->Owner != Tab) { diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index eefaeb74a..02ee98dae 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -63,7 +63,7 @@ unsigned Test (unsigned Label, int Invert) /* Read a boolean expression */ BoolExpr (hie0, &Expr); - /* Check for a constant expression */ + /* Check for a constant numeric expression */ if (ED_IsConstAbs (&Expr)) { /* Append deferred inc/dec at sequence point */ diff --git a/src/common/cpu.c b/src/common/cpu.c index b4c5c8dfe..b55a5ab00 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -55,6 +55,7 @@ const char* CPUNames[CPU_COUNT] = { "none", "6502", "6502X", + "6502DTV", "65SC02", "65C02", "65816", @@ -69,6 +70,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_NONE, CPU_ISET_6502, CPU_ISET_6502 | CPU_ISET_6502X, + CPU_ISET_6502 | CPU_ISET_6502DTV, CPU_ISET_6502 | CPU_ISET_65SC02, CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_65816, diff --git a/src/common/cpu.h b/src/common/cpu.h index dcf1815db..2e75feaaf 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -50,6 +50,7 @@ typedef enum { CPU_NONE, /* No CPU - for assembler */ CPU_6502, CPU_6502X, /* "Extended", that is: with illegal opcodes */ + CPU_6502DTV, /* CPU_6502 + DTV extra and illegal opcodes */ CPU_65SC02, CPU_65C02, CPU_65816, @@ -65,6 +66,7 @@ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, CPU_ISET_6502X = 1 << CPU_6502X, + CPU_ISET_6502DTV = 1 << CPU_6502DTV, CPU_ISET_65SC02 = 1 << CPU_65SC02, CPU_ISET_65C02 = 1 << CPU_65C02, CPU_ISET_65816 = 1 << CPU_65816, diff --git a/src/common/inttypes.h b/src/common/inttypes.h index 0d8caf32a..28ffb2cc5 100644 --- a/src/common/inttypes.h +++ b/src/common/inttypes.h @@ -51,6 +51,7 @@ /* Assume that ptrdiff_t and size_t are wide enough to hold pointers. ** Assume that they are the widest type. */ +#include #include typedef ptrdiff_t intptr_t; @@ -64,9 +65,55 @@ typedef size_t uintmax_t; #define INT8_MIN (-INT8_MAX - 1) #define INT16_MIN (-INT16_MAX - 1) +#define INT32_MIN (-INT32_MAX - 1) #define UINT8_MAX (0xFF) #define UINT16_MAX (0xFFFF) +#define UINT32_MAX (0xFFFFFFFF) + +#if UCHAR_MAX == UINT8_MAX +typedef unsigned char uint8_t; +#else +#error "No suitable type for uint8_t found." +#endif + +#if SCHAR_MIN == INT8_MIN && SCHAR_MAX == INT8_MAX +typedef signed char int8_t; +#else +#error "No suitable type for int8_t found." +#endif + +#if UINT_MAX == UINT16_MAX +typedef unsigned int uint16_t; +#elif USHRT_MAX == UINT16_MAX +typedef unsigned short uint16_t; +#else +#error "No suitable type for uint16_t found." +#endif + +#if INT_MIN == INT16_MIN && INT_MAX == INT16_MAX +typedef int int16_t; +#elif SHRT_MIN == INT16_MIN && SHRT_MAX == INT16_MAX +typedef short int16_t; +#else +#error "No suitable type for int16_t found." +#endif + +#if UINT_MAX == UINT32_MAX +typedef unsigned int uint32_t; +#elif ULONG_MAX == UINT32_MAX +typedef unsigned long uint32_t; +#else +#error "No suitable type for uint32_t found." +#endif + +#if INT_MIN == INT32_MIN && INT_MAX == INT32_MAX +typedef int int32_t; +#elif LONG_MIN == INT32_MIN && LONG_MAX == INT32_MAX +typedef long int32_t; +#else +#error "No suitable type for int32_t found." +#endif #endif diff --git a/src/common/version.c b/src/common/version.c index 202c61cc3..992be45ee 100644 --- a/src/common/version.c +++ b/src/common/version.c @@ -47,7 +47,7 @@ #define VER_MAJOR 2U -#define VER_MINOR 18U +#define VER_MINOR 19U diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 7a8b0de68..090c3030f 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -90,6 +90,7 @@ + @@ -114,6 +115,7 @@ + diff --git a/src/da65/opc6502dtv.c b/src/da65/opc6502dtv.c new file mode 100644 index 000000000..fe83ad598 --- /dev/null +++ b/src/da65/opc6502dtv.c @@ -0,0 +1,308 @@ +/*****************************************************************************/ +/* */ +/* opc6502dtv.c */ +/* */ +/* 6502 opcode description table with NMOS illegals and DTV opcodes */ +/* */ +/* */ +/* */ +/* (C) 2003-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* da65 */ +#include "handler.h" +#include "opc6502dtv.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes. Base table from opc6502x.c with DTV opcodes, +** where illegal opcodes are filtered based on their support on DTV. +*/ +const OpcDesc OpcTable_6502DTV[256] = { + { "brk", 1, flNone, OH_Implicit }, /* $00 */ + { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */ + { "", 1, flIllegal, OH_Illegal, }, /* $02 */ + { "", 1, flIllegal, OH_Illegal, }, /* $03 */ + { "nop", 2, flUseLabel, OH_Direct }, /* $04 */ + { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ + { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ + { "", 1, flIllegal, OH_Illegal, }, /* $07 */ + { "php", 1, flNone, OH_Implicit }, /* $08 */ + { "ora", 2, flNone, OH_Immediate }, /* $09 */ + { "asl", 1, flNone, OH_Accumulator }, /* $0a */ + { "anc", 2, flNone, OH_Immediate }, /* $0b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */ + { "", 1, flIllegal, OH_Illegal, }, /* $0f */ + { "bpl", 2, flLabel, OH_Relative }, /* $10 */ + { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */ + { "bra", 2, flLabel, OH_Relative }, /* $12 */ + { "", 1, flIllegal, OH_Illegal, }, /* $13 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $14 */ + { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ + { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ + { "", 1, flIllegal, OH_Illegal, }, /* $17 */ + { "clc", 1, flNone, OH_Implicit }, /* $18 */ + { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ + { "nop", 1, flNone, OH_Implicit }, /* $1a */ + { "", 1, flIllegal, OH_Illegal, }, /* $1b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ + { "", 1, flIllegal, OH_Illegal, }, /* $1f */ + { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ + { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ + { "", 1, flIllegal, OH_Illegal, }, /* $22 */ + { "rla", 2, flUseLabel, OH_DirectXIndirect }, /* $23 */ + { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ + { "and", 2, flUseLabel, OH_Direct }, /* $25 */ + { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ + { "rla", 2, flUseLabel, OH_Direct }, /* $27 */ + { "plp", 1, flNone, OH_Implicit }, /* $28 */ + { "and", 2, flNone, OH_Immediate }, /* $29 */ + { "rol", 1, flNone, OH_Accumulator }, /* $2a */ + { "anc", 2, flNone, OH_Immediate }, /* $2b */ + { "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */ + { "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */ + { "rla", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2f */ + { "bmi", 2, flLabel, OH_Relative }, /* $30 */ + { "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */ + { "sac", 2, flNone, OH_Immediate }, /* $32 */ + { "rla", 2, flUseLabel, OH_DirectIndirectY }, /* $33 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $34 */ + { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ + { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ + { "rla", 2, flUseLabel, OH_DirectX }, /* $37 */ + { "sec", 1, flNone, OH_Implicit }, /* $38 */ + { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ + { "nop", 1, flNone, OH_Implicit }, /* $3a */ + { "rla", 3, flUseLabel, OH_AbsoluteY }, /* $3b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3c */ + { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */ + { "rla", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3f */ + { "rti", 1, flNone, OH_Rts }, /* $40 */ + { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ + { "sir", 2, flNone, OH_Immediate }, /* $42 */ + { "", 1, flIllegal, OH_Illegal, }, /* $43 */ + { "nop", 2, flUseLabel, OH_Direct }, /* $44 */ + { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ + { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ + { "", 1, flIllegal, OH_Illegal, }, /* $47 */ + { "pha", 1, flNone, OH_Implicit }, /* $48 */ + { "eor", 2, flNone, OH_Immediate }, /* $49 */ + { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ + { "alr", 2, flNone, OH_Immediate }, /* $4b */ + { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */ + { "", 1, flIllegal, OH_Illegal, }, /* $4f */ + { "bvc", 2, flLabel, OH_Relative }, /* $50 */ + { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ + { "", 1, flIllegal, OH_Illegal, }, /* $52 */ + { "", 1, flIllegal, OH_Illegal, }, /* $53 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $54 */ + { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ + { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ + { "", 1, flIllegal, OH_Illegal, }, /* $57 */ + { "cli", 1, flNone, OH_Implicit }, /* $58 */ + { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ + { "nop", 1, flNone, OH_Implicit }, /* $5a */ + { "", 1, flIllegal, OH_Illegal, }, /* $5b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */ + { "", 1, flIllegal, OH_Illegal, }, /* $5f */ + { "rts", 1, flNone, OH_Rts }, /* $60 */ + { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ + { "", 1, flIllegal, OH_Illegal, }, /* $62 */ + { "rra", 2, flUseLabel, OH_DirectXIndirect }, /* $63 */ + { "nop", 2, flUseLabel, OH_Direct }, /* $64 */ + { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ + { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ + { "rra", 2, flUseLabel, OH_Direct }, /* $67 */ + { "pla", 1, flNone, OH_Implicit }, /* $68 */ + { "adc", 2, flNone, OH_Immediate }, /* $69 */ + { "ror", 1, flNone, OH_Accumulator }, /* $6a */ + { "arr", 2, flNone, OH_Immediate }, /* $6b */ + { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6e */ + { "rra", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6f */ + { "bvs", 2, flLabel, OH_Relative }, /* $70 */ + { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */ + { "", 1, flIllegal, OH_Illegal, }, /* $72 */ + { "rra", 2, flUseLabel, OH_DirectIndirectY }, /* $73 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $74 */ + { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ + { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ + { "rra", 2, flUseLabel, OH_DirectX }, /* $77 */ + { "sei", 1, flNone, OH_Implicit }, /* $78 */ + { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ + { "nop", 1, flNone, OH_Implicit }, /* $7a */ + { "rra", 3, flUseLabel, OH_AbsoluteY }, /* $7b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */ + { "rra", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7f */ + { "nop", 2, flNone, OH_Immediate }, /* $80 */ + { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */ + { "nop", 2, flNone, OH_Immediate }, /* $82 */ + { "", 1, flIllegal, OH_Illegal, }, /* $83 */ + { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ + { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ + { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ + { "", 1, flIllegal, OH_Illegal, }, /* $87 */ + { "dey", 1, flNone, OH_Implicit }, /* $88 */ + { "nop", 2, flNone, OH_Immediate }, /* $89 */ + { "txa", 1, flNone, OH_Implicit }, /* $8a */ + { "", 1, flIllegal, OH_Illegal, }, /* $8b */ + { "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */ + { "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */ + { "", 1, flIllegal, OH_Illegal, }, /* $8f */ + { "bcc", 2, flLabel, OH_Relative }, /* $90 */ + { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ + { "", 1, flIllegal, OH_Illegal, }, /* $92 */ + { "", 1, flIllegal, OH_Illegal, }, /* $93 */ + { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ + { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ + { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ + { "", 1, flIllegal, OH_Illegal, }, /* $97 */ + { "tya", 1, flNone, OH_Implicit }, /* $98 */ + { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ + { "txs", 1, flNone, OH_Implicit }, /* $9a */ + { "", 1, flIllegal, OH_Illegal, }, /* $9b */ + { "shy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */ + { "shx", 3, flUseLabel, OH_AbsoluteY }, /* $9e */ + { "", 1, flIllegal, OH_Illegal, }, /* $9f */ + { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ + { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ + { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ + { "lax", 2, flUseLabel, OH_DirectXIndirect }, /* $a3 */ + { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ + { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ + { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ + { "lax", 2, flUseLabel, OH_Direct }, /* $a7 */ + { "tay", 1, flNone, OH_Implicit }, /* $a8 */ + { "lda", 2, flNone, OH_Immediate }, /* $a9 */ + { "tax", 1, flNone, OH_Implicit }, /* $aa */ + { "lax", 2, flNone, OH_Immediate }, /* $ab */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */ + { "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */ + { "lax", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $af */ + { "bcs", 2, flLabel, OH_Relative }, /* $b0 */ + { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */ + { "", 1, flIllegal, OH_Illegal, }, /* $b2 */ + { "lax", 2, flUseLabel, OH_DirectIndirectY }, /* $b3 */ + { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ + { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ + { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ + { "lax", 2, flUseLabel, OH_DirectY }, /* $b7 */ + { "clv", 1, flNone, OH_Implicit }, /* $b8 */ + { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ + { "tsx", 1, flNone, OH_Implicit }, /* $ba */ + { "las", 3, flUseLabel, OH_AbsoluteY }, /* $bb */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */ + { "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */ + { "lax", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $bf */ + { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ + { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ + { "nop", 2, flNone, OH_Immediate }, /* $c2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $c3 */ + { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ + { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ + { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ + { "", 1, flIllegal, OH_Illegal, }, /* $c7 */ + { "iny", 1, flNone, OH_Implicit }, /* $c8 */ + { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ + { "dex", 1, flNone, OH_Implicit }, /* $ca */ + { "axs", 2, flNone, OH_Immediate }, /* $cb */ + { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ + { "", 1, flIllegal, OH_Illegal, }, /* $cf */ + { "bne", 2, flLabel, OH_Relative }, /* $d0 */ + { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d3 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $d4 */ + { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ + { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d7 */ + { "cld", 1, flNone, OH_Implicit }, /* $d8 */ + { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ + { "nop", 1, flNone, OH_Implicit }, /* $da */ + { "", 1, flIllegal, OH_Illegal, }, /* $db */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ + { "", 1, flIllegal, OH_Illegal, }, /* $df */ + { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ + { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ + { "nop", 2, flNone, OH_Immediate }, /* $e2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $e3 */ + { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ + { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ + { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ + { "", 1, flIllegal, OH_Illegal, }, /* $e7 */ + { "inx", 1, flNone, OH_Implicit }, /* $e8 */ + { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ + { "nop", 1, flNone, OH_Implicit }, /* $ea */ + { "sbc", 2, flNone, OH_Immediate }, /* $eb */ + { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */ + { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */ + { "", 1, flIllegal, OH_Illegal, }, /* $ef */ + { "beq", 2, flLabel, OH_Relative }, /* $f0 */ + { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f3 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $f4 */ + { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ + { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f7 */ + { "sed", 1, flNone, OH_Implicit }, /* $f8 */ + { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ + { "nop", 1, flNone, OH_Implicit }, /* $fa */ + { "", 1, flIllegal, OH_Illegal, }, /* $fb */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fc */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */ + { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */ + { "", 1, flIllegal, OH_Illegal, }, /* $ff */ +}; diff --git a/src/da65/opc6502dtv.h b/src/da65/opc6502dtv.h new file mode 100644 index 000000000..e63e4e44c --- /dev/null +++ b/src/da65/opc6502dtv.h @@ -0,0 +1,61 @@ +/*****************************************************************************/ +/* */ +/* opc6502dtv.h */ +/* */ +/* 6502 opcode description table with NMOS illegals and DTV opcodes */ +/* */ +/* */ +/* */ +/* (C) 2003-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef OPC6502DTV_H +#define OPC6502DTV_H + + + +#include "opcdesc.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +extern const OpcDesc OpcTable_6502DTV[256]; + + + +/* End of opc6502dtv.h */ +#endif + + + + diff --git a/src/da65/opctable.c b/src/da65/opctable.c index 031b1239b..255a3557f 100644 --- a/src/da65/opctable.c +++ b/src/da65/opctable.c @@ -38,6 +38,7 @@ #include "opc4510.h" #include "opc6502.h" #include "opc6502x.h" +#include "opc6502dtv.h" #include "opc65816.h" #include "opc65c02.h" #include "opc65sc02.h" @@ -70,6 +71,7 @@ void SetOpcTable (cpu_t CPU) switch (CPU) { case CPU_6502: OpcTable = OpcTable_6502; break; case CPU_6502X: OpcTable = OpcTable_6502X; break; + case CPU_6502DTV: OpcTable = OpcTable_6502DTV; break; case CPU_65SC02: OpcTable = OpcTable_65SC02; break; case CPU_65C02: OpcTable = OpcTable_65C02; break; case CPU_HUC6280: OpcTable = OpcTable_HuC6280; break; diff --git a/test/asm/6502dtv-cpudetect.ref b/test/asm/6502dtv-cpudetect.ref new file mode 100644 index 000000000..77a865eb4 Binary files /dev/null and b/test/asm/6502dtv-cpudetect.ref differ diff --git a/test/asm/6502dtv-opcodes.ref b/test/asm/6502dtv-opcodes.ref new file mode 100644 index 000000000..408d89be2 Binary files /dev/null and b/test/asm/6502dtv-opcodes.ref differ diff --git a/test/asm/6502dtv-opcodes.s b/test/asm/6502dtv-opcodes.s new file mode 100644 index 000000000..f2446cbe0 --- /dev/null +++ b/test/asm/6502dtv-opcodes.s @@ -0,0 +1,258 @@ +.setcpu "6502DTV" + + brk + ora ($12,x) + .byte $02 + .byte $03 + nop $12 + ora $12 + asl $12 + .byte $07 + php + ora #$12 + asl a + anc #$12 + nop $3456 + ora $3456 + asl $3456 + .byte $0f + bpl *+122 + ora ($12),y + bra *+122 + .byte $13 + nop $12,x + ora $12,x + asl $12,x + .byte $17 + clc + ora $3456,y + .byte $1a ; nop + .byte $1b + nop $3456,x + ora $3456,x + asl $3456,x + .byte $1f + jsr $3456 + and ($12,x) + .byte $22 + rla ($12,x) + bit $12 + and $12 + rol $12 + rla $12 + plp + and #$12 + rol a + .byte $2b,$12 ; anc #$12 + bit $3456 + and $3456 + rol $3456 + rla $3456 + bmi *+122 + and ($12),y + sac #$12 + rla ($12),y + .byte $34,$12 ; nop $12,x + and $12,x + rol $12,x + rla $12,x + sec + and $3456,y + .byte $3a ; nop + rla $3456,y + .byte $3c,$56,$34 ; nop $3456,x + and $3456,x + rol $3456,x + rla $3456,x + rti + eor ($12,x) + sir #$12 + .byte $43 + .byte $44,$12 ; nop $12 + eor $12 + lsr $12 + .byte $47 + pha + eor #$12 + lsr a + alr #$12 + jmp $3456 + eor $3456 + lsr $3456 + .byte $4f + bvc *+122 + eor ($12),y + .byte $52 + .byte $53 + .byte $54,$12 ; nop $12,x + eor $12,x + lsr $12,x + .byte $57 + cli + eor $3456,y + .byte $5a ; nop + .byte $5b + .byte $5c,$56,$34 ; nop $3456,x + eor $3456,x + lsr $3456,x + .byte $5f + rts + adc ($12,x) + .byte $62 + rra ($12,x) + .byte $64,$12 ; nop $12 + adc $12 + ror $12 + rra $12 + pla + adc #$12 + ror a + arr #$12 + jmp ($3456) + adc $3456 + ror $3456 + rra $3456 + bvs *+122 + adc ($12),y + .byte $72 + rra ($12),y + .byte $74,$12 ; nop $12,x + adc $12,x + ror $12,x + rra $12,x + sei + adc $3456,y + .byte $7a ; nop + rra $3456,y + .byte $7c,$56,$34 ; nop $3456,x + adc $3456,x + ror $3456,x + rra $3456,x + nop #$12 + sta ($12,x) + .byte $82,$12 ; nop #$12 + .byte $83 + sty $12 + sta $12 + stx $12 + .byte $87 + dey + .byte $89,$12 ; nop #$12 + txa + .byte $8b + sty $3456 + sta $3456 + stx $3456 + .byte $8f + bcc *+122 + sta ($12),y + .byte $92 + .byte $93 + sty $12,x + sta $12,x + stx $12,y + .byte $97 + tya + sta $3456,y + txs + .byte $9b + shy $3456,x + sta $3456,x + shx $3456,y + .byte $9f + ldy #$12 + lda ($12,x) + ldx #$12 + lax ($12,x) + ldy $12 + lda $12 + ldx $12 + lax $12 + tay + lda #$12 + tax + lax #$12 + ldy $3456 + lda $3456 + ldx $3456 + lax $3456 + bcs *+122 + lda ($12),y + .byte $b2 + lax ($12),y + ldy $12,x + lda $12,x + ldx $12,y + lax $12,y + clv + lda $3456,y + tsx + las $3456,y + ldy $3456,x + lda $3456,x + ldx $3456,y + lax $3456,y + cpy #$12 + cmp ($12,x) + .byte $c2,$12 ; nop #$12 + .byte $c3 + cpy $12 + cmp $12 + dec $12 + .byte $c7 + iny + cmp #$12 + dex + axs #$12 + cpy $3456 + cmp $3456 + dec $3456 + .byte $cf + bne *+122 + cmp ($12),y + .byte $d2 + .byte $d3 + .byte $d4,$12 ; nop $12,x + cmp $12,x + dec $12,x + .byte $d7 + cld + cmp $3456,y + .byte $da ; nop + .byte $db + .byte $dc,$56,$34 ; nop $3456,x + cmp $3456,x + dec $3456,x + .byte $df + cpx #$12 + sbc ($12,x) + .byte $e2,$12 ; nop #$12 + .byte $e3 + cpx $12 + sbc $12 + inc $12 + .byte $e7 + inx + sbc #$12 + nop + .byte $eb,$12 ; sbc #$12 + cpx $3456 + sbc $3456 + inc $3456 + .byte $ef + beq *+122 + sbc ($12),y + .byte $f2 + .byte $f3 + .byte $f4,$12 ; nop $12,x + sbc $12,x + inc $12,x + .byte $f7 + sed + sbc $3456,y + .byte $fa ; nop + .byte $fb + .byte $fc,$56,$34 ; nop $3456,x + sbc $3456,x + inc $3456,x + .byte $ff diff --git a/test/asm/Makefile b/test/asm/Makefile index 9b0aa582e..e951c2015 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -7,7 +7,7 @@ endif ifdef CMD_EXE EXE = .exe MKDIR = mkdir $(subst /,\,$1) - RMDIR = -rmdir /s /q $(subst /,\,$1) + RMDIR = -rmdir /q /s $(subst /,\,$1) else EXE = MKDIR = mkdir -p $1 @@ -23,7 +23,7 @@ LD65 := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) WORKDIR = ../../testwrk/asm -ISEQUAL = $(WORKDIR)/isequal$(EXE) +ISEQUAL = ../../testwrk/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -31,12 +31,12 @@ CFLAGS = -O2 .PHONY: all clean OPCODE_REFS := $(wildcard *-opcodes.ref) -OPCODE_CPUS = $(foreach ref,$(OPCODE_REFS),$(ref:%-opcodes.ref=%)) -OPCODE_BINS = $(foreach cpu,$(OPCODE_CPUS),$(WORKDIR)/$(cpu)-opcodes.bin) +OPCODE_BINS = $(OPCODE_REFS:%.ref=$(WORKDIR)/%.bin) +OPCODE_CPUS = $(OPCODE_REFS:%-opcodes.ref=%) CPUDETECT_REFS := $(wildcard *-cpudetect.ref) -CPUDETECT_CPUS = $(foreach ref,$(CPUDETECT_REFS),$(ref:%-cpudetect.ref=%)) -CPUDETECT_BINS = $(foreach cpu,$(CPUDETECT_CPUS),$(WORKDIR)/$(cpu)-cpudetect.bin) +CPUDETECT_BINS = $(CPUDETECT_REFS:%.ref=$(WORKDIR)/%.bin) +CPUDETECT_CPUS = $(CPUDETECT_REFS:%-cpudetect.ref=%) all: $(OPCODE_BINS) $(CPUDETECT_BINS) $(WORKDIR)/paramcount.o @@ -50,9 +50,9 @@ define OPCODE_template $(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(ISEQUAL) $(if $(QUIET),echo asm/$1-opcodes.bin) - $(CA65) --cpu $1 -t none -l $(WORKDIR)/$1-opcodes.lst -o $(WORKDIR)/$1-opcodes.o $$< - $(LD65) -t none -o $$@ $(WORKDIR)/$1-opcodes.o none.lib - $(ISEQUAL) $$@ $1-opcodes.ref + $(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< + $(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib + $(ISEQUAL) $1-opcodes.ref $$@ endef # OPCODE_template @@ -60,18 +60,18 @@ $(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu)))) define CPUDETECT_template -$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(ISEQUAL) +$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $1-cpudetect.ref $(ISEQUAL) $(if $(QUIET),echo asm/$1-cpudetect.bin) - $(CA65) --cpu $1 -t none -l $(WORKDIR)/$1-cpudetect.lst -o $(WORKDIR)/$1-cpudetect.o $$< - $(LD65) -t none -o $$@ $(WORKDIR)/$1-cpudetect.o none.lib - $(ISEQUAL) $$@ $1-cpudetect.ref + $(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< + $(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib + $(ISEQUAL) $1-cpudetect.ref $$@ endef # CPUDETECT_template $(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu)))) $(WORKDIR)/%.o: %.s | $(WORKDIR) - $(CA65) -l $(@:.o=.lst) -o $(WORKDIR)/$@ $< + $(CA65) -l $(@:.o=.lst) -o $@ $< clean: @$(call RMDIR,$(WORKDIR)) diff --git a/test/asm/cpudetect.s b/test/asm/cpudetect.s index adad7c1dc..7b2363b7f 100644 --- a/test/asm/cpudetect.s +++ b/test/asm/cpudetect.s @@ -24,6 +24,10 @@ taz .endif +.ifpdtv + sac #$00 +.endif + ; step 2: check for bitwise compatibility of instructions sets ; (made verbose for better reading with hexdump/hd(1)) @@ -64,3 +68,7 @@ .byte 0,"CPU_ISET_4510" .endif +.if (.cpu .bitand CPU_ISET_6502DTV) + .byte 0,"CPU_ISET_6502DTV" +.endif + diff --git a/test/asm/readme.txt b/test/asm/readme.txt index a2b1e9a41..1d135c895 100644 --- a/test/asm/readme.txt +++ b/test/asm/readme.txt @@ -1,4 +1,3 @@ - Assembler Testcases =================== @@ -7,7 +6,7 @@ Opcode Tests: These testcases are inspired by the ones now removed from test/assembler. The main purpose is to have each possible opcode generated at least once, -either by an assembly instruction or a ".byte"-placeholder. Typically +either by an Assembly instruction or a ".byte"-placeholder. Typically generated by disassembling a binary dump that contains data in the form of the pattern that each opcode is stated once in order followed by easy to recognise: @@ -24,25 +23,25 @@ leftover dummy opcode parameters with something more recognizable. The testcases for 6502, 6502x, 65sc02, 65c02, 4510, and huc6280 have been put together by Sven Oliver ("SvOlli") Moll, as well as a template for the -m740 instructions set. +m740 instructions set. Later 6502dtv support was also added. Still to do is to find a way to implement an opcode testcase for the 65816 processor, since it's capable of executing instructions with an 8-bit and -a 16-bit operator alike, only distinguished by one processor flag. +a 16-bit operator alike, distinguished by only one processor flag. -CPU detect Tests +CPU Detect Tests ---------------- These tests all assemble the same file "cpudetect.s" which contains several conditionals for several CPUs, only using every option known to the "--cpu" -commandline switch of ca65/cl65. +command-line switch of ca65/cl65. Reference (".ref") Files ------------------------ -A hint on creating these files: when running the test, it will fail due to -the missing ".ref" file. Review the output of the ".lst" very pedantic, then -copy the ".bin" to the ".ref" file. - +Some hints about creating new files: +Make an empty file with the CPU's name prepended to "-cpudetect.ref". Run the +tests; one of them will fail due to a mismatch. Review the output of the +".lst" file pedantically, then copy the ".bin" over the empty ".ref" file. diff --git a/test/dasm/Makefile b/test/dasm/Makefile index dc0b57c76..542ce7d5e 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -7,7 +7,7 @@ endif ifdef CMD_EXE EXE = .exe MKDIR = mkdir $(subst /,\,$1) - RMDIR = -rmdir /s /q $(subst /,\,$1) + RMDIR = -rmdir /q /s $(subst /,\,$1) else EXE = MKDIR = mkdir -p $1 @@ -23,7 +23,7 @@ DA65 := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) WORKDIR = ../../testwrk/dasm -ISEQUAL = $(WORKDIR)/isequal$(EXE) +ISEQUAL = ../../testwrk/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -33,10 +33,9 @@ START = --start-addr 0x8000 .PHONY: all clean SOURCES := $(wildcard *.s) -CPUS = $(foreach src,$(SOURCES),$(src:%-disass.s=%)) -BINS = $(foreach cpu,$(CPUS),$(WORKDIR)/$(cpu)-reass.bin) +BINS = $(SOURCES:%disass.s=$(WORKDIR)/%reass.bin) +CPUS = $(SOURCES:%-disass.s=%) -# default target defined later all: $(BINS) $(WORKDIR): @@ -56,7 +55,7 @@ $(WORKDIR)/$1-reass.s: $(WORKDIR)/$1-disass.bin $(WORKDIR)/$1-reass.bin: $(WORKDIR)/$1-reass.s $(ISEQUAL) $(if $(QUIET),echo dasm/$1-reass.bin) $(CL65) --cpu $1 -t none $(START) -o $$@ $$< - $(ISEQUAL) $$@ $(WORKDIR)/$1-disass.bin + $(ISEQUAL) $(WORKDIR)/$1-disass.bin $$@ endef # DISASS_template diff --git a/test/misc/Makefile b/test/misc/Makefile index b8c578405..7a1b82d5f 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -37,7 +37,7 @@ WORKDIR = ..$S..$Stestwrk$Smisc OPTIONS = g O Os Osi Osir Osr Oi Oir Or -ISEQUAL = $(WORKDIR)$Sisequal$(EXE) +ISEQUAL = ..$S..$Stestwrk$Sisequal$(EXE) CC = gcc CFLAGS = -O2 @@ -101,14 +101,13 @@ $(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # this one requires --std=c89, it fails with --std=c99 -# it fails currently at runtime $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1265.$1.$2.prg) $(CC65) --standard c89 -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) - $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) - + $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) + # should compile, but then hangs in an endless loop $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) $(if $(QUIET),echo misc/endless.$1.$2.prg) diff --git a/test/misc/bug1265.c b/test/misc/bug1265.c index 469946739..36d1459a7 100644 --- a/test/misc/bug1265.c +++ b/test/misc/bug1265.c @@ -14,11 +14,9 @@ int main (void) { int x, n; sprintf (str1, "%p\n", &x); - puts(str1); x = 1234; n = f1 (x); sprintf (str2, "%p\n", &x); - puts(str2); if (strcmp(str1, str2)) { puts("not equal"); @@ -30,11 +28,9 @@ int main (void) { } sprintf (str1, "%p\n", &x); - puts(str1); x = 2345; n = f2 (x); sprintf (str2, "%p\n", &x); - puts(str2); if (strcmp(str1, str2)) { puts("not equal"); diff --git a/test/ref/Makefile b/test/ref/Makefile index 5faf9fb19..d9c9817ee 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -35,7 +35,7 @@ WORKDIR = ..$S..$Stestwrk$Sref OPTIONS = g O Os Osi Osir Osr Oi Oir Or -ISEQUAL = $(WORKDIR)$Sisequal$(EXE) +ISEQUAL = ..$S..$Stestwrk$Sisequal$(EXE) CC = gcc CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow diff --git a/test/val/binlit.c b/test/val/binlit.c index 47e7a196e..f89ca60fc 100644 --- a/test/val/binlit.c +++ b/test/val/binlit.c @@ -3,531 +3,531 @@ static unsigned big[256]; int main() { - unsigned i; + unsigned i; - small[0] = 0b0; - small[1] = 0b1; - small[2] = 0b10; - small[3] = 0b11; - small[4] = 0b100; - small[5] = 0b101; - small[6] = 0b110; - small[7] = 0b000111; - small[8] = 0b1000; - small[9] = 0b1001; - small[10] = 0b0001010; - small[11] = 0b0001011; - small[12] = 0b1100; - small[13] = 0b1101; - small[14] = 0b1110; - small[15] = 0b1111; - small[16] = 0b10000; - small[17] = 0b10001; - small[18] = 0b00010010; - small[19] = 0b00010011; - small[20] = 0b00010100; - small[21] = 0b00010101; - small[22] = 0b10110; - small[23] = 0b10111; - small[24] = 0b11000; - small[25] = 0b11001; - small[26] = 0b11010; - small[27] = 0b11011; - small[28] = 0b11100; - small[29] = 0b11101; - small[30] = 0b11110; - small[31] = 0b11111; - small[32] = 0b00000000100000; - small[33] = 0b00000000100001; - small[34] = 0b100010; - small[35] = 0b100011; - small[36] = 0b100100; - small[37] = 0b100101; - small[38] = 0b100110; - small[39] = 0b100111; - small[40] = 0b101000; - small[41] = 0b101001; - small[42] = 0b101010; - small[43] = 0b101011; - small[44] = 0b101100; - small[45] = 0b101101; - small[46] = 0b101110; - small[47] = 0b101111; - small[48] = 0b110000; - small[49] = 0b110001; - small[50] = 0b110010; - small[51] = 0b110011; - small[52] = 0b110100; - small[53] = 0b110101; - small[54] = 0b110110; - small[55] = 0b110111; - small[56] = 0b111000; - small[57] = 0b111001; - small[58] = 0b111010; - small[59] = 0b111011; - small[60] = 0b111100; - small[61] = 0b111101; - small[62] = 0b111110; - small[63] = 0b111111; - small[64] = 0b1000000; - small[65] = 0b1000001; - small[66] = 0b1000010; - small[67] = 0b1000011; - small[68] = 0b1000100; - small[69] = 0b1000101; - small[70] = 0b1000110; - small[71] = 0b1000111; - small[72] = 0b1001000; - small[73] = 0b1001001; - small[74] = 0b1001010; - small[75] = 0b1001011; - small[76] = 0b1001100; - small[77] = 0b1001101; - small[78] = 0b1001110; - small[79] = 0b1001111; - small[80] = 0b1010000; - small[81] = 0b1010001; - small[82] = 0b1010010; - small[83] = 0b1010011; - small[84] = 0b1010100; - small[85] = 0b1010101; - small[86] = 0b1010110; - small[87] = 0b1010111; - small[88] = 0b1011000; - small[89] = 0b1011001; - small[90] = 0b1011010; - small[91] = 0b1011011; - small[92] = 0b1011100; - small[93] = 0b1011101; - small[94] = 0b1011110; - small[95] = 0b1011111; - small[96] = 0b1100000; - small[97] = 0b1100001; - small[98] = 0b1100010; - small[99] = 0b1100011; - small[100] = 0b1100100; - small[101] = 0b1100101; - small[102] = 0b1100110; - small[103] = 0b1100111; - small[104] = 0b1101000; - small[105] = 0b1101001; - small[106] = 0b1101010; - small[107] = 0b1101011; - small[108] = 0b1101100; - small[109] = 0b1101101; - small[110] = 0b1101110; - small[111] = 0b1101111; - small[112] = 0b1110000; - small[113] = 0b1110001; - small[114] = 0b1110010; - small[115] = 0b1110011; - small[116] = 0b1110100; - small[117] = 0b1110101; - small[118] = 0b1110110; - small[119] = 0b1110111; - small[120] = 0b1111000; - small[121] = 0b1111001; - small[122] = 0b1111010; - small[123] = 0b1111011; - small[124] = 0b1111100; - small[125] = 0b1111101; - small[126] = 0b1111110; - small[127] = 0b1111111; - small[128] = 0b10000000; - small[129] = 0b10000001; - small[130] = 0b10000010; - small[131] = 0b10000011; - small[132] = 0b10000100; - small[133] = 0b10000101; - small[134] = 0b10000110; - small[135] = 0b10000111; - small[136] = 0b10001000; - small[137] = 0b10001001; - small[138] = 0b10001010; - small[139] = 0b10001011; - small[140] = 0b10001100; - small[141] = 0b10001101; - small[142] = 0b10001110; - small[143] = 0b10001111; - small[144] = 0b10010000; - small[145] = 0b10010001; - small[146] = 0b10010010; - small[147] = 0b10010011; - small[148] = 0b10010100; - small[149] = 0b10010101; - small[150] = 0b10010110; - small[151] = 0b10010111; - small[152] = 0b10011000; - small[153] = 0b10011001; - small[154] = 0b10011010; - small[155] = 0b10011011; - small[156] = 0b10011100; - small[157] = 0b10011101; - small[158] = 0b10011110; - small[159] = 0b10011111; - small[160] = 0b10100000; - small[161] = 0b10100001; - small[162] = 0b10100010; - small[163] = 0b10100011; - small[164] = 0b10100100; - small[165] = 0b10100101; - small[166] = 0b10100110; - small[167] = 0b10100111; - small[168] = 0b10101000; - small[169] = 0b10101001; - small[170] = 0b10101010; - small[171] = 0b10101011; - small[172] = 0b10101100; - small[173] = 0b10101101; - small[174] = 0b10101110; - small[175] = 0b10101111; - small[176] = 0b10110000; - small[177] = 0b10110001; - small[178] = 0b10110010; - small[179] = 0b10110011; - small[180] = 0b10110100; - small[181] = 0b10110101; - small[182] = 0b10110110; - small[183] = 0b10110111; - small[184] = 0b10111000; - small[185] = 0b10111001; - small[186] = 0b10111010; - small[187] = 0b10111011; - small[188] = 0b10111100; - small[189] = 0b10111101; - small[190] = 0b10111110; - small[191] = 0b10111111; - small[192] = 0b11000000; - small[193] = 0b11000001; - small[194] = 0b11000010; - small[195] = 0b11000011; - small[196] = 0b11000100; - small[197] = 0b11000101; - small[198] = 0b11000110; - small[199] = 0b11000111; - small[200] = 0b11001000; - small[201] = 0b11001001; - small[202] = 0b11001010; - small[203] = 0b11001011; - small[204] = 0b11001100; - small[205] = 0b11001101; - small[206] = 0b11001110; - small[207] = 0b11001111; - small[208] = 0b11010000; - small[209] = 0b11010001; - small[210] = 0b11010010; - small[211] = 0b11010011; - small[212] = 0b11010100; - small[213] = 0b11010101; - small[214] = 0b11010110; - small[215] = 0b11010111; - small[216] = 0b11011000; - small[217] = 0b11011001; - small[218] = 0b11011010; - small[219] = 0b11011011; - small[220] = 0b11011100; - small[221] = 0b11011101; - small[222] = 0b11011110; - small[223] = 0b11011111; - small[224] = 0b11100000; - small[225] = 0b11100001; - small[226] = 0b11100010; - small[227] = 0b11100011; - small[228] = 0b11100100; - small[229] = 0b11100101; - small[230] = 0b11100110; - small[231] = 0b11100111; - small[232] = 0b11101000; - small[233] = 0b11101001; - small[234] = 0b11101010; - small[235] = 0b11101011; - small[236] = 0b11101100; - small[237] = 0b11101101; - small[238] = 0b11101110; - small[239] = 0b11101111; - small[240] = 0b11110000; - small[241] = 0b11110001; - small[242] = 0b11110010; - small[243] = 0b11110011; - small[244] = 0b11110100; - small[245] = 0b11110101; - small[246] = 0b11110110; - small[247] = 0b11110111; - small[248] = 0b11111000; - small[249] = 0b11111001; - small[250] = 0b11111010; - small[251] = 0b11111011; - small[252] = 0b11111100; - small[253] = 0b11111101; - small[254] = 0b11111110; - small[255] = 0b11111111; + small[0] = 0b0; + small[1] = 0b1; + small[2] = 0b10; + small[3] = 0b11; + small[4] = 0b100; + small[5] = 0b101; + small[6] = 0b110; + small[7] = 0b000111; + small[8] = 0b1000; + small[9] = 0b1001; + small[10] = 0b0001010; + small[11] = 0b0001011; + small[12] = 0b1100; + small[13] = 0b1101; + small[14] = 0b1110; + small[15] = 0b1111; + small[16] = 0b10000; + small[17] = 0b10001; + small[18] = 0b00010010; + small[19] = 0b00010011; + small[20] = 0b00010100; + small[21] = 0b00010101; + small[22] = 0b10110; + small[23] = 0b10111; + small[24] = 0b11000; + small[25] = 0b11001; + small[26] = 0b11010; + small[27] = 0b11011; + small[28] = 0b11100; + small[29] = 0b11101; + small[30] = 0b11110; + small[31] = 0b11111; + small[32] = 0b00000000100000; + small[33] = 0b00000000100001; + small[34] = 0b100010; + small[35] = 0b100011; + small[36] = 0b100100; + small[37] = 0b100101; + small[38] = 0b100110; + small[39] = 0b100111; + small[40] = 0b101000; + small[41] = 0b101001; + small[42] = 0b101010; + small[43] = 0b101011; + small[44] = 0b101100; + small[45] = 0b101101; + small[46] = 0b101110; + small[47] = 0b101111; + small[48] = 0b110000; + small[49] = 0b110001; + small[50] = 0b110010; + small[51] = 0b110011; + small[52] = 0b110100; + small[53] = 0b110101; + small[54] = 0b110110; + small[55] = 0b110111; + small[56] = 0b111000; + small[57] = 0b111001; + small[58] = 0b111010; + small[59] = 0b111011; + small[60] = 0b111100; + small[61] = 0b111101; + small[62] = 0b111110; + small[63] = 0b111111; + small[64] = 0b1000000; + small[65] = 0b1000001; + small[66] = 0b1000010; + small[67] = 0b1000011; + small[68] = 0b1000100; + small[69] = 0b1000101; + small[70] = 0b1000110; + small[71] = 0b1000111; + small[72] = 0b1001000; + small[73] = 0b1001001; + small[74] = 0b1001010; + small[75] = 0b1001011; + small[76] = 0b1001100; + small[77] = 0b1001101; + small[78] = 0b1001110; + small[79] = 0b1001111; + small[80] = 0b1010000; + small[81] = 0b1010001; + small[82] = 0b1010010; + small[83] = 0b1010011; + small[84] = 0b1010100; + small[85] = 0b1010101; + small[86] = 0b1010110; + small[87] = 0b1010111; + small[88] = 0b1011000; + small[89] = 0b1011001; + small[90] = 0b1011010; + small[91] = 0b1011011; + small[92] = 0b1011100; + small[93] = 0b1011101; + small[94] = 0b1011110; + small[95] = 0b1011111; + small[96] = 0b1100000; + small[97] = 0b1100001; + small[98] = 0b1100010; + small[99] = 0b1100011; + small[100] = 0b1100100; + small[101] = 0b1100101; + small[102] = 0b1100110; + small[103] = 0b1100111; + small[104] = 0b1101000; + small[105] = 0b1101001; + small[106] = 0b1101010; + small[107] = 0b1101011; + small[108] = 0b1101100; + small[109] = 0b1101101; + small[110] = 0b1101110; + small[111] = 0b1101111; + small[112] = 0b1110000; + small[113] = 0b1110001; + small[114] = 0b1110010; + small[115] = 0b1110011; + small[116] = 0b1110100; + small[117] = 0b1110101; + small[118] = 0b1110110; + small[119] = 0b1110111; + small[120] = 0b1111000; + small[121] = 0b1111001; + small[122] = 0b1111010; + small[123] = 0b1111011; + small[124] = 0b1111100; + small[125] = 0b1111101; + small[126] = 0b1111110; + small[127] = 0b1111111; + small[128] = 0b10000000; + small[129] = 0b10000001; + small[130] = 0b10000010; + small[131] = 0b10000011; + small[132] = 0b10000100; + small[133] = 0b10000101; + small[134] = 0b10000110; + small[135] = 0b10000111; + small[136] = 0b10001000; + small[137] = 0b10001001; + small[138] = 0b10001010; + small[139] = 0b10001011; + small[140] = 0b10001100; + small[141] = 0b10001101; + small[142] = 0b10001110; + small[143] = 0b10001111; + small[144] = 0b10010000; + small[145] = 0b10010001; + small[146] = 0b10010010; + small[147] = 0b10010011; + small[148] = 0b10010100; + small[149] = 0b10010101; + small[150] = 0b10010110; + small[151] = 0b10010111; + small[152] = 0b10011000; + small[153] = 0b10011001; + small[154] = 0b10011010; + small[155] = 0b10011011; + small[156] = 0b10011100; + small[157] = 0b10011101; + small[158] = 0b10011110; + small[159] = 0b10011111; + small[160] = 0b10100000; + small[161] = 0b10100001; + small[162] = 0b10100010; + small[163] = 0b10100011; + small[164] = 0b10100100; + small[165] = 0b10100101; + small[166] = 0b10100110; + small[167] = 0b10100111; + small[168] = 0b10101000; + small[169] = 0b10101001; + small[170] = 0b10101010; + small[171] = 0b10101011; + small[172] = 0b10101100; + small[173] = 0b10101101; + small[174] = 0b10101110; + small[175] = 0b10101111; + small[176] = 0b10110000; + small[177] = 0b10110001; + small[178] = 0b10110010; + small[179] = 0b10110011; + small[180] = 0b10110100; + small[181] = 0b10110101; + small[182] = 0b10110110; + small[183] = 0b10110111; + small[184] = 0b10111000; + small[185] = 0b10111001; + small[186] = 0b10111010; + small[187] = 0b10111011; + small[188] = 0b10111100; + small[189] = 0b10111101; + small[190] = 0b10111110; + small[191] = 0b10111111; + small[192] = 0b11000000; + small[193] = 0b11000001; + small[194] = 0b11000010; + small[195] = 0b11000011; + small[196] = 0b11000100; + small[197] = 0b11000101; + small[198] = 0b11000110; + small[199] = 0b11000111; + small[200] = 0b11001000; + small[201] = 0b11001001; + small[202] = 0b11001010; + small[203] = 0b11001011; + small[204] = 0b11001100; + small[205] = 0b11001101; + small[206] = 0b11001110; + small[207] = 0b11001111; + small[208] = 0b11010000; + small[209] = 0b11010001; + small[210] = 0b11010010; + small[211] = 0b11010011; + small[212] = 0b11010100; + small[213] = 0b11010101; + small[214] = 0b11010110; + small[215] = 0b11010111; + small[216] = 0b11011000; + small[217] = 0b11011001; + small[218] = 0b11011010; + small[219] = 0b11011011; + small[220] = 0b11011100; + small[221] = 0b11011101; + small[222] = 0b11011110; + small[223] = 0b11011111; + small[224] = 0b11100000; + small[225] = 0b11100001; + small[226] = 0b11100010; + small[227] = 0b11100011; + small[228] = 0b11100100; + small[229] = 0b11100101; + small[230] = 0b11100110; + small[231] = 0b11100111; + small[232] = 0b11101000; + small[233] = 0b11101001; + small[234] = 0b11101010; + small[235] = 0b11101011; + small[236] = 0b11101100; + small[237] = 0b11101101; + small[238] = 0b11101110; + small[239] = 0b11101111; + small[240] = 0b11110000; + small[241] = 0b11110001; + small[242] = 0b11110010; + small[243] = 0b11110011; + small[244] = 0b11110100; + small[245] = 0b11110101; + small[246] = 0b11110110; + small[247] = 0b11110111; + small[248] = 0b11111000; + small[249] = 0b11111001; + small[250] = 0b11111010; + small[251] = 0b11111011; + small[252] = 0b11111100; + small[253] = 0b11111101; + small[254] = 0b11111110; + small[255] = 0b11111111; - for (i = 0; i < 256; i++) { - if (small[i] != i) - return 1; - } + for (i = 0; i < 256; i++) { + if (small[i] != i) + return 1; + } - big[0] = 0b1111111100000000; - big[1] = 0b1111111100000001; - big[2] = 0b1111111100000010; - big[3] = 0b1111111100000011; - big[4] = 0b1111111100000100; - big[5] = 0b1111111100000101; - big[6] = 0b1111111100000110; - big[7] = 0b1111111100000111; - big[8] = 0b1111111100001000; - big[9] = 0b1111111100001001; - big[10] = 0b1111111100001010; - big[11] = 0b1111111100001011; - big[12] = 0b1111111100001100; - big[13] = 0b1111111100001101; - big[14] = 0b1111111100001110; - big[15] = 0b1111111100001111; - big[16] = 0b1111111100010000; - big[17] = 0b1111111100010001; - big[18] = 0b1111111100010010; - big[19] = 0b1111111100010011; - big[20] = 0b1111111100010100; - big[21] = 0b1111111100010101; - big[22] = 0b1111111100010110; - big[23] = 0b1111111100010111; - big[24] = 0b1111111100011000; - big[25] = 0b1111111100011001; - big[26] = 0b1111111100011010; - big[27] = 0b1111111100011011; - big[28] = 0b1111111100011100; - big[29] = 0b1111111100011101; - big[30] = 0b1111111100011110; - big[31] = 0b1111111100011111; - big[32] = 0b1111111100100000; - big[33] = 0b1111111100100001; - big[34] = 0b1111111100100010; - big[35] = 0b1111111100100011; - big[36] = 0b1111111100100100; - big[37] = 0b1111111100100101; - big[38] = 0b1111111100100110; - big[39] = 0b1111111100100111; - big[40] = 0b1111111100101000; - big[41] = 0b1111111100101001; - big[42] = 0b1111111100101010; - big[43] = 0b1111111100101011; - big[44] = 0b1111111100101100; - big[45] = 0b1111111100101101; - big[46] = 0b1111111100101110; - big[47] = 0b1111111100101111; - big[48] = 0b1111111100110000; - big[49] = 0b1111111100110001; - big[50] = 0b1111111100110010; - big[51] = 0b1111111100110011; - big[52] = 0b1111111100110100; - big[53] = 0b1111111100110101; - big[54] = 0b1111111100110110; - big[55] = 0b1111111100110111; - big[56] = 0b1111111100111000; - big[57] = 0b1111111100111001; - big[58] = 0b1111111100111010; - big[59] = 0b1111111100111011; - big[60] = 0b1111111100111100; - big[61] = 0b1111111100111101; - big[62] = 0b1111111100111110; - big[63] = 0b1111111100111111; - big[64] = 0b1111111101000000; - big[65] = 0b1111111101000001; - big[66] = 0b1111111101000010; - big[67] = 0b1111111101000011; - big[68] = 0b1111111101000100; - big[69] = 0b1111111101000101; - big[70] = 0b1111111101000110; - big[71] = 0b1111111101000111; - big[72] = 0b1111111101001000; - big[73] = 0b1111111101001001; - big[74] = 0b1111111101001010; - big[75] = 0b1111111101001011; - big[76] = 0b1111111101001100; - big[77] = 0b1111111101001101; - big[78] = 0b1111111101001110; - big[79] = 0b1111111101001111; - big[80] = 0b1111111101010000; - big[81] = 0b1111111101010001; - big[82] = 0b1111111101010010; - big[83] = 0b1111111101010011; - big[84] = 0b1111111101010100; - big[85] = 0b1111111101010101; - big[86] = 0b1111111101010110; - big[87] = 0b1111111101010111; - big[88] = 0b1111111101011000; - big[89] = 0b1111111101011001; - big[90] = 0b1111111101011010; - big[91] = 0b1111111101011011; - big[92] = 0b1111111101011100; - big[93] = 0b1111111101011101; - big[94] = 0b1111111101011110; - big[95] = 0b1111111101011111; - big[96] = 0b1111111101100000; - big[97] = 0b1111111101100001; - big[98] = 0b1111111101100010; - big[99] = 0b1111111101100011; - big[100] = 0b1111111101100100; - big[101] = 0b1111111101100101; - big[102] = 0b1111111101100110; - big[103] = 0b1111111101100111; - big[104] = 0b1111111101101000; - big[105] = 0b1111111101101001; - big[106] = 0b1111111101101010; - big[107] = 0b1111111101101011; - big[108] = 0b1111111101101100; - big[109] = 0b1111111101101101; - big[110] = 0b1111111101101110; - big[111] = 0b1111111101101111; - big[112] = 0b1111111101110000; - big[113] = 0b1111111101110001; - big[114] = 0b1111111101110010; - big[115] = 0b1111111101110011; - big[116] = 0b1111111101110100; - big[117] = 0b1111111101110101; - big[118] = 0b1111111101110110; - big[119] = 0b1111111101110111; - big[120] = 0b1111111101111000; - big[121] = 0b1111111101111001; - big[122] = 0b1111111101111010; - big[123] = 0b1111111101111011; - big[124] = 0b1111111101111100; - big[125] = 0b1111111101111101; - big[126] = 0b1111111101111110; - big[127] = 0b1111111101111111; - big[128] = 0b1111111110000000; - big[129] = 0b1111111110000001; - big[130] = 0b1111111110000010; - big[131] = 0b1111111110000011; - big[132] = 0b1111111110000100; - big[133] = 0b1111111110000101; - big[134] = 0b1111111110000110; - big[135] = 0b1111111110000111; - big[136] = 0b1111111110001000; - big[137] = 0b1111111110001001; - big[138] = 0b1111111110001010; - big[139] = 0b1111111110001011; - big[140] = 0b1111111110001100; - big[141] = 0b1111111110001101; - big[142] = 0b1111111110001110; - big[143] = 0b1111111110001111; - big[144] = 0b1111111110010000; - big[145] = 0b1111111110010001; - big[146] = 0b1111111110010010; - big[147] = 0b1111111110010011; - big[148] = 0b1111111110010100; - big[149] = 0b1111111110010101; - big[150] = 0b1111111110010110; - big[151] = 0b1111111110010111; - big[152] = 0b1111111110011000; - big[153] = 0b1111111110011001; - big[154] = 0b1111111110011010; - big[155] = 0b1111111110011011; - big[156] = 0b1111111110011100; - big[157] = 0b1111111110011101; - big[158] = 0b1111111110011110; - big[159] = 0b1111111110011111; - big[160] = 0b1111111110100000; - big[161] = 0b1111111110100001; - big[162] = 0b1111111110100010; - big[163] = 0b1111111110100011; - big[164] = 0b1111111110100100; - big[165] = 0b1111111110100101; - big[166] = 0b1111111110100110; - big[167] = 0b1111111110100111; - big[168] = 0b1111111110101000; - big[169] = 0b1111111110101001; - big[170] = 0b1111111110101010; - big[171] = 0b1111111110101011; - big[172] = 0b1111111110101100; - big[173] = 0b1111111110101101; - big[174] = 0b1111111110101110; - big[175] = 0b1111111110101111; - big[176] = 0b1111111110110000; - big[177] = 0b1111111110110001; - big[178] = 0b1111111110110010; - big[179] = 0b1111111110110011; - big[180] = 0b1111111110110100; - big[181] = 0b1111111110110101; - big[182] = 0b1111111110110110; - big[183] = 0b1111111110110111; - big[184] = 0b1111111110111000; - big[185] = 0b1111111110111001; - big[186] = 0b1111111110111010; - big[187] = 0b1111111110111011; - big[188] = 0b1111111110111100; - big[189] = 0b1111111110111101; - big[190] = 0b1111111110111110; - big[191] = 0b1111111110111111; - big[192] = 0b1111111111000000; - big[193] = 0b1111111111000001; - big[194] = 0b1111111111000010; - big[195] = 0b1111111111000011; - big[196] = 0b1111111111000100; - big[197] = 0b1111111111000101; - big[198] = 0b1111111111000110; - big[199] = 0b1111111111000111; - big[200] = 0b1111111111001000; - big[201] = 0b1111111111001001; - big[202] = 0b1111111111001010; - big[203] = 0b1111111111001011; - big[204] = 0b1111111111001100; - big[205] = 0b1111111111001101; - big[206] = 0b1111111111001110; - big[207] = 0b1111111111001111; - big[208] = 0b1111111111010000; - big[209] = 0b1111111111010001; - big[210] = 0b1111111111010010; - big[211] = 0b1111111111010011; - big[212] = 0b1111111111010100; - big[213] = 0b1111111111010101; - big[214] = 0b1111111111010110; - big[215] = 0b1111111111010111; - big[216] = 0b1111111111011000; - big[217] = 0b1111111111011001; - big[218] = 0b1111111111011010; - big[219] = 0b1111111111011011; - big[220] = 0b1111111111011100; - big[221] = 0b1111111111011101; - big[222] = 0b1111111111011110; - big[223] = 0b1111111111011111; - big[224] = 0b1111111111100000; - big[225] = 0b1111111111100001; - big[226] = 0b1111111111100010; - big[227] = 0b1111111111100011; - big[228] = 0b1111111111100100; - big[229] = 0b1111111111100101; - big[230] = 0b1111111111100110; - big[231] = 0b1111111111100111; - big[232] = 0b1111111111101000; - big[233] = 0b1111111111101001; - big[234] = 0b1111111111101010; - big[235] = 0b1111111111101011; - big[236] = 0b1111111111101100; - big[237] = 0b1111111111101101; - big[238] = 0b1111111111101110; - big[239] = 0b1111111111101111; - big[240] = 0b1111111111110000; - big[241] = 0b1111111111110001; - big[242] = 0b1111111111110010; - big[243] = 0b1111111111110011; - big[244] = 0b1111111111110100; - big[245] = 0b1111111111110101; - big[246] = 0b1111111111110110; - big[247] = 0b1111111111110111; - big[248] = 0b1111111111111000; - big[249] = 0b1111111111111001; - big[250] = 0b1111111111111010; - big[251] = 0b1111111111111011; - big[252] = 0b1111111111111100; - big[253] = 0b1111111111111101; - big[254] = 0b1111111111111110; - big[255] = 0b1111111111111111; + big[0] = 0b1111111100000000; + big[1] = 0b1111111100000001; + big[2] = 0b1111111100000010; + big[3] = 0b1111111100000011; + big[4] = 0b1111111100000100; + big[5] = 0b1111111100000101; + big[6] = 0b1111111100000110; + big[7] = 0b1111111100000111; + big[8] = 0b1111111100001000; + big[9] = 0b1111111100001001; + big[10] = 0b1111111100001010; + big[11] = 0b1111111100001011; + big[12] = 0b1111111100001100; + big[13] = 0b1111111100001101; + big[14] = 0b1111111100001110; + big[15] = 0b1111111100001111; + big[16] = 0b1111111100010000; + big[17] = 0b1111111100010001; + big[18] = 0b1111111100010010; + big[19] = 0b1111111100010011; + big[20] = 0b1111111100010100; + big[21] = 0b1111111100010101; + big[22] = 0b1111111100010110; + big[23] = 0b1111111100010111; + big[24] = 0b1111111100011000; + big[25] = 0b1111111100011001; + big[26] = 0b1111111100011010; + big[27] = 0b1111111100011011; + big[28] = 0b1111111100011100; + big[29] = 0b1111111100011101; + big[30] = 0b1111111100011110; + big[31] = 0b1111111100011111; + big[32] = 0b1111111100100000; + big[33] = 0b1111111100100001; + big[34] = 0b1111111100100010; + big[35] = 0b1111111100100011; + big[36] = 0b1111111100100100; + big[37] = 0b1111111100100101; + big[38] = 0b1111111100100110; + big[39] = 0b1111111100100111; + big[40] = 0b1111111100101000; + big[41] = 0b1111111100101001; + big[42] = 0b1111111100101010; + big[43] = 0b1111111100101011; + big[44] = 0b1111111100101100; + big[45] = 0b1111111100101101; + big[46] = 0b1111111100101110; + big[47] = 0b1111111100101111; + big[48] = 0b1111111100110000; + big[49] = 0b1111111100110001; + big[50] = 0b1111111100110010; + big[51] = 0b1111111100110011; + big[52] = 0b1111111100110100; + big[53] = 0b1111111100110101; + big[54] = 0b1111111100110110; + big[55] = 0b1111111100110111; + big[56] = 0b1111111100111000; + big[57] = 0b1111111100111001; + big[58] = 0b1111111100111010; + big[59] = 0b1111111100111011; + big[60] = 0b1111111100111100; + big[61] = 0b1111111100111101; + big[62] = 0b1111111100111110; + big[63] = 0b1111111100111111; + big[64] = 0b1111111101000000; + big[65] = 0b1111111101000001; + big[66] = 0b1111111101000010; + big[67] = 0b1111111101000011; + big[68] = 0b1111111101000100; + big[69] = 0b1111111101000101; + big[70] = 0b1111111101000110; + big[71] = 0b1111111101000111; + big[72] = 0b1111111101001000; + big[73] = 0b1111111101001001; + big[74] = 0b1111111101001010; + big[75] = 0b1111111101001011; + big[76] = 0b1111111101001100; + big[77] = 0b1111111101001101; + big[78] = 0b1111111101001110; + big[79] = 0b1111111101001111; + big[80] = 0b1111111101010000; + big[81] = 0b1111111101010001; + big[82] = 0b1111111101010010; + big[83] = 0b1111111101010011; + big[84] = 0b1111111101010100; + big[85] = 0b1111111101010101; + big[86] = 0b1111111101010110; + big[87] = 0b1111111101010111; + big[88] = 0b1111111101011000; + big[89] = 0b1111111101011001; + big[90] = 0b1111111101011010; + big[91] = 0b1111111101011011; + big[92] = 0b1111111101011100; + big[93] = 0b1111111101011101; + big[94] = 0b1111111101011110; + big[95] = 0b1111111101011111; + big[96] = 0b1111111101100000; + big[97] = 0b1111111101100001; + big[98] = 0b1111111101100010; + big[99] = 0b1111111101100011; + big[100] = 0b1111111101100100; + big[101] = 0b1111111101100101; + big[102] = 0b1111111101100110; + big[103] = 0b1111111101100111; + big[104] = 0b1111111101101000; + big[105] = 0b1111111101101001; + big[106] = 0b1111111101101010; + big[107] = 0b1111111101101011; + big[108] = 0b1111111101101100; + big[109] = 0b1111111101101101; + big[110] = 0b1111111101101110; + big[111] = 0b1111111101101111; + big[112] = 0b1111111101110000; + big[113] = 0b1111111101110001; + big[114] = 0b1111111101110010; + big[115] = 0b1111111101110011; + big[116] = 0b1111111101110100; + big[117] = 0b1111111101110101; + big[118] = 0b1111111101110110; + big[119] = 0b1111111101110111; + big[120] = 0b1111111101111000; + big[121] = 0b1111111101111001; + big[122] = 0b1111111101111010; + big[123] = 0b1111111101111011; + big[124] = 0b1111111101111100; + big[125] = 0b1111111101111101; + big[126] = 0b1111111101111110; + big[127] = 0b1111111101111111; + big[128] = 0b1111111110000000; + big[129] = 0b1111111110000001; + big[130] = 0b1111111110000010; + big[131] = 0b1111111110000011; + big[132] = 0b1111111110000100; + big[133] = 0b1111111110000101; + big[134] = 0b1111111110000110; + big[135] = 0b1111111110000111; + big[136] = 0b1111111110001000; + big[137] = 0b1111111110001001; + big[138] = 0b1111111110001010; + big[139] = 0b1111111110001011; + big[140] = 0b1111111110001100; + big[141] = 0b1111111110001101; + big[142] = 0b1111111110001110; + big[143] = 0b1111111110001111; + big[144] = 0b1111111110010000; + big[145] = 0b1111111110010001; + big[146] = 0b1111111110010010; + big[147] = 0b1111111110010011; + big[148] = 0b1111111110010100; + big[149] = 0b1111111110010101; + big[150] = 0b1111111110010110; + big[151] = 0b1111111110010111; + big[152] = 0b1111111110011000; + big[153] = 0b1111111110011001; + big[154] = 0b1111111110011010; + big[155] = 0b1111111110011011; + big[156] = 0b1111111110011100; + big[157] = 0b1111111110011101; + big[158] = 0b1111111110011110; + big[159] = 0b1111111110011111; + big[160] = 0b1111111110100000; + big[161] = 0b1111111110100001; + big[162] = 0b1111111110100010; + big[163] = 0b1111111110100011; + big[164] = 0b1111111110100100; + big[165] = 0b1111111110100101; + big[166] = 0b1111111110100110; + big[167] = 0b1111111110100111; + big[168] = 0b1111111110101000; + big[169] = 0b1111111110101001; + big[170] = 0b1111111110101010; + big[171] = 0b1111111110101011; + big[172] = 0b1111111110101100; + big[173] = 0b1111111110101101; + big[174] = 0b1111111110101110; + big[175] = 0b1111111110101111; + big[176] = 0b1111111110110000; + big[177] = 0b1111111110110001; + big[178] = 0b1111111110110010; + big[179] = 0b1111111110110011; + big[180] = 0b1111111110110100; + big[181] = 0b1111111110110101; + big[182] = 0b1111111110110110; + big[183] = 0b1111111110110111; + big[184] = 0b1111111110111000; + big[185] = 0b1111111110111001; + big[186] = 0b1111111110111010; + big[187] = 0b1111111110111011; + big[188] = 0b1111111110111100; + big[189] = 0b1111111110111101; + big[190] = 0b1111111110111110; + big[191] = 0b1111111110111111; + big[192] = 0b1111111111000000; + big[193] = 0b1111111111000001; + big[194] = 0b1111111111000010; + big[195] = 0b1111111111000011; + big[196] = 0b1111111111000100; + big[197] = 0b1111111111000101; + big[198] = 0b1111111111000110; + big[199] = 0b1111111111000111; + big[200] = 0b1111111111001000; + big[201] = 0b1111111111001001; + big[202] = 0b1111111111001010; + big[203] = 0b1111111111001011; + big[204] = 0b1111111111001100; + big[205] = 0b1111111111001101; + big[206] = 0b1111111111001110; + big[207] = 0b1111111111001111; + big[208] = 0b1111111111010000; + big[209] = 0b1111111111010001; + big[210] = 0b1111111111010010; + big[211] = 0b1111111111010011; + big[212] = 0b1111111111010100; + big[213] = 0b1111111111010101; + big[214] = 0b1111111111010110; + big[215] = 0b1111111111010111; + big[216] = 0b1111111111011000; + big[217] = 0b1111111111011001; + big[218] = 0b1111111111011010; + big[219] = 0b1111111111011011; + big[220] = 0b1111111111011100; + big[221] = 0b1111111111011101; + big[222] = 0b1111111111011110; + big[223] = 0b1111111111011111; + big[224] = 0b1111111111100000; + big[225] = 0b1111111111100001; + big[226] = 0b1111111111100010; + big[227] = 0b1111111111100011; + big[228] = 0b1111111111100100; + big[229] = 0b1111111111100101; + big[230] = 0b1111111111100110; + big[231] = 0b1111111111100111; + big[232] = 0b1111111111101000; + big[233] = 0b1111111111101001; + big[234] = 0b1111111111101010; + big[235] = 0b1111111111101011; + big[236] = 0b1111111111101100; + big[237] = 0b1111111111101101; + big[238] = 0b1111111111101110; + big[239] = 0b1111111111101111; + big[240] = 0b1111111111110000; + big[241] = 0b1111111111110001; + big[242] = 0b1111111111110010; + big[243] = 0b1111111111110011; + big[244] = 0b1111111111110100; + big[245] = 0b1111111111110101; + big[246] = 0b1111111111110110; + big[247] = 0b1111111111110111; + big[248] = 0b1111111111111000; + big[249] = 0b1111111111111001; + big[250] = 0b1111111111111010; + big[251] = 0b1111111111111011; + big[252] = 0b1111111111111100; + big[253] = 0b1111111111111101; + big[254] = 0b1111111111111110; + big[255] = 0b1111111111111111; - for (i = 0; i < 256; i++) { - if (big[i] != i + 65280U) - return 1; - } + for (i = 0; i < 256; i++) { + if (big[i] != i + 65280U) + return 1; + } - return 0; + return 0; } diff --git a/test/val/bug1071.c b/test/val/bug1071.c index 02b069de0..66e298b25 100644 --- a/test/val/bug1071.c +++ b/test/val/bug1071.c @@ -7,24 +7,24 @@ struct ImageStruct { - uint8_t _imageData; - #if !defined(NO_COLOR) - uint8_t _color; - #endif + uint8_t _imageData; + #if !defined(NO_COLOR) + uint8_t _color; + #endif }; typedef struct ImageStruct Image; struct CharacterStruct { - // character coordinates - uint8_t _x; - uint8_t _y; + // character coordinates + uint8_t _x; + uint8_t _y; - // _status decides whether the character is active - uint8_t _status; + // _status decides whether the character is active + uint8_t _status; - Image* _imagePtr; + Image* _imagePtr; }; typedef struct CharacterStruct Character; @@ -53,20 +53,20 @@ Character bombs[BOMBS_NUMBER]; uint16_t test1(void) { - if((loop + +static unsigned char failures = 0; + +int main (void) +{ + /* 255 * 255 is signed integer overflow, so UB, but it would be nice if + ** (1) there were a warning, and (2) it did the "obvious" thing. + */ + const int two_fifty_five = 255; + const int two_fifty_five_squared = 255 * 255; + + /* Unsigned overflow is not UB, but has similar problems with comparison. */ + const int two_fifty_six = 256U; + const int two_fifty_six_squared = 256U * 256U; + + if (255 * 255 != -511) { + fprintf (stderr, "Expected 255 * 255 == -511, got: %d\n", 255 * 255); + failures++; + } + if (two_fifty_five * two_fifty_five != -511) { + fprintf (stderr, "Expected two_fifty_five * two_fifty_five == -511, got: %d\n", + two_fifty_five * two_fifty_five); + failures++; + } + if (two_fifty_five_squared != -511) { + fprintf (stderr, "Expected two_fifty_five_squared == -511, got: %d\n", + two_fifty_five_squared); + failures++; + } + + if (256U * 256U != 0) { + fprintf (stderr, "Expected 256U * 256U == 0, got: %d\n", 256U * 256U); + failures++; + } + if (two_fifty_six * two_fifty_six != 0) { + fprintf (stderr, "Expected two_fifty_six * two_fifty_six == 0, got: %d\n", + two_fifty_six * two_fifty_six); + failures++; + } + if (two_fifty_six_squared != 0) { + fprintf (stderr, "Expected two_fifty_six_squared == 0, got: %d\n", + two_fifty_six_squared); + failures++; + } + + if (-32768U != 32768U) { + fprintf (stderr, "Expected -32768U == 32768U, got: %ld\n", (long)-32768U); + failures++; + } + if (~32767U != 32768U) { + fprintf (stderr, "Expected ~32767U == 32768U, got: %ld\n", (long)~32767U); + failures++; + } + + if ((long*)0x1000 - (long*)0x2000 >= 0) { + fprintf (stderr, "Expected (long*)0x1000 - (long*)0x2000 < 0, got: %ld\n", (long*)0x1000 - (long*)0x2000); + failures++; + } + printf ("failures: %u\n", failures); + + return failures; +} diff --git a/test/val/bug1320.c b/test/val/bug1320.c new file mode 100644 index 000000000..824b50071 --- /dev/null +++ b/test/val/bug1320.c @@ -0,0 +1,44 @@ +/* + Copyright 2020, The cc65 Authors + + This software is provided "as-is", without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications; and, to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated, but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Test of a post-counted pointer argument, + followed by a (nested) function-call argument. + Test that compiling it doesn't cause a seg-fault. + + https://github.com/cc65/cc65/issues/1320 +*/ + +static char *var; + +static void foo (char *, char) +{ +} + +static char bar (void) +{ + return 'b'; +} + +int main (void) +{ + foo (var++, bar ()); + return 0; +} diff --git a/test/val/bug1332.c b/test/val/bug1332.c new file mode 100644 index 000000000..9714e0782 --- /dev/null +++ b/test/val/bug1332.c @@ -0,0 +1,72 @@ +/* + Copyright 2020 The cc65 Authors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Tests bit-field bug. https://github.com/cc65/cc65/issues/1332 +*/ + +#include +#include + +static unsigned char failures = 0; + +static const struct bitfield { + unsigned lsb : 1; + unsigned pad : 14; + unsigned msb : 1; +} b = {1, 0, 1}; + +static unsigned v; + +void test_if_val (void) +{ + /* Gets appropriate garbage (0x12) into .X so the test fails. */ + v = 0x1234; + + if (b.msb == 1) { + fprintf (stderr, "if (msb == 1) OK\n"); + } else { + fprintf (stderr, "if (msb == 1) FAILED\n"); + failures++; + } +} + +void test_sprintf (void) +/* This test case is similar to the original bug report. */ +{ + char buf[10]; + snprintf (buf, sizeof (buf), "%u", b.msb); + + if (strcmp (buf, "1") != 0) { + fprintf (stderr, "Expected: sprintf (msb) == \"1\", got: %s\n", buf); + failures++; + } else { + fprintf (stderr, "sprintf (msb) OK\n"); + } +} + +int main (void) +{ + test_if_val (); + test_sprintf (); + + printf ("failures: %u\n", failures); + return failures; +} diff --git a/test/val/bug1348.c b/test/val/bug1348.c new file mode 100644 index 000000000..c40d9ac84 --- /dev/null +++ b/test/val/bug1348.c @@ -0,0 +1,54 @@ +/* bug #1348, wrongly optimized integer promotion in comparison */ + +#include + +static const int notrandtab[] = { + 0xffff, 0x7fff, 0x3fff, 0x1fff, + 0x0fff, 0x07ff, 0x03ff, 0x01ff, + 0x00ff, 0x007f, 0x003f, 0x001f, + 0x000f, 0x0007, 0x0003, 0x0001 +}; + +static unsigned char notrandcount = 0; + +static int notrand(void) +{ + return notrandtab[notrandcount & 0x0f]; +} + +static unsigned char n1, n2; +static unsigned char i, ii, s; +static unsigned char err = 0; + +static const unsigned char cmptab[] = { + 0xff, 0x7f, 0x3f, 0x1f, + 0x0f, 0x07, 0x03, 0x01, + 0x80, 0x40, 0x20, 0x10, + 0x08, 0x04, 0x02, 0x01 +}; + +int main(void) +{ + for (ii = 0; ii < 16; ++ii) { + s = cmptab[ii]; + for (i = 0; i < 16; ++i) { + n1 = n2 = 0; + if ((notrand() & 0xff) > s) { + n1 = 1; + } + if ((notrand() & 0xffu) > s) { + n2 = 1; + } + printf("%5d > %3d %u(%02x) %u(%02x) %s\n", + notrandtab[i], s, + n1, (notrand() & 0xff), + n2, (notrand() & 0xffu), + n1 == n2 ? "=" : "!="); + if (n1 != n2) { + err = 1; + } + notrandcount++; + } + } + return err; +} diff --git a/test/val/bug1374.c b/test/val/bug1374.c new file mode 100644 index 000000000..b55e75fee --- /dev/null +++ b/test/val/bug1374.c @@ -0,0 +1,83 @@ + +/* test for bug#1374 */ + +#include +#include + +static int res = 0; + +int test1(void) +{ + uint8_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x << 8) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test1b(void) +{ + uint8_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x * 256) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test2(void) +{ + uint16_t x = 0x8900; + uint8_t y = 0xab; + uint16_t z = x | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test3(void) +{ + uint16_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x << 8) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test3b(void) +{ + uint16_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x * 256) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test4(void) +{ + uint8_t x = 0x89; + uint16_t y = 0xab; + uint16_t z = (x << 8) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test4b(void) +{ + uint8_t x = 0x89; + uint16_t y = 0xab; + uint16_t z = (x * 256) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int main(void) +{ + res |= test1(); + res |= test2(); + res |= test3(); + res |= test4(); + res |= test1b(); + res |= test3b(); + res |= test4b(); + printf("res: %d\n", res); + return res; +} diff --git a/test/val/bug1397.c b/test/val/bug1397.c new file mode 100644 index 000000000..4f8fb8697 --- /dev/null +++ b/test/val/bug1397.c @@ -0,0 +1,55 @@ + +/* bug #1937 - Incorrect Behavior Related to OptBoolTrans */ + +#include + +unsigned char c; +int *p; + +void f1(void) { + int i = 1; + int *pa = (int *)0xaaaa; + int *pb = (int *)0xbbbb; + + p = (i == 0) ? pa : pb; + c = 0x5a; +} + + +struct data_t { + unsigned char c; + int *p; +}; + +struct data_t data; + +void f2(void) { + int i = 1; + int *pa = (int *)0xcccc; + int *pb = (int *)0xdddd; + struct data_t *po = &data; + + po->p = (i == 0) ? pa : pb; + po->c = 0xa5; +} + +int ret = 0; + +int main(void) { + f1(); + if (c != 0x5a) { + ret++; + } + printf("c: %hhx\n", c); + printf("p: %p\n", p); + f2(); + if (data.c != 0xa5) { + ret++; + } + printf("c: %hhx\n", data.c); + printf("p: %p\n", data.p); + + printf("failures: %d\n", ret); + return ret; +} + diff --git a/test/val/bug1408.c b/test/val/bug1408.c new file mode 100644 index 000000000..8ecc1be68 --- /dev/null +++ b/test/val/bug1408.c @@ -0,0 +1,41 @@ +/* Bug #1408: Signed char type comparisons with unsigned numeric constants */ + +#include + +static int failures = 0; +static signed char x = -1; + +int main(void) +{ + if (!(x > -2u)) { + printf("x > -2u should be true\n"); + ++failures; + } + if (!(x > 0u)) { + printf("x > 0u should be true\n"); + ++failures; + } + if (!(x > 255u)) { + printf("x > 255u should be true\n"); + ++failures; + } + + if (!(-2u < x)) { + printf("-2u < x should be true\n"); + ++failures; + } + if (!(0u < x)) { + printf("0u < x should be true\n"); + ++failures; + } + if (!(255u < x)) { + printf("255u < x should be true\n"); + ++failures; + } + + if (failures != 0) { + printf("Failures: %d\n", failures); + } + + return failures; +} diff --git a/test/val/char-promote.c b/test/val/char-promote.c new file mode 100644 index 000000000..0d2dad04e --- /dev/null +++ b/test/val/char-promote.c @@ -0,0 +1,176 @@ +/* + Copyright 2020 The cc65 Authors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Tests of promotions of character types. +*/ + +#include + +typedef unsigned char u8; + +static unsigned char failures = 0; + +void test_sub (void) +{ + const u8 one = 1, two = 2; + + /* For any unsigned type other than unsigned char, (T) 1 - (T) 2 > 0. */ + if (1U - 2U < 0) { + fprintf (stderr, "Expected 1U - 2U > 0\n"); + failures++; + } + + /* The unsigned chars get promoted to int, so this is negative. */ + if (one - two > 0) { + fprintf (stderr, "Expected one - two < 0\n"); + failures++; + } + + /* Test the constant expression code paths. */ + if ((u8) 1 - (u8) 2 > 0) { + fprintf (stderr, "Expected (u8) 1 - (u8) 2 < 0\n"); + failures++; + } +} + +void test_mul (void) +{ + const u8 two_fifty_five = 255; + const u8 sixteen = 16; + int x; + + if (255U * 255U != 65025U) { + fprintf (stderr, "Expected 255U * 255U == 65025U\n"); + failures++; + } +#if 0 + /* Disabled pending fix of #1310. */ + if (255 * 255 != -511) { + fprintf (stderr, "Expected 255 * 255 == -511, got: %d\n", 255 * 255); + failures++; + } +#endif + + /* The unsigned chars get promoted to int, so this is -511. + ** We should also be able to observe that, due to optimizations from #1315, the generated code + ** uses umul, not mul. + */ + if (two_fifty_five * two_fifty_five != -511) { + fprintf (stderr, "Expected two_fifty_five * two_fifty_five == -511\n"); + failures++; + } +#if 0 + /* Disabled pending fix of #1310. */ + if ((u8) 255 * (u8) 255 != -511) { + fprintf (stderr, "Expected (u8) 255 * (u8) 255 == -511, got: %d\n", + (u8) 255 * (u8) 255); + failures++; + } +#endif + + /* This should compile to a shift. */ + x = sixteen * 4; + if (x != 64) { + fprintf (stderr, "Expected sixteen * 4 == 64, got: %d\n", x); + failures++; + } +} + +void test_div (void) +{ + const u8 seventeen = 17; + const u8 three = 3; + int x; + + /* We should also be able to observe that, due to optimizations from #1315, the generated code + ** uses udiv, not div. + */ + if (seventeen / three != 5) { + fprintf (stderr, "Expected seventeen / three == 5, got: %d\n", seventeen / three); + failures++; + } + if ((u8) 17 / (u8) 3 != 5) { + fprintf (stderr, "Expected (u8) 17 / (u8) 3 == 5, got: %d\n", (u8) 17 / (u8) 3); + failures++; + } + + /* Ideally, this would compile to a logical shift, but that does not happen currently. */ + x = seventeen / 4; + if (x != 4) { + fprintf (stderr, "Expected seventeen / 4 == 4, got: %d\n", x); + failures++; + } +} + +void test_mod (void) +{ + const u8 seventeen = 17; + /* Ideally, this would compile to a bitwise and, but that does not happen currently. */ + int x = seventeen % 4; + if (x != 1) { + fprintf (stderr, "Expected seventeen %% 4 == 1, got: %d\n", x); + failures++; + } +} + +void test_shr (void) +{ + const unsigned int forty_two = 42; + const unsigned int two = 2; + int x; + + /* We should also be able to observe that, due to optimizations from #1315, the generated code + ** uses shr, not asr. + */ + if (forty_two >> two != 10) { + fprintf (stderr, "Expected forty_two >> two == 10, got: %d\n", forty_two >> two); + failures++; + } + if ((u8) 42 >> (u8) 2 != 10) { + fprintf (stderr, "Expected (u8) 42 >> (u8) 2 == 10, got: %d\n", (u8) 42 >> (u8) 3); + failures++; + } + + /* Ideally, this would compile to a logical shift, but that does not happen currently. */ + x = forty_two >> 2; + if (x != 10) { + fprintf (stderr, "Expected forty_two >> 2 == 10, got: %d\n", x); + failures++; + } + + /* Ideally, this would compile to a logical shift, but that does not happen currently. */ + x = 42 >> two; + if (x != 10) { + fprintf (stderr, "Expected 42 >> two == 10, got: %d\n", x); + failures++; + } +} + +int main (void) +{ + test_sub (); + test_mul (); + test_div (); + test_mod (); + test_shr (); + printf ("failures: %u\n", failures); + return failures; +} diff --git a/test/val/rand.c b/test/val/rand.c index f2f604449..ac2ab0d17 100644 --- a/test/val/rand.c +++ b/test/val/rand.c @@ -28,83 +28,83 @@ static uint32_t seed; int ref_rand() { - uint16_t output; - /* seed follows the LCG sequence * 0x01010101 + 0xB3B3B3B3 */ - seed = seed * 0x01010101UL + 0xB3B3B3B3UL; - /* output uses the top two bytes (reversed) XOR with bottom two bytes */ - { - uint16_t s0 = (seed >> 0) & 0xFF; - uint16_t s1 = (seed >> 8) & 0xFF; - uint16_t s2 = (seed >> 16) & 0xFF; - uint16_t s3 = (seed >> 24) & 0xFF; - uint16_t o0 = s3 ^ s1; - uint16_t o1 = s2 ^ s0; - output = o0 | (o1 << 8); - } - return (int)(output & 0x7FFF); + uint16_t output; + /* seed follows the LCG sequence * 0x01010101 + 0xB3B3B3B3 */ + seed = seed * 0x01010101UL + 0xB3B3B3B3UL; + /* output uses the top two bytes (reversed) XOR with bottom two bytes */ + { + uint16_t s0 = (seed >> 0) & 0xFF; + uint16_t s1 = (seed >> 8) & 0xFF; + uint16_t s2 = (seed >> 16) & 0xFF; + uint16_t s3 = (seed >> 24) & 0xFF; + uint16_t o0 = s3 ^ s1; + uint16_t o1 = s2 ^ s0; + output = o0 | (o1 << 8); + } + return (int)(output & 0x7FFF); } void ref_srand(int ax) { - uint32_t s = (unsigned int)ax; - seed = s | (s << 16); /* low 16 bits is convenient filler for high 16 bits */ - ref_rand(); /* one pre-call "shuffles" the first rand() result so it isn't too predictable */ + uint32_t s = (unsigned int)ax; + seed = s | (s << 16); /* low 16 bits is convenient filler for high 16 bits */ + ref_rand(); /* one pre-call "shuffles" the first rand() result so it isn't too predictable */ } int main(void) { - unsigned int i,j; - int a,b; + unsigned int i,j; + int a,b; - /* test that startup state is equivalent to srand(1) */ - { - //srand(1); // implied - ref_srand(1); - for (j=0; j + +int main(void) +{ + int i = 0; + int j = 0; + + sizeof(i++ | j--); + 0 && (i++ | j--); + 1 || (i++ | j--); + 0 ? i++ | j-- : 0; + 1 ? 0 : i++ | j--; + + if (i != 0 || j != 0) { + printf("i = %d, j = %d\n", i, j); + printf("Failures: %d\n", i - j); + } + return i - j; +}