mirror of
https://github.com/cc65/cc65.git
synced 2025-02-03 07:30:52 +00:00
Merge branch 'master' of https://github.com/cc65/cc65 into c1p
This commit is contained in:
commit
4e03d7448c
@ -24,7 +24,7 @@ endif
|
||||
|
||||
SF_USER = oliverschmidt
|
||||
SF_HOST = frs.sourceforge.net
|
||||
SF_FILE = /home/frs/project/cc65/cc65-snapshot-win64.zip
|
||||
SF_FILE = /home/frs/project/cc65/cc65-snapshot-win32.zip
|
||||
|
||||
SCPFLAGS = -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q
|
||||
|
||||
|
@ -1,22 +1,31 @@
|
||||
SYMBOLS {
|
||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||
__TAPEHDR__: type = import;
|
||||
__BASHDR__: type = import;
|
||||
__PROGFLAG__: type = weak, value = $00; # $00=BASIC, $80=machine code
|
||||
__AUTORUN__: type = weak, value = $00; # $00=only load, $C7=run
|
||||
__STACKSIZE__: type = weak, value = $0800; # 2K stack
|
||||
__GRAB__: type = weak, value = 0; # 0=don't grab graphics RAM, 1=grab graphics RAM
|
||||
__RAMEND__: type = weak, value = $9800 + $1C00 * __GRAB__;
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", define = yes, start = $00E2, size = $001A;
|
||||
TAPEHDR: file = %O, type = ro, start = $0000, size = $0011;
|
||||
RAM: file = %O, define = yes, start = $0500, size = $9300 - __STACKSIZE__;
|
||||
TAPEHDR: file = %O, type = ro, start = $0000, size = $001F;
|
||||
BASHEAD: file = %O, define = yes, start = $0501, size = $000D;
|
||||
RAM: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __RAM_START__ - __STACKSIZE__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
TAPEHDR: load = TAPEHDR, type = ro;
|
||||
BASHDR: load = BASHEAD, type = ro, define = yes, optional = yes;
|
||||
STARTUP: load = RAM, type = ro;
|
||||
LOWCODE: load = RAM, type = ro, optional = yes;
|
||||
INIT: load = RAM, type = ro, define = yes, optional = yes;
|
||||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
INIT: load = RAM, type = ro, define = yes, optional = yes;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss, define = yes;
|
||||
ZPSAVE1: load = RAM, type = rw, define = yes; # ZPSAVE1, ZPSAVE2 must be together
|
||||
ZPSAVE2: load = RAM, type = bss; # see "libsrc/atmos/crt0.s"
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
|
@ -7,7 +7,7 @@
|
||||
<url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
|
||||
<url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal">,<newline>
|
||||
<url url="mailto:greg.king5@verizon.net" name="Greg King">
|
||||
<date>2014-03-27
|
||||
<date>2015-01-09
|
||||
|
||||
<abstract>
|
||||
An overview over the Atmos runtime system as it is implemented for the cc65 C
|
||||
@ -32,27 +32,39 @@ more than one platform. Please see the function reference for more
|
||||
information.
|
||||
|
||||
|
||||
|
||||
<sect>Binary format<p>
|
||||
|
||||
The standard binary output format generated by the linker for the Atmos target
|
||||
is a machine language program with a 17 byte tape header including a cc65 tag.
|
||||
The standard load and autostart address is $500.
|
||||
is a machine language program with a one-line BASIC stub that jumps to the
|
||||
machine-language part through <tt/CALL/. It has one sacrificial byte attached
|
||||
to the end (a bug in the Oric ROM means that BASIC can put a variable on top
|
||||
of the last byte that was loaded). It has a 24-byte tape header. A file can
|
||||
be CLOADed as a BASIC program, and started by typing <tt/RUN/. The standard
|
||||
load address is $501.
|
||||
|
||||
|
||||
|
||||
<sect>Memory layout<p>
|
||||
|
||||
In the standard setup, cc65 generated programs use the memory from
|
||||
$500 to $9800, so nearly 37K of memory (including the stack) is
|
||||
In the standard setup, cc65-generated programs use the memory from
|
||||
$0501 to $9800; so, nearly 37K of memory (including the stack) is
|
||||
available. ROM calls are possible without further precautions.
|
||||
|
||||
If your program needs more memory, and it won't use TGI graphics, then you can
|
||||
use the ld65 command-line option, <tt/-D __GRAB__=1/, when building the
|
||||
program, to include the graphics screen RAM. Then, nearly 44K of memory
|
||||
($0501 to $B400) is available.
|
||||
|
||||
Special locations:
|
||||
|
||||
<descrip>
|
||||
<tag/Stack/
|
||||
The C runtime stack is located at $97FF and growing downwards.
|
||||
The C runtime stack is located at $97FF (or $B3FF), and grows
|
||||
downwards.
|
||||
|
||||
<tag/Heap/
|
||||
The C heap is located at the end of the program and grows towards the C
|
||||
The C heap is located at the end of the program, and grows towards the C
|
||||
runtime stack.
|
||||
|
||||
</descrip><p>
|
||||
@ -90,7 +102,7 @@ structures; accessing the struct fields will access the chip registers.
|
||||
<descrip>
|
||||
|
||||
<tag><tt/VIA/</tag>
|
||||
Access to the VIA (versatile interface adapter) chip is available via the
|
||||
Access to the VIA (Versatile Interface Adapter) chip is available via the
|
||||
<tt/VIA/ variable. The structure behind this variable is explained in <tt/_6522.h/.
|
||||
|
||||
</descrip><p>
|
||||
@ -117,7 +129,8 @@ The names in the parentheses denote the symbols to be used for static linking of
|
||||
|
||||
<sect1>Graphics drivers<p>
|
||||
|
||||
The default drivers, <tt/tgi_stddrv (tgi_static_stddrv)/, point to <tt/atmos-240-200-2.tgi (atmos_240_200_2_tgi)/.
|
||||
The default drivers, <tt/tgi_stddrv (tgi_static_stddrv)/,
|
||||
point to <tt/atmos-240-200-2.tgi (atmos_240_200_2_tgi)/.
|
||||
|
||||
<descrip>
|
||||
|
||||
@ -175,13 +188,14 @@ No mouse drivers are currently available for the Atmos.
|
||||
|
||||
<sect1>Disk I/O<p>
|
||||
|
||||
The existing library for the Atmos doesn't implement C file
|
||||
I/O. There are hacks for the <tt/read()/ and <tt/write()/ routines in
|
||||
place, which will make functions work that read from and write to <tt/stdout/
|
||||
(like <tt/printf()/). However, those functions have some shortcomings which
|
||||
won't be fixed, because they're going to be replaced anyway.
|
||||
The existing library for the Atmos doesn't implement C file I/O. There are
|
||||
hacks for the <tt/read()/ and <tt/write()/ routines in place, which will make
|
||||
functions work that read from <tt/stdin/ and write to <tt/stdout/ and
|
||||
<tt/stderr/ (such as <tt/printf()/). However, those functions have some
|
||||
shortcomings which won't be fixed, because they're going to be replaced
|
||||
anyway.
|
||||
|
||||
To be more concrete, the limitation means that you cannot use any of the
|
||||
To be more concrete, that limitation means that you cannot use any of the
|
||||
following functions (and a few others):
|
||||
|
||||
<itemize>
|
||||
@ -202,7 +216,14 @@ following functions (and a few others):
|
||||
|
||||
<sect1>Function keys<p>
|
||||
|
||||
These are defined to be FUNCT + number key.
|
||||
They are defined to be FUNCT + a number key.
|
||||
|
||||
|
||||
<sect1>Capitals lock<p>
|
||||
|
||||
The keyboard's "CAPS Lock" mode is turned off while the program is running.
|
||||
The previous mode (usually, CAPS Lock turned on [because Oric BASIC keywords
|
||||
must be UPPER-case]) is restored when the program stops.
|
||||
|
||||
|
||||
<sect1>Passing arguments to the program<p>
|
||||
@ -211,10 +232,12 @@ Command-line arguments can be passed to <tt/main()/. Since that is not
|
||||
supported directly by BASIC, the following syntax was chosen:
|
||||
|
||||
<tscreen><verb>
|
||||
CALL#500:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5
|
||||
RUN:REM arg1 " ARG2 IS QUOTED" ARG3 "" ARG5
|
||||
</verb></tscreen>
|
||||
|
||||
<enum>
|
||||
<item>You must turn <tt/CAPS/ lock off (tap CTRL-T) when you want to type
|
||||
lower-case arguments (but, <tt/RUN/ and <tt/REM/ must be UPPER-case).
|
||||
<item>Arguments are separated by spaces.
|
||||
<item>Arguments may be quoted.
|
||||
<item>Leading and trailing spaces around an argument are ignored. Spaces within
|
||||
@ -225,6 +248,15 @@ supported directly by BASIC, the following syntax was chosen:
|
||||
</enum>
|
||||
|
||||
|
||||
<sect1>Automatic starting<p>
|
||||
|
||||
Usually, a cc65-built program just will sit quietly in memory, after it is
|
||||
CLOADed. It waits for you to start it (by typing BASIC's <tt/RUN/ command).
|
||||
But, if you want to create a program that will start running immediately after
|
||||
it is loaded, then you can use the linker command-line option
|
||||
<tt/-D __AUTORUN__=$C7/.
|
||||
|
||||
|
||||
<sect1>Interrupts<p>
|
||||
|
||||
The runtime for the Atmos uses routines marked as <tt/.INTERRUPTOR/ for
|
||||
|
122
doc/da65.sgml
122
doc/da65.sgml
@ -2,12 +2,14 @@
|
||||
|
||||
<article>
|
||||
<title>da65 Users Guide
|
||||
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">
|
||||
<date>2003-08-08
|
||||
<author>
|
||||
<url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
|
||||
<url url="mailto:greg.king5@verizon.net" name="Greg King">
|
||||
<date>2014-11-23
|
||||
|
||||
<abstract>
|
||||
da65 is a 6502/65C02 disassembler that is able to read user supplied
|
||||
information about its input data for better results. The output is ready for
|
||||
da65 is a 6502/65C02 disassembler that is able to read user-supplied
|
||||
information about its input data, for better results. The output is ready for
|
||||
feeding into ca65, the macro assembler supplied with the cc65 C compiler.
|
||||
</abstract>
|
||||
|
||||
@ -23,7 +25,7 @@ the cc65 C compiler and generates output that is suitable for the ca65
|
||||
macro assembler.
|
||||
|
||||
Besides generating output for ca65, one of the design goals was that the user
|
||||
is able to feed additional information about the code into the disassembler
|
||||
is able to feed additional information about the code into the disassembler,
|
||||
for improved results. This information may include the location and size of
|
||||
tables, and their format.
|
||||
|
||||
@ -106,11 +108,16 @@ Here is a description of all the command line options:
|
||||
<tag><tt>--cpu type</tt></tag>
|
||||
|
||||
Set the CPU type. The option takes a parameter, which may be one of
|
||||
<itemize>
|
||||
<item>6502
|
||||
<item>6502x
|
||||
<item>65sc02
|
||||
<item>65c02
|
||||
<item>huc6280
|
||||
</itemize>
|
||||
|
||||
6502, 6502x, 65sc02, 65c02, huc6280
|
||||
|
||||
6502x is the NMOS 6502 with illegal opcodes. huc6280 is the CPU of the PC
|
||||
engine. Support for the 65816 is currently not available.
|
||||
6502x is for the NMOS 6502 with unofficial opcodes. huc6280 is the CPU of
|
||||
the PC engine. Support for the 65816 currently is not available.
|
||||
|
||||
|
||||
<label id="option--formfeeds">
|
||||
@ -125,7 +132,7 @@ Here is a description of all the command line options:
|
||||
<tag><tt>-g, --debug-info</tt></tag>
|
||||
|
||||
This option adds the <tt/.DEBUGINFO/ command to the output file, so the
|
||||
assembler will generate debug information when reassembling the generated
|
||||
assembler will generate debug information when re-assembling the generated
|
||||
output.
|
||||
|
||||
|
||||
@ -241,7 +248,7 @@ unsupported.
|
||||
The disassembler works by creating an attribute map for the whole address
|
||||
space ($0000 - $FFFF). Initially, all attributes are cleared. Then, an
|
||||
external info file (if given) is read. Disassembly is done in several passes.
|
||||
In all passes with the exception of the last one, information about the
|
||||
In all passes, with the exception of the last one, information about the
|
||||
disassembled code is gathered and added to the symbol and attribute maps. The
|
||||
last pass generates output using the information from the maps.
|
||||
|
||||
@ -275,19 +282,19 @@ braces. Attributes have a name followed by a value. The syntax of the value
|
||||
depends on the type of the attribute. String attributes are places in double
|
||||
quotes, numeric attributes may be specified as decimal numbers or hexadecimal
|
||||
with a leading dollar sign. There are also attributes where the attribute
|
||||
value is a keyword, in this case the keyword is given as is (without quotes or
|
||||
value is a keyword; in this case, the keyword is given as-is (without quotes or
|
||||
anything). Each attribute is terminated by a semicolon.
|
||||
|
||||
<tscreen><verb>
|
||||
group-name { attribute1 attribute-value; attribute2 attribute-value; }
|
||||
group-name { attribute1 attribute-value; attribute2 attribute-value; }
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
<sect1>Comments<p>
|
||||
|
||||
Comments start with a hash mark (<tt/#/) and extend from the position of
|
||||
Comments start with a hash mark (<tt/#/); and, extend from the position of
|
||||
the mark to the end of the current line. Hash marks inside of strings will
|
||||
of course <em/not/ start a comment.
|
||||
<em/not/ start a comment, of course.
|
||||
|
||||
|
||||
<sect1>Specifying global options<label id="global-options"><p>
|
||||
@ -543,18 +550,17 @@ disassembled code. The following attributes are recognized:
|
||||
|
||||
<tag><tt>END</tt></tag>
|
||||
Followed by a numerical value. Specifies the end address of the segment. The
|
||||
end address is last the address that is part of the segment.
|
||||
end address is the last address that is a part of the segment.
|
||||
|
||||
<tag><tt>NAME</tt></tag>
|
||||
The attribute is followed by a string value which gives the name of the
|
||||
segment.
|
||||
</descrip>
|
||||
|
||||
All attributes are mandatory. Segments may not overlap. Since there is no
|
||||
explicit "end this segment" pseudo op, the disassembler cannot notify the
|
||||
assembler that one segment has ended. This may lead to errors if you don't
|
||||
define your segments carefully. As a rule of thumb, if you're using segments,
|
||||
your should define segments for all disassembled code.
|
||||
All attributes are mandatory. Segments must not overlap. The disassembler will
|
||||
change back to the (default) <tt/.code/ segment after the end of each defined
|
||||
segment. That might not be what you want. As a rule of thumb, if you're using
|
||||
segments, you should define segments for all disassembled code.
|
||||
|
||||
|
||||
<sect1>Specifying Assembler Includes<label id="infofile-asminc"><p>
|
||||
@ -563,8 +569,8 @@ The <tt/ASMINC/ directive is used to give the names of input files containing
|
||||
symbol assignments in assembler syntax:
|
||||
|
||||
<tscreen><verb>
|
||||
Name = value
|
||||
Name := value
|
||||
Name = value
|
||||
Name := value
|
||||
</verb></tscreen>
|
||||
|
||||
The usual conventions apply for symbol names. Values may be specified as hex
|
||||
@ -613,48 +619,46 @@ directives explained above:
|
||||
};
|
||||
|
||||
# One segment for the whole stuff
|
||||
SEGMENT { START $E000; END $FFFF; NAME kernal; };
|
||||
SEGMENT { START $E000; END $FFFF; NAME "kernal"; };
|
||||
|
||||
RANGE { START $E612; END $E631; TYPE Code; };
|
||||
RANGE { START $E632; END $E640; TYPE ByteTable; };
|
||||
RANGE { START $EA51; END $EA84; TYPE RtsTable; };
|
||||
RANGE { START $EC6C; END $ECAB; TYPE RtsTable; };
|
||||
RANGE { START $ED08; END $ED11; TYPE AddrTable; };
|
||||
RANGE { START $E612; END $E631; TYPE Code; };
|
||||
RANGE { START $E632; END $E640; TYPE ByteTable; };
|
||||
RANGE { START $EA51; END $EA84; TYPE RtsTable; };
|
||||
RANGE { START $EC6C; END $ECAB; TYPE RtsTable; };
|
||||
RANGE { START $ED08; END $ED11; TYPE AddrTable; };
|
||||
|
||||
# Zero page variables
|
||||
LABEL { NAME "fnadr"; ADDR $90; SIZE 3; };
|
||||
LABEL { NAME "sal"; ADDR $93; };
|
||||
LABEL { NAME "sah"; ADDR $94; };
|
||||
LABEL { NAME "sas"; ADDR $95; };
|
||||
# Zero-page variables
|
||||
LABEL { NAME "fnadr"; ADDR $90; SIZE 3; };
|
||||
LABEL { NAME "sal"; ADDR $93; };
|
||||
LABEL { NAME "sah"; ADDR $94; };
|
||||
LABEL { NAME "sas"; ADDR $95; };
|
||||
|
||||
# Stack
|
||||
LABEL { NAME "stack"; ADDR $100; SIZE 255; };
|
||||
LABEL { NAME "stack"; ADDR $100; SIZE 255; };
|
||||
|
||||
# Indirect vectors
|
||||
LABEL { NAME "cinv"; ADDR $300; SIZE 2; }; # IRQ
|
||||
LABEL { NAME "cbinv"; ADDR $302; SIZE 2; }; # BRK
|
||||
LABEL { NAME "nminv"; ADDR $304; SIZE 2; }; # NMI
|
||||
LABEL { NAME "cinv"; ADDR $300; SIZE 2; }; # IRQ
|
||||
LABEL { NAME "cbinv"; ADDR $302; SIZE 2; }; # BRK
|
||||
LABEL { NAME "nminv"; ADDR $304; SIZE 2; }; # NMI
|
||||
|
||||
# Jump table at end of kernal ROM
|
||||
LABEL { NAME "kscrorg"; ADDR $FFED; };
|
||||
LABEL { NAME "kplot"; ADDR $FFF0; };
|
||||
LABEL { NAME "kiobase"; ADDR $FFF3; };
|
||||
LABEL { NAME "kgbye"; ADDR $FFF6; };
|
||||
LABEL { NAME "kscrorg"; ADDR $FFED; };
|
||||
LABEL { NAME "kplot"; ADDR $FFF0; };
|
||||
LABEL { NAME "kiobase"; ADDR $FFF3; };
|
||||
LABEL { NAME "kgbye"; ADDR $FFF6; };
|
||||
|
||||
# Hardware vectors
|
||||
LABEL { NAME "hanmi"; ADDR $FFFA; };
|
||||
LABEL { NAME "hares"; ADDR $FFFC; };
|
||||
LABEL { NAME "hairq"; ADDR $FFFE; };
|
||||
LABEL { NAME "hanmi"; ADDR $FFFA; };
|
||||
LABEL { NAME "hares"; ADDR $FFFC; };
|
||||
LABEL { NAME "hairq"; ADDR $FFFE; };
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<sect>Copyright<p>
|
||||
|
||||
da65 (and all cc65 binutils) are (C) Copyright 1998-2007 Ullrich von
|
||||
Bassewitz. For usage of the binaries and/or sources the following
|
||||
da65 (and all cc65 binutils) is (C) Copyright 1998-2011, Ullrich von
|
||||
Bassewitz. For usage of the binaries and/or sources, the following
|
||||
conditions do apply:
|
||||
|
||||
This software is provided 'as-is', without any expressed or implied
|
||||
@ -666,20 +670,16 @@ including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
<enum>
|
||||
<item> 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.
|
||||
<item> Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
<item> This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
<item> 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.
|
||||
<item> Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
<item> This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
</enum>
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
|
||||
|
24
libsrc/atmos/bashdr.s
Normal file
24
libsrc/atmos/bashdr.s
Normal file
@ -0,0 +1,24 @@
|
||||
;
|
||||
; 2010-11-14, Ullrich von Bassewitz
|
||||
; 2014-09-06, Greg King
|
||||
;
|
||||
; This module supplies a small BASIC stub program that uses CALL
|
||||
; to jump to the machine-language code that follows it.
|
||||
;
|
||||
|
||||
; The following symbol is used by the linker config. file
|
||||
; to force this module to be included into the output file.
|
||||
.export __BASHDR__:abs = 1
|
||||
|
||||
|
||||
.segment "BASHDR"
|
||||
|
||||
.addr Next
|
||||
.word .version ; Line number
|
||||
.byte $BF,'#' ; CALL token, mark number as hexadecimal
|
||||
.byte <(Start >> 8 ) + '0' + (Start >> 8 > $09) * $07
|
||||
.byte <(Start >> 4 & $0F) + '0' + (Start >> 4 & $0F > $09) * $07
|
||||
.byte <(Start & $0F) + '0' + (Start & $0F > $09) * $07
|
||||
.byte $00 ; End of BASIC line
|
||||
Next: .addr $0000 ; BASIC program end marker
|
||||
Start:
|
@ -2,39 +2,18 @@
|
||||
; Startup code for cc65 (Oric version)
|
||||
;
|
||||
; By Debrune Jérôme <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org>
|
||||
; 2014-08-22, Greg King
|
||||
; 2015-01-09, Greg King
|
||||
;
|
||||
|
||||
.export _exit
|
||||
.export __STARTUP__ : absolute = 1 ; Mark as startup
|
||||
.import initlib, donelib
|
||||
.import callmain, zerobss
|
||||
.import __RAM_START__, __RAM_SIZE__
|
||||
.import __ZPSAVE_LOAD__, __STACKSIZE__
|
||||
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "atmos.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Oric tape header
|
||||
|
||||
.segment "TAPEHDR"
|
||||
|
||||
.byte $16, $16, $16 ; Sync bytes
|
||||
.byte $24 ; End of header marker
|
||||
|
||||
.byte $00 ; $2B0
|
||||
.byte $00 ; $2AF
|
||||
.byte $80 ; $2AE Machine code flag
|
||||
.byte $C7 ; $2AD Autoload flag
|
||||
.dbyt __ZPSAVE_LOAD__ - 1 ; $2AB
|
||||
.dbyt __RAM_START__ ; $2A9
|
||||
.byte $00 ; $2A8
|
||||
.byte ((.VERSION >> 8) & $0F) + '0'
|
||||
.byte ((.VERSION >> 4) & $0F) + '0'
|
||||
.byte (.VERSION & $0F) + '0'
|
||||
.byte $00 ; Zero terminated compiler version
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Place the startup code in a special segment.
|
||||
|
||||
@ -52,7 +31,8 @@ L1: lda sp,x
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Unprotect screen columns 0 and 1.
|
||||
; Currently, color isn't supported on the text screen.
|
||||
; Unprotect screen columns 0 and 1 (where each line's color codes would sit).
|
||||
|
||||
lda STATUS
|
||||
sta stsave
|
||||
@ -79,7 +59,7 @@ L1: lda sp,x
|
||||
|
||||
; Call the module destructors. This is also the exit() entry.
|
||||
|
||||
_exit: jsr donelib ; Run module destructors
|
||||
_exit: jsr donelib
|
||||
|
||||
; Restore the system stuff.
|
||||
|
||||
@ -102,9 +82,23 @@ L2: lda zpsave,x
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "ZPSAVE"
|
||||
.segment "ZPSAVE1"
|
||||
|
||||
zpsave: .res zpspace
|
||||
zpsave:
|
||||
|
||||
; This padding is needed by a bug in the ROM.
|
||||
; (The CLOAD command starts BASIC's variables table on top of the last byte
|
||||
; that was loaded [instead of at the next address].)
|
||||
; This is overlaid on a buffer, so that it doesn't use extra space in RAM.
|
||||
|
||||
.byte 0
|
||||
|
||||
; The segments "ZPSAVE1" and "ZPSAVE2" always must be together.
|
||||
; They create a single object (the zpsave buffer).
|
||||
|
||||
.segment "ZPSAVE2"
|
||||
|
||||
.res zpspace - 1
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
|
31
libsrc/atmos/tapehdr.s
Normal file
31
libsrc/atmos/tapehdr.s
Normal file
@ -0,0 +1,31 @@
|
||||
;
|
||||
; Based on code by Debrune Jérôme <jede@oric.org>
|
||||
; 2015-01-08, Greg King
|
||||
;
|
||||
|
||||
; The following symbol is used by the linker config. file
|
||||
; to force this module to be included into the output file.
|
||||
.export __TAPEHDR__:abs = 1
|
||||
|
||||
; These symbols, also, come from the configuration file.
|
||||
.import __BASHDR_LOAD__, __ZPSAVE1_LOAD__, __AUTORUN__, __PROGFLAG__
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Oric cassette-tape header
|
||||
|
||||
.segment "TAPEHDR"
|
||||
|
||||
.byte $16, $16, $16 ; Sync bytes
|
||||
.byte $24 ; Beginning-of-header marker
|
||||
|
||||
.byte $00 ; $2B0
|
||||
.byte $00 ; $2AF
|
||||
.byte <__PROGFLAG__ ; $2AE Language flag ($00=BASIC, $80=machine code)
|
||||
.byte <__AUTORUN__ ; $2AD Auto-run flag ($C7=run, $00=only load)
|
||||
.dbyt __ZPSAVE1_LOAD__ ;$2AB Address of end of file
|
||||
.dbyt __BASHDR_LOAD__ ; $2A9 Address of start of file
|
||||
.byte $00 ; $2A8
|
||||
|
||||
; File name (a maximum of 17 characters), zero-terminated
|
||||
.asciiz .sprintf("%u", .time)
|
@ -713,9 +713,9 @@ static const struct {
|
||||
{ "ROR", 0x000006F, 0x62, 1, PutAll },
|
||||
{ "RTI", 0x0000001, 0x40, 0, PutAll },
|
||||
{ "RTS", 0x0000001, 0x60, 0, PutAll },
|
||||
{ "SBC", 0x080A66C, 0xe0, 0, PutAll },
|
||||
{ "SAX", 0x0000001, 0x22, 0, PutAll },
|
||||
{ "SAY", 0x0000001, 0x42, 0, PutAll },
|
||||
{ "SBC", 0x080A66C, 0xe0, 0, PutAll },
|
||||
{ "SEC", 0x0000001, 0x38, 0, PutAll },
|
||||
{ "SED", 0x0000001, 0xf8, 0, PutAll },
|
||||
{ "SEI", 0x0000001, 0x78, 0, PutAll },
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@ -66,6 +66,18 @@ void AddrCheck (unsigned Addr)
|
||||
|
||||
|
||||
|
||||
attr_t GetAttr (unsigned Addr)
|
||||
/* Return the attribute for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return AttrTab[Addr];
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SegmentDefined (unsigned Start, unsigned End)
|
||||
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||
{
|
||||
@ -79,14 +91,18 @@ int SegmentDefined (unsigned Start, unsigned End)
|
||||
|
||||
|
||||
|
||||
int HaveSegmentChange (unsigned Addr)
|
||||
/* Return true if the segment change attribute is set for the given address */
|
||||
int IsSegmentEnd (unsigned Addr)
|
||||
/* Return true if a segment ends at the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
return (GetAttr (Addr) & atSegmentEnd) != 0x0000;
|
||||
}
|
||||
|
||||
/* Return the attribute */
|
||||
return (AttrTab[Addr] & atSegmentChange) != 0;
|
||||
|
||||
|
||||
int IsSegmentStart (unsigned Addr)
|
||||
/* Return true if a segment starts at the given address */
|
||||
{
|
||||
return (GetAttr (Addr) & atSegmentStart) != 0x0000;
|
||||
}
|
||||
|
||||
|
||||
@ -145,18 +161,6 @@ void MarkAddr (unsigned Addr, attr_t Attr)
|
||||
|
||||
|
||||
|
||||
attr_t GetAttr (unsigned Addr)
|
||||
/* Return the attribute for the given address */
|
||||
{
|
||||
/* Check the given address */
|
||||
AddrCheck (Addr);
|
||||
|
||||
/* Return the attribute */
|
||||
return AttrTab[Addr];
|
||||
}
|
||||
|
||||
|
||||
|
||||
attr_t GetStyleAttr (unsigned Addr)
|
||||
/* Return the style attribute for the given address */
|
||||
{
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||
/* Römerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@ -47,33 +47,34 @@
|
||||
typedef enum attr_t {
|
||||
|
||||
/* Styles */
|
||||
atDefault = 0x0000, /* Default style */
|
||||
atCode = 0x0001,
|
||||
atIllegal = 0x0002,
|
||||
atByteTab = 0x0003, /* Same as illegal */
|
||||
atDByteTab = 0x0004,
|
||||
atWordTab = 0x0005,
|
||||
atDWordTab = 0x0006,
|
||||
atAddrTab = 0x0007,
|
||||
atRtsTab = 0x0008,
|
||||
atTextTab = 0x0009,
|
||||
atSkip = 0x000A, /* Skip code completely */
|
||||
atDefault = 0x0000, /* Default style */
|
||||
atCode = 0x0001,
|
||||
atIllegal = 0x0002,
|
||||
atByteTab = 0x0003, /* Same as illegal */
|
||||
atDByteTab = 0x0004,
|
||||
atWordTab = 0x0005,
|
||||
atDWordTab = 0x0006,
|
||||
atAddrTab = 0x0007,
|
||||
atRtsTab = 0x0008,
|
||||
atTextTab = 0x0009,
|
||||
atSkip = 0x000A, /* Skip code completely */
|
||||
|
||||
/* Label flags */
|
||||
atNoLabel = 0x0000, /* No label for this address */
|
||||
atExtLabel = 0x0010, /* External label */
|
||||
atIntLabel = 0x0020, /* Internally generated label */
|
||||
atDepLabel = 0x0040, /* Dependent label */
|
||||
atUnnamedLabel = 0x0080, /* Unnamed label */
|
||||
atNoLabel = 0x0000, /* No label for this address */
|
||||
atExtLabel = 0x0010, /* External label */
|
||||
atIntLabel = 0x0020, /* Internally generated label */
|
||||
atDepLabel = 0x0040, /* Dependent label */
|
||||
atUnnamedLabel = 0x0080, /* Unnamed label */
|
||||
|
||||
atLabelDefined = 0x0100, /* True if we defined the label */
|
||||
atLabelDefined = 0x0100, /* True if we defined the label */
|
||||
|
||||
atStyleMask = 0x000F, /* Output style */
|
||||
atLabelMask = 0x00F0, /* Label information */
|
||||
atStyleMask = 0x000F, /* Output style */
|
||||
atLabelMask = 0x00F0, /* Label information */
|
||||
|
||||
/* Segment */
|
||||
atSegment = 0x0100, /* Code is in a segment */
|
||||
atSegmentChange = 0x0200, /* Either segment start or segment end */
|
||||
atSegment = 0x0100, /* Code is in a segment */
|
||||
atSegmentEnd = 0x0200, /* Segment end */
|
||||
atSegmentStart = 0x0400, /* Segment start */
|
||||
} attr_t;
|
||||
|
||||
|
||||
@ -87,11 +88,17 @@ typedef enum attr_t {
|
||||
void AddrCheck (unsigned Addr);
|
||||
/* Check if the given address has a valid range */
|
||||
|
||||
attr_t GetAttr (unsigned Addr);
|
||||
/* Return the attribute for the given address */
|
||||
|
||||
int SegmentDefined (unsigned Start, unsigned End);
|
||||
/* Return true if the atSegment bit is set somewhere in the given range */
|
||||
|
||||
int HaveSegmentChange (unsigned Addr);
|
||||
/* Return true if the segment change attribute is set for the given address */
|
||||
int IsSegmentEnd (unsigned Addr);
|
||||
/* Return true if a segment ends at the given address */
|
||||
|
||||
int IsSegmentStart (unsigned Addr);
|
||||
/* Return true if a segment starts at the given address */
|
||||
|
||||
unsigned GetGranularity (attr_t Style);
|
||||
/* Get the granularity for the given style */
|
||||
@ -102,9 +109,6 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr);
|
||||
void MarkAddr (unsigned Addr, attr_t Attr);
|
||||
/* Mark an address with an attribute */
|
||||
|
||||
attr_t GetAttr (unsigned Addr);
|
||||
/* Return the attribute for the given address */
|
||||
|
||||
attr_t GetStyleAttr (unsigned Addr);
|
||||
/* Return the style attribute for the given address */
|
||||
|
||||
@ -114,5 +118,4 @@ attr_t GetLabelAttr (unsigned Addr);
|
||||
|
||||
|
||||
/* End of attrtab.h */
|
||||
|
||||
#endif
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@ -65,12 +65,12 @@ static unsigned GetSpan (attr_t Style)
|
||||
attr_t Attr;
|
||||
if (MustDefLabel(PC+Count)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Attr = GetAttr (PC+Count);
|
||||
if ((Attr & atStyleMask) != Style) {
|
||||
break;
|
||||
}
|
||||
if ((Attr & atSegmentChange)) {
|
||||
if ((Attr & (atSegmentStart | atSegmentEnd))) {
|
||||
break;
|
||||
}
|
||||
++Count;
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2011, Ullrich von Bassewitz */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -748,16 +748,13 @@ static void SegmentSection (void)
|
||||
if (Start < 0) {
|
||||
InfoError ("Start address is missing");
|
||||
}
|
||||
if (Start == End) {
|
||||
InfoError ("Segment is empty");
|
||||
}
|
||||
if (Start > End) {
|
||||
InfoError ("Start address of segment is greater than end address");
|
||||
}
|
||||
|
||||
/* Check that segments do not overlap */
|
||||
if (SegmentDefined ((unsigned) Start, (unsigned) End)) {
|
||||
InfoError ("Segments cannot overlap");
|
||||
InfoError ("Segments must not overlap");
|
||||
}
|
||||
|
||||
/* Remember the segment data */
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -60,6 +60,7 @@
|
||||
#include "opctable.h"
|
||||
#include "output.h"
|
||||
#include "scanner.h"
|
||||
#include "segment.h"
|
||||
|
||||
|
||||
|
||||
@ -347,6 +348,8 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
||||
static void OneOpcode (unsigned RemainingBytes)
|
||||
/* Disassemble one opcode */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
/* Get the opcode from the current address */
|
||||
unsigned char OPC = GetCodeByte (PC);
|
||||
|
||||
@ -356,6 +359,14 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
/* Get the output style for the current PC */
|
||||
attr_t Style = GetStyleAttr (PC);
|
||||
|
||||
/* If a segment begins here, then name that segment.
|
||||
** Note that the segment is named even if its code is being skipped,
|
||||
** because some of its later code might not be skipped.
|
||||
*/
|
||||
if (IsSegmentStart (PC)) {
|
||||
StartSegment (GetSegmentStartName (PC), GetSegmentAddrSize (PC));
|
||||
}
|
||||
|
||||
/* If we have a label at this address, output the label and an attached
|
||||
** comment, provided that we aren't in a skip area.
|
||||
*/
|
||||
@ -371,7 +382,8 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
** - ...if we have enough bytes remaining for the code at this address.
|
||||
** - ...if the current instruction is valid for the given CPU.
|
||||
** - ...if there is no label somewhere between the instruction bytes.
|
||||
** If any of these conditions is false, switch to data mode.
|
||||
** - ...if there is no segment change between the instruction bytes.
|
||||
** If any one of those conditions is false, switch to data mode.
|
||||
*/
|
||||
if (Style == atDefault) {
|
||||
if (D->Size > RemainingBytes) {
|
||||
@ -381,9 +393,15 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
} else {
|
||||
unsigned I;
|
||||
for (I = 1; I < D->Size; ++I) {
|
||||
if (HaveLabel (PC+I) || HaveSegmentChange (PC+I)) {
|
||||
for (I = PC + D->Size; --I > PC; ) {
|
||||
if (HaveLabel (I) || IsSegmentStart (I)) {
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (I = 0; I < D->Size - 1u; ++I) {
|
||||
if (IsSegmentEnd (PC + I)) {
|
||||
Style = atIllegal;
|
||||
MarkAddr (PC, Style);
|
||||
break;
|
||||
@ -406,7 +424,6 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
*/
|
||||
if (D->Size <= RemainingBytes) {
|
||||
/* Output labels within the next insn */
|
||||
unsigned I;
|
||||
for (I = 1; I < D->Size; ++I) {
|
||||
ForwardLabel (I);
|
||||
}
|
||||
@ -453,7 +470,16 @@ static void OneOpcode (unsigned RemainingBytes)
|
||||
DataByteLine (1);
|
||||
++PC;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Change back to the default CODE segment if
|
||||
** a named segment stops at the current address.
|
||||
*/
|
||||
for (I = D->Size; I >= 1; --I) {
|
||||
if (IsSegmentEnd (PC - I)) {
|
||||
EndSegment ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2009, Ullrich von Bassewitz */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -63,6 +63,8 @@ static unsigned Col = 1; /* Current column */
|
||||
static unsigned Line = 0; /* Current line on page */
|
||||
static unsigned Page = 1; /* Current output page */
|
||||
|
||||
static const char* SegmentName = 0; /* Name of current segment */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -223,23 +225,6 @@ void DefConst (const char* Name, const char* Comment, unsigned Addr)
|
||||
|
||||
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize)
|
||||
/* Start a segment */
|
||||
{
|
||||
if (Pass == PassCount) {
|
||||
Output (".segment");
|
||||
Indent (ACol);
|
||||
if (AddrSize == ADDR_SIZE_DEFAULT) {
|
||||
Output ("\"%s\"", Name);
|
||||
} else {
|
||||
Output ("\"%s\": %s", Name, AddrSizeToStr (AddrSize));
|
||||
}
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataByteLine (unsigned ByteCount)
|
||||
/* Output a line with bytes */
|
||||
{
|
||||
@ -335,6 +320,39 @@ void SeparatorLine (void)
|
||||
|
||||
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize)
|
||||
/* Start a segment */
|
||||
{
|
||||
if (Pass == PassCount) {
|
||||
LineFeed ();
|
||||
Output (".segment");
|
||||
Indent (ACol);
|
||||
SegmentName = Name;
|
||||
Output ("\"%s\"", Name);
|
||||
if (AddrSize != ADDR_SIZE_DEFAULT) {
|
||||
Output (": %s", AddrSizeToStr (AddrSize));
|
||||
}
|
||||
LineFeed ();
|
||||
LineFeed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EndSegment (void)
|
||||
/* End a segment */
|
||||
{
|
||||
LineFeed ();
|
||||
Output ("; End of \"%s\" segment", SegmentName);
|
||||
LineFeed ();
|
||||
SeparatorLine ();
|
||||
Output (".code");
|
||||
LineFeed ();
|
||||
LineFeed ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void UserComment (const char* Comment)
|
||||
/* Output a comment line */
|
||||
{
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2000-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@ -74,12 +74,6 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs);
|
||||
|
||||
void DefConst (const char* Name, const char* Comment, unsigned Addr);
|
||||
/* Define an address constant */
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize);
|
||||
/* Start a segment */
|
||||
|
||||
void EndSegment (void);
|
||||
/* End a segment */
|
||||
|
||||
void OneDataByte (void);
|
||||
/* Output a .byte line with the current code byte */
|
||||
@ -99,6 +93,12 @@ void DataDWordLine (unsigned ByteCount);
|
||||
void SeparatorLine (void);
|
||||
/* Print a separator line */
|
||||
|
||||
void StartSegment (const char* Name, unsigned AddrSize);
|
||||
/* Start a segment */
|
||||
|
||||
void EndSegment (void);
|
||||
/* End a segment */
|
||||
|
||||
void UserComment (const char* Comment);
|
||||
/* Output a comment line */
|
||||
|
||||
@ -111,5 +111,4 @@ void OutputSettings (void);
|
||||
|
||||
|
||||
/* End of output.h */
|
||||
|
||||
#endif
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2007-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@ -58,18 +58,15 @@
|
||||
typedef struct Segment Segment;
|
||||
struct Segment {
|
||||
Segment* NextStart; /* Pointer to next segment */
|
||||
Segment* NextEnd; /* Pointer to next segment */
|
||||
unsigned long Start;
|
||||
unsigned long End;
|
||||
unsigned AddrSize;
|
||||
char Name[1]; /* Name, dynamically allocated */
|
||||
};
|
||||
|
||||
/* Tables containing the segments. A segment is inserted using it's hash
|
||||
** value. Collision is done by single linked lists.
|
||||
/* Table containing the segments. A segment is inserted using its hash
|
||||
** value. Collisions are handled by single-linked lists.
|
||||
*/
|
||||
static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */
|
||||
static Segment* EndTab[HASH_SIZE]; /* Table containing segment ends */
|
||||
|
||||
|
||||
|
||||
@ -90,20 +87,53 @@ void AddAbsSegment (unsigned Start, unsigned End, const char* Name)
|
||||
|
||||
/* Fill in the data */
|
||||
S->Start = Start;
|
||||
S->End = End;
|
||||
S->AddrSize = ADDR_SIZE_ABS;
|
||||
memcpy (S->Name, Name, Len + 1);
|
||||
|
||||
/* Insert the segment into the hash tables */
|
||||
/* Insert the segment into the hash table */
|
||||
S->NextStart = StartTab[Start % HASH_SIZE];
|
||||
StartTab[Start % HASH_SIZE] = S;
|
||||
S->NextEnd = EndTab[End % HASH_SIZE];
|
||||
EndTab[End % HASH_SIZE] = S;
|
||||
|
||||
/* Mark start and end of the segment */
|
||||
MarkAddr (Start, atSegmentChange);
|
||||
MarkAddr (End, atSegmentChange);
|
||||
MarkAddr (Start, atSegmentStart);
|
||||
MarkAddr (End, atSegmentEnd);
|
||||
|
||||
/* Mark the addresses within the segment */
|
||||
MarkRange (Start, End, atSegment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char* GetSegmentStartName (unsigned Addr)
|
||||
/* Return the name of the segment which starts at the given address */
|
||||
{
|
||||
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||
|
||||
/* Search the collision list for the exact address */
|
||||
while (S != 0) {
|
||||
if (S->Start == Addr) {
|
||||
return S->Name;
|
||||
}
|
||||
S = S->NextStart;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned GetSegmentAddrSize (unsigned Addr)
|
||||
/* Return the address size of the segment which starts at the given address */
|
||||
{
|
||||
Segment* S = StartTab[Addr % HASH_SIZE];
|
||||
|
||||
/* Search the collision list for the exact address */
|
||||
while (S != 0) {
|
||||
if (S->Start == Addr) {
|
||||
return S->AddrSize;
|
||||
}
|
||||
S = S->NextStart;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2007 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 2007-2014, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@ -47,8 +47,13 @@
|
||||
void AddAbsSegment (unsigned Start, unsigned End, const char* Name);
|
||||
/* Add an absolute segment to the segment table */
|
||||
|
||||
char* GetSegmentStartName (unsigned Addr);
|
||||
/* Return the name of the segment which starts at the given address */
|
||||
|
||||
unsigned GetSegmentAddrSize (unsigned Addr);
|
||||
/* Return the address size of the segment which starts at the given address */
|
||||
|
||||
|
||||
|
||||
/* End of segment.h */
|
||||
|
||||
#endif
|
||||
|
@ -1,41 +1,41 @@
|
||||
|
||||
# toplevel makefile for the regression tests
|
||||
# top-level makefile for the regression tests
|
||||
|
||||
MAKE := make --no-print-dir
|
||||
# You can comment this special target when you debug the regression tests.
|
||||
# Then, make will give you more progress reports.
|
||||
.SILENT:
|
||||
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
CMD_EXE := 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
RM := del /f
|
||||
EXE := .exe
|
||||
MKDIR = mkdir
|
||||
RMDIR = rmdir
|
||||
MKDIR := mkdir
|
||||
RMDIR := rmdir
|
||||
else
|
||||
RM := rm -f
|
||||
EXE :=
|
||||
MKDIR = mkdir -p
|
||||
RMDIR = rmdir
|
||||
MKDIR := mkdir -p
|
||||
RMDIR := rmdir
|
||||
endif
|
||||
|
||||
WORKDIR := ../testwrk
|
||||
|
||||
.PHONY: dotests clean
|
||||
.PHONY: all dotests continue mostly-clean clean
|
||||
|
||||
all: dotests
|
||||
|
||||
$(WORKDIR):
|
||||
@$(MKDIR) $(WORKDIR)
|
||||
$(MKDIR) $(WORKDIR)
|
||||
|
||||
$(WORKDIR)/bdiff$(EXE): $(WORKDIR)
|
||||
@$(CC) -o $(WORKDIR)/bdiff$(EXE) bdiff.c
|
||||
$(WORKDIR)/bdiff$(EXE): bdiff.c | $(WORKDIR)
|
||||
$(CC) -O2 -o $@ $<
|
||||
|
||||
dotests: $(WORKDIR)/bdiff$(EXE)
|
||||
@$(MAKE) -C val clean all
|
||||
@$(MAKE) -C ref clean all
|
||||
@$(MAKE) -C err clean all
|
||||
@$(MAKE) -C misc clean all
|
||||
.NOTPARALLEL:
|
||||
|
||||
dotests: mostly-clean continue
|
||||
|
||||
continue: $(WORKDIR)/bdiff$(EXE)
|
||||
@$(MAKE) -C val all
|
||||
@ -43,10 +43,12 @@ continue: $(WORKDIR)/bdiff$(EXE)
|
||||
@$(MAKE) -C err all
|
||||
@$(MAKE) -C misc all
|
||||
|
||||
clean:
|
||||
mostly-clean:
|
||||
@$(MAKE) -C val clean
|
||||
@$(MAKE) -C ref clean
|
||||
@$(MAKE) -C err clean
|
||||
@$(MAKE) -C misc clean
|
||||
@$(RM) $(WORKDIR)/bdiff$(EXE)
|
||||
@$(RMDIR) $(WORKDIR)
|
||||
|
||||
clean: mostly-clean
|
||||
$(RM) $(WORKDIR)/bdiff$(EXE)
|
||||
$(RMDIR) $(WORKDIR)
|
||||
|
@ -2,10 +2,10 @@
|
||||
# makefile for the tests that MUST NOT compile
|
||||
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
CMD_EXE := 1
|
||||
endif
|
||||
|
||||
CC65FLAGS = -t sim6502
|
||||
CC65FLAGS := -t sim6502
|
||||
|
||||
CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
|
||||
@ -15,19 +15,12 @@ else
|
||||
RM := rm -f
|
||||
endif
|
||||
|
||||
WORKDIR := ./../../testwrk
|
||||
WORKDIR := ../../testwrk
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
SOURCES := $(wildcard *.c)
|
||||
TESTS := $(SOURCES:%.c=$(WORKDIR)/%.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.o.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.os.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.or.prg)
|
||||
TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c=$(WORKDIR)/%$(option)prg))
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
@ -47,6 +40,7 @@ $(WORKDIR)/%.oir.prg: %.c
|
||||
! $(CL65) -Oir $(CC65FLAGS) $< -o $@
|
||||
$(WORKDIR)/%.or.prg: %.c
|
||||
! $(CL65) -Or $(CC65FLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
@$(RM) $(TESTS)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o)
|
||||
@$(RM) $(SOURCES:.c=.o)
|
||||
|
@ -2,11 +2,11 @@
|
||||
# makefile for the remaining tests that need special care in one way or another
|
||||
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
CMD_EXE := 1
|
||||
endif
|
||||
|
||||
CC65FLAGS = -t sim6502
|
||||
SIM65FLAGS = -x 200000000
|
||||
CC65FLAGS := -t sim6502
|
||||
SIM65FLAGS := -x 200000000
|
||||
|
||||
CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65)
|
||||
@ -17,51 +17,40 @@ else
|
||||
RM := rm -f
|
||||
endif
|
||||
|
||||
WORKDIR := ./../../testwrk
|
||||
WORKDIR := ../../testwrk
|
||||
|
||||
DIFF := $(WORKDIR)/bdiff
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
SOURCES := $(wildcard *.c)
|
||||
TESTS := $(SOURCES:%.c=$(WORKDIR)/%.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.o.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.os.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.or.prg)
|
||||
|
||||
# FIXME: actually use/build differently optimized programs here
|
||||
TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c=$(WORKDIR)/%$(option)prg))
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
# should compile, but then hangs in an endless loop
|
||||
$(WORKDIR)/endless%prg: endless.c
|
||||
$(CL65) $(CC65FLAGS) $< -o $@
|
||||
$(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@
|
||||
! $(SIM65) $(SIM65FLAGS) $@
|
||||
|
||||
# these need reference data that cant be generated by a host compiled program
|
||||
# these need reference data that can't be generated by a host-compiled program,
|
||||
# in a useful way
|
||||
$(WORKDIR)/limits%prg: limits.c
|
||||
$(CL65) $(CC65FLAGS) $< -o $@
|
||||
$(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@
|
||||
$(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/limits.out
|
||||
$(DIFF) $(WORKDIR)/limits.out limits.ref
|
||||
|
||||
# the rest are tests that fail currently for one reason or another
|
||||
$(WORKDIR)/fields%prg: fields.c
|
||||
@echo "FIXME: " $@ "will currently fail"
|
||||
$(CL65) $(CC65FLAGS) $< -o $@
|
||||
@echo "FIXME: " $@ "currently will fail."
|
||||
$(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@
|
||||
-$(SIM65) $(SIM65FLAGS) $@
|
||||
$(WORKDIR)/sitest%prg: sitest.c
|
||||
@echo "FIXME: " $@ "will currently fail"
|
||||
-$(CL65) $(CC65FLAGS) $< -o $@
|
||||
-$(SIM65) $(SIM65FLAGS) $@
|
||||
@echo "FIXME: " $@ "currently will fail."
|
||||
-$(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@
|
||||
# -$(SIM65) $(SIM65FLAGS) $@
|
||||
|
||||
clean:
|
||||
@$(RM) $(TESTS)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o)
|
||||
@$(RM) $(SOURCES:.c=.o)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.out)
|
||||
|
||||
|
||||
|
@ -3,11 +3,11 @@
|
||||
# compared with reference output
|
||||
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
CMD_EXE := 1
|
||||
endif
|
||||
|
||||
CC65FLAGS = -t sim6502
|
||||
SIM65FLAGS = -x 200000000
|
||||
CC65FLAGS := -t sim6502
|
||||
SIM65FLAGS := -x 200000000
|
||||
|
||||
CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65)
|
||||
@ -18,7 +18,7 @@ else
|
||||
RM := rm -f
|
||||
endif
|
||||
|
||||
WORKDIR := ./../../testwrk
|
||||
WORKDIR := ../../testwrk
|
||||
|
||||
DIFF := $(WORKDIR)/bdiff
|
||||
|
||||
@ -26,17 +26,9 @@ CFLAGS := -O2 -Wall -W -Wextra -fwrapv -fno-strict-overflow
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
REFS := $(patsubst %.c,$(WORKDIR)/%.ref,$(wildcard *.c))
|
||||
|
||||
SOURCES := $(wildcard *.c)
|
||||
TESTS := $(SOURCES:%.c=$(WORKDIR)/%.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.o.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.os.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.or.prg)
|
||||
REFS := $(SOURCES:%.c=$(WORKDIR)/%.ref)
|
||||
TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c=$(WORKDIR)/%$(option)prg))
|
||||
|
||||
all: $(REFS) $(TESTS)
|
||||
|
||||
@ -86,7 +78,7 @@ $(WORKDIR)/%.or.prg: %.c $(WORKDIR)/%.ref
|
||||
|
||||
clean:
|
||||
@$(RM) $(TESTS)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o)
|
||||
@$(RM) $(SOURCES:.c=.o)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.out)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.ref)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.host)
|
||||
|
@ -2,11 +2,11 @@
|
||||
# makefile for the regression tests that return an error code on failure
|
||||
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
CMD_EXE := 1
|
||||
endif
|
||||
|
||||
CC65FLAGS = -t sim6502
|
||||
SIM65FLAGS = -x 200000000
|
||||
CC65FLAGS := -t sim6502
|
||||
SIM65FLAGS := -x 200000000
|
||||
|
||||
CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65)
|
||||
@ -17,19 +17,12 @@ else
|
||||
RM := rm -f
|
||||
endif
|
||||
|
||||
WORKDIR := ./../../testwrk
|
||||
WORKDIR := ../../testwrk
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
SOURCES := $(wildcard *.c)
|
||||
TESTS := $(SOURCES:%.c=$(WORKDIR)/%.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.o.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.os.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.osir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oi.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.oir.prg)
|
||||
TESTS += $(SOURCES:%.c=$(WORKDIR)/%.or.prg)
|
||||
TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c=$(WORKDIR)/%$(option)prg))
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
@ -67,4 +60,4 @@ $(WORKDIR)/%.or.prg: %.c
|
||||
|
||||
clean:
|
||||
@$(RM) $(TESTS)
|
||||
@$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o)
|
||||
@$(RM) $(SOURCES:.c=.o)
|
||||
|
Loading…
x
Reference in New Issue
Block a user