Closed ProxyPlayerHD closed 1 year ago
Can you add --list-file=image.lst --cross-reference
to the linker line and inspect the generated list file image.lst
?
it already had the --cross-reference
option, but besides that here the generated .lst
file:
###############################################################################
# #
# Calypsi linker for 65816 version 3.6.12 #
# 02/Apr/2023 20:59:30 #
# Command line: --hosted --list-file Output\test.lst --cross-reference #
# --rtattr cstartup=SBCv1 --verbose --output-format pgz -o #
# test.pgz Config\SBC_816.scm Include\FixedMath.a #
# Include\BasicGraphics.a Config\cstartup.o #
# Config\stdio_functions.o Temp\test.o clib-lc-ld-double64.a #
# #
###############################################################################
####################
# #
# Memories summary #
# #
####################
Name Range Size Used Checksum Largest unallocated
-----------------------------------------------------------------------------------
DirectPage 000000-0000ff 000100 7.8% none 0000ec
LoRAM 000100-00fbff 00fb00 12.7% none 00db00
LoROM 00ff00-00ffff 000100 0.0% none 000100
IO 010000-0100ff 000100 0.0% none 000100
HiROM 010100-013fff 003f00 0.0% none 003f00
HiDB 020000-02ffff 010000 0.0% none 010000
> HiRAM-02-far-cbits 020000-020009 00000a 100.0% none none
> HiRAM-02-far-nobits 02000a-02000b 000002 100.0% none none
> HiRAM-02-farcode 02000c-0200a4 000099 100.0% none 00ff5b
HiRAM-02 020000-02ffff 010000 50.3% none 007f5b
HiRAM-03 030000-03ffff 010000 0.0% none 010000
HiRAM-04 040000-04ffff 010000 0.0% none 010000
HiRAM-05 050000-05ffff 010000 0.0% none 010000
HiRAM-06 060000-06ffff 010000 0.0% none 010000
HiRAM-07 070000-07ffff 010000 0.0% none 010000
HiRAM-08 080000-08ffff 010000 0.0% none 010000
HiRAM-09 090000-09ffff 010000 0.0% none 010000
HiRAM-0a 0a0000-0affff 010000 0.0% none 010000
HiRAM-0b 0b0000-0bffff 010000 0.0% none 010000
HiRAM-0c 0c0000-0cffff 010000 0.0% none 010000
HiRAM-0d 0d0000-0dffff 010000 0.0% none 010000
HiRAM-0e 0e0000-0effff 010000 0.0% none 010000
HiRAM-0f 0f0000-0fffff 010000 0.0% none 010000
VRAM ff0000-ffffff 010000 0.0% none 010000
####################
# #
# Sections summary #
# #
####################
Name Range Size Memory Fragments
--------------------------------------------------------------------
registers 000000-000013 000014 DirectPage 1
stack 000100-0020ff 002000 LoRAM 1
data_init_table 020000-020009 00000a HiRAM-02-far-cbits 1
zfar 02000a-02000b 000002 HiRAM-02-far-nobits 1
farcode 02000c-0200a4 000099 HiRAM-02-farcode 9
heap 0200a5-0280a4 008000 HiRAM-02 1
################
# #
# Object files #
# #
################
Unit Filename Archive
---------------------------------------------------
2 Config\cstartup.o -
# picked based on cstartup=SBCv1
> farcode 000004
3 Config\stdio_functions.o -
> farcode 000091
4 Temp\test.o -
> farcode 000004
8 pseudoRegisters.o clib-lc-ld-double64.a
> registers 000014
9 errno.o clib-lc-ld-double64.a
> zfar 000002
###################
# #
# Cross reference #
# #
###################
_Dp in section 'registers' placed at address 000000-000013 of size 000014
(pseudoRegisters.o (from clib-lc-ld-double64.a) unit 8 section index 2)
Defines:
_Vfp = 000010
_Dp = 000000
Referenced from:
_Stub_write (Config\stdio_functions.o unit 3 section index 2)
_Stub_read (Config\stdio_functions.o unit 3 section index 3)
Section 'heap' placed at address 0200a5-0280a4 of size 008000
(linker generated)
Section 'data_init_table' placed at address 020000-020009 of size 00000a
(linker generated)
errno in section 'zfar' placed at address 02000a-02000b of size 000002
(errno.o (from clib-lc-ld-double64.a) unit 9 section index 2)
Defines:
errno = 02000a
Referenced from:
_Stub_write (Config\stdio_functions.o unit 3 section index 2)
_Stub_read (Config\stdio_functions.o unit 3 section index 3)
_Stub_open in section 'farcode' placed at address 02000c-02000f of size 000004
(Config\stdio_functions.o unit 3 section index 5)
Defines:
_Stub_open = 02000c
__low_level_init in section 'farcode' placed at address 02000c of size 000000
(Config\cstartup.o unit 2 section index 6)
Defines:
__low_level_init = 02000c
_Stub_close in section 'farcode'
placed at address 020010-020013 of size 000004
(Config\stdio_functions.o unit 3 section index 6)
Defines:
_Stub_close = 020010
main in section 'farcode' placed at address 020014-020017 of size 000004
(Temp\test.o unit 4 section index 2)
Defines:
main = 020014
__program_start in section 'farcode'
placed at address 020018-02001b of size 000004
(Config\cstartup.o unit 2 section index 2)
Defines:
__program_start = 020018
__program_root_section = 020018
_Stub_lseek in section 'farcode'
placed at address 02001c-020022 of size 000007
(Config\stdio_functions.o unit 3 section index 4)
Defines:
_Stub_lseek = 02001c
__data_initialization_needed in section 'farcode'
placed at address 02001c of size 000000
(Config\cstartup.o unit 2 section index 3)
Defines:
__data_initialization_needed = 02001c
_Stub_write in section 'farcode'
placed at address 020023-02005e of size 00003c
(Config\stdio_functions.o unit 3 section index 2)
Defines:
_Stub_write = 020023
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 8 section index 2)
errno in (errno.o (from clib-lc-ld-double64.a) unit 9 section index 2)
_Stub_read in section 'farcode' placed at address 02005f-0200a4 of size 000046
(Config\stdio_functions.o unit 3 section index 3)
Defines:
_Stub_read = 02005f
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 8 section index 2)
errno in (errno.o (from clib-lc-ld-double64.a) unit 9 section index 2)
Section 'stack' placed at address 000100-0020ff of size 002000
(linker generated)
##########################
# #
# Memory sizes (decimal) #
# #
##########################
Executable (Text): 163 bytes
Data : 2 bytes
Non-initialized : 40980 bytes
This is due to a bug when it lays out the memory bits. The culprit is the section with __low_level_init
which is empty. I have fixed it in my upcoming version. In the mean time you should be able to work around the problem by inserting an instruction in that section or remove it since it is not used.
but __low_level_init
has always been empty in my setup (containing just a single RTS/RTL instruction), so why would it just break all the sudden? and even when i add a NOP instruction in __low_level_init
or remove it entirely it doesn't change anything...
the issue still persists.
here the current cstartup.s
.lst
file and the linker's .lst
file:
###############################################################################
# #
# Calypsi assembler for 65816 version 3.6.12 #
# 03/Apr/2023 09:59:10 #
# Command line: -l --code-model large --data-model large -o cstartup.o #
# cstartup.s #
# #
###############################################################################
0001 ;;; Startup variant, change attribute value if you make your own
0002 .rtmodel cstartup,"SBCv1"
0003
0004 .rtmodel version, "1"
0005 .rtmodel core, "*"
0006
0007 .section cstack
0008 .section stack
0009 .section heap
0010 .section data_init_table
0011
0012 .extern main
0013 .extern _Dp, _Vfp
0014 .extern _DirectPageStart
0015
0016 #ifndef __CALYPSI_DATA_MODEL_SMALL__
0017 .extern _NearBaseAddress
0018 #endif
0019
0020 #include "macros.h"
0021
0022
0023 ;;; ***************************************************************************
0024 ;;;
0025 ;;; __program_start - actual start point of the program
0026 ;;;
0027 ;;; Set up CPU stack, initialize sections and call main().
0028 ;;; You can override this with your own routine, or tailor it as needed.
0029 ;;; The easiest way to make custom initialization is to provide your own
0030 ;;; __low_level_init which gets called after stacks have been initialized.
0031 ;;;
0032 ;;; ***************************************************************************
0033
0034 .section farcode, noreorder
0035 .pubweak __program_root_section
0036 __program_root_section:
0037 .pubweak __program_start
0038 __program_start:
0039 ai16 ; 16-bit registers
\ 000000 c230 rep #48
0040 000002 a2.... LDX ##.sectionEnd stack
0041 000005 9a TXS ; set stack
0042 000006 a9.... LDA ##_DirectPageStart
0043 000009 5b TCD ; set direct page
0044 #ifdef __CALYPSI_DATA_MODEL_SMALL__
0045 LDA ##0
0046 #else
0047 00000a a9.... LDA ##.word2 _NearBaseAddress
0048 #endif
0049 00000d 64.. STZ dp:.tiny(_Vfp+2)
0050 00000f eb XBA ; A upper half = data bank
0051 000010 48 PHA
0052 000011 ab PLB ; pop 8 dummy
0053 000012 ab PLB ; set data bank
0054 ; call __low_level_init
0055
0056 ;;;; **** Initialize data sections if needed.
0057 .section farcode, noroot, noreorder
0058 .pubweak __data_initialization_needed
0059 .extern __initialize_sections
0060 __data_initialization_needed:
0061 000000 a9.... LDA ##.word2 (.sectionEnd data_init_table)
0062 000003 85.. STA dp:.tiny(_Dp+6)
0063 000005 a9.... LDA ##.word0 (.sectionEnd data_init_table)
0064 000008 85.. STA dp:.tiny(_Dp+4)
0065 00000a a9.... LDA ##.word2 (.sectionStart data_init_table)
0066 00000d 85.. STA dp:.tiny(_Dp+2)
0067 00000f a9.... LDA ##.word0 (.sectionStart data_init_table)
0068 000012 85.. STA dp:.tiny(_Dp+0)
0069 call __initialize_sections
\ 000014 22...... jsl long:__initialize_sections
0070
0071 ;;;; **** Initialize streams if needed.
0072 .section farcode, noroot, noreorder
0073 .pubweak __call_initialize_global_streams
0074 .extern __initialize_global_streams
0075 __call_initialize_global_streams:
0076 call __initialize_global_streams
\ 000000 22...... jsl long:__initialize_global_streams
0077
0078 ;;;; **** Initialize heap if needed.
0079 .section farcode, noroot, noreorder
0080 .pubweak __call_heap_initialize
0081 .extern __heap_initialize, __default_heap
0082 __call_heap_initialize:
0083 000000 a9.... LDA ##.word2 (.sectionStart heap)
0084 000003 85.. STA dp:.tiny(_Dp+6)
0085 000005 a9.... LDA ##.word0 (.sectionStart heap)
0086 000008 85.. STA dp:.tiny(_Dp+4)
0087 00000a a9.... LDA ##.word2 __default_heap
0088 00000d 85.. STA dp:.tiny(_Dp+2)
0089 00000f a9.... LDA ##.word0 __default_heap
0090 000012 85.. STA dp:.tiny(_Dp+0)
0091 000014 a2.... LDX ##.word2 (.sectionSize heap)
0092 000017 a9.... LDA ##.word0 (.sectionSize heap)
0093 call __heap_initialize
\ 00001a 22...... jsl long:__heap_initialize
0094
0095 .section farcode, root, noreorder
0096 000000 a90000 LDA ##0
0097 call main ; Jump to Main
\ 000003 22...... jsl long:main
0098 000007 dcf0ff JMP [0xFFF0] ; Once Returned, jump to the Termination Vector
0099
0100
0101 ;;;; ***************************************************************************
0102 ;;;;
0103 ;;;; __low_level_init - custom low level initialization
0104 ;;;;
0105 ;;;; This default routine just returns doing nothing. You can provide your own
0106 ;;;; routine, either in C or assembly for doing custom low leve initialization.
0107 ;;;;
0108 ;;;; ***************************************************************************
0109
0110 ; .section libcode
0111 ; .pubweak __low_level_init
0112 ;__low_level_init:
0113 ; NOP
0114 ; return
0115
##########################
# #
# Memory sizes (decimal) #
# #
##########################
Executable (Text): 87 bytes
###############################################################################
# #
# Calypsi linker for 65816 version 3.6.12 #
# 03/Apr/2023 10:01:17 #
# Command line: --hosted --list-file Output\test.lst --cross-reference #
# --rtattr cstartup=SBCv1 --verbose --output-format pgz -o #
# test.pgz Config\SBC_816.scm Include\FixedMath.a #
# Include\BasicGraphics.a Config\cstartup.o #
# Config\stdio_functions.o Temp\test.o clib-lc-ld-double64.a #
# #
###############################################################################
####################
# #
# Memories summary #
# #
####################
Name Range Size Used Checksum Largest unallocated
-----------------------------------------------------------------------------------
DirectPage 000000-0000ff 000100 7.8% none 0000ec
LoRAM 000100-00fbff 00fb00 12.7% none 00db00
LoROM 00ff00-00ffff 000100 0.0% none 000100
IO 010000-0100ff 000100 0.0% none 000100
HiROM 010100-013fff 003f00 0.0% none 003f00
HiDB 020000-02ffff 010000 0.0% none 010000
> HiRAM-02-far-cbits 020000-020009 00000a 100.0% none none
> HiRAM-02-far-nobits 02000a-02000b 000002 100.0% none none
> HiRAM-02-farcode 02000c-0201f0 0001e5 100.0% none 00fe0f
HiRAM-02 020000-02ffff 010000 50.8% none 007e0f
HiRAM-03 030000-03ffff 010000 0.0% none 010000
HiRAM-04 040000-04ffff 010000 0.0% none 010000
HiRAM-05 050000-05ffff 010000 0.0% none 010000
HiRAM-06 060000-06ffff 010000 0.0% none 010000
HiRAM-07 070000-07ffff 010000 0.0% none 010000
HiRAM-08 080000-08ffff 010000 0.0% none 010000
HiRAM-09 090000-09ffff 010000 0.0% none 010000
HiRAM-0a 0a0000-0affff 010000 0.0% none 010000
HiRAM-0b 0b0000-0bffff 010000 0.0% none 010000
HiRAM-0c 0c0000-0cffff 010000 0.0% none 010000
HiRAM-0d 0d0000-0dffff 010000 0.0% none 010000
HiRAM-0e 0e0000-0effff 010000 0.0% none 010000
HiRAM-0f 0f0000-0fffff 010000 0.0% none 010000
VRAM ff0000-ffffff 010000 0.0% none 010000
####################
# #
# Sections summary #
# #
####################
Name Range Size Memory Fragments
--------------------------------------------------------------------
registers 000000-000013 000014 DirectPage 1
stack 000100-0020ff 002000 LoRAM 1
data_init_table 020000-020009 00000a HiRAM-02-far-cbits 1
zfar 02000a-02000b 000002 HiRAM-02-far-nobits 1
farcode 02000c-0201f0 0001e5 HiRAM-02-farcode 12
heap 0201f1-0281f0 008000 HiRAM-02 1
################
# #
# Object files #
# #
################
Unit Filename Archive
---------------------------------------------------
2 Config\cstartup.o -
# picked based on cstartup=SBCv1
> farcode 000035
3 Config\stdio_functions.o -
> farcode 000091
4 Temp\test.o -
> farcode 000004
7 pseudoRegisters.o clib-lc-ld-double64.a
> registers 000014
9 errno.o clib-lc-ld-double64.a
> zfar 000002
14 initialize.o clib-lc-ld-double64.a
> farcode 000083
15 lib_memset.o clib-lc-ld-double64.a
> farcode 000049
16 lib_memcpy.o clib-lc-ld-double64.a
> farcode 00004f
###################
# #
# Cross reference #
# #
###################
_Dp in section 'registers' placed at address 000000-000013 of size 000014
(pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
Defines:
_Vfp = 000010
_Dp = 000000
Referenced from:
__program_root_section (Config\cstartup.o unit 2 section index 2)
__data_initialization_needed (Config\cstartup.o unit 2 section index 3)
_Stub_write (Config\stdio_functions.o unit 3 section index 2)
_Stub_read (Config\stdio_functions.o unit 3 section index 3)
__initialize_sections (initialize.o (from clib-lc-ld-double64.a) unit 14 section index 2)
memset (lib_memset.o (from clib-lc-ld-double64.a) unit 15 section index 2)
memcpy (lib_memcpy.o (from clib-lc-ld-double64.a) unit 16 section index 2)
Section 'heap' placed at address 0201f1-0281f0 of size 008000
(linker generated)
Section 'data_init_table' placed at address 020000-020009 of size 00000a
(linker generated)
errno in section 'zfar' placed at address 02000a-02000b of size 000002
(errno.o (from clib-lc-ld-double64.a) unit 9 section index 2)
Defines:
errno = 02000a
Referenced from:
_Stub_write (Config\stdio_functions.o unit 3 section index 2)
_Stub_read (Config\stdio_functions.o unit 3 section index 3)
_Stub_open in section 'farcode' placed at address 02000c-02000f of size 000004
(Config\stdio_functions.o unit 3 section index 5)
Defines:
_Stub_open = 02000c
_Stub_close in section 'farcode'
placed at address 020010-020013 of size 000004
(Config\stdio_functions.o unit 3 section index 6)
Defines:
_Stub_close = 020010
main in section 'farcode' placed at address 020014-020017 of size 000004
(Temp\test.o unit 4 section index 2)
Defines:
main = 020014
Referenced from:
(Config\cstartup.o unit 2 section index 6)
_Stub_lseek in section 'farcode'
placed at address 020018-02001e of size 000007
(Config\stdio_functions.o unit 3 section index 4)
Defines:
_Stub_lseek = 020018
__program_start in section 'farcode'
placed at address 02001f-020031 of size 000013
(Config\cstartup.o unit 2 section index 2)
Defines:
__program_start = 02001f
__program_root_section = 02001f
References:
_DirectPageStart
_NearBaseAddress
.sectionEnd(stack)
_Vfp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
__data_initialization_needed in section 'farcode'
placed at address 020032-020049 of size 000018
(Config\cstartup.o unit 2 section index 3)
Defines:
__data_initialization_needed = 020032
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
.sectionEnd(data_init_table)
.sectionStart(data_init_table)
__initialize_sections in (initialize.o (from clib-lc-ld-double64.a) unit 14 section index 2)
Section 'farcode' placed at address 02004a-020053 of size 00000a
(Config\cstartup.o unit 2 section index 6)
References:
main in (Temp\test.o unit 4 section index 2)
_Stub_write in section 'farcode'
placed at address 020054-02008f of size 00003c
(Config\stdio_functions.o unit 3 section index 2)
Defines:
_Stub_write = 020054
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
errno in (errno.o (from clib-lc-ld-double64.a) unit 9 section index 2)
_Stub_read in section 'farcode' placed at address 020090-0200d5 of size 000046
(Config\stdio_functions.o unit 3 section index 3)
Defines:
_Stub_read = 020090
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
errno in (errno.o (from clib-lc-ld-double64.a) unit 9 section index 2)
memset in section 'farcode' placed at address 0200d6-02011e of size 000049
(lib_memset.o (from clib-lc-ld-double64.a) unit 15 section index 2)
Defines:
memset = 0200d6
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
Referenced from:
__initialize_sections (initialize.o (from clib-lc-ld-double64.a) unit 14 section index 2)
memcpy in section 'farcode' placed at address 02011f-02016d of size 00004f
(lib_memcpy.o (from clib-lc-ld-double64.a) unit 16 section index 2)
Defines:
memcpy = 02011f
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
Referenced from:
__initialize_sections (initialize.o (from clib-lc-ld-double64.a) unit 14 section index 2)
__initialize_sections in section 'farcode'
placed at address 02016e-0201f0 of size 000083
(initialize.o (from clib-lc-ld-double64.a) unit 14 section index 2)
Defines:
__initialize_sections = 02016e
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 7 section index 2)
memcpy in (lib_memcpy.o (from clib-lc-ld-double64.a) unit 16 section index 2)
memset in (lib_memset.o (from clib-lc-ld-double64.a) unit 15 section index 2)
Referenced from:
__data_initialization_needed (Config\cstartup.o unit 2 section index 3)
Section 'stack' placed at address 000100-0020ff of size 002000
(linker generated)
##########################
# #
# Memory sizes (decimal) #
# #
##########################
Executable (Text): 495 bytes
Data : 2 bytes
Non-initialized : 40980 bytes
Hmmm... that should have worked, I will take another look at it when I can find time,
but __low_level_init has always been empty in my setup (containing just a single RTS/RTL instruction), so why would it just break all the sudden?
I took a look at and removed the section lines at the bottom here:
.section farcode, noreorder
.pubweak __program_root_section
__program_root_section:
.pubweak __program_start
__program_start:
NOP
JMP [0xFFF0]
.section farcode, noroot, noreorder
.pubweak __data_initialization_needed
.extern __initialize_sections
__data_initialization_needed:
.section farcode, noroot, noreorder
.pubweak __call_initialize_global_streams
.extern __initialize_global_streams
__call_initialize_global_streams:
.section farcode, noroot, noreorder
.pubweak __call_heap_initialize
.extern __heap_initialize, __default_heap
__call_heap_initialize:
; .section farcode, root, noreorder
; .section farcode
; .pubweak __low_level_init
;__low_level_init:
This gets rid of the problem on the previous example you sent.
What happens is that it wants to place the memory bits in the memory block to be written out. It sorts the sections that belongs to the memory on their start addresses. Then it traverses the sections knowing the current address.
As there is an empty section it has the same address as another one with bits. The sort function can place them in either order, so depending on the sort order it ends up with, it will either work fine or it will insert incorrect padding (of the same length as the section at the same address as the empty one).
In more detail, when it gets wrong it has placed the section with actual bits first, then it get to the empty one and realizes that it is not in sync (which is fine as there can be padding), so it attempts to pad it. As it actually behind as it already placed a section at the same address, so it gets a huge number and it wraps and becomes negative. It ends up with the size of the section at the same address negated, -4
in this case. The pad function actually will not pad negative numbers, so no padding occurs. Then it corrects the current address, which means it steps it back four steps and loops around. Now the addresses match up so it is good. No bytes are inserted as the section is empty. However, as it (incorrectly) stepped the address back. the following section is seen as 4 bytes ahead and it needs to pad by 4 to reach that section start so it inserts 0,0,0,0
in the output.
I have debugged this carefully and this is a problem that caused it to incorrectly insert 0,0,0,0
in the output. Please go back and try it. I have observed the behavior and work around in my setup. I also fixed it for the next release (filtering out empty sections at this point) and then the work around is no needed.
There may be something more going on here, so it may need additional work, but I want you to carefully check the first example first, removal of that empty section should have the desired effect of getting rid of those bogus four 00
.
In the output when it goes wrong I have:
00000010: 000c 0002 a900 00a9 0000 6b00 0000 00a9
^^ ^^^^ ^^
i was able to replicate your work around for the first example i showed.
i also found out that the second cstartup.s
file i showed also works but only when i remove the Config\stdio_functions.o
part of the Linker command.
so there's still something off...
I released a version 4.1 yesterday which contains a fix to the first issue. Can you provide a complete example to show the new issue?
alright i updated to 4.1.
here the list file for cstartup.s
:
###############################################################################
# #
# Calypsi assembler for 65816 version 4.1 #
# 09/Apr/2023 22:02:28 #
# Command line: -l --code-model large --data-model large -o cstartup.o #
# cstartup.s #
# #
###############################################################################
0001 ;;; Startup variant, change attribute value if you make your own
0002 .rtmodel cstartup,"SBCv1"
0003
0004 .rtmodel version, "1"
0005 .rtmodel core, "*"
0006
0007 .section cstack
0008 .section stack
0009 .section heap
0010 .section data_init_table
0011
0012 .extern main
0013 .extern _Dp, _Vfp
0014 .extern _DirectPageStart
0015
0016 #ifndef __CALYPSI_DATA_MODEL_SMALL__
0017 .extern _NearBaseAddress
0018 #endif
0019
0020 #include "macros.h"
0021
0022
0023 ;;; ***************************************************************************
0024 ;;;
0025 ;;; __program_start - actual start point of the program
0026 ;;;
0027 ;;; Set up CPU stack, initialize sections and call main().
0028 ;;; You can override this with your own routine, or tailor it as needed.
0029 ;;; The easiest way to make custom initialization is to provide your own
0030 ;;; __low_level_init which gets called after stacks have been initialized.
0031 ;;;
0032 ;;; ***************************************************************************
0033
0034 .section farcode, noreorder
0035 .pubweak __program_root_section
0036 __program_root_section:
0037 .pubweak __program_start
0038 __program_start:
0039 ai16 ; 16-bit registers
\ 000000 c230 rep #48
0040 000002 a2.... LDX ##.sectionEnd stack
0041 000005 9a TXS ; set stack
0042 000006 a9.... LDA ##_DirectPageStart
0043 000009 5b TCD ; set direct page
0044 #ifdef __CALYPSI_DATA_MODEL_SMALL__
0045 LDA ##0
0046 #else
0047 00000a a9.... LDA ##.word2 _NearBaseAddress
0048 #endif
0049 00000d 64.. STZ dp:.tiny(_Vfp+2)
0050 00000f eb XBA ; A upper half = data bank
0051 000010 48 PHA
0052 000011 ab PLB ; pop 8 dummy
0053 000012 ab PLB ; set data bank
0054 ;call __low_level_init
0055
0056 ;;;; **** Initialize data sections if needed.
0057 .section farcode, noroot, noreorder
0058 .pubweak __data_initialization_needed
0059 .extern __initialize_sections
0060 __data_initialization_needed:
0061 000000 a9.... LDA ##.word2 (.sectionEnd data_init_table)
0062 000003 85.. STA dp:.tiny(_Dp+6)
0063 000005 a9.... LDA ##.word0 (.sectionEnd data_init_table)
0064 000008 85.. STA dp:.tiny(_Dp+4)
0065 00000a a9.... LDA ##.word2 (.sectionStart data_init_table)
0066 00000d 85.. STA dp:.tiny(_Dp+2)
0067 00000f a9.... LDA ##.word0 (.sectionStart data_init_table)
0068 000012 85.. STA dp:.tiny(_Dp+0)
0069 call __initialize_sections
\ 000014 22...... jsl long:__initialize_sections
0070
0071 ;;;; **** Initialize streams if needed.
0072 .section farcode, noroot, noreorder
0073 .pubweak __call_initialize_global_streams
0074 .extern __initialize_global_streams
0075 __call_initialize_global_streams:
0076 call __initialize_global_streams
\ 000000 22...... jsl long:__initialize_global_streams
0077
0078 ;;;; **** Initialize heap if needed.
0079 .section farcode, noroot, noreorder
0080 .pubweak __call_heap_initialize
0081 .extern __heap_initialize, __default_heap
0082 __call_heap_initialize:
0083 000000 a9.... LDA ##.word2 (.sectionStart heap)
0084 000003 85.. STA dp:.tiny(_Dp+6)
0085 000005 a9.... LDA ##.word0 (.sectionStart heap)
0086 000008 85.. STA dp:.tiny(_Dp+4)
0087 00000a a9.... LDA ##.word2 __default_heap
0088 00000d 85.. STA dp:.tiny(_Dp+2)
0089 00000f a9.... LDA ##.word0 __default_heap
0090 000012 85.. STA dp:.tiny(_Dp+0)
0091 000014 a2.... LDX ##.word2 (.sectionSize heap)
0092 000017 a9.... LDA ##.word0 (.sectionSize heap)
0093 call __heap_initialize
\ 00001a 22...... jsl long:__heap_initialize
0094
0095 .section farcode, root, noreorder
0096 000000 a90000 LDA ##0
0097 call main ; Jump to Main
\ 000003 22...... jsl long:main
0098 000007 dcf0ff JMP [0xFFF0] ; Once Returned, jump to the Termination Vector
0099
0100
0101 ;;;; ***************************************************************************
0102 ;;;;
0103 ;;;; __low_level_init - custom low level initialization
0104 ;;;;
0105 ;;;; This default routine just returns doing nothing. You can provide your own
0106 ;;;; routine, either in C or assembly for doing custom low leve initialization.
0107 ;;;;
0108 ;;;; ***************************************************************************
0109
0110 ; .section libcode
0111 ; .pubweak __low_level_init
0112 ;__low_level_init:
0113 ; return
0114
##########################
# #
# Memory sizes (decimal) #
# #
##########################
Executable (Text): 87 bytes
and the list file for the linker:
###############################################################################
# #
# Calypsi linker for 65816 version 4.1 #
# 09/Apr/2023 22:03:27 #
# Command line: --hosted --list-file Output\blank_lnk.lst --cross-reference #
# --rtattr cstartup=SBCv1 --verbose --output-format pgz -o #
# blank.pgz Config\SBC_816.scm Config\cstartup.o #
# Config\stdio_functions.o Temp\blank.o clib-lc-ld-double64.a #
# #
###############################################################################
####################
# #
# Memories summary #
# #
####################
Name Range Size Used Checksum Largest unallocated
-----------------------------------------------------------------------------------
DirectPage 000000-0000ff 000100 7.8% none 0000ec
LoRAM 000100-00fbff 00fb00 12.7% none 00db00
LoROM 00ff00-00ffff 000100 0.0% none 000100
IO 010000-0100ff 000100 0.0% none 000100
HiROM 010100-013fff 003f00 0.0% none 003f00
HiDB 020000-02ffff 010000 0.0% none 010000
HiRAM-02 020000-02ffff 010000 50.8% none 007e0f
> HiRAM-02-far-cbits 020000-020009 00000a 100.0% none none
> HiRAM-02-far-nobits 02000a-02000b 000002 100.0% none none
> HiRAM-02-farcode 02000c-0201f0 0001e5 100.0% none 00fe0f
HiRAM-03 030000-03ffff 010000 0.0% none 010000
HiRAM-04 040000-04ffff 010000 0.0% none 010000
HiRAM-05 050000-05ffff 010000 0.0% none 010000
HiRAM-06 060000-06ffff 010000 0.0% none 010000
HiRAM-07 070000-07ffff 010000 0.0% none 010000
HiRAM-08 080000-08ffff 010000 0.0% none 010000
HiRAM-09 090000-09ffff 010000 0.0% none 010000
HiRAM-0a 0a0000-0affff 010000 0.0% none 010000
HiRAM-0b 0b0000-0bffff 010000 0.0% none 010000
HiRAM-0c 0c0000-0cffff 010000 0.0% none 010000
HiRAM-0d 0d0000-0dffff 010000 0.0% none 010000
HiRAM-0e 0e0000-0effff 010000 0.0% none 010000
HiRAM-0f 0f0000-0fffff 010000 0.0% none 010000
VRAM ff0000-ffffff 010000 0.0% none 010000
####################
# #
# Sections summary #
# #
####################
Name Range Size Memory Fragments
--------------------------------------------------------------------
registers 000000-000013 000014 DirectPage 1
stack 000100-0020ff 002000 LoRAM 1
data_init_table 020000-020009 00000a HiRAM-02-far-cbits 1
zfar 02000a-02000b 000002 HiRAM-02-far-nobits 1
farcode 02000c-0201f0 0001e5 HiRAM-02-farcode 12
heap 0201f1-0281f0 008000 HiRAM-02 1
################
# #
# Object files #
# #
################
Unit Filename Archive
---------------------------------------------------
0 Config\cstartup.o -
# picked based on cstartup=SBCv1
> farcode 000035
1 Config\stdio_functions.o -
> farcode 000091
2 Temp\blank.o -
> farcode 000004
5 pseudoRegisters.o clib-lc-ld-double64.a
> registers 000014
7 errno.o clib-lc-ld-double64.a
> zfar 000002
12 initialize.o clib-lc-ld-double64.a
> farcode 000083
13 lib_memset.o clib-lc-ld-double64.a
> farcode 000049
14 lib_memcpy.o clib-lc-ld-double64.a
> farcode 00004f
###################
# #
# Cross reference #
# #
###################
_Dp in section 'registers' placed at address 000000-000013 of size 000014
(pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
Defines:
_Vfp = 000010
_Dp = 000000
Referenced from:
__program_root_section (Config\cstartup.o unit 0 section index 2)
__data_initialization_needed (Config\cstartup.o unit 0 section index 3)
_Stub_write (Config\stdio_functions.o unit 1 section index 2)
_Stub_read (Config\stdio_functions.o unit 1 section index 3)
__initialize_sections (initialize.o (from clib-lc-ld-double64.a) unit 12 section index 2)
memset (lib_memset.o (from clib-lc-ld-double64.a) unit 13 section index 2)
memcpy (lib_memcpy.o (from clib-lc-ld-double64.a) unit 14 section index 2)
Section 'heap' placed at address 0201f1-0281f0 of size 008000
(linker generated)
Section 'data_init_table' placed at address 020000-020009 of size 00000a
(linker generated)
errno in section 'zfar' placed at address 02000a-02000b of size 000002
(errno.o (from clib-lc-ld-double64.a) unit 7 section index 2)
Defines:
errno = 02000a
Referenced from:
_Stub_write (Config\stdio_functions.o unit 1 section index 2)
_Stub_read (Config\stdio_functions.o unit 1 section index 3)
_Stub_open in section 'farcode' placed at address 02000c-02000f of size 000004
(Config\stdio_functions.o unit 1 section index 5)
Defines:
_Stub_open = 02000c
_Stub_close in section 'farcode'
placed at address 020010-020013 of size 000004
(Config\stdio_functions.o unit 1 section index 6)
Defines:
_Stub_close = 020010
main in section 'farcode' placed at address 020014-020017 of size 000004
(Temp\blank.o unit 2 section index 2)
Defines:
main = 020014
Referenced from:
(Config\cstartup.o unit 0 section index 6)
_Stub_lseek in section 'farcode'
placed at address 020018-02001e of size 000007
(Config\stdio_functions.o unit 1 section index 4)
Defines:
_Stub_lseek = 020018
__program_start in section 'farcode'
placed at address 02001f-020031 of size 000013
(Config\cstartup.o unit 0 section index 2)
Defines:
__program_start = 02001f
__program_root_section = 02001f
References:
_DirectPageStart
_NearBaseAddress
.sectionEnd(stack)
_Vfp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
__data_initialization_needed in section 'farcode'
placed at address 020032-020049 of size 000018
(Config\cstartup.o unit 0 section index 3)
Defines:
__data_initialization_needed = 020032
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
.sectionEnd(data_init_table)
.sectionStart(data_init_table)
__initialize_sections in (initialize.o (from clib-lc-ld-double64.a) unit 12 section index 2)
Section 'farcode' placed at address 02004a-020053 of size 00000a
(Config\cstartup.o unit 0 section index 6)
References:
main in (Temp\blank.o unit 2 section index 2)
_Stub_write in section 'farcode'
placed at address 020054-02008f of size 00003c
(Config\stdio_functions.o unit 1 section index 2)
Defines:
_Stub_write = 020054
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
errno in (errno.o (from clib-lc-ld-double64.a) unit 7 section index 2)
_Stub_read in section 'farcode' placed at address 020090-0200d5 of size 000046
(Config\stdio_functions.o unit 1 section index 3)
Defines:
_Stub_read = 020090
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
errno in (errno.o (from clib-lc-ld-double64.a) unit 7 section index 2)
memset in section 'farcode' placed at address 0200d6-02011e of size 000049
(lib_memset.o (from clib-lc-ld-double64.a) unit 13 section index 2)
Defines:
memset = 0200d6
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
Referenced from:
__initialize_sections (initialize.o (from clib-lc-ld-double64.a) unit 12 section index 2)
memcpy in section 'farcode' placed at address 02011f-02016d of size 00004f
(lib_memcpy.o (from clib-lc-ld-double64.a) unit 14 section index 2)
Defines:
memcpy = 02011f
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
Referenced from:
__initialize_sections (initialize.o (from clib-lc-ld-double64.a) unit 12 section index 2)
__initialize_sections in section 'farcode'
placed at address 02016e-0201f0 of size 000083
(initialize.o (from clib-lc-ld-double64.a) unit 12 section index 2)
Defines:
__initialize_sections = 02016e
References:
_Dp in (pseudoRegisters.o (from clib-lc-ld-double64.a) unit 5 section index 2)
memcpy in (lib_memcpy.o (from clib-lc-ld-double64.a) unit 14 section index 2)
memset in (lib_memset.o (from clib-lc-ld-double64.a) unit 13 section index 2)
Referenced from:
__data_initialization_needed (Config\cstartup.o unit 0 section index 3)
Section 'stack' placed at address 000100-0020ff of size 002000
(linker generated)
##########################
# #
# Memory sizes (decimal) #
# #
##########################
Executable (Text): 495 bytes
Data : 2 bytes
Non-initialized : 40980 bytes
and for good measure the output of my SBC:
020000
00000A
0A 00 02 00 00 00 00 00 02 00
02000C
0001E5
A9 00 00 6B A9 00 00 6B A9 00 00 6B A9 FF FF
A2 FF FF 6B C2 30 A2 FF 20 9A A9 00 00 5B A9
02 00 64 12 EB 48 AB AB A9 02 00 85 06 A9 09
00 85 04 A9 02 00 85 02 A9 00 00 85 00 22 6E
01 02 A9 00 00 22 14 00 02 DC F0 FF 5A A0 00
00 C9 01 00 F0 0B A9 09 00 8F 0A 00 02 98 3A
80 26 A6 04 F0 21 AF 00 00 01 89 40 00 D0 F7
E2 20 A7 00 8F 01 00 01 C2 20 E6 00 98 1A A8
8A 3A 83 01 A3 01 AA 80 DD 98 7A 6B 5A AA A9
00 00 83 01 E0 01 00 F0 0C A9 09 00 8F 0A 00
02 A9 FF FF 80 2C A6 04 A3 01 E8 CA F0 22 AF
FF FF 00 30 FA E2 20 AF 01 00 01 87 00 C2 20
E6 00 A3 01 1A A8 8A 3A 83 01 A3 01 AA 98 83
01 80 DA A3 01 7A 6B D4 08 D4 0A 5A 5A 5A 83
01 A5 00 85 08 A5 02 85 0A A5 04 83 05 A3 05
83 03 A3 05 3A 83 05 A9 00 00 C3 03 B0 16 A5
08 85 04 A5 0A 85 06 E6 08 E2 20 A3 01 87 04
C2 20 A3 05 80 DA A6 02 A5 00 7A 7A 7A 7A 84
0A 7A 84 08 6B D4 08 D4 0A D4 0C D4 0E 5A 83
01 A5 00 85 08 A5 02 85 0A A3 01 A3 01 A8 3A
AA 64 0C A5 0C 84 0C C5 0C B0 19 A5 08 85 0C
A5 0A 85 0E E6 08 A7 04 E6 04 E2 20 87 0C C2
20 8A 83 01 80 D8 A6 02 A5 00 7A 7A 84 0E 7A
84 0C 7A 84 0A 7A 84 08 6B D4 08 D4 0A D4 0C
D4 0E A5 04 85 08 A5 06 85 0A A5 00 85 0C A5
02 85 0E A5 0C 85 00 A5 0E 85 02 A5 00 C5 08
A5 02 E5 0A B0 4C A0 04 00 B7 0C C8 C8 17 0C
F0 1F B7 0C 85 06 88 88 B7 0C 85 04 88 88 B7
0C 85 02 A7 0C 85 00 A0 08 00 B7 0C 22 1F 01
02 80 18 C8 C8 B7 0C 85 04 A0 02 00 B7 0C 85
02 A7 0C 85 00 A9 00 00 22 D6 00 02 18 A5 0C
69 0A 00 85 0C 80 A2 7A 84 0E 7A 84 0C 7A 84
0A 7A 84 08 6B
02001F
000000
everything else is as before.
What is the problem you observe?
The start address is 02001f
, which is where the cross reference says it is. If I count into the hex output that appears to be pointing to c2 30
which corresponds to the rep #48
which is the first instruction in the C startup. That looks reasonable?
well my SBC crashes once it jumps to the program, which it didn't do when i excluded the stdio_functions.o
file (which never gets called so it shouldn't effect anything anyways).
i have a debug print macro that just prints a single ASCII character directly to Serial it will always print something, which helps when debugging assembly.
putting one of those at the very start of cstartup.s
that prints a single !
, it never appears when i include stdio_functions.o
in the linker. meaning that it never actually reaches the start of the program... for some reason.
i know my SBC jumps to the correct address, otherwise it wouldn't load any program... so why would this one crash?
actually nvm. i'm able to recreate the crash using an assembly program as well by just having a lot of data in it.
so i did actually break something in my BIOS that casues it to crash when a program is too large... i'll have to look into that more later, but that implies that the issue is actually resolved. as we both saw that the address it should jump to is correct.
alright i fixed the issue in my BIOS code and now it's all working fine again. so i guess we both fixed something, thanks!
while reworking parts of my SBC's BIOS ROM i somehow broke my C environment and now i'm not sure how to fix it again...
basically when compiling some code the last segment of the PGZ file (which denotes the address where execution should jump to) does not seem to line up with where it should point to. for the sake of testing i'm compiling a C file containing just an empty main function and nothing else, and
cstartup.s
only contains the required labels and a single instruction to jump to my ROM's Termination Vector.compiling the C file generates a correct and functional PGZ file here the Serial output of my SBC:
the
DC F0 FF
is the Indirect Jump to the BIOS ROM, and as you can see it's located at the start of the Code Segment at address0x02000C
which is also where execution jumps to acording to the last segment. and it does indeed work and return successfully.but watch what happens when i add just a single
NOP
instruction tocstartup.s
:suddendly the
DC F0 FF
is further into the code segment. theA9 00 00 6B
seems to be from the C file as that's just theLDA ##0
andRTL
instructions of the empty main function. after that you have theEA DC F0 FF
which form theNOP
andJMP []
instructions. doing the math manually, from the start of the code segment at0x02000C
to the NOP instruction is a total of 16 Bytes, so the last segment should point to address0x02001C
... but it doesn't, it points to0x020018
instead. so it's off by 4 bytes, but why?that's where i hope you can help me out with this. i know it's not a problem with the ROM or loader as a purely assembly written program using ca65 works perfectly no matter how large or small the segments are.
.
so here all the info i can give: the commands used to compile, assemble, and link everything:
the
SBC_816.scm
file looks like this:cstartup.s
:test.c
is literally just:the
stdio_functions.c
file is likely from the src folder of Calypsi C itself and i only have it included because i usually use it forprintf
. it shouldn't matter that it's present.i hope that is everything needed to hopefully recreate this issue, or tell me if anything sticks out as obviously wrong....