Merge branch 'master' of https://github.com/jedeoric/cc65
This commit is contained in:
@@ -15,6 +15,7 @@ PROMPT := $33 ; Used by GETLN
|
|||||||
RNDL := $4E ; Random counter low
|
RNDL := $4E ; Random counter low
|
||||||
RNDH := $4F ; Random counter high
|
RNDH := $4F ; Random counter high
|
||||||
HIMEM := $73 ; Highest available memory address+1
|
HIMEM := $73 ; Highest available memory address+1
|
||||||
|
CURLIN := $75 ; Current line number being executed
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
; Vectors
|
; Vectors
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
; Zero page, Commodore stuff
|
; Zero page, Commodore stuff
|
||||||
|
|
||||||
TXTPTR := $3D ; Pointer into BASIC source code
|
TXTPTR := $3D ; Pointer into BASIC source code
|
||||||
|
STATUS := $90 ; Kernal I/O completion status
|
||||||
TIME := $A0 ; 60HZ clock
|
TIME := $A0 ; 60HZ clock
|
||||||
FNAM_LEN := $B7 ; Length of filename
|
FNAM_LEN := $B7 ; Length of filename
|
||||||
SECADR := $B9 ; Secondary address
|
SECADR := $B9 ; Secondary address
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
VARTAB := $2D ; Pointer to start of BASIC variables
|
VARTAB := $2D ; Pointer to start of BASIC variables
|
||||||
MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1)
|
MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1)
|
||||||
TXTPTR := $7A ; Pointer into BASIC source code
|
TXTPTR := $7A ; Pointer into BASIC source code
|
||||||
|
STATUS := $90 ; Kernal I/O completion status
|
||||||
TIME := $A0 ; 60 HZ clock
|
TIME := $A0 ; 60 HZ clock
|
||||||
FNAM_LEN := $B7 ; Length of filename
|
FNAM_LEN := $B7 ; Length of filename
|
||||||
SECADR := $B9 ; Secondary address
|
SECADR := $B9 ; Secondary address
|
||||||
|
|||||||
@@ -2,18 +2,20 @@
|
|||||||
CPU_ISET_NONE = $0001
|
CPU_ISET_NONE = $0001
|
||||||
CPU_ISET_6502 = $0002
|
CPU_ISET_6502 = $0002
|
||||||
CPU_ISET_6502X = $0004
|
CPU_ISET_6502X = $0004
|
||||||
CPU_ISET_65SC02 = $0008
|
CPU_ISET_6502DTV = $0008
|
||||||
CPU_ISET_65C02 = $0010
|
CPU_ISET_65SC02 = $0010
|
||||||
CPU_ISET_65816 = $0020
|
CPU_ISET_65C02 = $0020
|
||||||
CPU_ISET_SWEET16 = $0040
|
CPU_ISET_65816 = $0040
|
||||||
CPU_ISET_HUC6280 = $0080
|
CPU_ISET_SWEET16 = $0080
|
||||||
;CPU_ISET_M740 = $0100 not actually implemented
|
CPU_ISET_HUC6280 = $0100
|
||||||
CPU_ISET_4510 = $0200
|
;CPU_ISET_M740 = $0200 not actually implemented
|
||||||
|
CPU_ISET_4510 = $0400
|
||||||
|
|
||||||
; CPU capabilities
|
; CPU capabilities
|
||||||
CPU_NONE = CPU_ISET_NONE
|
CPU_NONE = CPU_ISET_NONE
|
||||||
CPU_6502 = CPU_ISET_6502
|
CPU_6502 = CPU_ISET_6502
|
||||||
CPU_6502X = CPU_ISET_6502|CPU_ISET_6502X
|
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_65SC02 = CPU_ISET_6502|CPU_ISET_65SC02
|
||||||
CPU_65C02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02
|
CPU_65C02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02
|
||||||
CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816
|
CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816
|
||||||
|
|||||||
@@ -505,4 +505,12 @@ OPC_ISC_aby = $FB
|
|||||||
OPC_NOP_abx = $FC
|
OPC_NOP_abx = $FC
|
||||||
OPC_ISC_abx = $FF
|
OPC_ISC_abx = $FF
|
||||||
|
|
||||||
|
.if (.cpu .bitand ::CPU_ISET_6502DTV)
|
||||||
|
|
||||||
|
OPC_BRA = $12
|
||||||
|
OPC_SAC_imm = $32
|
||||||
|
OPC_SIR_imm = $42
|
||||||
|
|
||||||
|
.endif
|
||||||
|
|
||||||
.endif
|
.endif
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ TMPPTR := $22 ; Temporary ptr used by BASIC
|
|||||||
VARTAB := $2D ; Pointer to start of BASIC variables
|
VARTAB := $2D ; Pointer to start of BASIC variables
|
||||||
MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1)
|
MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1)
|
||||||
TXTPTR := $3B ; Pointer into BASIC source code
|
TXTPTR := $3B ; Pointer into BASIC source code
|
||||||
|
STATUS := $90 ; Kernal I/O completion status
|
||||||
TIME := $A3 ; 60HZ clock
|
TIME := $A3 ; 60HZ clock
|
||||||
FNAM_LEN := $AB ; Length of filename
|
FNAM_LEN := $AB ; Length of filename
|
||||||
LFN := $AC ; Logical file number
|
LFN := $AC ; Logical file number
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
VARTAB := $2D ; Pointer to start of BASIC variables
|
VARTAB := $2D ; Pointer to start of BASIC variables
|
||||||
MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1)
|
MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1)
|
||||||
TXTPTR := $7A ; Pointer into BASIC source code
|
TXTPTR := $7A ; Pointer into BASIC source code
|
||||||
|
STATUS := $90 ; Kernal I/O completion status
|
||||||
TIME := $A0 ; 60HZ clock
|
TIME := $A0 ; 60HZ clock
|
||||||
FNAM_LEN := $B7 ; Length of filename
|
FNAM_LEN := $B7 ; Length of filename
|
||||||
SECADR := $B9 ; Secondary address
|
SECADR := $B9 ; Secondary address
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ SEGMENTS {
|
|||||||
EXEHDR: load = HEADER, type = ro, optional = yes;
|
EXEHDR: load = HEADER, type = ro, optional = yes;
|
||||||
STARTUP: load = MAIN, type = ro;
|
STARTUP: load = MAIN, type = ro;
|
||||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
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;
|
CODE: load = MAIN, type = ro start = $4000;
|
||||||
RODATA: load = MAIN, type = ro;
|
RODATA: load = MAIN, type = ro;
|
||||||
DATA: load = MAIN, type = rw;
|
DATA: load = MAIN, type = rw;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ SEGMENTS {
|
|||||||
EXEHDR: load = HEADER, type = ro, optional = yes;
|
EXEHDR: load = HEADER, type = ro, optional = yes;
|
||||||
STARTUP: load = MAIN, type = ro;
|
STARTUP: load = MAIN, type = ro;
|
||||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
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;
|
CODE: load = MAIN, type = ro start = $4000;
|
||||||
RODATA: load = MAIN, type = ro;
|
RODATA: load = MAIN, type = ro;
|
||||||
DATA: load = MAIN, type = rw;
|
DATA: load = MAIN, type = rw;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ SYMBOLS {
|
|||||||
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
|
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
|
||||||
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
|
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
|
||||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||||
|
__CHARGENSIZE__: type = weak, value = $0400;
|
||||||
__STARTADDRESS__: type = export, value = %S;
|
__STARTADDRESS__: type = export, value = %S;
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
@@ -37,10 +38,10 @@ MEMORY {
|
|||||||
TRAILER: file = %O, start = $0000, size = $0006;
|
TRAILER: file = %O, start = $0000, size = $0006;
|
||||||
|
|
||||||
# address of relocated character generator
|
# 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
|
# 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 {
|
SEGMENTS {
|
||||||
ZEROPAGE: load = ZP, type = zp;
|
ZEROPAGE: load = ZP, type = zp;
|
||||||
@@ -53,7 +54,7 @@ SEGMENTS {
|
|||||||
SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
|
SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
|
||||||
|
|
||||||
SRPREPHDR: load = SRPREPHDR, type = ro;
|
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;
|
SRPREP: load = SRPREPCHNK, type = rw, define = yes;
|
||||||
SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = 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;
|
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
|
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
|
||||||
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
|
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
|
||||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||||
|
__CHARGENSIZE__: type = weak, value = $0400;
|
||||||
__OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
|
__OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
|
||||||
__STARTADDRESS__: type = export, value = %S;
|
__STARTADDRESS__: type = export, value = %S;
|
||||||
}
|
}
|
||||||
@@ -37,10 +38,10 @@ MEMORY {
|
|||||||
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
|
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
|
||||||
|
|
||||||
# address of relocated character generator (same addess as ROM version)
|
# 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
|
# 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
|
# overlays
|
||||||
OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__;
|
OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__;
|
||||||
@@ -64,7 +65,7 @@ SEGMENTS {
|
|||||||
SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
|
SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
|
||||||
|
|
||||||
SRPREPHDR: load = SRPREPHDR, type = ro;
|
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;
|
SRPREP: load = SRPREPCHNK, type = rw, define = yes;
|
||||||
SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = 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;
|
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
|
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
|
||||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||||
__STARTADDRESS__: type = export, value = %S;
|
__STARTADDRESS__: type = export, value = %S;
|
||||||
|
__CHARGENSIZE__: type = weak, value = $0400;
|
||||||
__SYSCHKHDR__: type = export, value = 0; # Disable system check header
|
__SYSCHKHDR__: type = export, value = 0; # Disable system check header
|
||||||
__SYSCHKTRL__: type = export, value = 0; # Disable system check trailer
|
__SYSCHKTRL__: type = export, value = 0; # Disable system check trailer
|
||||||
}
|
}
|
||||||
@@ -26,10 +27,10 @@ MEMORY {
|
|||||||
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
|
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
|
||||||
|
|
||||||
# address of relocated character generator (same addess as ROM version)
|
# 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
|
# 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 - hide
|
||||||
UNUSED: file = "", start = $0, size = $10;
|
UNUSED: file = "", start = $0, size = $10;
|
||||||
@@ -47,7 +48,7 @@ SEGMENTS {
|
|||||||
EXTZP: load = ZP, type = zp, optional = yes;
|
EXTZP: load = ZP, type = zp, optional = yes;
|
||||||
|
|
||||||
SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, 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;
|
SRPREP: load = SRPREPCHNK, type = rw, define = yes;
|
||||||
SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = 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;
|
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
|
__SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
|
||||||
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
|
__AUTOSTART__: type = import; # force inclusion of autostart "trailer"
|
||||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||||
|
__CHARGENSIZE__: type = weak, value = $0400;
|
||||||
__STARTADDRESS__: type = export, value = %S;
|
__STARTADDRESS__: type = export, value = %S;
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
@@ -35,10 +36,10 @@ MEMORY {
|
|||||||
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
|
HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800;
|
||||||
|
|
||||||
# address of relocated character generator (same addess as ROM version)
|
# 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
|
# 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 {
|
SEGMENTS {
|
||||||
ZEROPAGE: load = ZP, type = zp;
|
ZEROPAGE: load = ZP, type = zp;
|
||||||
@@ -51,7 +52,7 @@ SEGMENTS {
|
|||||||
SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
|
SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes;
|
||||||
|
|
||||||
SRPREPHDR: load = SRPREPHDR, type = ro;
|
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;
|
SRPREP: load = SRPREPCHNK, type = rw, define = yes;
|
||||||
SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = 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;
|
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;
|
EXEHDR: load = MAIN, type = ro, optional = yes;
|
||||||
CODE: load = MAIN, type = ro;
|
CODE: load = MAIN, type = ro;
|
||||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||||
|
ONCE: load = MAIN, type = ro, optional = yes;
|
||||||
RODATA: load = MAIN, type = ro;
|
RODATA: load = MAIN, type = ro;
|
||||||
DATA: load = MAIN, type = rw;
|
DATA: load = MAIN, type = rw;
|
||||||
|
INIT: load = MAIN, type = bss, optional = yes;
|
||||||
BSS: load = MAIN, type = bss, define = yes;
|
BSS: load = MAIN, type = bss, define = yes;
|
||||||
}
|
}
|
||||||
FEATURES {
|
FEATURES {
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ MEMORY {
|
|||||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
|
||||||
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__;
|
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;
|
BRAM01ADDR: file = "%O.01", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $01;
|
BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $01;
|
||||||
BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
@@ -36,64 +34,62 @@ MEMORY {
|
|||||||
BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $08;
|
BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $08;
|
||||||
BRAM09ADDR: file = "%O.09", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM09ADDR: file = "%O.09", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $09;
|
BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $09;
|
||||||
BRAM0AADDR: file = "%O.0a", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM0AADDR: file = "%O.0A", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM0A: file = "%O.0a", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0A;
|
BRAM0A: file = "%O.0A", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0A;
|
||||||
BRAM0BADDR: file = "%O.0b", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM0BADDR: file = "%O.0B", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM0B: file = "%O.0b", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0B;
|
BRAM0B: file = "%O.0B", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0B;
|
||||||
BRAM0CADDR: file = "%O.0c", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM0CADDR: file = "%O.0C", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM0C: file = "%O.0c", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0C;
|
BRAM0C: file = "%O.0C", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0C;
|
||||||
BRAM0DADDR: file = "%O.0d", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM0DADDR: file = "%O.0D", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM0D: file = "%O.0d", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0D;
|
BRAM0D: file = "%O.0D", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0D;
|
||||||
BRAM0EADDR: file = "%O.0e", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM0EADDR: file = "%O.0E", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM0E: file = "%O.0e", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0E;
|
BRAM0E: file = "%O.0E", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0E;
|
||||||
BRAM0FADDR: file = "%O.0f", start = __BANKRAMSTART__ - 2, size = $0002;
|
BRAM0FADDR: file = "%O.0F", start = __BANKRAMSTART__ - 2, size = $0002;
|
||||||
BRAM0F: file = "%O.0f", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0F;
|
BRAM0F: file = "%O.0F", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0F;
|
||||||
}
|
}
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
ZEROPAGE: load = ZP, type = zp;
|
ZEROPAGE: load = ZP, type = zp;
|
||||||
EXTZP: load = ZP, type = zp, optional = yes;
|
EXTZP: load = ZP, type = zp, optional = yes;
|
||||||
LOADADDR: load = LOADADDR, type = ro;
|
LOADADDR: load = LOADADDR, type = ro;
|
||||||
EXEHDR: load = HEADER, 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;
|
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||||
CODE: load = MAIN, type = ro;
|
CODE: load = MAIN, type = ro;
|
||||||
RODATA: load = MAIN, type = ro;
|
RODATA: load = MAIN, type = ro;
|
||||||
DATA: load = MAIN, type = rw;
|
DATA: load = MAIN, type = rw;
|
||||||
INIT: load = MAIN, type = rw;
|
INIT: load = MAIN, type = rw, optional = yes;
|
||||||
ONCE: load = MAIN, type = ro, define = yes;
|
ONCE: load = MAIN, type = ro, define = yes;
|
||||||
BSS: load = BSS, type = bss, 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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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 {
|
FEATURES {
|
||||||
CONDES: type = constructor,
|
CONDES: type = constructor,
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ SEGMENTS {
|
|||||||
EXTZP: load = ZP, type = zp, optional = yes;
|
EXTZP: load = ZP, type = zp, optional = yes;
|
||||||
LOADADDR: load = LOADADDR, type = ro;
|
LOADADDR: load = LOADADDR, type = ro;
|
||||||
EXEHDR: load = HEADER, 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;
|
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||||
CODE: load = MAIN, type = ro;
|
CODE: load = MAIN, type = ro;
|
||||||
RODATA: load = MAIN, type = ro;
|
RODATA: load = MAIN, type = ro;
|
||||||
DATA: load = MAIN, type = rw;
|
DATA: load = MAIN, type = rw;
|
||||||
INIT: load = MAIN, type = rw;
|
INIT: load = MAIN, type = rw, optional = yes;
|
||||||
ONCE: load = MAIN, type = ro, define = yes;
|
ONCE: load = MAIN, type = ro, define = yes;
|
||||||
BSS: load = BSS, type = bss, 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
|
# for assembler
|
||||||
|
|
||||||
# ld65 config file
|
# ld65 config file
|
||||||
@@ -30,8 +30,23 @@ SEGMENTS {
|
|||||||
BANK5: load = BANKROM5, type = ro;
|
BANK5: load = BANKROM5, type = ro;
|
||||||
BANK6: load = BANKROM6, type = ro;
|
BANK6: load = BANKROM6, type = ro;
|
||||||
BANK7: load = BANKROM7, type = ro;
|
BANK7: load = BANKROM7, type = ro;
|
||||||
ZEROPAGE: load = RAM, type = bss, define = yes;
|
ZEROPAGE: load = RAM, type = zp, define = yes;
|
||||||
DATA: load = RAM, type = bss, define = yes, offset = $0200;
|
DATA: load = RAM, type = rw, define = yes, offset = $0200;
|
||||||
BSS: load = RAM, type = bss, define = yes;
|
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;
|
CODE: load = ROM, type = ro, define = yes;
|
||||||
RODATA: load = ROM, type = ro, define = yes;
|
RODATA: load = ROM, type = ro, define = yes;
|
||||||
DATA: load = ROM, run = RAM, type = rw, define = yes;
|
DATA: load = ROM, run = RAM, type = rw, define = yes;
|
||||||
FFF0: load = ROM, type = ro, offset = $3FF0;
|
FFF0: load = ROM, type = ro, start = $FFF0;
|
||||||
VECTOR: load = ROM, type = ro, offset = $3FFA;
|
VECTORS: load = ROM, type = ro, start = $FFFA;
|
||||||
BSS: load = RAM, type = bss, define = yes;
|
BSS: load = RAM, type = bss, define = yes;
|
||||||
}
|
}
|
||||||
FEATURES {
|
FEATURES {
|
||||||
|
|||||||
@@ -23,8 +23,23 @@ SEGMENTS {
|
|||||||
BANK1: load = BANKROM1, type = ro;
|
BANK1: load = BANKROM1, type = ro;
|
||||||
BANK2: load = BANKROM2, type = ro;
|
BANK2: load = BANKROM2, type = ro;
|
||||||
BANK3: load = BANKROM3, type = ro;
|
BANK3: load = BANKROM3, type = ro;
|
||||||
ZEROPAGE: load = RAM, type = bss, define = yes;
|
ZEROPAGE: load = RAM, type = zp, define = yes;
|
||||||
DATA: load = RAM, type = bss, define = yes, offset = $0200;
|
DATA: load = RAM, type = rw, define = yes, offset = $0200;
|
||||||
BSS: load = RAM, type = bss, define = yes;
|
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;
|
CODE: load = ROM, type = ro, define = yes;
|
||||||
RODATA: load = ROM, type = ro, define = yes;
|
RODATA: load = ROM, type = ro, define = yes;
|
||||||
DATA: load = ROM, run = RAM, type = rw, define = yes;
|
DATA: load = ROM, run = RAM, type = rw, define = yes;
|
||||||
FFF0: load = ROM, type = ro, offset = $7FF0;
|
FFF0: load = ROM, type = ro, start = $FFF0;
|
||||||
VECTOR: load = ROM, type = ro, offset = $7FFA;
|
VECTORS: load = ROM, type = ro, start = $FFFA;
|
||||||
BSS: load = RAM, type = bss, define = yes;
|
BSS: load = RAM, type = bss, define = yes;
|
||||||
}
|
}
|
||||||
FEATURES {
|
FEATURES {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
SYMBOLS {
|
SYMBOLS {
|
||||||
__LOADADDR__: type = import;
|
__LOADADDR__: type = import;
|
||||||
__EXEHDR__: type = import;
|
__EXEHDR__: type = import;
|
||||||
__STACKSIZE__: type = weak, value = $0400; # 1k stack
|
__STACKSIZE__: type = weak, value = $0100;
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ZP: file = "", define = yes, start = $0002, size = $001A;
|
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>_scroll
|
||||||
<item>_setcolor
|
<item>_setcolor
|
||||||
<item>_setcolor_low
|
<item>_setcolor_low
|
||||||
|
<item>waitvsync
|
||||||
</itemize>
|
</itemize>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ information.
|
|||||||
|
|
||||||
<sect>Binary format<p>
|
<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
|
is a cartridge image. It is of course
|
||||||
possible to change this behaviour by using a modified startup file and linker
|
possible to change this behaviour by using a modified startup file and linker
|
||||||
config.
|
config.
|
||||||
@@ -73,11 +73,22 @@ Special locations:
|
|||||||
|
|
||||||
Programs containing Atari 5200 specific code may use the <tt/atari5200.h/ header file.
|
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>
|
<sect1>Atari 5200 specific functions<p>
|
||||||
|
|
||||||
<itemize>
|
<itemize>
|
||||||
<item>TBD.
|
<item>waitvsync
|
||||||
</itemize>
|
</itemize>
|
||||||
|
|
||||||
|
|
||||||
@@ -208,10 +219,58 @@ you cannot use any of the following functions (and a few others):
|
|||||||
|
|
||||||
<sect>Other hints<p>
|
<sect>Other hints<p>
|
||||||
|
|
||||||
|
<sect1>CAR format<p>
|
||||||
|
|
||||||
AtariROMMaker (<url url="https://www.wudsn.com/index.php/productions-atari800/tools/atarirommaker"> )
|
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.
|
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.
|
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>
|
<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
|
Set the default for the CPU type. The option takes a parameter, which
|
||||||
may be one of
|
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">
|
<label id="option-create-dep">
|
||||||
@@ -419,6 +419,8 @@ The assembler accepts
|
|||||||
<tt><ref id=".P02" name=".P02"></tt> command was given).
|
<tt><ref id=".P02" name=".P02"></tt> command was given).
|
||||||
<item>all valid 6502 mnemonics plus a set of illegal instructions when in
|
<item>all valid 6502 mnemonics plus a set of illegal instructions when in
|
||||||
<ref id="6502X-mode" name="6502X mode">.
|
<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
|
<item>all valid 65SC02 mnemonics when in 65SC02 mode (after the
|
||||||
<tt><ref id=".PSC02" name=".PSC02"></tt> command was given).
|
<tt><ref id=".PSC02" name=".PSC02"></tt> command was given).
|
||||||
<item>all valid 65C02 mnemonics when in 65C02 mode (after the
|
<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).
|
(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>
|
<sect1><tt>.IFPSC02</tt><label id=".IFPSC02"><p>
|
||||||
|
|
||||||
Conditional assembly: Check if the assembler is currently in 65SC02 mode
|
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>
|
<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>
|
<sect1><tt>.POPCPU</tt><label id=".POPCPU"><p>
|
||||||
|
|
||||||
Pop the last CPU setting from the stack, and activate it.
|
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
|
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
|
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,
|
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>,
|
See: <tt><ref id=".CPU" name=".CPU"></tt>,
|
||||||
<tt><ref id=".IFP02" name=".IFP02"></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=".IFP816" name=".IFP816"></tt>,
|
||||||
<tt><ref id=".IFPC02" name=".IFPC02"></tt>,
|
<tt><ref id=".IFPC02" name=".IFPC02"></tt>,
|
||||||
<tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
|
<tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
|
||||||
@@ -4586,6 +4603,7 @@ each supported CPU a constant similar to
|
|||||||
CPU_SWEET16
|
CPU_SWEET16
|
||||||
CPU_HUC6280
|
CPU_HUC6280
|
||||||
CPU_4510
|
CPU_4510
|
||||||
|
CPU_6502DTV
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
is defined. These constants may be used to determine the exact type of the
|
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_SWEET16
|
||||||
CPU_ISET_HUC6280
|
CPU_ISET_HUC6280
|
||||||
CPU_ISET_4510
|
CPU_ISET_4510
|
||||||
|
CPU_ISET_6502DTV
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may
|
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">
|
<url url="mailto:gregdk@users.sf.net" name="Greg King">
|
||||||
|
|
||||||
<abstract>
|
<abstract>
|
||||||
cc65 is a C compiler for 6502 targets. It supports several 6502 based home
|
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.
|
computers such as the Commodore and Atari machines, but it easily is
|
||||||
|
retargetable.
|
||||||
</abstract>
|
</abstract>
|
||||||
|
|
||||||
<!-- Table of contents -->
|
<!-- Table of contents -->
|
||||||
@@ -548,6 +549,8 @@ Here is a description of all the command line options:
|
|||||||
<tag><tt/remap-zero/</tag>
|
<tag><tt/remap-zero/</tag>
|
||||||
Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/
|
Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/
|
||||||
that changes a character's code number from/to 0x00.
|
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>
|
<tag><tt/struct-param/</tag>
|
||||||
Warn when passing structs by value.
|
Warn when passing structs by value.
|
||||||
<tag><tt/unknown-pragma/</tag>
|
<tag><tt/unknown-pragma/</tag>
|
||||||
@@ -706,12 +709,13 @@ This cc65 version has some extensions to the ISO C standard.
|
|||||||
places.
|
places.
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/.
|
<item> There are three pseudo variables named <tt/__A__/, <tt/__AX__/ and
|
||||||
Both refer to the primary register that is used by the compiler to
|
<tt/__EAX__/. They all refer to the primary register that is used
|
||||||
evaluate expressions or return function results. <tt/__AX__/ is of
|
by the compiler to evaluate expressions or return function results.
|
||||||
type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/
|
<tt/__A__/ is of type <tt/unsigned char/, <tt/__AX__/ is of type
|
||||||
respectively. The pseudo variables may be used as lvalue and rvalue as
|
<tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/
|
||||||
every other variable. They are most useful together with short
|
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
|
sequences of assembler code. For example, the macro
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
@@ -1045,26 +1049,39 @@ parameter with the <tt/#pragma/.
|
|||||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
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
|
This pragma changes the name used for the BSS segment (the BSS segment is
|
||||||
is used to store variables with static storage duration and no explicit
|
used to store variables with static storage duration and no explicit
|
||||||
initializer). The argument is a string enclosed in double quotes.
|
initializers). The <tt/name/ argument is a string enclosed in quotation
|
||||||
|
marks.
|
||||||
|
|
||||||
Note: The default linker configuration file does only map the standard
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||||
segments. If you use other segments, you have to create a new linker
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||||
configuration file.
|
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
|
Note: The default linker configuration file maps only the standard segments.
|
||||||
use another BSS segment, you have to do that yourself, otherwise
|
If you use other segments, you must create a new linker configuration file.
|
||||||
variables with static storage duration and no explicit initializer will
|
|
||||||
not have the value zero.
|
|
||||||
|
|
||||||
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>
|
<tscreen><verb>
|
||||||
#pragma bss-name ("MyBSS")
|
#pragma bss-name ("MyBSS")
|
||||||
|
#pragma bss-name (push, "MyBSS")
|
||||||
|
#pragma bss-name ("MyBSS", "zp")
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
|
|
||||||
@@ -1120,21 +1137,33 @@ parameter with the <tt/#pragma/.
|
|||||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
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
|
This pragma changes the name used for the CODE segment (the CODE segment is
|
||||||
is used to store executable code). The argument is a string enclosed in
|
used to store executable code). The <tt/name/ argument is a string enclosed
|
||||||
double quotes.
|
in quotation marks.
|
||||||
|
|
||||||
Note: The default linker configuration file does only map the standard
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||||
segments. If you use other segments, you have to create a new linker
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||||
configuration file.
|
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>
|
<tscreen><verb>
|
||||||
#pragma code-name ("MyCODE")
|
#pragma code-name ("MyCODE")
|
||||||
|
#pragma code-name (push, "MyCODE")
|
||||||
|
#pragma code-name (push, "MyCODE", "far")
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
|
|
||||||
@@ -1148,21 +1177,33 @@ parameter with the <tt/#pragma/.
|
|||||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
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
|
This pragma changes the name used for the DATA segment (the DATA segment is
|
||||||
is used to store initialized data). The argument is a string enclosed in
|
used to store initialized data). The <tt/name/ argument is a string enclosed
|
||||||
double quotes.
|
in quotation marks.
|
||||||
|
|
||||||
Note: The default linker configuration file does only map the standard
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||||
segments. If you use other segments, you have to create a new linker
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||||
configuration file.
|
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>
|
<tscreen><verb>
|
||||||
#pragma data-name ("MyDATA")
|
#pragma data-name ("MyDATA")
|
||||||
|
#pragma data-name (push, "MyDATA")
|
||||||
|
#pragma data-name ("MyDATA", "zeropage")
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
|
|
||||||
@@ -1224,21 +1265,32 @@ parameter with the <tt/#pragma/.
|
|||||||
The <tt/#pragma/ understands the push and pop parameters as explained above.
|
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
|
This pragma changes the name used for the RODATA segment (the RODATA segment
|
||||||
segment is used to store readonly data). The argument is a string
|
is used to store read-only data). The <tt/name/ argument is a string enclosed
|
||||||
enclosed in double quotes.
|
in quotation marks.
|
||||||
|
|
||||||
Note: The default linker configuration file does only map the standard
|
<tt/addrsize/ is an optional string that gives a hint about where the
|
||||||
segments. If you use other segments, you have to create a new linker
|
<tt/name/ segment will be put in the CPU's address space. It describes the
|
||||||
configuration file.
|
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>
|
<tscreen><verb>
|
||||||
#pragma rodata-name ("MyRODATA")
|
#pragma rodata-name ("MyRODATA")
|
||||||
|
#pragma rodata-name (push, "MyRODATA")
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -112,15 +112,17 @@ Here is a description of all the command line options:
|
|||||||
<itemize>
|
<itemize>
|
||||||
<item>6502
|
<item>6502
|
||||||
<item>6502x
|
<item>6502x
|
||||||
|
<item>6502dtv
|
||||||
<item>65sc02
|
<item>65sc02
|
||||||
<item>65c02
|
<item>65c02
|
||||||
<item>huc6280
|
<item>huc6280
|
||||||
<item>4510
|
<item>4510
|
||||||
</itemize>
|
</itemize>
|
||||||
|
|
||||||
6502x is for the NMOS 6502 with unofficial opcodes. huc6280 is the CPU of
|
6502x is for the NMOS 6502 with unofficial opcodes. 6502dtv is for the
|
||||||
the PC engine. 4510 is the CPU of the Commodore C65. Support for the 65816
|
emulated CPU of the C64DTV device. huc6280 is the CPU of the PC engine.
|
||||||
currently is not available.
|
4510 is the CPU of the Commodore C65. Support for the 65816 currently
|
||||||
|
is not available.
|
||||||
|
|
||||||
|
|
||||||
<label id="option--formfeeds">
|
<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
|
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
|
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
|
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
|
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
|
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>
|
<p>
|
||||||
<tt/struct filehandle *GetNxtDirEntry (void)/
|
<tt/struct filehandle *GetNxtDirEntry (void)/
|
||||||
<p>
|
<p>
|
||||||
These two functions are best suited for scanning the whole directory for particular files. Note that
|
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 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/
|
The return value is <tt/NULL/ if there are no more slots, or if there was a disk error. The
|
||||||
function or read directly after a call to those two functions from <tt/r5/. The current sector number
|
<tt/_oserror/ variable is non-zero if it was a disk error (see <tt>geos/gdisk.h</tt>). The current
|
||||||
is in <tt/r1/ and the sector data itself is in <tt/diskBlkBuf/.
|
directory track and sector numbers are in <tt/r1L/ and <tt/r1H/. The sector data itself is in
|
||||||
|
<tt/diskBlkBuf/.
|
||||||
|
|
||||||
<sect3>FindFile
|
<sect3>FindFile
|
||||||
<p>
|
<p>
|
||||||
<tt/char FindFile (char *fName)/
|
<tt/char FindFile (char *fName)/
|
||||||
<p>
|
<p>
|
||||||
This function scans the whole directory for the given filename. It returns either 0 (success) or 5
|
This function scans the whole directory for the given filename. It returns either 0 (success), 5
|
||||||
(FILE_NOT_FOUND, defined in <tt/gdisk.h/) or any other fatal disk read error. After a successful
|
(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
|
<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/.
|
other registers set as described in <tt/GetNxtDirEntry()/.
|
||||||
|
|
||||||
<sect3>FindFTypes
|
<sect3>FindFTypes
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -921,9 +921,8 @@ name="6502 binary relocation format specification">). It is defined like this:
|
|||||||
}
|
}
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
The other format available is the Atari (xex) segmented file format, this is
|
The other format available is the Atari segmented file format (xex), this is
|
||||||
the standard format used by Atari DOS 2.0 and upward file managers in the Atari
|
the standard format used by Atari DOS 2.0 and upwards, and it is defined like this:
|
||||||
8-bit computers, and it is defined like this:
|
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
FILES {
|
FILES {
|
||||||
@@ -1010,7 +1009,8 @@ The <tt/CONDES/ feature has several attributes:
|
|||||||
<tag><tt>segment</tt></tag>
|
<tag><tt>segment</tt></tag>
|
||||||
|
|
||||||
This attribute tells the linker into which segment the table should be
|
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>
|
<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
|
Without specifying the <tt/CONDES/ feature, the linker will not create any
|
||||||
tables, even if there are <tt/condes/ entries in the object files.
|
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">.
|
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
|
the compiler and the libraries that come with it. If you replace the builtin
|
||||||
config files, you will need the following information.
|
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>
|
<sect1>ONCE<p>
|
||||||
|
|
||||||
The ONCE segment is used for initialization code run only once before
|
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
|
may for example add the ONCE segment to the heap in really memory
|
||||||
constrained systems.
|
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>
|
<sect1>STARTUP<p>
|
||||||
|
|
||||||
This segment contains the startup code which initializes the C software stack
|
This segment contains the startup code which initializes the C software stack
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ declaration and usage.
|
|||||||
<item>cbm_save
|
<item>cbm_save
|
||||||
<item>cbm_write
|
<item>cbm_write
|
||||||
<item>get_tv
|
<item>get_tv
|
||||||
|
<item>waitvsync
|
||||||
</itemize>
|
</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> */
|
/* Freddy Offenga <taf_offenga@yahoo.com> */
|
||||||
/* Christian Groessler <chris@groessler.org> */
|
/* Christian Groessler <chris@groessler.org> */
|
||||||
/* Bill Kendrick <nbs@sonic.net> */
|
/* Bill Kendrick <nbs@sonic.net> */
|
||||||
|
/* et al. */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -219,7 +220,7 @@
|
|||||||
/* Color register functions */
|
/* 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 void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value);
|
||||||
extern unsigned char __fastcall__ _getcolor (unsigned char color_reg);
|
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 */
|
/* 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 int __fastcall__ _graphics (unsigned char mode); /* mode value same as in BASIC */
|
||||||
extern void __fastcall__ _scroll (signed char numlines);
|
extern void __fastcall__ _scroll (signed char numlines);
|
||||||
/* numlines > 0 scrolls up */
|
/* numlines > 0 scrolls up */
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Check for errors */
|
/* check for errors */
|
||||||
#if !defined(__ATARI5200__)
|
#if !defined(__ATARI5200__)
|
||||||
# error This module may only be used when compiling for the Atari 5200!
|
# error This module may only be used when compiling for the Atari 5200!
|
||||||
#endif
|
#endif
|
||||||
@@ -46,14 +46,14 @@
|
|||||||
/* the addresses of the static drivers */
|
/* the addresses of the static drivers */
|
||||||
extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */
|
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_UP_MASK 0x01
|
||||||
#define JOY_DOWN_MASK 0x02
|
#define JOY_DOWN_MASK 0x02
|
||||||
#define JOY_LEFT_MASK 0x04
|
#define JOY_LEFT_MASK 0x04
|
||||||
#define JOY_RIGHT_MASK 0x08
|
#define JOY_RIGHT_MASK 0x08
|
||||||
#define JOY_BTN_1_MASK 0x10
|
#define JOY_BTN_1_MASK 0x10
|
||||||
|
|
||||||
/* Character codes */
|
/* character codes */
|
||||||
#define CH_ULCORNER 0x0B /* '+' sign */
|
#define CH_ULCORNER 0x0B /* '+' sign */
|
||||||
#define CH_URCORNER 0x0B
|
#define CH_URCORNER 0x0B
|
||||||
#define CH_LLCORNER 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_NTSC 0
|
||||||
#define AT_PAL 1
|
#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>
|
#include <_gtia.h>
|
||||||
#define GTIA_READ (*(struct __gtia_read*)0xC000)
|
#define GTIA_READ (*(struct __gtia_read*)0xC000)
|
||||||
#define GTIA_WRITE (*(struct __gtia_write*)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
|
#define _bordercolor(color) 0
|
||||||
|
|
||||||
/* End of atari5200.h */
|
/* wait for start of next frame */
|
||||||
|
extern void waitvsync (void);
|
||||||
|
|
||||||
|
/* end of atari5200.h */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ unsigned char get_tv (void);
|
|||||||
unsigned char __fastcall__ kbrepeat (unsigned char mode);
|
unsigned char __fastcall__ kbrepeat (unsigned char mode);
|
||||||
/* Changes which keys have automatic repeat. */
|
/* Changes which keys have automatic repeat. */
|
||||||
|
|
||||||
#if !defined(__CBM610__) && !defined(__PET__)
|
#if !defined(__CBM610__)
|
||||||
void waitvsync (void);
|
void waitvsync (void);
|
||||||
/* Wait for the start of the next video field. */
|
/* Wait for the start of the next video field. */
|
||||||
#endif
|
#endif
|
||||||
@@ -191,6 +191,8 @@ unsigned char cbm_k_acptr (void);
|
|||||||
unsigned char cbm_k_basin (void);
|
unsigned char cbm_k_basin (void);
|
||||||
void __fastcall__ cbm_k_bsout (unsigned char C);
|
void __fastcall__ cbm_k_bsout (unsigned char C);
|
||||||
unsigned char __fastcall__ cbm_k_chkin (unsigned char FN);
|
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);
|
void __fastcall__ cbm_k_ciout (unsigned char C);
|
||||||
unsigned char __fastcall__ cbm_k_ckout (unsigned char FN);
|
unsigned char __fastcall__ cbm_k_ckout (unsigned char FN);
|
||||||
void cbm_k_clall (void);
|
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.
|
/* Reads one directory line into cbm_dirent structure.
|
||||||
** Returns 0 if reading directory-line was successful.
|
** Returns 0 if reading directory-line was successful.
|
||||||
** Returns non-zero if reading directory failed, or no more file-names to read.
|
** 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);
|
void __fastcall__ cbm_closedir (unsigned char lfn);
|
||||||
|
|||||||
@@ -83,46 +83,31 @@ extern struct _timezone {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__ATARI__)
|
#if defined(__ATARI5200__)
|
||||||
/* The clock depends on the video standard, so read it at runtime */
|
# define CLOCKS_PER_SEC 60
|
||||||
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 */
|
|
||||||
#elif defined(__ATMOS__)
|
#elif defined(__ATMOS__)
|
||||||
# define CLK_TCK 100 /* POSIX */
|
# define CLOCKS_PER_SEC 100
|
||||||
# define CLOCKS_PER_SEC 100 /* ANSI */
|
|
||||||
#elif defined(__CBM__)
|
#elif defined(__CBM__)
|
||||||
# if defined(__CBM510__) || defined(__CBM610__)
|
# if defined(__CBM510__) || defined(__CBM610__)
|
||||||
/* The 510/610 gets its clock from the AC current */
|
/* The 510/610 gets its clock from the AC current */
|
||||||
# define CLK_TCK 50 /* POSIX */
|
# define CLOCKS_PER_SEC 50
|
||||||
# define CLOCKS_PER_SEC 50 /* ANSI */
|
|
||||||
# else
|
# else
|
||||||
# define CLK_TCK 60 /* POSIX */
|
# define CLOCKS_PER_SEC 60
|
||||||
# define CLOCKS_PER_SEC 60 /* ANSI */
|
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__NES__)
|
#elif defined(__NES__)
|
||||||
# define CLK_TCK 50 /* POSIX */
|
# define CLOCKS_PER_SEC 50
|
||||||
# define CLOCKS_PER_SEC 50 /* ANSI */
|
|
||||||
#elif defined(__PCE__)
|
#elif defined(__PCE__)
|
||||||
# define CLK_TCK 60 /* POSIX */
|
# define CLOCKS_PER_SEC 60
|
||||||
# define CLOCKS_PER_SEC 60 /* ANSI */
|
|
||||||
#elif defined(__GAMATE__)
|
#elif defined(__GAMATE__)
|
||||||
# define CLK_TCK 135 /* POSIX */ /* FIXME */
|
# define CLOCKS_PER_SEC 135 /* FIXME */
|
||||||
# define CLOCKS_PER_SEC 135 /* ANSI */ /* FIXME */
|
|
||||||
#elif defined(__GEOS__)
|
#elif defined(__GEOS__)
|
||||||
# define CLK_TCK 1 /* POSIX */
|
# define CLOCKS_PER_SEC 1
|
||||||
# define CLOCKS_PER_SEC 1 /* ANSI */
|
#else
|
||||||
#elif defined(__LYNX__)
|
/* Read the clock rate at runtime */
|
||||||
/* The clock-rate depends on the video scan-rate;
|
clock_t _clocks_per_sec (void);
|
||||||
** so, read it at run-time.
|
# define CLOCKS_PER_SEC _clocks_per_sec()
|
||||||
*/
|
|
||||||
extern clock_t _clk_tck (void);
|
|
||||||
# define CLK_TCK _clk_tck()
|
|
||||||
# define CLOCKS_PER_SEC _clk_tck()
|
|
||||||
#endif
|
#endif
|
||||||
|
#define CLK_TCK CLOCKS_PER_SEC
|
||||||
#define CLOCK_REALTIME 0
|
#define CLOCK_REALTIME 0
|
||||||
|
|
||||||
|
|
||||||
@@ -149,6 +134,3 @@ int __fastcall__ clock_settime (clockid_t clock_id, const struct timespec *tp);
|
|||||||
/* End of time.h */
|
/* End of time.h */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -133,8 +133,7 @@ MKINC = $(GEOS) \
|
|||||||
|
|
||||||
TARGETUTIL = apple2 \
|
TARGETUTIL = apple2 \
|
||||||
apple2enh \
|
apple2enh \
|
||||||
atari \
|
atari
|
||||||
geos-apple
|
|
||||||
|
|
||||||
GEOSDIRS = common \
|
GEOSDIRS = common \
|
||||||
conio \
|
conio \
|
||||||
|
|||||||
@@ -19,11 +19,14 @@
|
|||||||
.segment "ONCE"
|
.segment "ONCE"
|
||||||
|
|
||||||
initprompt:
|
initprompt:
|
||||||
; Set prompt <> ']' to let DOS 3.3 know that we're
|
; Set prompt <> ']' and currently executed Applesoft
|
||||||
; not in Applesoft immediate mode and thus keep it
|
; line number hibyte <> $FF to let DOS 3.3 (at $A65E)
|
||||||
; from scanning our device I/O for DOS commands.
|
; 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
|
lda #$80 ; Same value used at $D52C
|
||||||
sta PROMPT
|
sta PROMPT
|
||||||
|
sta CURLIN+1 ; Any value <> $FF will do
|
||||||
rts
|
rts
|
||||||
|
|
||||||
.code
|
.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)
|
../libwrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../libwrk/$(TARGET)
|
||||||
$(ASSEMBLE_recipe)
|
$(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
|
../target/$(TARGET)/util/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../target/$(TARGET)/util
|
||||||
$(LD65) -o $@ -C $(filter %.cfg,$^) $(filter-out %.cfg,$^)
|
$(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
|
; originally by Ullrich von Bassewitz and Sidney Cadot
|
||||||
;
|
;
|
||||||
; clock_t clock (void);
|
; clock_t clock (void);
|
||||||
; unsigned _clocks_per_sec (void);
|
; clock_t _clocks_per_sec (void);
|
||||||
;
|
;
|
||||||
|
|
||||||
.export _clock, __clocks_per_sec
|
.export _clock, __clocks_per_sec
|
||||||
@@ -30,8 +30,10 @@
|
|||||||
|
|
||||||
.proc __clocks_per_sec
|
.proc __clocks_per_sec
|
||||||
|
|
||||||
ldx #$00 ; Clear high byte of return value
|
ldx #$00 ; Clear byte 1 of return value
|
||||||
lda PAL ; use hw register, PALNTS is only supported on XL/XE ROM
|
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
|
and #$0e
|
||||||
bne @NTSC
|
bne @NTSC
|
||||||
lda #50
|
lda #50
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
;
|
;
|
||||||
; Christian Groessler, June-2016
|
; 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
|
; returns 0/1 if after program termination the screen isn't/is cleared
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
SHRAM_HANDLERS = 1
|
SHRAM_HANDLERS = 1
|
||||||
.include "atari.inc"
|
.include "atari.inc"
|
||||||
.include "romswitch.inc"
|
.include "romswitch.inc"
|
||||||
|
.import __CHARGEN_START__
|
||||||
.export set_VTIMR1_handler
|
.export set_VTIMR1_handler
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
SHRAM_HANDLERS = 1
|
SHRAM_HANDLERS = 1
|
||||||
.include "atari.inc"
|
.include "atari.inc"
|
||||||
.include "romswitch.inc"
|
.include "romswitch.inc"
|
||||||
|
.import __CHARGEN_START__
|
||||||
.export set_VTIMR2_handler
|
.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
|
; from Atari computer version by Christian Groessler, 2014
|
||||||
;
|
;
|
||||||
; clock_t clock (void);
|
; clock_t clock (void);
|
||||||
; unsigned _clocks_per_sec (void);
|
|
||||||
;
|
;
|
||||||
|
|
||||||
.export _clock
|
.export _clock
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
.import zerobss, copydata
|
.import zerobss, copydata
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
.include "atari5200.inc"
|
|
||||||
|
|
||||||
start:
|
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 _cputcxy, _cputc
|
||||||
.export setscrptr, putchar
|
.export setscrptr, cputdirect, putchar
|
||||||
.constructor initcputc
|
.constructor initcputc
|
||||||
.import rvs
|
.import rvs
|
||||||
.import popax
|
.import popax
|
||||||
@@ -32,13 +32,13 @@ _cputc: cmp #$0D ; CR?
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
L1: cmp #$0A ; LF?
|
L1: cmp #$0A ; LF?
|
||||||
bne output
|
bne cputdirect
|
||||||
inc CURS_Y ; Newline
|
inc CURS_Y ; Newline
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Output the character, then advance the cursor position
|
; Output the character, then advance the cursor position
|
||||||
|
|
||||||
output:
|
cputdirect:
|
||||||
jsr putchar
|
jsr putchar
|
||||||
|
|
||||||
advance:
|
advance:
|
||||||
|
|||||||
@@ -20,18 +20,19 @@
|
|||||||
|
|
||||||
sta ptr3
|
sta ptr3
|
||||||
stx ptr3+1 ; save count as result
|
stx ptr3+1 ; save count as result
|
||||||
eor #$FF
|
|
||||||
sta ptr2
|
inx
|
||||||
txa
|
stx ptr2+1
|
||||||
eor #$FF
|
tax
|
||||||
sta ptr2+1 ; Remember -count-1
|
inx
|
||||||
|
stx ptr2 ; save count with each byte incremented separately
|
||||||
|
|
||||||
jsr popptr1 ; get buf
|
jsr popptr1 ; get buf
|
||||||
jsr popax ; get fd and discard
|
jsr popax ; get fd and discard
|
||||||
|
|
||||||
L1: inc ptr2
|
L1: dec ptr2
|
||||||
bnz L2
|
bnz L2
|
||||||
inc ptr2+1
|
dec ptr2+1
|
||||||
bze L9 ; no more room in buf
|
bze L9 ; no more room in buf
|
||||||
|
|
||||||
; If there are no more characters in BASIC's input buffer, then get a line from
|
; If there are no more characters in BASIC's input buffer, then get a line from
|
||||||
|
|||||||
@@ -17,17 +17,17 @@
|
|||||||
sta ptr3
|
sta ptr3
|
||||||
stx ptr3+1 ; save count as result
|
stx ptr3+1 ; save count as result
|
||||||
|
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr2
|
stx ptr2+1
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr2+1 ; Remember -count-1
|
stx ptr2 ; save count with each byte incremented separately
|
||||||
|
|
||||||
jsr popptr1 ; get buf
|
jsr popptr1 ; get buf
|
||||||
jsr popax ; get fd and discard
|
jsr popax ; get fd and discard
|
||||||
L1: inc ptr2
|
L1: dec ptr2
|
||||||
bne L2
|
bne L2
|
||||||
inc ptr2+1
|
dec ptr2+1
|
||||||
beq L9
|
beq L9
|
||||||
L2: ldy #0
|
L2: ldy #0
|
||||||
lda (ptr1),y
|
lda (ptr1),y
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
MOUSE_SPR = 0 ; Sprite used for the mouse
|
MOUSE_SPR = 0 ; Sprite used for the mouse
|
||||||
MOUSE_SPR_MEM = $0E00 ; Memory location
|
MOUSE_SPR_MEM = $0E00 ; Memory location
|
||||||
MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask
|
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_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register
|
||||||
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
|
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
.importzp ST
|
.importzp ST
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
.include "plus4.inc"
|
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Startup code
|
; Startup code
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
.importzp ST
|
.importzp ST
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
.include "c64.inc"
|
|
||||||
|
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
; of the sprite used for the mouse. All others depend on this value.
|
; of the sprite used for the mouse. All others depend on this value.
|
||||||
MOUSE_SPR = 0 ; Sprite used for the mouse
|
MOUSE_SPR = 0 ; Sprite used for the mouse
|
||||||
MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask
|
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_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register
|
||||||
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
|
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,16 @@
|
|||||||
; Ullrich von Bassewitz, 03.06.1999
|
; Ullrich von Bassewitz, 03.06.1999
|
||||||
;
|
;
|
||||||
; unsigned char cbm_k_basin (void);
|
; unsigned char cbm_k_basin (void);
|
||||||
|
; unsigned char cbm_k_chrin (void);
|
||||||
;
|
;
|
||||||
|
|
||||||
.include "cbm.inc"
|
.include "cbm.inc"
|
||||||
|
|
||||||
.export _cbm_k_basin
|
.export _cbm_k_basin, _cbm_k_chrin
|
||||||
|
|
||||||
|
|
||||||
_cbm_k_basin:
|
_cbm_k_basin:
|
||||||
|
_cbm_k_chrin:
|
||||||
jsr BASIN
|
jsr BASIN
|
||||||
ldx #0 ; Clear high byte
|
ldx #0 ; Clear high byte
|
||||||
rts
|
rts
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
; Ullrich von Bassewitz, 03.06.1999
|
; Ullrich von Bassewitz, 03.06.1999
|
||||||
;
|
;
|
||||||
; void __fastcall__ cbm_k_bsout (unsigned char C);
|
; void __fastcall__ cbm_k_bsout (unsigned char C);
|
||||||
|
; void __fastcall__ cbm_k_chrout (unsigned char C);
|
||||||
;
|
;
|
||||||
|
|
||||||
.include "cbm.inc"
|
.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 */
|
/* 2009-10-10 -- Version 0.3 */
|
||||||
/* 2011-04-07 -- Version 0.4, groepaz */
|
/* 2011-04-07 -- Version 0.4, groepaz */
|
||||||
/* 2011-04-14 -- Version 0.5, Greg King */
|
/* 2011-04-14 -- Version 0.5, Greg King */
|
||||||
|
/* 2021-02-15 -- Version 0.6, Greg King */
|
||||||
|
|
||||||
/* Tested with floppy-drive and IDE64 devices. */
|
/* Tested with floppy-drive and IDE64 devices. */
|
||||||
/* Not tested with messed (buggy) directory listings. */
|
/* Not tested with messed (buggy) directory listings. */
|
||||||
@@ -29,7 +30,7 @@ unsigned char cbm_opendir (unsigned char lfn, unsigned char device, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
const char* name = "$";
|
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) {
|
if (__argsize__ == 4) {
|
||||||
va_start (ap, device);
|
va_start (ap, device);
|
||||||
name = va_arg (ap, const char*);
|
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();
|
byte = cbm_k_basin();
|
||||||
switch (byte) {
|
switch (byte) {
|
||||||
|
/* "B" BLOCKS FREE/USED. */
|
||||||
/* "B" BLOCKS FREE. */
|
/* "M" MB FREE. */
|
||||||
case 'b':
|
case 'b':
|
||||||
|
case 'm':
|
||||||
/* Read until end; careless callers might call us again. */
|
/* Read until end; careless callers might call us again. */
|
||||||
while (!cbm_k_readst()) {
|
while (!cbm_k_readst()) {
|
||||||
cbm_k_basin();
|
cbm_k_basin();
|
||||||
@@ -168,7 +170,6 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d
|
|||||||
}
|
}
|
||||||
|
|
||||||
rv = 0;
|
rv = 0;
|
||||||
goto ret_val;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,11 @@
|
|||||||
|
|
||||||
|
|
||||||
_cbm_read:
|
_cbm_read:
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr1
|
stx ptr1+1
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr1+1 ; Save -size-1
|
stx ptr1 ; Save size with both bytes incremented separately.
|
||||||
|
|
||||||
jsr popax
|
jsr popax
|
||||||
sta ptr2
|
sta ptr2
|
||||||
@@ -92,9 +92,9 @@ _cbm_read:
|
|||||||
bne @L3
|
bne @L3
|
||||||
inc ptr3+1 ; ++bytesread;
|
inc ptr3+1 ; ++bytesread;
|
||||||
|
|
||||||
@L3: inc ptr1
|
@L3: dec ptr1
|
||||||
bne @L1
|
bne @L1
|
||||||
inc ptr1+1
|
dec ptr1+1
|
||||||
bne @L1
|
bne @L1
|
||||||
|
|
||||||
@L4: jsr CLRCH
|
@L4: jsr CLRCH
|
||||||
|
|||||||
@@ -39,11 +39,11 @@
|
|||||||
_cbm_write:
|
_cbm_write:
|
||||||
sta ptr3
|
sta ptr3
|
||||||
stx ptr3+1 ; Save size
|
stx ptr3+1 ; Save size
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr1
|
stx ptr1+1
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr1+1 ; Save -size-1
|
stx ptr1 ; Save size with both bytes incremented separately
|
||||||
|
|
||||||
jsr popax
|
jsr popax
|
||||||
sta ptr2
|
sta ptr2
|
||||||
@@ -69,9 +69,9 @@ _cbm_write:
|
|||||||
|
|
||||||
@L2: jsr BSOUT ; cbm_k_bsout (A);
|
@L2: jsr BSOUT ; cbm_k_bsout (A);
|
||||||
|
|
||||||
@L3: inc ptr1 ; --size;
|
@L3: dec ptr1 ; --size;
|
||||||
bne @L1
|
bne @L1
|
||||||
inc ptr1+1
|
dec ptr1+1
|
||||||
bne @L1
|
bne @L1
|
||||||
|
|
||||||
jsr CLRCH
|
jsr CLRCH
|
||||||
|
|||||||
@@ -106,9 +106,9 @@
|
|||||||
|
|
||||||
; Decrement the count
|
; Decrement the count
|
||||||
|
|
||||||
@L3: inc ptr2
|
@L3: dec ptr2
|
||||||
bne @L0
|
bne @L0
|
||||||
inc ptr2+1
|
dec ptr2+1
|
||||||
bne @L0
|
bne @L0
|
||||||
beq done ; Branch always
|
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 */
|
/* Bump the directory offset and include the bytes for line-link and size */
|
||||||
dir->off += count + 4;
|
dir->off += count + 4;
|
||||||
|
|
||||||
/* End of directory is reached if the buffer contains "blocks free". It is
|
/* End of directory is reached if the buffer contains "blocks free/used" or
|
||||||
** sufficient here to check for the leading 'b'. buffer will contain at
|
** "mb free.". It is sufficient here to check for the leading 'b' and 'm'.
|
||||||
** least one byte if we come here.
|
** buffer will contain at least one byte if we come here.
|
||||||
*/
|
*/
|
||||||
if (buffer[0] == 'b') {
|
switch (buffer[0]) {
|
||||||
|
case 'b':
|
||||||
|
case 'm':
|
||||||
goto exitpoint;
|
goto exitpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +71,6 @@ struct dirent* __fastcall__ readdir (register DIR* dir)
|
|||||||
b = buffer;
|
b = buffer;
|
||||||
while (i < count) {
|
while (i < count) {
|
||||||
switch (s) {
|
switch (s) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
/* Searching for start of file name */
|
/* Searching for start of file name */
|
||||||
if (*b == '"') {
|
if (*b == '"') {
|
||||||
@@ -127,6 +130,3 @@ struct dirent* __fastcall__ readdir (register DIR* dir)
|
|||||||
exitpoint:
|
exitpoint:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
.proc rwcommon
|
.proc rwcommon
|
||||||
|
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr2
|
stx ptr2+1
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr2+1 ; Remember -count-1
|
stx ptr2 ; Save count with each byte incremented separately
|
||||||
|
|
||||||
jsr popptr1 ; Get buf to ptr1, Y=0 by call
|
jsr popptr1 ; Get buf to ptr1, Y=0 by call
|
||||||
|
|
||||||
|
|||||||
@@ -83,9 +83,9 @@
|
|||||||
|
|
||||||
; Decrement count
|
; Decrement count
|
||||||
|
|
||||||
@L2: inc ptr2
|
@L2: dec ptr2
|
||||||
bne @L0
|
bne @L0
|
||||||
inc ptr2+1
|
dec ptr2+1
|
||||||
bne @L0
|
bne @L0
|
||||||
|
|
||||||
; Wrote all chars or disk full. Close the output channel
|
; Wrote all chars or disk full. Close the output channel
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
MOUSE_SPR = 0 ; Sprite used for the mouse
|
MOUSE_SPR = 0 ; Sprite used for the mouse
|
||||||
MOUSE_SPR_MEM = $F400 ; Memory location
|
MOUSE_SPR_MEM = $F400 ; Memory location
|
||||||
MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask
|
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_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register
|
||||||
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
|
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
|
||||||
|
|
||||||
|
|||||||
@@ -17,22 +17,22 @@
|
|||||||
|
|
||||||
.proc _getcwd
|
.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
|
inx
|
||||||
sta ptr2
|
stx ptr2+1
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr2+1
|
stx ptr2 ; Save size with each byte incremented separately
|
||||||
|
|
||||||
jsr popptr1 ; Get buf to ptr1
|
jsr popptr1 ; Get buf to ptr1
|
||||||
|
|
||||||
; Copy __cwd to the given buffer checking the length
|
; Copy __cwd to the given buffer checking the length
|
||||||
|
|
||||||
; ldy #$00 is guaranteed by popptr1
|
; ldy #$00 is guaranteed by popptr1
|
||||||
loop: inc ptr2
|
loop: dec ptr2
|
||||||
bne @L1
|
bne @L1
|
||||||
inc ptr2+1
|
dec ptr2+1
|
||||||
beq overflow
|
beq overflow
|
||||||
|
|
||||||
; Copy one character, end the loop if the zero terminator is reached. We
|
; Copy one character, end the loop if the zero terminator is reached. We
|
||||||
|
|||||||
@@ -10,14 +10,14 @@
|
|||||||
|
|
||||||
_memcmp:
|
_memcmp:
|
||||||
|
|
||||||
; Calculate (-count-1) and store it into ptr3. This is some overhead here but
|
; Calculate a special count, and store it into ptr3. That is some overhead here,
|
||||||
; saves time in the compare loop
|
; but saves time in the compare loop
|
||||||
|
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr3
|
stx ptr3+1
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr3+1
|
stx ptr3 ; Save count with each byte incremented separately
|
||||||
|
|
||||||
; Get the pointer parameters
|
; Get the pointer parameters
|
||||||
|
|
||||||
@@ -29,12 +29,12 @@ _memcmp:
|
|||||||
; Loop initialization
|
; Loop initialization
|
||||||
|
|
||||||
;ldy #$00 ; Initialize pointer (Y=0 guaranteed by popptr1)
|
;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
|
; Head of compare loop: Test for the end condition
|
||||||
|
|
||||||
Loop: inx ; Bump low byte of (-count-1)
|
Loop: dex
|
||||||
beq BumpHiCnt ; Jump on overflow
|
beq BumpHiCnt ; Jump on end of inner count
|
||||||
|
|
||||||
; Do the compare
|
; Do the compare
|
||||||
|
|
||||||
@@ -50,10 +50,10 @@ Comp: lda (ptr1),y
|
|||||||
inc ptr2+1
|
inc ptr2+1
|
||||||
bne Loop ; Branch always (pointer wrap is illegal)
|
bne Loop ; Branch always (pointer wrap is illegal)
|
||||||
|
|
||||||
; Entry on low counter byte overflow
|
; Entry on inner loop end
|
||||||
|
|
||||||
BumpHiCnt:
|
BumpHiCnt:
|
||||||
inc ptr3+1 ; Bump high byte of (-count-1)
|
dec ptr3+1
|
||||||
bne Comp ; Jump if not done
|
bne Comp ; Jump if not done
|
||||||
jmp return0 ; Count is zero, areas are identical
|
jmp return0 ; Count is zero, areas are identical
|
||||||
|
|
||||||
@@ -67,4 +67,3 @@ NotEqual:
|
|||||||
Greater:
|
Greater:
|
||||||
ldx #$01 ; Make result positive
|
ldx #$01 ; Make result positive
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
.macpack cpu
|
.macpack cpu
|
||||||
|
|
||||||
_strncat:
|
_strncat:
|
||||||
eor #$FF ; one's complement to count upwards
|
inx
|
||||||
sta tmp1
|
stx tmp2
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta tmp2
|
stx tmp1 ; save count with each byte incremented separately
|
||||||
|
|
||||||
jsr popptr1 ; get src
|
jsr popptr1 ; get src
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ L2: sty ptr2
|
|||||||
L3: ldy #0
|
L3: ldy #0
|
||||||
ldx tmp1 ; low counter byte
|
ldx tmp1 ; low counter byte
|
||||||
|
|
||||||
L4: inx
|
L4: dex
|
||||||
bne L5
|
bne L5
|
||||||
inc tmp2
|
dec tmp2
|
||||||
beq L6 ; jump if done
|
beq L6 ; jump if done
|
||||||
L5: lda (ptr1),y
|
L5: lda (ptr1),y
|
||||||
sta (ptr2),y
|
sta (ptr2),y
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
.proc _strncpy
|
.proc _strncpy
|
||||||
|
|
||||||
eor #$FF
|
inx
|
||||||
sta tmp1
|
stx tmp2
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta tmp2 ; Store -size - 1
|
stx tmp1 ; save count with each byte incremented separately
|
||||||
|
|
||||||
jsr popptr1 ; get src
|
jsr popptr1 ; get src
|
||||||
jsr popax ; get dest
|
jsr popax ; get dest
|
||||||
@@ -24,11 +24,11 @@
|
|||||||
|
|
||||||
; Copy src -> dest up to size bytes
|
; Copy src -> dest up to size bytes
|
||||||
|
|
||||||
ldx tmp1 ; Load low byte of ones complement of size
|
ldx tmp1
|
||||||
ldy #$00
|
ldy #$00
|
||||||
L1: inx
|
L1: dex
|
||||||
bne L2
|
bne L2
|
||||||
inc tmp2
|
dec tmp2
|
||||||
beq L9
|
beq L9
|
||||||
|
|
||||||
L2: lda (ptr1),y ; Copy one character
|
L2: lda (ptr1),y ; Copy one character
|
||||||
@@ -42,8 +42,8 @@ L2: lda (ptr1),y ; Copy one character
|
|||||||
|
|
||||||
; Fill the remaining bytes.
|
; Fill the remaining bytes.
|
||||||
|
|
||||||
L3: inx ; Counter low byte
|
L3: dex ; Counter low byte
|
||||||
beq L6 ; Branch on overflow
|
beq L6
|
||||||
L4: sta (ptr2),y ; Clear one byte
|
L4: sta (ptr2),y ; Clear one byte
|
||||||
L5: iny ; Bump pointer
|
L5: iny ; Bump pointer
|
||||||
bne L3
|
bne L3
|
||||||
@@ -52,7 +52,7 @@ L5: iny ; Bump pointer
|
|||||||
|
|
||||||
; Bump the counter high byte
|
; Bump the counter high byte
|
||||||
|
|
||||||
L6: inc tmp2
|
L6: dec tmp2
|
||||||
bne L4
|
bne L4
|
||||||
|
|
||||||
; Done, return dest
|
; Done, return dest
|
||||||
|
|||||||
@@ -15,17 +15,11 @@
|
|||||||
_strnicmp:
|
_strnicmp:
|
||||||
_strncasecmp:
|
_strncasecmp:
|
||||||
|
|
||||||
; Convert the given counter value in a/x from a downward counter into an
|
inx
|
||||||
; upward counter, so we can increment the counter in the loop below instead
|
stx ptr3+1
|
||||||
; of decrementing it. This adds some overhead now, but is cheaper than
|
tax
|
||||||
; executing a more complex test in each iteration of the loop. We do also
|
inx
|
||||||
; correct the value by one, so we can do the test on top of the loop.
|
stx ptr3 ; save count with each byte incremented separately
|
||||||
|
|
||||||
eor #$FF
|
|
||||||
sta ptr3
|
|
||||||
txa
|
|
||||||
eor #$FF
|
|
||||||
sta ptr3+1
|
|
||||||
|
|
||||||
; Get the remaining arguments
|
; Get the remaining arguments
|
||||||
|
|
||||||
@@ -40,8 +34,8 @@ _strncasecmp:
|
|||||||
|
|
||||||
; Start of compare loop. Check the counter.
|
; Start of compare loop. Check the counter.
|
||||||
|
|
||||||
Loop: inc ptr3
|
Loop: dec ptr3 ; decrement high byte
|
||||||
beq IncHi ; increment high byte
|
beq IncHi
|
||||||
|
|
||||||
; Compare a byte from the strings
|
; Compare a byte from the strings
|
||||||
|
|
||||||
@@ -79,7 +73,7 @@ L2: ldx tmp1
|
|||||||
|
|
||||||
; Increment hi byte
|
; Increment hi byte
|
||||||
|
|
||||||
IncHi: inc ptr3+1
|
IncHi: dec ptr3+1
|
||||||
bne Comp ; jump if counter not zero
|
bne Comp ; jump if counter not zero
|
||||||
|
|
||||||
; Exit code if strings are equal. a/x not set
|
; Exit code if strings are equal. a/x not set
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ outdesc: ; Static outdesc structure
|
|||||||
|
|
||||||
out: jsr popax ; count
|
out: jsr popax ; count
|
||||||
sta ptr2
|
sta ptr2
|
||||||
eor #$FF
|
stx ptr2+1
|
||||||
sta outdesc+6
|
inx
|
||||||
txa
|
stx outdesc+7
|
||||||
sta ptr2+1
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta outdesc+7
|
stx outdesc+6
|
||||||
|
|
||||||
jsr popptr1 ; buf
|
jsr popptr1 ; buf
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ out: jsr popax ; count
|
|||||||
|
|
||||||
; Loop outputting characters
|
; Loop outputting characters
|
||||||
|
|
||||||
@L1: inc outdesc+6
|
@L1: dec outdesc+6
|
||||||
beq @L4
|
beq @L4
|
||||||
@L2: ldy tmp1
|
@L2: ldy tmp1
|
||||||
lda (ptr1),y
|
lda (ptr1),y
|
||||||
@@ -85,7 +85,7 @@ out: jsr popax ; count
|
|||||||
jsr _cputc
|
jsr _cputc
|
||||||
jmp @L1
|
jmp @L1
|
||||||
|
|
||||||
@L4: inc outdesc+7
|
@L4: dec outdesc+7
|
||||||
bne @L2
|
bne @L2
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ next: inx
|
|||||||
jsr closecmdchannel
|
jsr closecmdchannel
|
||||||
ldx tmp2
|
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).
|
; here too (instead of calling READST).
|
||||||
|
|
||||||
lda STATUS
|
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"
|
.include "geossym.inc"
|
||||||
|
|
||||||
_CalcBlksFree:
|
_CalcBlksFree:
|
||||||
|
lda #<curDirHead
|
||||||
|
ldx #>curDirHead
|
||||||
|
sta r5L
|
||||||
|
stx r5H
|
||||||
jsr CalcBlksFree
|
jsr CalcBlksFree
|
||||||
stx __oserror
|
stx __oserror
|
||||||
lda r4L
|
lda r4L
|
||||||
|
|||||||
@@ -94,11 +94,12 @@ _read:
|
|||||||
; popax - fd, must be == to the above one
|
; popax - fd, must be == to the above one
|
||||||
; return -1+__oserror or number of bytes read
|
; return -1+__oserror or number of bytes read
|
||||||
|
|
||||||
eor #$ff
|
inx
|
||||||
sta ptr1
|
stx ptr1+1
|
||||||
txa
|
tax
|
||||||
eor #$ff
|
inx
|
||||||
sta ptr1+1 ; -(# of bytes to read)-1
|
stx ptr1 ; save count with each byte incremented separately
|
||||||
|
|
||||||
jsr popax
|
jsr popax
|
||||||
sta ptr2
|
sta ptr2
|
||||||
stx ptr2+1 ; buffer ptr
|
stx ptr2+1 ; buffer ptr
|
||||||
@@ -152,9 +153,9 @@ _read:
|
|||||||
beq @done ; yes, we're done
|
beq @done ; yes, we're done
|
||||||
jmp __mappederrno ; no, we're screwed
|
jmp __mappederrno ; no, we're screwed
|
||||||
|
|
||||||
@L3: inc ptr1 ; decrement the count
|
@L3: dec ptr1 ; decrement the count
|
||||||
bne @L0
|
bne @L0
|
||||||
inc ptr1+1
|
dec ptr1+1
|
||||||
bne @L0
|
bne @L0
|
||||||
|
|
||||||
@done:
|
@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);
|
; struct filehandle* Get1stDirEntry (void);
|
||||||
|
|
||||||
.import __oserror
|
.import __oserror, return0
|
||||||
.export _Get1stDirEntry
|
.export _Get1stDirEntry
|
||||||
|
|
||||||
.include "diskdrv.inc"
|
.include "diskdrv.inc"
|
||||||
@@ -14,6 +14,10 @@
|
|||||||
_Get1stDirEntry:
|
_Get1stDirEntry:
|
||||||
jsr Get1stDirEntry
|
jsr Get1stDirEntry
|
||||||
stx __oserror
|
stx __oserror
|
||||||
|
txa
|
||||||
|
bne L1 ; jump if disk error
|
||||||
lda r5L
|
lda r5L
|
||||||
ldx r5H
|
ldx r5H
|
||||||
rts
|
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);
|
; struct filehandle* GetNxtDirEntry (void);
|
||||||
|
|
||||||
.import __oserror
|
.import __oserror, return0
|
||||||
.export _GetNxtDirEntry
|
.export _GetNxtDirEntry
|
||||||
|
|
||||||
.include "diskdrv.inc"
|
.include "diskdrv.inc"
|
||||||
@@ -14,6 +14,12 @@
|
|||||||
_GetNxtDirEntry:
|
_GetNxtDirEntry:
|
||||||
jsr GetNxtDirEntry
|
jsr GetNxtDirEntry
|
||||||
stx __oserror
|
stx __oserror
|
||||||
|
txa
|
||||||
|
bne L1 ; jump if disk error
|
||||||
|
tya
|
||||||
|
bne L1 ; jump when no more entries
|
||||||
lda r5L
|
lda r5L
|
||||||
ldx r5H
|
ldx r5H
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
L1: jmp return0 ; return NULL if not valid entry
|
||||||
|
|||||||
@@ -2,18 +2,14 @@
|
|||||||
; 2003-04-13, Ullrich von Bassewitz
|
; 2003-04-13, Ullrich von Bassewitz
|
||||||
; 2012-02-06, Greg King
|
; 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 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.
|
; 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)
|
.interruptor update_clock, 2 ; (low priority)
|
||||||
.constructor init_clock
|
.constructor init_clock
|
||||||
|
|
||||||
@@ -42,7 +38,7 @@
|
|||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
; Return the number of clock ticks in one second.
|
; Return the number of clock ticks in one second.
|
||||||
;
|
;
|
||||||
__clk_tck:
|
__clocks_per_sec:
|
||||||
ldx #$00 ; >50, >60, >75
|
ldx #$00 ; >50, >60, >75
|
||||||
ldy PBKUP
|
ldy PBKUP
|
||||||
lda #<75
|
lda #<75
|
||||||
|
|||||||
@@ -50,16 +50,15 @@ LINEDIST = $20 ; Offset in video RAM between two lines
|
|||||||
ldx #>load_addr
|
ldx #>load_addr
|
||||||
sta load
|
sta load
|
||||||
stx load+1
|
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
|
bnz L2
|
||||||
inc count+1
|
dec count+1
|
||||||
bze L3
|
bze L3
|
||||||
L2: jsr GETCHAR ; (doesn't change .Y)
|
L2: jsr GETCHAR ; (doesn't change .Y)
|
||||||
sta (load),y
|
sta (load),y
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
.include "pet.inc"
|
.include "pet.inc"
|
||||||
.include "../cbm/cbm.inc"
|
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Startup code
|
; 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"
|
.segment "INIT"
|
||||||
|
|
||||||
zpsave: .res zpspace
|
zpsave: .res zpspace
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,5 +78,3 @@ not_dma:
|
|||||||
.word nmi
|
.word nmi
|
||||||
.word reset32kcode
|
.word reset32kcode
|
||||||
.word irq
|
.word irq
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
.import __MAIN_START__, __MAIN_SIZE__
|
.import __MAIN_START__, __MAIN_SIZE__
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
.include "telestrat.inc"
|
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Place the startup code in a special segment.
|
; 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
|
sta ptr3
|
||||||
stx ptr3+1 ; save count as result
|
stx ptr3+1 ; save count as result
|
||||||
|
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr2
|
stx ptr2+1
|
||||||
txa
|
tax
|
||||||
eor #$FF
|
inx
|
||||||
sta ptr2+1 ; remember -count-1
|
stx ptr2 ; save count with each byte incremented separately
|
||||||
|
|
||||||
jsr popptr1 ; get buf
|
jsr popptr1 ; get buf
|
||||||
jsr popax ; get fd and discard
|
jsr popax ; get fd and discard
|
||||||
@@ -51,9 +51,9 @@ next:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
L1: inc ptr2
|
L1: dec ptr2
|
||||||
bne L2
|
bne L2
|
||||||
inc ptr2+1
|
dec ptr2+1
|
||||||
beq L9
|
beq L9
|
||||||
L2: ldy #0
|
L2: ldy #0
|
||||||
lda (ptr1),y
|
lda (ptr1),y
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
.importzp ST
|
.importzp ST
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
.include "vic20.inc"
|
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Startup code
|
; Startup code
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
/* Workaround missing clock stuff */
|
/* Workaround missing clock stuff */
|
||||||
#ifdef __APPLE2__
|
#ifdef __APPLE2__
|
||||||
# define clock() 0
|
# define clock() 0
|
||||||
|
# undef CLK_TCK
|
||||||
# define CLK_TCK 1
|
# define CLK_TCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************\
|
/*****************************************************************************\
|
||||||
** plasma test program for cc65. **
|
** plasma test program for cc65. **
|
||||||
** **
|
** **
|
||||||
** (w)2001 by groepaz/hitmen **
|
** (w)2001 by groepaz **
|
||||||
** **
|
** **
|
||||||
** Cleanup and porting by Ullrich von Bassewitz. **
|
** Cleanup and porting by Ullrich von Bassewitz. **
|
||||||
** **
|
** **
|
||||||
@@ -54,7 +54,6 @@
|
|||||||
#pragma static-locals (1);
|
#pragma static-locals (1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const unsigned char sinustable[0x100] = {
|
static const unsigned char sinustable[0x100] = {
|
||||||
0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a,
|
0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a,
|
||||||
0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52,
|
0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52,
|
||||||
@@ -131,8 +130,6 @@ static void doplasma (register unsigned char* scrn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void makechar (void)
|
static void makechar (void)
|
||||||
{
|
{
|
||||||
static const unsigned char bittab[8] = {
|
static const unsigned char bittab[8] = {
|
||||||
@@ -147,7 +144,7 @@ static void makechar (void)
|
|||||||
for (i = 0; i < 8; ++i){
|
for (i = 0; i < 8; ++i){
|
||||||
b = 0;
|
b = 0;
|
||||||
for (ii = 0; ii < 8; ++ii) {
|
for (ii = 0; ii < 8; ++ii) {
|
||||||
if ((rand() & 0xFF) > s) {
|
if ((rand() & 0xFFu) > s) {
|
||||||
b |= bittab[ii];
|
b |= bittab[ii];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -416,6 +416,16 @@ void DoConditionals (void)
|
|||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_IFPDTV:
|
||||||
|
D = AllocIf (".IFPDTV", 1);
|
||||||
|
NextTok ();
|
||||||
|
if (IfCond) {
|
||||||
|
SetIfCond (D, GetCPU() == CPU_6502DTV);
|
||||||
|
}
|
||||||
|
ExpectSep ();
|
||||||
|
CalcOverallIfCond ();
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_IFPSC02:
|
case TOK_IFPSC02:
|
||||||
D = AllocIf (".IFPSC02", 1);
|
D = AllocIf (".IFPSC02", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -470,6 +480,7 @@ int CheckConditionals (void)
|
|||||||
case TOK_IFP4510:
|
case TOK_IFP4510:
|
||||||
case TOK_IFP816:
|
case TOK_IFP816:
|
||||||
case TOK_IFPC02:
|
case TOK_IFPC02:
|
||||||
|
case TOK_IFPDTV:
|
||||||
case TOK_IFPSC02:
|
case TOK_IFPSC02:
|
||||||
case TOK_IFREF:
|
case TOK_IFREF:
|
||||||
DoConditionals ();
|
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 */
|
/* Instruction table for the 65SC02 */
|
||||||
static const struct {
|
static const struct {
|
||||||
unsigned Count;
|
unsigned Count;
|
||||||
@@ -930,6 +1015,7 @@ static const InsTable* InsTabs[CPU_COUNT] = {
|
|||||||
(const InsTable*) &InsTabNone,
|
(const InsTable*) &InsTabNone,
|
||||||
(const InsTable*) &InsTab6502,
|
(const InsTable*) &InsTab6502,
|
||||||
(const InsTable*) &InsTab6502X,
|
(const InsTable*) &InsTab6502X,
|
||||||
|
(const InsTable*) &InsTab6502DTV,
|
||||||
(const InsTable*) &InsTab65SC02,
|
(const InsTable*) &InsTab65SC02,
|
||||||
(const InsTable*) &InsTab65C02,
|
(const InsTable*) &InsTab65C02,
|
||||||
(const InsTable*) &InsTab65816,
|
(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)
|
static void DoPageLength (void)
|
||||||
/* Set the page length for the listing */
|
/* Set the page length for the listing */
|
||||||
{
|
{
|
||||||
@@ -2058,6 +2066,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
|||||||
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
|
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFP816 */
|
{ ccKeepToken, DoConditionals }, /* .IFP816 */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
|
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
|
||||||
|
{ ccKeepToken, DoConditionals }, /* .IFPDTV */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
|
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFREF */
|
{ ccKeepToken, DoConditionals }, /* .IFREF */
|
||||||
{ ccNone, DoImport },
|
{ ccNone, DoImport },
|
||||||
@@ -2091,6 +2100,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
|||||||
{ ccNone, DoPageLength },
|
{ ccNone, DoPageLength },
|
||||||
{ ccNone, DoUnexpected }, /* .PARAMCOUNT */
|
{ ccNone, DoUnexpected }, /* .PARAMCOUNT */
|
||||||
{ ccNone, DoPC02 },
|
{ ccNone, DoPC02 },
|
||||||
|
{ ccNone, DoPDTV },
|
||||||
{ ccNone, DoPopCPU },
|
{ ccNone, DoPopCPU },
|
||||||
{ ccNone, DoPopSeg },
|
{ ccNone, DoPopSeg },
|
||||||
{ ccNone, DoProc },
|
{ ccNone, DoProc },
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ struct DotKeyword {
|
|||||||
{ ".IFP4510", TOK_IFP4510 },
|
{ ".IFP4510", TOK_IFP4510 },
|
||||||
{ ".IFP816", TOK_IFP816 },
|
{ ".IFP816", TOK_IFP816 },
|
||||||
{ ".IFPC02", TOK_IFPC02 },
|
{ ".IFPC02", TOK_IFPC02 },
|
||||||
|
{ ".IFPDTV", TOK_IFPDTV },
|
||||||
{ ".IFPSC02", TOK_IFPSC02 },
|
{ ".IFPSC02", TOK_IFPSC02 },
|
||||||
{ ".IFREF", TOK_IFREF },
|
{ ".IFREF", TOK_IFREF },
|
||||||
{ ".IMPORT", TOK_IMPORT },
|
{ ".IMPORT", TOK_IMPORT },
|
||||||
@@ -258,6 +259,7 @@ struct DotKeyword {
|
|||||||
{ ".PAGELENGTH", TOK_PAGELENGTH },
|
{ ".PAGELENGTH", TOK_PAGELENGTH },
|
||||||
{ ".PARAMCOUNT", TOK_PARAMCOUNT },
|
{ ".PARAMCOUNT", TOK_PARAMCOUNT },
|
||||||
{ ".PC02", TOK_PC02 },
|
{ ".PC02", TOK_PC02 },
|
||||||
|
{ ".PDTV", TOK_PDTV },
|
||||||
{ ".POPCPU", TOK_POPCPU },
|
{ ".POPCPU", TOK_POPCPU },
|
||||||
{ ".POPSEG", TOK_POPSEG },
|
{ ".POPSEG", TOK_POPSEG },
|
||||||
{ ".PROC", TOK_PROC },
|
{ ".PROC", TOK_PROC },
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ typedef enum token_t {
|
|||||||
TOK_IFP4510,
|
TOK_IFP4510,
|
||||||
TOK_IFP816,
|
TOK_IFP816,
|
||||||
TOK_IFPC02,
|
TOK_IFPC02,
|
||||||
|
TOK_IFPDTV,
|
||||||
TOK_IFPSC02,
|
TOK_IFPSC02,
|
||||||
TOK_IFREF,
|
TOK_IFREF,
|
||||||
TOK_IMPORT,
|
TOK_IMPORT,
|
||||||
@@ -229,6 +230,7 @@ typedef enum token_t {
|
|||||||
TOK_PAGELENGTH,
|
TOK_PAGELENGTH,
|
||||||
TOK_PARAMCOUNT,
|
TOK_PARAMCOUNT,
|
||||||
TOK_PC02,
|
TOK_PC02,
|
||||||
|
TOK_PDTV,
|
||||||
TOK_POPCPU,
|
TOK_POPCPU,
|
||||||
TOK_POPSEG,
|
TOK_POPSEG,
|
||||||
TOK_PROC,
|
TOK_PROC,
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ void g_preamble (void)
|
|||||||
switch (CPU) {
|
switch (CPU) {
|
||||||
case CPU_6502: AddTextLine ("\t.setcpu\t\t\"6502\""); break;
|
case CPU_6502: AddTextLine ("\t.setcpu\t\t\"6502\""); break;
|
||||||
case CPU_6502X: AddTextLine ("\t.setcpu\t\t\"6502X\""); 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_65SC02: AddTextLine ("\t.setcpu\t\t\"65SC02\""); break;
|
||||||
case CPU_65C02: AddTextLine ("\t.setcpu\t\t\"65C02\""); break;
|
case CPU_65C02: AddTextLine ("\t.setcpu\t\t\"65C02\""); break;
|
||||||
case CPU_65816: AddTextLine ("\t.setcpu\t\t\"65816\""); 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. */
|
/* 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. */
|
/* Apply integral promotions for types char/short. */
|
||||||
lhs = g_intpromotion (lhs);
|
lhs = g_intpromotion (lhs);
|
||||||
rhs = g_intpromotion (rhs);
|
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.
|
** 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));
|
AddCodeLine ("bra %s", LocalLabelName (Label));
|
||||||
} else {
|
} else {
|
||||||
g_jump (Label);
|
g_jump (Label);
|
||||||
@@ -3090,18 +3107,33 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
"tosasrax", "tosshrax", "tosasreax", "tosshreax"
|
"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.
|
** in the primary register.
|
||||||
*/
|
*/
|
||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
|
|
||||||
switch (flags & CF_TYPEMASK) {
|
switch (flags & CF_TYPEMASK) {
|
||||||
|
|
||||||
case CF_CHAR:
|
case CF_CHAR:
|
||||||
if (flags & CF_FORCECHAR) {
|
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--) {
|
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;
|
return;
|
||||||
} else if (val <= 2) {
|
} else if (val <= 2) {
|
||||||
@@ -3111,19 +3143,28 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
}
|
}
|
||||||
return;
|
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 */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case CF_INT:
|
case CF_INT:
|
||||||
val &= 0x0F;
|
val &= 0x0F;
|
||||||
if (val >= 8) {
|
if (val >= 8) {
|
||||||
if (flags & CF_UNSIGNED) {
|
|
||||||
AddCodeLine ("txa");
|
AddCodeLine ("txa");
|
||||||
|
if (flags & CF_UNSIGNED) {
|
||||||
AddCodeLine ("ldx #$00");
|
AddCodeLine ("ldx #$00");
|
||||||
} else {
|
} else {
|
||||||
unsigned L = GetLocalLabel ();
|
unsigned L = GetLocalLabel ();
|
||||||
|
|
||||||
AddCodeLine ("cpx #$80"); /* Sign bit into carry */
|
AddCodeLine ("cpx #$80"); /* Sign bit into carry */
|
||||||
AddCodeLine ("txa");
|
|
||||||
AddCodeLine ("ldx #$00");
|
AddCodeLine ("ldx #$00");
|
||||||
AddCodeLine ("bcc %s", LocalLabelName (L));
|
AddCodeLine ("bcc %s", LocalLabelName (L));
|
||||||
AddCodeLine ("dex"); /* Make $FF */
|
AddCodeLine ("dex"); /* Make $FF */
|
||||||
@@ -3141,9 +3182,9 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
}
|
}
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
AddCodeLine ("jsr shrax%ld", val);
|
AddCodeLine ("jsr shrax%lu", val);
|
||||||
} else {
|
} else {
|
||||||
AddCodeLine ("jsr asrax%ld", val);
|
AddCodeLine ("jsr asrax%lu", val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -3155,6 +3196,7 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
AddCodeLine ("lda sreg+1");
|
AddCodeLine ("lda sreg+1");
|
||||||
if ((flags & CF_UNSIGNED) == 0) {
|
if ((flags & CF_UNSIGNED) == 0) {
|
||||||
unsigned L = GetLocalLabel ();
|
unsigned L = GetLocalLabel ();
|
||||||
|
|
||||||
AddCodeLine ("bpl %s", LocalLabelName (L));
|
AddCodeLine ("bpl %s", LocalLabelName (L));
|
||||||
AddCodeLine ("dex");
|
AddCodeLine ("dex");
|
||||||
g_defcodelabel (L);
|
g_defcodelabel (L);
|
||||||
@@ -3168,6 +3210,7 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
AddCodeLine ("ldx sreg+1");
|
AddCodeLine ("ldx sreg+1");
|
||||||
if ((flags & CF_UNSIGNED) == 0) {
|
if ((flags & CF_UNSIGNED) == 0) {
|
||||||
unsigned L = GetLocalLabel ();
|
unsigned L = GetLocalLabel ();
|
||||||
|
|
||||||
AddCodeLine ("bpl %s", LocalLabelName (L));
|
AddCodeLine ("bpl %s", LocalLabelName (L));
|
||||||
AddCodeLine ("dey");
|
AddCodeLine ("dey");
|
||||||
g_defcodelabel (L);
|
g_defcodelabel (L);
|
||||||
@@ -3184,6 +3227,7 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
AddCodeLine ("sty sreg");
|
AddCodeLine ("sty sreg");
|
||||||
if ((flags & CF_UNSIGNED) == 0) {
|
if ((flags & CF_UNSIGNED) == 0) {
|
||||||
unsigned L = GetLocalLabel ();
|
unsigned L = GetLocalLabel ();
|
||||||
|
|
||||||
AddCodeLine ("cpy #$80");
|
AddCodeLine ("cpy #$80");
|
||||||
AddCodeLine ("ldy #$00");
|
AddCodeLine ("ldy #$00");
|
||||||
AddCodeLine ("bcc %s", LocalLabelName (L));
|
AddCodeLine ("bcc %s", LocalLabelName (L));
|
||||||
@@ -3205,9 +3249,9 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
}
|
}
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
AddCodeLine ("jsr shreax%ld", val);
|
AddCodeLine ("jsr shreax%lu", val);
|
||||||
} else {
|
} else {
|
||||||
AddCodeLine ("jsr asreax%ld", val);
|
AddCodeLine ("jsr asreax%lu", val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -3237,18 +3281,28 @@ void g_asl (unsigned flags, unsigned long val)
|
|||||||
"tosaslax", "tosshlax", "tosasleax", "tosshleax"
|
"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.
|
** in the primary register.
|
||||||
*/
|
*/
|
||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
|
|
||||||
switch (flags & CF_TYPEMASK) {
|
switch (flags & CF_TYPEMASK) {
|
||||||
|
|
||||||
case CF_CHAR:
|
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--) {
|
while (val--) {
|
||||||
AddCodeLine ("asl a");
|
AddCodeLine ("asl a");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
unsigned i;
|
||||||
|
for (i = val; i < 9; ++i) {
|
||||||
|
AddCodeLine ("ror a");
|
||||||
|
}
|
||||||
|
AddCodeLine ("and #$%02X", (~0U << val) & 0xFF);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@@ -3270,9 +3324,9 @@ void g_asl (unsigned flags, unsigned long val)
|
|||||||
}
|
}
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
AddCodeLine ("jsr shlax%ld", val);
|
AddCodeLine ("jsr shlax%lu", val);
|
||||||
} else {
|
} else {
|
||||||
AddCodeLine ("jsr aslax%ld", val);
|
AddCodeLine ("jsr aslax%lu", val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -3311,9 +3365,9 @@ void g_asl (unsigned flags, unsigned long val)
|
|||||||
}
|
}
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
if (flags & CF_UNSIGNED) {
|
if (flags & CF_UNSIGNED) {
|
||||||
AddCodeLine ("jsr shleax%ld", val);
|
AddCodeLine ("jsr shleax%lu", val);
|
||||||
} else {
|
} else {
|
||||||
AddCodeLine ("jsr asleax%ld", val);
|
AddCodeLine ("jsr asleax%lu", val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -493,13 +493,16 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg)
|
|||||||
** registers.
|
** registers.
|
||||||
*/
|
*/
|
||||||
*Use = REG_EAXY;
|
*Use = REG_EAXY;
|
||||||
} else if (D->ParamCount > 0 &&
|
} else if ((D->ParamCount > 0 ||
|
||||||
|
(D->Flags & FD_EMPTY) != 0) &&
|
||||||
(AutoCDecl ?
|
(AutoCDecl ?
|
||||||
IsQualFastcall (E->Type) :
|
IsQualFastcall (E->Type) :
|
||||||
!IsQualCDecl (E->Type))) {
|
!IsQualCDecl (E->Type))) {
|
||||||
/* Will use registers depending on the last param. If the last
|
/* 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)) {
|
switch (SizeOf(D->LastParam->Type)) {
|
||||||
case 1u:
|
case 1u:
|
||||||
*Use = REG_A;
|
*Use = REG_A;
|
||||||
@@ -510,6 +513,9 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg)
|
|||||||
default:
|
default:
|
||||||
*Use = REG_EAX;
|
*Use = REG_EAX;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
*Use = REG_EAX;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Will not use any registers */
|
/* Will not use any registers */
|
||||||
*Use = REG_NONE;
|
*Use = REG_NONE;
|
||||||
|
|||||||
@@ -1080,7 +1080,7 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ((LI->A.Flags & LI_CHECK_Y) == 0) {
|
if ((LI->X.Flags & LI_CHECK_Y) == 0) {
|
||||||
/* ldy #const */
|
/* ldy #const */
|
||||||
X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->X.Offs), 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->X.Offs), 0, D->OpEntry->LI);
|
||||||
} else {
|
} 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);
|
X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI);
|
||||||
} else {
|
} else {
|
||||||
/* opc src,y */
|
/* 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++);
|
InsertEntry (D, X, D->IP++);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -944,7 +944,9 @@ unsigned OptCmp9 (CodeSeg* S)
|
|||||||
if (L[0]->OPC == OP65_SBC &&
|
if (L[0]->OPC == OP65_SBC &&
|
||||||
CS_GetEntries (S, L+1, I+1, 4) &&
|
CS_GetEntries (S, L+1, I+1, 4) &&
|
||||||
(L[1]->OPC == OP65_BVC ||
|
(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 != 0 &&
|
||||||
L[1]->JumpTo->Owner == L[3] &&
|
L[1]->JumpTo->Owner == L[3] &&
|
||||||
L[2]->OPC == OP65_EOR &&
|
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->Info & OF_UBRA) != 0 &&
|
||||||
E->JumpTo != 0 &&
|
E->JumpTo != 0 &&
|
||||||
IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner))) {
|
IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner))) {
|
||||||
|
|||||||
@@ -988,7 +988,7 @@ unsigned OptPtrLoad12 (CodeSeg* S)
|
|||||||
L[4]->OPC == OP65_CLC &&
|
L[4]->OPC == OP65_CLC &&
|
||||||
L[5]->OPC == OP65_ADC &&
|
L[5]->OPC == OP65_ADC &&
|
||||||
CE_IsKnownImm (L[5], 1) &&
|
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 != 0 &&
|
||||||
L[6]->JumpTo->Owner == L[8] &&
|
L[6]->JumpTo->Owner == L[8] &&
|
||||||
L[7]->OPC == OP65_INX &&
|
L[7]->OPC == OP65_INX &&
|
||||||
|
|||||||
@@ -341,7 +341,10 @@ unsigned OptShift2 (CodeSeg* S)
|
|||||||
L[0] = CS_GetEntry (S, I);
|
L[0] = CS_GetEntry (S, I);
|
||||||
|
|
||||||
/* Check for the sequence */
|
/* 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 &&
|
L[0]->JumpTo != 0 &&
|
||||||
CS_GetEntries (S, L+1, I+1, 3) &&
|
CS_GetEntries (S, L+1, I+1, 3) &&
|
||||||
L[1]->OPC == OP65_DEX &&
|
L[1]->OPC == OP65_DEX &&
|
||||||
|
|||||||
@@ -453,6 +453,7 @@ static unsigned Opt_staxspidx (StackOpData* D)
|
|||||||
/* Optimize the staxspidx sequence */
|
/* Optimize the staxspidx sequence */
|
||||||
{
|
{
|
||||||
CodeEntry* X;
|
CodeEntry* X;
|
||||||
|
const char* Arg = 0;
|
||||||
|
|
||||||
/* Check if we're using a register variable */
|
/* Check if we're using a register variable */
|
||||||
if (!IsRegVar (D)) {
|
if (!IsRegVar (D)) {
|
||||||
@@ -469,7 +470,7 @@ static unsigned Opt_staxspidx (StackOpData* D)
|
|||||||
|
|
||||||
if (RegValIsKnown (D->OpEntry->RI->In.RegY)) {
|
if (RegValIsKnown (D->OpEntry->RI->In.RegY)) {
|
||||||
/* Value of Y is known */
|
/* 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);
|
X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
||||||
} else {
|
} else {
|
||||||
X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, D->OpEntry->LI);
|
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)) {
|
if (RegValIsKnown (D->OpEntry->RI->In.RegX)) {
|
||||||
/* Value of X is known */
|
/* 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);
|
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
||||||
} else {
|
} else {
|
||||||
/* Value unknown */
|
/* 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
|
/* If we remove staxspidx, we must restore the Y register to what the
|
||||||
** function would return.
|
** 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);
|
InsertEntry (D, X, D->OpIndex+5);
|
||||||
|
|
||||||
/* Remove the push and the call to the staxspidx function */
|
/* 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)
|
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;
|
CodeEntry* X;
|
||||||
cmp_t Cond;
|
cmp_t Cond;
|
||||||
@@ -1119,9 +1125,8 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer)
|
|||||||
D->Rhs.A.Flags |= LI_REMOVE;
|
D->Rhs.A.Flags |= LI_REMOVE;
|
||||||
|
|
||||||
} else if ((D->Lhs.A.Flags & LI_DIRECT) != 0) {
|
} else if ((D->Lhs.A.Flags & LI_DIRECT) != 0) {
|
||||||
|
/* If the lhs is direct (but not stack relative), encode compares with lhs,
|
||||||
/* If the lhs is direct (but not stack relative), encode compares with lhs
|
** effectively reversing the order (which doesn't matter for == and !=).
|
||||||
** effectively reverting the order (which doesn't matter for ==).
|
|
||||||
*/
|
*/
|
||||||
Cond = FindBoolCmpCond (BoolTransformer);
|
Cond = FindBoolCmpCond (BoolTransformer);
|
||||||
Cond = GetRevertedCond (Cond);
|
Cond = GetRevertedCond (Cond);
|
||||||
@@ -1138,7 +1143,6 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer)
|
|||||||
D->Lhs.A.Flags |= LI_REMOVE;
|
D->Lhs.A.Flags |= LI_REMOVE;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* We'll do reverse-compare */
|
/* We'll do reverse-compare */
|
||||||
Cond = FindBoolCmpCond (BoolTransformer);
|
Cond = FindBoolCmpCond (BoolTransformer);
|
||||||
Cond = GetRevertedCond (Cond);
|
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);
|
X = NewCodeEntry (OP65_JSR, AM65_ABS, BoolTransformer, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->IP++);
|
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);
|
RemoveRemainders (D);
|
||||||
|
|
||||||
/* We changed the sequence */
|
/* 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)
|
static unsigned Opt_a_tosicmp (StackOpData* D)
|
||||||
/* Replace tosicmp with CMP */
|
/* Replace tosicmp with CMP */
|
||||||
{
|
{
|
||||||
@@ -1268,15 +1256,15 @@ static unsigned Opt_a_tosicmp (StackOpData* D)
|
|||||||
InsertEntry (D, X, D->IP-3);
|
InsertEntry (D, X, D->IP-3);
|
||||||
|
|
||||||
} else {
|
} 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 &&
|
if ((RI = GetLastChangedRegInfo (D, &D->Lhs.A)) != 0 &&
|
||||||
RegValIsKnown (RI->Out.RegA) &&
|
RegValIsKnown (RI->Out.RegA) &&
|
||||||
(RI->Out.RegA & 0xFF) == 0) {
|
(RI->Out.RegA & 0xFF) == 0) {
|
||||||
Arg = MakeHexArg (0);
|
|
||||||
X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->OpIndex + 1);
|
InsertEntry (D, X, D->OpIndex + 1);
|
||||||
} else {
|
} else {
|
||||||
Arg = MakeHexArg (0);
|
|
||||||
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
||||||
InsertEntry (D, X, D->OpIndex + 1);
|
InsertEntry (D, X, D->OpIndex + 1);
|
||||||
X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI);
|
||||||
@@ -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)
|
static unsigned Opt_a_tosne (StackOpData* D)
|
||||||
/* Optimize the toseqax sequence */
|
/* Optimize the tosneax sequence */
|
||||||
{
|
{
|
||||||
return Opt_a_toscmpbool (D, "boolne");
|
return Opt_a_toscmpbool (D, "boolne");
|
||||||
}
|
}
|
||||||
@@ -1317,7 +1289,7 @@ static unsigned Opt_a_tosne (StackOpData* D)
|
|||||||
|
|
||||||
|
|
||||||
static unsigned Opt_a_tosuge (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");
|
return Opt_a_toscmpbool (D, "booluge");
|
||||||
}
|
}
|
||||||
@@ -1325,7 +1297,7 @@ static unsigned Opt_a_tosuge (StackOpData* D)
|
|||||||
|
|
||||||
|
|
||||||
static unsigned Opt_a_tosugt (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");
|
return Opt_a_toscmpbool (D, "boolugt");
|
||||||
}
|
}
|
||||||
@@ -1333,7 +1305,7 @@ static unsigned Opt_a_tosugt (StackOpData* D)
|
|||||||
|
|
||||||
|
|
||||||
static unsigned Opt_a_tosule (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");
|
return Opt_a_toscmpbool (D, "boolule");
|
||||||
}
|
}
|
||||||
@@ -1341,7 +1313,7 @@ static unsigned Opt_a_tosule (StackOpData* D)
|
|||||||
|
|
||||||
|
|
||||||
static unsigned Opt_a_tosult (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");
|
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[] = {
|
static const OptFuncDesc FuncTable[] = {
|
||||||
{ "__bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN },
|
{ "__bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN },
|
||||||
{ "staspidx", Opt_staspidx, REG_NONE, OP_NONE },
|
{ "staspidx", Opt_staspidx, REG_NONE, OP_NONE },
|
||||||
@@ -1379,11 +1353,11 @@ static const OptFuncDesc FuncTable[] = {
|
|||||||
|
|
||||||
static const OptFuncDesc FuncRegATable[] = {
|
static const OptFuncDesc FuncRegATable[] = {
|
||||||
{ "toseqax", Opt_a_toseq, REG_NONE, OP_NONE },
|
{ "toseqax", Opt_a_toseq, REG_NONE, OP_NONE },
|
||||||
{ "tosgeax", Opt_a_tosge, REG_NONE, OP_NONE },
|
{ "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE },
|
||||||
{ "tosgtax", Opt_a_tosgt, REG_NONE, OP_NONE },
|
{ "tosgtax", Opt_a_tosugt, REG_NONE, OP_NONE },
|
||||||
{ "tosicmp", Opt_a_tosicmp, REG_NONE, OP_NONE },
|
{ "tosicmp", Opt_a_tosicmp, REG_NONE, OP_NONE },
|
||||||
{ "tosleax", Opt_a_tosle, REG_NONE, OP_NONE },
|
{ "tosleax", Opt_a_tosule, REG_NONE, OP_NONE },
|
||||||
{ "tosltax", Opt_a_toslt, REG_NONE, OP_NONE },
|
{ "tosltax", Opt_a_tosult, REG_NONE, OP_NONE },
|
||||||
{ "tosneax", Opt_a_tosne, REG_NONE, OP_NONE },
|
{ "tosneax", Opt_a_tosne, REG_NONE, OP_NONE },
|
||||||
{ "tosugeax", Opt_a_tosuge, REG_NONE, OP_NONE },
|
{ "tosugeax", Opt_a_tosuge, REG_NONE, OP_NONE },
|
||||||
{ "tosugtax", Opt_a_tosugt, REG_NONE, OP_NONE },
|
{ "tosugtax", Opt_a_tosugt, REG_NONE, OP_NONE },
|
||||||
@@ -1732,7 +1706,7 @@ unsigned OptStackOps (CodeSeg* S)
|
|||||||
int I;
|
int I;
|
||||||
int OldEntryCount; /* Old number of entries */
|
int OldEntryCount; /* Old number of entries */
|
||||||
unsigned Used; /* What registers would be used */
|
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 RhsAChgIndex; /* Track if rhs is changed more than once */
|
||||||
int RhsXChgIndex; /* 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 */
|
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
Reference in New Issue
Block a user