mirror of
https://github.com/cc65/cc65.git
synced 2024-12-23 19:29:37 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
ba4310f589
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -23,7 +23,7 @@ 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;
|
||||
HGR: load = MAIN, type = rw, start = $2000;
|
||||
CODE: load = MAIN, type = ro start = $4000;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
|
@ -23,7 +23,7 @@ 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;
|
||||
HGR: load = MAIN, type = rw, start = $2000;
|
||||
CODE: load = MAIN, type = ro start = $4000;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
|
@ -11,6 +11,7 @@ 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 {
|
||||
@ -37,10 +38,10 @@ MEMORY {
|
||||
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;
|
||||
|
@ -6,6 +6,7 @@ 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;
|
||||
__OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
|
||||
__STARTADDRESS__: type = export, value = %S;
|
||||
}
|
||||
@ -37,10 +38,10 @@ MEMORY {
|
||||
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;
|
||||
|
@ -7,6 +7,7 @@ SYMBOLS {
|
||||
__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
|
||||
}
|
||||
@ -26,10 +27,10 @@ MEMORY {
|
||||
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;
|
||||
@ -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;
|
||||
|
@ -6,6 +6,7 @@ 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 {
|
||||
@ -35,10 +36,10 @@ MEMORY {
|
||||
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;
|
||||
|
@ -22,8 +22,10 @@ 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;
|
||||
INIT: load = MAIN, type = bss, optional = yes;
|
||||
BSS: load = MAIN, type = bss, define = yes;
|
||||
}
|
||||
FEATURES {
|
||||
|
@ -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;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = MAIN, type = ro;
|
||||
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;
|
||||
INIT: load = MAIN, type = rw, optional = yes;
|
||||
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;
|
||||
BANKRAM01: load = BRAM01, type = rw, optional = yes, define = yes;
|
||||
BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes;
|
||||
BANKRAM02: load = BRAM02, type = rw, define = yes, optional = yes;
|
||||
BANKRAM02: load = BRAM02, type = rw, optional = yes, define = yes;
|
||||
BRAM03ADDR: load = BRAM03ADDR, type = ro, optional = yes;
|
||||
BANKRAM03: load = BRAM03, type = rw, define = yes, optional = yes;
|
||||
BANKRAM03: load = BRAM03, type = rw, optional = yes, define = yes;
|
||||
BRAM04ADDR: load = BRAM04ADDR, type = ro, optional = yes;
|
||||
BANKRAM04: load = BRAM04, type = rw, define = yes, optional = yes;
|
||||
BANKRAM04: load = BRAM04, type = rw, optional = yes, define = yes;
|
||||
BRAM05ADDR: load = BRAM05ADDR, type = ro, optional = yes;
|
||||
BANKRAM05: load = BRAM05, type = rw, define = yes, optional = yes;
|
||||
BANKRAM05: load = BRAM05, type = rw, optional = yes, define = yes;
|
||||
BRAM06ADDR: load = BRAM06ADDR, type = ro, optional = yes;
|
||||
BANKRAM06: load = BRAM06, type = rw, define = yes, optional = yes;
|
||||
BANKRAM06: load = BRAM06, type = rw, optional = yes, define = yes;
|
||||
BRAM07ADDR: load = BRAM07ADDR, type = ro, optional = yes;
|
||||
BANKRAM07: load = BRAM07, type = rw, define = yes, optional = yes;
|
||||
BANKRAM07: load = BRAM07, type = rw, optional = yes, define = yes;
|
||||
BRAM08ADDR: load = BRAM08ADDR, type = ro, optional = yes;
|
||||
BANKRAM08: load = BRAM08, type = rw, define = yes, optional = yes;
|
||||
BANKRAM08: load = BRAM08, type = rw, optional = yes, define = yes;
|
||||
BRAM09ADDR: load = BRAM09ADDR, type = ro, optional = yes;
|
||||
BANKRAM09: load = BRAM09, type = rw, define = yes, optional = yes;
|
||||
BANKRAM09: load = BRAM09, type = rw, optional = yes, define = yes;
|
||||
BRAM0AADDR: load = BRAM0AADDR, type = ro, optional = yes;
|
||||
BANKRAM0A: load = BRAM0A, type = rw, define = yes, optional = yes;
|
||||
BANKRAM0A: load = BRAM0A, type = rw, optional = yes, define = yes;
|
||||
BRAM0BADDR: load = BRAM0BADDR, type = ro, optional = yes;
|
||||
BANKRAM0B: load = BRAM0B, type = rw, define = yes, optional = yes;
|
||||
BANKRAM0B: load = BRAM0B, type = rw, optional = yes, define = yes;
|
||||
BRAM0CADDR: load = BRAM0CADDR, type = ro, optional = yes;
|
||||
BANKRAM0C: load = BRAM0C, type = rw, define = yes, optional = yes;
|
||||
BANKRAM0C: load = BRAM0C, type = rw, optional = yes, define = yes;
|
||||
BRAM0DADDR: load = BRAM0DADDR, type = ro, optional = yes;
|
||||
BANKRAM0D: load = BRAM0D, type = rw, define = yes, optional = yes;
|
||||
BANKRAM0D: load = BRAM0D, type = rw, optional = yes, define = yes;
|
||||
BRAM0EADDR: load = BRAM0EADDR, type = ro, optional = yes;
|
||||
BANKRAM0E: load = BRAM0E, type = rw, define = yes, optional = yes;
|
||||
BANKRAM0E: load = BRAM0E, type = rw, optional = yes, define = yes;
|
||||
BRAM0FADDR: load = BRAM0FADDR, type = ro, optional = yes;
|
||||
BANKRAM0F: load = BRAM0F, type = rw, define = yes, optional = yes;
|
||||
BANKRAM0F: load = BRAM0F, type = rw, optional = yes, define = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
|
@ -19,12 +19,12 @@ SEGMENTS {
|
||||
EXTZP: load = ZP, type = zp, optional = yes;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = MAIN, type = ro;
|
||||
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;
|
||||
INIT: load = MAIN, type = rw, optional = yes;
|
||||
ONCE: load = MAIN, type = ro, define = yes;
|
||||
BSS: load = BSS, type = bss, define = yes;
|
||||
}
|
||||
|
@ -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__;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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__;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -332,6 +332,7 @@ See the <url url="funcref.html" name="function reference"> for declaration and u
|
||||
<item>_scroll
|
||||
<item>_setcolor
|
||||
<item>_setcolor_low
|
||||
<item>waitvsync
|
||||
</itemize>
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ information.
|
||||
|
||||
<sect>Binary format<p>
|
||||
|
||||
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 <tt/atari5200.h/ header file.
|
||||
|
||||
This also includes access to operating system locations (e.g. hardware shadow registers) by a structure called
|
||||
"<tt/OS/".
|
||||
The names are the usual ones you can find in system reference manuals. Example:
|
||||
|
||||
<tscreen><verb>
|
||||
...
|
||||
OS.sdmctl = 0x00; // screen off
|
||||
OS.color4 = 14; // white frame
|
||||
tics = OS.rtclok[1] // get ticks
|
||||
...
|
||||
</verb></tscreen>
|
||||
|
||||
<sect1>Atari 5200 specific functions<p>
|
||||
|
||||
<itemize>
|
||||
<item>TBD.
|
||||
<item>waitvsync
|
||||
</itemize>
|
||||
|
||||
|
||||
@ -208,10 +219,58 @@ you cannot use any of the following functions (and a few others):
|
||||
|
||||
<sect>Other hints<p>
|
||||
|
||||
<sect1>CAR format<p>
|
||||
|
||||
AtariROMMaker (<url url="https://www.wudsn.com/index.php/productions-atari800/tools/atarirommaker"> )
|
||||
can be used to create a <tt/.CAR/ file from the binary ROM image cc65 generates.
|
||||
This might be more convenient when working with emulators.
|
||||
|
||||
<sect1>Changing the splash screen<p>
|
||||
|
||||
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".
|
||||
|
||||
<sect2>Changing the game name<p>
|
||||
|
||||
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 "<tt/CARTNAME/" segment.
|
||||
|
||||
For reference, here's the default version used by the cc65 libary:
|
||||
<tscreen><verb>
|
||||
.export __CART_NAME__: absolute = 1
|
||||
.macpack atari
|
||||
.segment "CARTNAME"
|
||||
scrcode " cc"
|
||||
.byte '6' + 32, '5' + 32 ; use playfield 1
|
||||
scrcode " compiled"
|
||||
</verb></tscreen>
|
||||
|
||||
'<tt/__CART_NAME__/' needs to be defined in order that the linker is
|
||||
satisfied and doesn't try to include the version of the runtime library.
|
||||
|
||||
20 bytes are available in the <tt/CARTNAME/ segment (one line) for the
|
||||
game/program name.
|
||||
|
||||
<sect2>Changing the copyright year / changing the cartridge type<p>
|
||||
|
||||
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
|
||||
|
||||
<tscreen><verb>
|
||||
.export __CART_YEAR__: absolute = 1
|
||||
.segment "CARTYEAR"
|
||||
.byte '9' + 32,'8' + 32 ; "98", using playfield 1
|
||||
</verb></tscreen>
|
||||
|
||||
If the second byte of the year in the <tt/CARTYEAR/ segment is 255,
|
||||
the cartridge is seen as a 'diagnostic' cartridge, and the splash
|
||||
screen and most of the other startup initializations are bypassed.
|
||||
|
||||
<sect>License<p>
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
<label id="option-create-dep">
|
||||
@ -419,6 +419,8 @@ The assembler accepts
|
||||
<tt><ref id=".P02" name=".P02"></tt> command was given).
|
||||
<item>all valid 6502 mnemonics plus a set of illegal instructions when in
|
||||
<ref id="6502X-mode" name="6502X mode">.
|
||||
<item>all valid 6502DTV mnemonics when in 6502DTV mode (after the
|
||||
<tt><ref id=".PDTV" name=".PDTV"></tt> command was given).
|
||||
<item>all valid 65SC02 mnemonics when in 65SC02 mode (after the
|
||||
<tt><ref id=".PSC02" name=".PSC02"></tt> command was given).
|
||||
<item>all valid 65C02 mnemonics when in 65C02 mode (after the
|
||||
@ -3153,6 +3155,12 @@ Here's a list of all control commands and a description, what they do:
|
||||
(see <tt><ref id=".PC02" name=".PC02"></tt> command).
|
||||
|
||||
|
||||
<sect1><tt>.IFPDTV</tt><label id=".IFPDTV"><p>
|
||||
|
||||
Conditional assembly: Check if the assembler is currently in 6502DTV mode
|
||||
(see <tt><ref id=".PDTV" name=".PDTV"></tt> command).
|
||||
|
||||
|
||||
<sect1><tt>.IFPSC02</tt><label id=".IFPSC02"><p>
|
||||
|
||||
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:
|
||||
<tt><ref id=".P4510" name=".P4510"></tt>
|
||||
|
||||
|
||||
<sect1><tt>.PDTV</tt><label id=".PDTV"><p>
|
||||
|
||||
Enable the 6502DTV instruction set. This is a superset of the 6502
|
||||
instruction set.
|
||||
|
||||
See: <tt><ref id=".P02" name=".P02"></tt>
|
||||
|
||||
|
||||
<sect1><tt>.POPCPU</tt><label id=".POPCPU"><p>
|
||||
|
||||
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 <tt><ref id="option--cpu" name="--cpu"></tt> command line option,
|
||||
namely: 6502, 6502X, 65SC02, 65C02, 65816, 4510 and HuC6280.
|
||||
namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510 and HuC6280.
|
||||
|
||||
See: <tt><ref id=".CPU" name=".CPU"></tt>,
|
||||
<tt><ref id=".IFP02" name=".IFP02"></tt>,
|
||||
<tt><ref id=".IFPDTV" name=".IFPDTV"></tt>,
|
||||
<tt><ref id=".IFP816" name=".IFP816"></tt>,
|
||||
<tt><ref id=".IFPC02" name=".IFPC02"></tt>,
|
||||
<tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
|
||||
@ -4586,6 +4603,7 @@ each supported CPU a constant similar to
|
||||
CPU_SWEET16
|
||||
CPU_HUC6280
|
||||
CPU_4510
|
||||
CPU_6502DTV
|
||||
</verb></tscreen>
|
||||
|
||||
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
|
||||
</verb></tscreen>
|
||||
|
||||
The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may
|
||||
|
148
doc/cc65.sgml
148
doc/cc65.sgml
@ -6,8 +6,9 @@
|
||||
<url url="mailto:gregdk@users.sf.net" name="Greg King">
|
||||
|
||||
<abstract>
|
||||
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.
|
||||
</abstract>
|
||||
|
||||
<!-- Table of contents -->
|
||||
@ -548,6 +549,8 @@ Here is a description of all the command line options:
|
||||
<tag><tt/remap-zero/</tag>
|
||||
Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/
|
||||
that changes a character's code number from/to 0x00.
|
||||
<tag><tt/return-type/</tag>
|
||||
Warn about no return statement in function returning non-void.
|
||||
<tag><tt/struct-param/</tag>
|
||||
Warn when passing structs by value.
|
||||
<tag><tt/unknown-pragma/</tag>
|
||||
@ -706,12 +709,13 @@ This cc65 version has some extensions to the ISO C standard.
|
||||
places.
|
||||
<p>
|
||||
|
||||
<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/.
|
||||
Both refer to the primary register that is used by the compiler to
|
||||
evaluate expressions or return function results. <tt/__AX__/ is of
|
||||
type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/
|
||||
respectively. The pseudo variables may be used as lvalue and rvalue as
|
||||
every other variable. They are most useful together with short
|
||||
<item> There are three pseudo variables named <tt/__A__/, <tt/__AX__/ and
|
||||
<tt/__EAX__/. They all refer to the primary register that is used
|
||||
by the compiler to evaluate expressions or return function results.
|
||||
<tt/__A__/ is of type <tt/unsigned char/, <tt/__AX__/ is of type
|
||||
<tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/
|
||||
respectively. The pseudo variables may be used as lvalue and rvalue
|
||||
as every other variable. They are most useful together with short
|
||||
sequences of assembler code. For example, the macro
|
||||
|
||||
<tscreen><verb>
|
||||
@ -1045,26 +1049,39 @@ parameter with the <tt/#pragma/.
|
||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
|
||||
|
||||
<sect1><tt>#pragma bss-name ([push,] <name>)</tt><label id="pragma-bss-name"><p>
|
||||
<sect1><tt>#pragma bss-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-bss-name"><p>
|
||||
|
||||
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 <tt/name/ argument is a string enclosed in quotation
|
||||
marks.
|
||||
|
||||
Note: The default linker configuration file does only map the standard
|
||||
segments. If you use other segments, you have to create a new linker
|
||||
configuration file.
|
||||
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||
width of address numbers that point into that segment. Only words that
|
||||
are known to ca65 are allowed:
|
||||
<enum>
|
||||
<item>"zp", "zeropage", "direct"
|
||||
<item>"abs", "absolute", "near", "default"
|
||||
<item>"far"
|
||||
<item>"long", "dword"
|
||||
</enum>
|
||||
|
||||
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 <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
Beware: The start-up code will zero only the default BSS segment. If you use
|
||||
another BSS segment, then you must do that yourself; otherwise, variables
|
||||
with static storage duration and no explicit initializer will not have the
|
||||
value zero.
|
||||
|
||||
Example:
|
||||
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
||||
|
||||
Examples:
|
||||
<tscreen><verb>
|
||||
#pragma bss-name ("MyBSS")
|
||||
#pragma bss-name (push, "MyBSS")
|
||||
#pragma bss-name ("MyBSS", "zp")
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
@ -1120,21 +1137,33 @@ parameter with the <tt/#pragma/.
|
||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
|
||||
|
||||
<sect1><tt>#pragma code-name ([push,] <name>)</tt><label id="pragma-code-name"><p>
|
||||
<sect1><tt>#pragma code-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-code-name"><p>
|
||||
|
||||
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 <tt/name/ argument is a string enclosed
|
||||
in quotation marks.
|
||||
|
||||
Note: The default linker configuration file does only map the standard
|
||||
segments. If you use other segments, you have to create a new linker
|
||||
configuration file.
|
||||
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||
width of address numbers that point into that segment. Only words that
|
||||
are known to ca65 are allowed:
|
||||
<enum>
|
||||
<item>"zp", "zeropage", "direct"
|
||||
<item>"abs", "absolute", "near", "default"
|
||||
<item>"far"
|
||||
<item>"long", "dword"
|
||||
</enum>
|
||||
|
||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
Note: The default linker configuration file maps only the standard segments.
|
||||
If you use other segments, you must create a new linker configuration file.
|
||||
|
||||
Example:
|
||||
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
||||
|
||||
Examples:
|
||||
<tscreen><verb>
|
||||
#pragma code-name ("MyCODE")
|
||||
#pragma code-name (push, "MyCODE")
|
||||
#pragma code-name (push, "MyCODE", "far")
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
@ -1148,21 +1177,33 @@ parameter with the <tt/#pragma/.
|
||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
|
||||
|
||||
<sect1><tt>#pragma data-name ([push,] <name>)</tt><label id="pragma-data-name"><p>
|
||||
<sect1><tt>#pragma data-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-data-name"><p>
|
||||
|
||||
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 <tt/name/ argument is a string enclosed
|
||||
in quotation marks.
|
||||
|
||||
Note: The default linker configuration file does only map the standard
|
||||
segments. If you use other segments, you have to create a new linker
|
||||
configuration file.
|
||||
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||
width of address numbers that point into that segment. Only words that
|
||||
are known to ca65 are allowed:
|
||||
<enum>
|
||||
<item>"zp", "zeropage", "direct"
|
||||
<item>"abs", "absolute", "near", "default"
|
||||
<item>"far"
|
||||
<item>"long", "dword"
|
||||
</enum>
|
||||
|
||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
Note: The default linker configuration file maps only the standard segments.
|
||||
If you use other segments, you must create a new linker configuration file.
|
||||
|
||||
Example:
|
||||
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
||||
|
||||
Examples:
|
||||
<tscreen><verb>
|
||||
#pragma data-name ("MyDATA")
|
||||
#pragma data-name (push, "MyDATA")
|
||||
#pragma data-name ("MyDATA", "zeropage")
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
@ -1224,21 +1265,32 @@ parameter with the <tt/#pragma/.
|
||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
|
||||
|
||||
<sect1><tt>#pragma rodata-name ([push,] <name>)</tt><label id="pragma-rodata-name"><p>
|
||||
<sect1><tt>#pragma rodata-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-rodata-name"><p>
|
||||
|
||||
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 <tt/name/ argument is a string enclosed
|
||||
in quotation marks.
|
||||
|
||||
Note: The default linker configuration file does only map the standard
|
||||
segments. If you use other segments, you have to create a new linker
|
||||
configuration file.
|
||||
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||
width of address numbers that point into that segment. Only words that
|
||||
are known to ca65 are allowed:
|
||||
<enum>
|
||||
<item>"zp", "zeropage", "direct"
|
||||
<item>"abs", "absolute", "near", "default"
|
||||
<item>"far"
|
||||
<item>"long", "dword"
|
||||
</enum>
|
||||
|
||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
||||
Note: The default linker configuration file maps only the standard segments.
|
||||
If you use other segments, you must create a new linker configuration file.
|
||||
|
||||
Example:
|
||||
The <tt/#pragma/ understands the push and pop parameters, as explained above.
|
||||
|
||||
Examples:
|
||||
<tscreen><verb>
|
||||
#pragma rodata-name ("MyRODATA")
|
||||
#pragma rodata-name (push, "MyRODATA")
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
|
@ -112,15 +112,17 @@ Here is a description of all the command line options:
|
||||
<itemize>
|
||||
<item>6502
|
||||
<item>6502x
|
||||
<item>6502dtv
|
||||
<item>65sc02
|
||||
<item>65c02
|
||||
<item>huc6280
|
||||
<item>4510
|
||||
</itemize>
|
||||
|
||||
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.
|
||||
|
||||
|
||||
<label id="option--formfeeds">
|
||||
@ -251,7 +253,10 @@ for this CPU. Invalid opcodes are translated into <tt/.byte/ commands.
|
||||
With the command line option <tt><ref id="option--cpu" name="--cpu"></tt>, the
|
||||
disassembler may be told to recognize either the 65SC02 or 65C02 CPUs. The
|
||||
latter understands the same opcodes as the former, plus 16 additional bit
|
||||
manipulation and bit test-and-branch commands.
|
||||
manipulation and bit test-and-branch commands. Using 6502x as CPU the illegal
|
||||
opcodes of 6502 CPU are detected and displayed. 6502dtv setting recognizes the
|
||||
emulated CPU instructons of the C64DTV device.
|
||||
|
||||
|
||||
When disassembling 4510 code, due to handling of 16-bit wide branches, da65
|
||||
can produce output that can not be re-assembled, when one or more of those
|
||||
|
@ -858,20 +858,21 @@ The functions described here are common for SEQ and VLIR structures.
|
||||
<p>
|
||||
<tt/struct filehandle *GetNxtDirEntry (void)/
|
||||
<p>
|
||||
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 <tt/unsigned/ - as in the <tt/SetNextFree/
|
||||
function or read directly after a call to those two functions from <tt/r5/. The current sector number
|
||||
is in <tt/r1/ and the sector data itself is in <tt/diskBlkBuf/.
|
||||
Those 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 is <tt/NULL/ if there are no more slots, or if there was a disk error. The
|
||||
<tt/_oserror/ variable is non-zero if it was a disk error (see <tt>geos/gdisk.h</tt>). The current
|
||||
directory track and sector numbers are in <tt/r1L/ and <tt/r1H/. The sector data itself is in
|
||||
<tt/diskBlkBuf/.
|
||||
|
||||
<sect3>FindFile
|
||||
<p>
|
||||
<tt/char FindFile (char *fName)/
|
||||
<p>
|
||||
This function scans the whole directory for the given filename. It returns either 0 (success) or 5
|
||||
(FILE_NOT_FOUND, defined in <tt/gdisk.h/) or any other fatal disk read error. After a successful
|
||||
<tt/FindFile/ you will have <tt/struct filehandle/ at <tt/dirEntryBuf/ filled with the file's data and
|
||||
other registers set as described in <tt/GetNxtDirEntry/.
|
||||
This function scans the whole directory for the given filename. It returns either 0 (success), 5
|
||||
(FILE_NOT_FOUND, defined in <tt>geos/gdisk.h</tt>), or any other fatal disk read error. After a successful
|
||||
<tt/FindFile()/, you will have <tt/struct filehandle/ at <tt/dirEntryBuf/ filled with the file's data, and
|
||||
other registers set as described in <tt/GetNxtDirEntry()/.
|
||||
|
||||
<sect3>FindFTypes
|
||||
<p>
|
||||
|
@ -921,9 +921,8 @@ name="6502 binary relocation format specification">). It is defined like this:
|
||||
}
|
||||
</verb></tscreen>
|
||||
|
||||
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:
|
||||
|
||||
<tscreen><verb>
|
||||
FILES {
|
||||
@ -1010,7 +1009,8 @@ The <tt/CONDES/ feature has several attributes:
|
||||
<tag><tt>segment</tt></tag>
|
||||
|
||||
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.
|
||||
|
||||
|
||||
<tag><tt>type</tt></tag>
|
||||
@ -1059,7 +1059,7 @@ The <tt/CONDES/ feature has several attributes:
|
||||
Without specifying the <tt/CONDES/ feature, the linker will not create any
|
||||
tables, even if there are <tt/condes/ entries in the object files.
|
||||
|
||||
For more information see the <tt/.CONDES/ command in the <url
|
||||
For more information, see the <tt/.CONDES/ command in the <url
|
||||
url="ca65.html" name="ca65 manual">.
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
<sect1>INIT<p>
|
||||
|
||||
The INIT segment is some kind of 'bss' segment since it contains
|
||||
uninitialized data. Unlike <tt>.bss</tt> 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.
|
||||
|
||||
<sect1>LOWCODE<p>
|
||||
|
||||
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.
|
||||
|
||||
<sect1>ONCE<p>
|
||||
|
||||
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.
|
||||
|
||||
<sect1>LOWCODE<p>
|
||||
|
||||
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.
|
||||
|
||||
<sect1>STARTUP<p>
|
||||
|
||||
This segment contains the startup code which initializes the C software stack
|
||||
|
@ -105,6 +105,7 @@ declaration and usage.
|
||||
<item>cbm_save
|
||||
<item>cbm_write
|
||||
<item>get_tv
|
||||
<item>waitvsync
|
||||
</itemize>
|
||||
|
||||
|
||||
|
80
include/_atari5200os.h
Normal file
80
include/_atari5200os.h
Normal file
@ -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
|
@ -6,10 +6,11 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2019 Mark Keates <markk@dendrite.co.uk> */
|
||||
/* (C) 2000-2021 Mark Keates <markk@dendrite.co.uk> */
|
||||
/* Freddy Offenga <taf_offenga@yahoo.com> */
|
||||
/* Christian Groessler <chris@groessler.org> */
|
||||
/* Bill Kendrick <nbs@sonic.net> */
|
||||
/* 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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -133,8 +133,7 @@ MKINC = $(GEOS) \
|
||||
|
||||
TARGETUTIL = apple2 \
|
||||
apple2enh \
|
||||
atari \
|
||||
geos-apple
|
||||
atari
|
||||
|
||||
GEOSDIRS = common \
|
||||
conio \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
;
|
||||
|
@ -11,6 +11,7 @@
|
||||
SHRAM_HANDLERS = 1
|
||||
.include "atari.inc"
|
||||
.include "romswitch.inc"
|
||||
.import __CHARGEN_START__
|
||||
.export set_VTIMR1_handler
|
||||
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
SHRAM_HANDLERS = 1
|
||||
.include "atari.inc"
|
||||
.include "romswitch.inc"
|
||||
.import __CHARGEN_START__
|
||||
.export set_VTIMR2_handler
|
||||
|
||||
|
||||
|
15
libsrc/atari/waitvsync.s
Normal file
15
libsrc/atari/waitvsync.s
Normal file
@ -0,0 +1,15 @@
|
||||
;
|
||||
; Written by Christian Groessler <chris@groessler.org>
|
||||
;
|
||||
; void waitvsync (void);
|
||||
;
|
||||
|
||||
.include "atari.inc"
|
||||
.export _waitvsync
|
||||
|
||||
.proc _waitvsync
|
||||
lda RTCLOK+2
|
||||
@lp: cmp RTCLOK+2
|
||||
beq @lp
|
||||
rts
|
||||
.endproc
|
@ -2,7 +2,6 @@
|
||||
; from Atari computer version by Christian Groessler, 2014
|
||||
;
|
||||
; clock_t clock (void);
|
||||
; unsigned _clocks_per_sec (void);
|
||||
;
|
||||
|
||||
.export _clock
|
||||
|
@ -13,7 +13,6 @@
|
||||
.import zerobss, copydata
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "atari5200.inc"
|
||||
|
||||
start:
|
||||
|
||||
|
15
libsrc/atari5200/waitvsync.s
Normal file
15
libsrc/atari5200/waitvsync.s
Normal file
@ -0,0 +1,15 @@
|
||||
;
|
||||
; Written by Christian Groessler <chris@groessler.org>
|
||||
;
|
||||
; void waitvsync (void);
|
||||
;
|
||||
|
||||
.include "atari5200.inc"
|
||||
.export _waitvsync
|
||||
|
||||
.proc _waitvsync
|
||||
lda RTCLOK+1
|
||||
@lp: cmp RTCLOK+1
|
||||
beq @lp
|
||||
rts
|
||||
.endproc
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -22,7 +22,7 @@
|
||||
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
|
||||
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
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
.importzp ST
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "plus4.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Startup code
|
||||
|
@ -13,7 +13,6 @@
|
||||
.importzp ST
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "c64.inc"
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
@ -23,7 +23,7 @@
|
||||
; 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
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,11 +54,13 @@ 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') {
|
||||
switch (buffer[0]) {
|
||||
case 'b':
|
||||
case 'm':
|
||||
goto exitpoint;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -24,7 +24,7 @@
|
||||
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
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -11,11 +11,11 @@
|
||||
.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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -13,6 +13,10 @@
|
||||
.include "geossym.inc"
|
||||
|
||||
_CalcBlksFree:
|
||||
lda #<curDirHead
|
||||
ldx #>curDirHead
|
||||
sta r5L
|
||||
stx r5H
|
||||
jsr CalcBlksFree
|
||||
stx __oserror
|
||||
lda r4L
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -2,18 +2,14 @@
|
||||
; 2003-04-13, Ullrich von Bassewitz
|
||||
; 2012-02-06, Greg King
|
||||
;
|
||||
; #include <time.h>
|
||||
;
|
||||
; typedef unsigned long int clock_t;
|
||||
; clock_t _clk_tck(void);
|
||||
; #define CLOCKS_PER_SEC _clk_tck()
|
||||
; clock_t clock (void);
|
||||
; clock_t _clocks_per_sec (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
|
||||
|
@ -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 ; store (-size - 1)
|
||||
lda #>load_size
|
||||
eor #$FF
|
||||
sta count+1
|
||||
|
||||
L1: inc count ; pre-count one's-complement upwards
|
||||
ldx #(<load_size) + 1
|
||||
stx count
|
||||
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
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "pet.inc"
|
||||
.include "../cbm/cbm.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Startup code
|
||||
|
16
libsrc/pet/waitvsync.s
Normal file
16
libsrc/pet/waitvsync.s
Normal file
@ -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
|
@ -198,5 +198,3 @@ irqcount: .byte 0
|
||||
.segment "INIT"
|
||||
|
||||
zpsave: .res zpspace
|
||||
|
||||
|
||||
|
@ -78,5 +78,3 @@ not_dma:
|
||||
.word nmi
|
||||
.word reset32kcode
|
||||
.word irq
|
||||
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
.import __MAIN_START__, __MAIN_SIZE__
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "telestrat.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Place the startup code in a special segment.
|
||||
|
17
libsrc/telestrat/kbhit.s
Normal file
17
libsrc/telestrat/kbhit.s
Normal file
@ -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
|
@ -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
|
||||
|
@ -13,7 +13,6 @@
|
||||
.importzp ST
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "vic20.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Startup code
|
||||
|
@ -31,6 +31,7 @@
|
||||
/* Workaround missing clock stuff */
|
||||
#ifdef __APPLE2__
|
||||
# define clock() 0
|
||||
# undef CLK_TCK
|
||||
# define CLK_TCK 1
|
||||
#endif
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
@ -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,
|
||||
|
@ -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 },
|
||||
|
@ -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 },
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
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");
|
||||
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) {
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("txa");
|
||||
if (flags & CF_UNSIGNED) {
|
||||
AddCodeLine ("ldx #$00");
|
||||
} else {
|
||||
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;
|
||||
@ -3155,6 +3196,7 @@ void g_asr (unsigned flags, unsigned long val)
|
||||
AddCodeLine ("lda sreg+1");
|
||||
if ((flags & CF_UNSIGNED) == 0) {
|
||||
unsigned L = GetLocalLabel ();
|
||||
|
||||
AddCodeLine ("bpl %s", LocalLabelName (L));
|
||||
AddCodeLine ("dex");
|
||||
g_defcodelabel (L);
|
||||
@ -3168,6 +3210,7 @@ void g_asr (unsigned flags, unsigned long val)
|
||||
AddCodeLine ("ldx sreg+1");
|
||||
if ((flags & CF_UNSIGNED) == 0) {
|
||||
unsigned L = GetLocalLabel ();
|
||||
|
||||
AddCodeLine ("bpl %s", LocalLabelName (L));
|
||||
AddCodeLine ("dey");
|
||||
g_defcodelabel (L);
|
||||
@ -3184,6 +3227,7 @@ void g_asr (unsigned flags, unsigned long val)
|
||||
AddCodeLine ("sty sreg");
|
||||
if ((flags & CF_UNSIGNED) == 0) {
|
||||
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,18 +3281,28 @@ 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) {
|
||||
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;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@ -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;
|
||||
|
@ -493,13 +493,16 @@ 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__.
|
||||
*/
|
||||
if (D->LastParam != 0) {
|
||||
switch (SizeOf(D->LastParam->Type)) {
|
||||
case 1u:
|
||||
*Use = REG_A;
|
||||
@ -510,6 +513,9 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg)
|
||||
default:
|
||||
*Use = REG_EAX;
|
||||
}
|
||||
} else {
|
||||
*Use = REG_EAX;
|
||||
}
|
||||
} else {
|
||||
/* Will not use any registers */
|
||||
*Use = REG_NONE;
|
||||
|
@ -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++);
|
||||
}
|
||||
|
@ -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 &&
|
||||
|
@ -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))) {
|
||||
|
@ -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 &&
|
||||
|
@ -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 &&
|
||||
|
@ -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 */
|
||||
{
|
||||
@ -1268,15 +1256,15 @@ 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);
|
||||
InsertEntry (D, X, D->OpIndex + 1);
|
||||
} else {
|
||||
Arg = MakeHexArg (0);
|
||||
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);
|
||||
@ -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 */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user