diff --git a/.travis.yml b/.travis.yml index a11412230..6c6a428e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ install: script: - make bin USER_CFLAGS=-Werror - make lib QUIET=1 + - make -C test - make -C src clean - make bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- - make doc zip diff --git a/LICENSE b/LICENSE index 03eefac67..88cacf148 100644 --- a/LICENSE +++ b/LICENSE @@ -1,44 +1,3 @@ -This is the original cc65 compiler copyright: - - -*- Mode: Text -*- - - This is the copyright notice for RA65, LINK65, LIBR65, and other - Atari 8-bit programs. Said programs are Copyright 1989, by John R. - Dunning. All rights reserved, with the following exceptions: - - Anyone may copy or redistribute these programs, provided that: - - 1: You don't charge anything for the copy. It is permissable to - charge a nominal fee for media, etc. - - 2: All source code and documentation for the programs is made - available as part of the distribution. - - 3: This copyright notice is preserved verbatim, and included in - the distribution. - - You are allowed to modify these programs, and redistribute the - modified versions, provided that the modifications are clearly noted. - - There is NO WARRANTY with this software, it comes as is, and is - distributed in the hope that it may be useful. - - This copyright notice applies to any program which contains - this text, or the refers to this file. - - This copyright notice is based on the one published by the Free - Software Foundation, sometimes known as the GNU project. The idea - is the same as theirs, ie the software is free, and is intended to - stay that way. Everybody has the right to copy, modify, and re- - distribute this software. Nobody has the right to prevent anyone - else from copying, modifying or redistributing it. - -In acknowledgment of this copyright, I (Ullrich von Bassewitz) will place -my own changes to the compiler under the same copyright. - -The library and the binary utils are a complete rewrite done by me and -covered by the following license: - This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/Makefile.travis b/Makefile.travis index 78ded63e6..4c0f688f8 100644 --- a/Makefile.travis +++ b/Makefile.travis @@ -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 diff --git a/README.md b/README.md index bf7d6dcde..660798128 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ including - the Supervision console. - the Oric Atmos. - the Lynx console. +- the Ohio Scientific Challenger 1P The libraries are fairly portable, so creating a version for other 6502s shouldn't be too much work. diff --git a/cfg/atmos.cfg b/cfg/atmos.cfg index 137c0e9a9..a1f935efa 100644 --- a/cfg/atmos.cfg +++ b/cfg/atmos.cfg @@ -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, diff --git a/cfg/osic1p-asm.cfg b/cfg/osic1p-asm.cfg new file mode 100644 index 000000000..4000890be --- /dev/null +++ b/cfg/osic1p-asm.cfg @@ -0,0 +1,25 @@ +FEATURES { + STARTADDRESS: default = $0200; +} +SYMBOLS { +# If you want ld65 to output a loadable-format file by default, then uncomment +# the next line. (Then, "-u __BOOT__" wouldn't be needed on the command line.) +# __BOOT__: type = import; + __STACKSIZE__: type = weak, value = $0400; # 1 kB stack + __HIMEM__: type = weak, value = $8000; # 32 kB RAM +} +MEMORY { + # for size of ZP, see runtime/zeropage.s and c1p/extzp.s + ZP: file = "", define = yes, start = $0002, size = $001A + $0006; + HEAD: file = %O, start = $0000, size = $00B6; + RAM: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; +} +SEGMENTS { + BOOT: load = HEAD, type = ro, optional = yes; + INIT: load = RAM, type = ro, define = yes, optional = yes; + CODE: load = RAM, type = rw; + RODATA: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp; +} diff --git a/cfg/osic1p.cfg b/cfg/osic1p.cfg new file mode 100644 index 000000000..fd9aa604e --- /dev/null +++ b/cfg/osic1p.cfg @@ -0,0 +1,38 @@ +FEATURES { + STARTADDRESS: default = $0200; +} +SYMBOLS { +# If you want ld65 to output a loadable-format file by default, then uncomment +# the next line. (Then, "-u __BOOT__" wouldn't be needed on the command line.) +# __BOOT__: type = import; + __STACKSIZE__: type = weak, value = $0400; # 1 kB stack + __HIMEM__: type = weak, value = $8000; # 32 kB RAM +} +MEMORY { + # for size of ZP, see runtime/zeropage.s and c1p/extzp.s + ZP: file = "", define = yes, start = $0002, size = $001A + $0020; + HEAD: file = %O, start = $0000, size = $00B6; + RAM: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; +} +SEGMENTS { + BOOT: load = HEAD, type = ro, 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 = rw; + RODATA: load = RAM, type = rw; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, define = yes, optional = yes; +} +FEATURES { + CONDES: type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__, + segment = INIT; + CONDES: type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__, + segment = RODATA; +} diff --git a/doc/Makefile b/doc/Makefile index 02ed6b1d3..967443ef0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,7 +2,7 @@ ifneq ($(shell echo),) CMD_EXE = 1 endif -.PHONY: all mostlyclean clean install zip doc html info gh-pages +.PHONY: all mostlyclean clean install zip doc html info .SUFFIXES: diff --git a/doc/atmos.sgml b/doc/atmos.sgml index 805fc7a03..68f7f9d65 100644 --- a/doc/atmos.sgml +++ b/doc/atmos.sgml @@ -7,7 +7,7 @@ , , -2014-03-27 +2015-01-09 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. + Binary format

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 Memory layout

-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,

@@ -90,7 +102,7 @@ structures; accessing the struct fields will access the chip registers. - Access to the VIA (versatile interface adapter) chip is available via the + Access to the VIA (Versatile Interface Adapter) chip is available via the

@@ -117,7 +129,8 @@ The names in the parentheses denote the symbols to be used for static linking of Graphics drivers

-The default drivers, @@ -175,13 +188,14 @@ No mouse drivers are currently available for the Atmos. Disk I/O

-The existing library for the Atmos doesn't implement C file -I/O. There are hacks for the @@ -202,7 +216,14 @@ following functions (and a few others): Function keys

-These are defined to be FUNCT + number key. +They are defined to be FUNCT + a number key. + + +Capitals lock

+ +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. Passing arguments to the program

@@ -211,10 +232,12 @@ Command-line arguments can be passed to - CALL#500:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5 + RUN:REM arg1 " ARG2 IS QUOTED" ARG3 "" ARG5 +You must turn Arguments are separated by spaces. Arguments may be quoted. Leading and trailing spaces around an argument are ignored. Spaces within @@ -225,6 +248,15 @@ supported directly by BASIC, the following syntax was chosen: +Automatic starting

+ +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 Interrupts

The runtime for the Atmos uses routines marked as .ADDRSIZE

+ + The + .macro myLDA foo + .if .ADDRSIZE(foo) = 1 + ;do custom command based on zeropage addressing: + .byte 0A5h, foo + .elseif .ADDRSIZE(foo) = 2 + ;do custom command based on absolute addressing: + .byte 0ADh + .word foo + .elseif .ADDRSIZE(foo) = 0 + ; no address size defined for this symbol: + .out .sprintf("Error, address size unknown for symbol %s", .string(foo)) + .endif + .endmacro + + + This command is new and must be enabled with the + + .BANK

The +.ISMNEM, .ISMNEMONIC

+ + Builtin function. The function expects an identifier as argument in braces. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + + .DESTRUCTOR

Export a symbol and mark it as a module destructor. This may be used @@ -2596,6 +2643,12 @@ Here's a list of all control commands and a description, what they do: + addrsize + + Enables the .ADDRSIZE pseudo function. This function is experimental and not enabled by default. + + See also: + at_in_identifiers Accept the at character (`@') as a valid character in identifiers. The @@ -4418,6 +4471,7 @@ compiler, depending on the target system selected: cc65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2000-09-03, 2001-10-02, 2005-08-01 +<date>2015-05-26 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home @@ -74,6 +74,7 @@ Short options: Long options: --add-source Include source as comment + --all-cdecl Make functions default to __cdecl__ --bss-name seg Set the name of the BSS segment --check-stack Generate stack overflow checks --code-name seg Set the name of the CODE segment @@ -114,6 +115,14 @@ Here is a description of all the command line options: <descrip> + <tag><tt>--all-cdecl</tt></tag> + + Tells the compiler that functions which aren't declared explicitly with + either the <tt/__cdecl__/ or <tt/__fastcall__/ calling conventions should + have the cdecl convention. (Normally, functions that aren't variadic are + fast-called.) + + <label id="option-bss-name"> <tag><tt>--bss-name seg</tt></tag> @@ -348,6 +357,7 @@ Here is a description of all the command line options: <item>lunix <item>lynx <item>nes + <item>osic1p <item>pet (all CBM PET systems except the 2001) <item>plus4 <item>sim6502 @@ -549,9 +559,10 @@ and the one defined by the ISO standard: be passed as parameters by value. However, struct assignment *is* possible. <p> -<item> Part of the C library is available only with fastcall calling - conventions (see below). It means that you must not mix pointers to - those functions with pointers to user-written, not-fastcall functions. +<item> Most of the C library is available with only the fastcall calling + convention (<ref id="extension-fastcall" name="see below">). It means + that you must not mix pointers to those functions with pointers to + user-written, cdecl functions (the calling conventions are incompatible). <p> <item> The <tt/volatile/ keyword doesn't have an effect. This is not as bad as it sounds, since the 6502 has so few registers that it isn't @@ -589,30 +600,58 @@ This cc65 version has some extensions to the ISO C standard. <ref id="inline-asm" name="see there">. <p> -<item> There is a special calling convention named "fastcall". - The syntax for a function declaration using fastcall is +<label id="extension-fastcall"> +<item> The normal calling convention -- for non-variadic functions -- is + named "fastcall". The syntax for a function declaration that + <em/explicitly/ uses fastcall is <tscreen><verb> <return type> fastcall <function name> (<parameter list>) </verb></tscreen> or <tscreen><verb> - <return type> __fastcall__ <function name> (<parameter list>) + <return type> __fastcall__ <function name> (<parameter list>) </verb></tscreen> - An example would be + An example is <tscreen><verb> - void __fastcall__ f (unsigned char c) + void __fastcall__ f (unsigned char c) </verb></tscreen> The first form of the fastcall keyword is in the user namespace and can therefore be disabled with the <tt><ref id="option--standard" name="--standard"></tt> command line option. - For functions declared as <tt/fastcall/, the rightmost parameter is not + For functions that are <tt/fastcall/, the rightmost parameter is not pushed on the stack but left in the primary register when the function - is called. This will reduce the cost when calling assembler functions - significantly, especially when the function itself is rather small. + is called. That significantly reduces the cost of calling those functions. + <newline><newline> <p> +<item> There is another calling convention named "cdecl". Variadic functions + (their prototypes have an ellipsis [<tt/.../]) always use that + convention. The syntax for a function declaration using cdecl is + + <tscreen><verb> + <return type> cdecl <function name> (<parameter list>) + </verb></tscreen> + or + <tscreen><verb> + <return type> __cdecl__ <function name> (<parameter list>) + </verb></tscreen> + An example is + <tscreen><verb> + int* __cdecl__ f (unsigned char c) + </verb></tscreen> + + The first form of the cdecl keyword is in the user namespace; + and therefore, can be disabled with the <tt/<ref id="option--standard" + name="--standard">/ command-line option. + + For functions that are <tt/cdecl/, the rightmost parameter is pushed + onto the stack before the function is called. That increases the cost + of calling those functions, especially when they are called from many + places.<newline><newline> + <p> + <item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/. Both refer to the primary register that is used by the compiler to evaluate expressions or return function results. <tt/__AX__/ is of @@ -819,6 +858,11 @@ The compiler defines several macros at startup: Is defined if the compiler was called with the <tt/-Os/ command line option. + <tag><tt>__OSIC1P__</tt></tag> + + This macro is defined if the target is the Ohio Scientific Challenger 1P + (-t osic1p). + <tag><tt>__PET__</tt></tag> This macro is defined if the target is the PET family of computers (-t pet). diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 23cf8c5e8..0a0b8c87e 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -3,7 +3,7 @@ <article> <title>Defining a Custom cc65 Target <author>Bruce Reidenbach -<date>2010-02-22 +<date>2015-03-13 <abstract> This section provides step-by-step instructions on how to use the cc65 @@ -525,15 +525,16 @@ The first step in creating the assembly language code for the driver is to determine how to pass the C arguments to the assembly language routine. The cc65 toolset allows the user to specify whether the data is passed to a subroutine via the stack or by the processor registers by -using the <tt>__fastcall__</tt> function declaration (note that there -are two underscore characters in front of and two behind the -<tt>fastcall</tt> declaration). When <tt>__fastcall__</tt> is -specified, the rightmost argument in the function call is passed to the +using the <tt/__fastcall__/ and <tt/__cdecl__/ function qualifiers (note that +there are two underscore characters in front of and two behind each +qualifier). <tt/__fastcall__/ is the default. When <tt/__cdecl__/ <em/isn't/ +specified, and the function isn't variadic (i.e., its prototype doesn't have +an ellipsis), the rightmost argument in the function call is passed to the subroutine using the 6502 registers instead of the stack. Note that if there is only one argument in the function call, the execution overhead required by the stack interface routines is completely avoided. -Without <tt>__fastcall__</tt>, the argument is loaded in the A and X +With <tt/__cdecl__</tt>, the last argument is loaded into the A and X registers and then pushed onto the stack via a call to <tt>pushax</tt>. The first thing the subroutine does is retrieve the argument from the stack via a call to <tt>ldax0sp</tt>, which copies the values into the A @@ -561,7 +562,7 @@ _foo: jsr ldax0sp ; Retrieve A and X from the stack jmp incsp2 ; Pop A and X from the stack (includes return) </verb></tscreen> -If <tt>__fastcall__</tt> is specified, the argument is loaded into the A +If <tt/__cdecl__/ isn't specified, then the argument is loaded into the A and X registers as before, but the subroutine is then called immediately. The subroutine does not need to retrieve the argument since the value is already available in the A and X registers. diff --git a/doc/da65.sgml b/doc/da65.sgml index 2b8cdb2a3..df8cd7772 100644 --- a/doc/da65.sgml +++ b/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> - - - - diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 60b8360ed..ebe63be45 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -39,7 +39,7 @@ Each entry for a function contains a detailed description <tag/Declaration/Describes the needed header files and declaration of the function. <tag/Description/Description of the function. -<tag/Limits/Limits. +<tag/Notes/Notes on the function. <tag/Availability/The availability of the function. <tag/See also/Other related functions. <tag/Example/A piece of actual code using the function. @@ -744,8 +744,7 @@ communication. <tag/Description/The function is called with the type of a directory entry taken from a <tt/struct dirent/ and returns true if the entry designates a directory. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. </itemize> <tag/Availability/cc65 @@ -768,8 +767,7 @@ a directory. <tag/Description/The function is called with the type of a directory entry taken from a <tt/struct dirent/ and returns true if the entry designates a disk label. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. </itemize> <tag/Availability/cc65 @@ -792,8 +790,7 @@ a disk label. <tag/Description/The function is called with the type of a directory entry taken from a <tt/struct dirent/ and returns true if the entry designates a link. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. </itemize> <tag/Availability/cc65 @@ -816,8 +813,7 @@ a link. <tag/Description/The function is called with the type of a directory entry taken from a <tt/struct dirent/ and returns true if the entry designates a regular file. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>A "regular file" means anything with data in it. This might still mean that special processing is needed, when accessing the file. Relative files of @@ -841,8 +837,7 @@ the CBM systems are classified as being "regular" files, for example. <tag/Header/<tt/<ref id="stdlib.h" name="stdlib.h">/ <tag/Declaration/<tt/void __fastcall__ _heapadd (void* mem, size_t size);/ <tag/Description/The function adds a block of raw memory to the heap. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The minimum blocksize that can be added is 6 bytes; the function will ignore smaller blocks. </itemize> @@ -870,8 +865,7 @@ ignore smaller blocks. <tag/Description/The function returns the size of a block that must have previously been allocated by <tt/<ref id="malloc" name="malloc">/, <tt/<ref id="calloc" name="calloc">/ or <tt/<ref id="realloc" name="realloc">/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>Passing a pointer to a block that was is not the result of one of the allocation functions, or that has been free'd will give unpredicable results. </itemize> @@ -921,8 +915,7 @@ be allocated from the heap using <tt/<ref id="malloc" name="malloc">/. <tag/Declaration/<tt/size_t __fastcall__ _heapmemavail (void);/ <tag/Description/The function returns the total number of bytes available on the heap. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>This function is of less use than usually assumed, since the returned heap space may be available but not in one block. So even if this function says that several times more heap space is available than needed, <ref @@ -955,8 +948,7 @@ a colon and a blank. Then the error message for the current contents of <tt/_oserror/ are printed followed by a newline. The message output is the same as returned by <tt/<ref id="_stroserror" name="_stroserror">/ with an argument of <tt/_oserror/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>Since operating system specific error code are - you guessed it - operating system specific, the value in <tt/_oserror/ and the message that is printed depends on the cc65 target. @@ -982,7 +974,7 @@ be used in presence of a prototype. <tag/Description/The function initializes the random number generator with a seed derived from fast changing hardware events, so the seed itself can be considered random to a certain degree. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The randomness of the seed depends on the machine hardware. </itemize> <tag/Availability/cc65 @@ -1003,7 +995,7 @@ considered random to a certain degree. <tag/Declaration/<tt/const char* __fastcall__ _stroserror (unsigned char errcode);/ <tag/Description/<tt/_stroserror/ will return a string describing the given operating system specific error code. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Since operating system specific error code are - you guessed it - operating system specific, the parameter and the string returned depend on the cc65 target. @@ -1028,7 +1020,7 @@ used in presence of a prototype. <tag/Description/<tt/_swap/ will swap (exchange) the contents of the two memory areas pointed to by <tt/p/ and <tt/q/. Both memory areas are assumed to be <tt/size/ bytes in size. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The memory areas may not overlap, otherwise the results are undefined. <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. @@ -1054,7 +1046,7 @@ specified in the <tt/pc/ member of the passed <tt/regs/ structure. All registers and the CPU flags are set to the values given in the <tt/regs/ structure. On return from the subroutine, the new values of the registers and flags are stored back overwriting the old values. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Bits 4 and 5 of the flags value in the <tt/regs/ structure are ignored when calling the subroutine (they are unchanged from their current values). <item>The function is only available as fastcall function, so it may only be @@ -1075,7 +1067,7 @@ used in presence of a prototype. <tag/Declaration/<tt/void BRK (void);/ <tag/Description/The function will insert a 6502 BRK instruction into the code which may be used to trigger a debugger. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>The inserted instruction may lead to unexpected results if no debugger is present. @@ -1099,7 +1091,7 @@ is present. <tag/Description/The function will insert a 6502 CLI instruction into the code, so interrupts are enabled. Enabling interrupts has no effects if they are already enabled (the default). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>Disabling interrupts may lead to unexpected results. </itemize> @@ -1121,7 +1113,7 @@ already enabled (the default). <tag/Declaration/<tt/unsigned char PEEK (unsigned addr);/ <tag/Description/The function will read the absolute memory given by <tt/addr/ and return the value read. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>This function depends highly on the platform and environment. </itemize> @@ -1144,7 +1136,7 @@ and return the value read. <tag/Description/The function will read the absolute memory given by <tt/addr/ and return the value read. The byte read from the higher address is the high byte of the return value. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>This function depends highly on the platform and environment. <item>The order in which the two bytes are read is unspecified and may @@ -1168,7 +1160,7 @@ depend of the address expression used. <tag/Declaration/<tt/void POKE (unsigned addr, unsigned char val);/ <tag/Description/The function writes the value <tt/val/ to the absolute memory address given by <tt/addr/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>This function depends highly on the platform and environment. <item>Careless use will cause the program to act strange or may crash the @@ -1193,7 +1185,7 @@ machine. <tag/Description/The function writes the value <tt/val/ to the absolute memory address given by <tt/addr/. The low byte of <tt/val/ is written to the <tt/addr/, the high byte is written to <tt/addr+1/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>This function depends highly on the platform and environment. <item>Careless use will cause the program to act strange or may crash the @@ -1220,7 +1212,7 @@ depend of the address expression used. <tag/Description/The function will insert a 6502 SEI instruction into the code, so interrupts are disabled. Note that non maskable interrupts cannot be disabled. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. <item>Disabling interrupts may lead to unexpected results. </itemize> @@ -1261,7 +1253,7 @@ on stderr, then terminates the program with an exit code of 3. <tag/Declaration/<tt/int __fastcall__ abs (int v);/ <tag/Description/<tt/abs/ returns the absolute value of the argument passed to the function. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The return value is undefined if <tt/INT_MIN/ is passed to the function. <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. @@ -1284,7 +1276,7 @@ used in presence of a prototype. <tag/Description/<tt/assert/ is a macro that expands to a <tt/id/ statement. If the condition evaluates t zero (false), assert prints a message on stderr and aborts the program. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. </itemize> <tag/Availability/ISO 9899 @@ -1308,7 +1300,7 @@ on stderr and aborts the program. terminates, they are called in LIFO order (the last function registered is called first). <tt/atexit/ returns zero on success and a nonzero value on failure. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>A maximum of 5 exit functions can be registered. <item>There is no way to unregister an exit function. <item>The function is only available as fastcall function, so it may only be @@ -1366,7 +1358,7 @@ atmos_save("hires", 0xa000, 0xc000); <tag/Declaration/<tt/int __fastcall__ atoi (const char* s);/ <tag/Description/<tt/atoi/ converts the given string into an integer. Conversion stops as soon as any invalid character is encountered. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>There is no way to detect any conversion errors. <item>The function does not check for an numerical overflow when converting. <item>The function is only available as fastcall function, so it may only be @@ -1393,7 +1385,7 @@ used in presence of a prototype. <tag/Declaration/<tt/long __fastcall__ atol (const char* s);/ <tag/Description/<tt/atol/ converts the given string into a long integer. Conversion stops as soon as any invalid character is encountered. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>There is no way to detect any conversion errors. <item>The function does not check for an numerical overflow when converting. <item>The function is only available as fastcall function, so it may only be @@ -1421,7 +1413,7 @@ used in presence of a prototype. <tag/Description/The function will set a new background color and return the old (current) one. The background color is valid for the whole text output area of the screen, not just for new text. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Background colors are system dependent. The function may have no effect on systems where the background color cannot be changed. <item>The function is only available as fastcall function, so it may only be @@ -1445,7 +1437,7 @@ used in presence of a prototype. <tag/Declaration/<tt/unsigned char __fastcall__ bordercolor (unsigned char color);/ <tag/Description/The function will set a new border color. It returns the old (current) border color. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Border colors are system dependent. The function may have no effect on systems where the border color cannot be changed. <item>The function is only available as fastcall function, so it may only @@ -1474,8 +1466,7 @@ matches the one pointed to by <tt/key/. <tt/base/ is the address of the array, <tt/n/ is the number of elements, <tt/size/ the size of an element and <tt/cmp/ the function used to compare the members against the key. The function returns a pointer to the member found, or <tt/NULL/ if there was no match. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The contents of the array must be sorted in ascending order according to the compare function given. <item>If there are multiple members that match the key, the function will @@ -1500,8 +1491,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ bzero (void* p, size_t count);/ <tag/Description/<tt/bzero/ fills the memory area pointed to by <tt/p/ with zero. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is non standard and therefore only available in non ANSI mode. You should use <tt/<ref id="memset" name="memset">/ instead. <item>The function is only available as fastcall function, so it may only @@ -1526,7 +1516,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="c128.h" name="c128.h">/ <tag/Declaration/<tt/void c64mode (void);/ <tag/Description/The function will cause the machine to reboot into C64 mode. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is specific to the C128. <item>The function will not return to the caller. </itemize> @@ -1547,8 +1537,7 @@ be used in presence of a prototype. of size <tt/size/, clears the whole block with binary zeroes and returns a pointer to it. On error (not enough memory available), <tt/calloc/ returns <tt/NULL/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>Clearing the memory may not have the expected effect on all platforms: pointers in the block may not be <tt/NULL/ and floating point variables may not be zero (0.0). In other words: The "clearing" effect of this function @@ -1581,7 +1570,7 @@ be used in presence of a prototype. gets from the current TALKer on the serial bus. In order to receive the data, the device must have previously been sent a command to TALK and a secondary address if it needs one. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1603,7 +1592,7 @@ sent a command to TALK and a secondary address if it needs one. Device must first have been OPENed and then designated as the input channel by the CHKIN routine. When this function is called, the next byte of data available from the device is returned. Exception is the routine for the keyboard device (which is the default input device). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1629,7 +1618,7 @@ printed to the screen, which is the default output device. If the cassette is the current device, outputting a byte will only add it to the buffer. No actual transmission of data will occur until the 192-byte buffer is full. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1659,7 +1648,7 @@ address as the current secondary address. If the device on the channel is a serial device, which requires a TALK command and sometimes a secondary address, function will send them over the serial bus. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1687,7 +1676,7 @@ secondary address if necessary. This routine always buffers the current character, and defers sending it until the next byte is buffered. When the UNLISTEN command is sent, the last byte will be sent with an End or Identify (EOI). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1716,7 +1705,7 @@ file, its device as the current device, and its secondary address as the current secondary address. If the device on the channel uses the serial bus, and therefore requires a LISTEN command and possibly a secondary address, this information will be sent on the bus. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1739,7 +1728,7 @@ only be used in presence of a prototype. <tag/Description/It closes all open files, by resetting the index into open files to zero and restores the default I/O devices. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1761,7 +1750,7 @@ zero and restores the default I/O devices. <tag/Description/It is used to close a logical file after all I/O operations involving that file have been completed. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1787,7 +1776,7 @@ the screen. Also, if the current input device was formerly a serial device, the routine sends it an UNTALK command on the serial bus, and if a serial device was formerly the current output device, the routine sends it an UNLISTEN command. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1807,7 +1796,7 @@ sends it an UNLISTEN command. <tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ <tag/Declaration/<tt/unsigned char cbm_k_getin (void);/ <tag/Description/Function gets a character from the current input device. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1835,7 +1824,7 @@ VIC-20, and future models of the Commodore 64. If the I/O locations for a program are set by a call to this function, they should still remain compatible with future versions of the Commodore 64, the KERNAL and BASIC. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1858,7 +1847,7 @@ receive data. The KERNAL routine will OR the supplied device number bit by bit to convert it to a listen address, then transmits this data as a command on the serial bus. The specified device will then go into listen mode, and be ready to accept information. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1888,7 +1877,7 @@ loaded into memory starting at the location specified by the header. Function returns the address of the highest RAM location loaded. Before this function can be called, the KERNAL SETLFS, and SETNAM routines must be called. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1914,7 +1903,7 @@ Input/Output operations. In order to specify the logical file number, the device number, and the secondary address if any, the cbm_k_setlfs() function must first be called. Likewise, in order to designate the filename, the cbm_k_setnam() function must be used first. After these two functions are called, cbm_k_open() is then called. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1935,7 +1924,7 @@ functions are called, cbm_k_open() is then called. <tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ <tag/Declaration/<tt/unsigned char cbm_k_readst (void);/ <tag/Description/This function returns the current status of the I/O devices. It is usually called after new communication to an I/O device and gives information about device status, or errors that have occurred during the I/O operation. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -1957,7 +1946,7 @@ functions are called, cbm_k_open() is then called. used before calling this function. However, a file name is not required to SAVE to device 1 (the Datassette(TM) recorder). Any attempt to save to other devices without using a file name results in an error. NOTE: Device 0 (the keyboard), device 2 (RS-232), and device 3 (the screen) cannot be SAVEd to. If the attempt is made, an error occurs, and the SAVE is stopped. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -1980,7 +1969,7 @@ only be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cbm_k_setlfs (unsigned char LFN, unsigned char DEV, unsigned char SA);/ <tag/Description/This functions sets up the logical file by setting its number, device address, and secondary address. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2001,7 +1990,7 @@ only be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cbm_k_setnam (const char* Name);/ <tag/Description/This function is used to set up the file name for the OPEN, SAVE, or LOAD operations. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2024,7 +2013,7 @@ only be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cbm_k_talk (unsigned char dev);/ <tag/Description/When called, it ORs the device number with the TALK code (64, $40) and sends it on the serial bus. This commands the device to TALK. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2050,7 +2039,7 @@ bus. Only devices previously commanded to LISTEN are affected. This function is normally used after the host computer is finished sending data to external devices. Sending the UNLISTEN commands the listening devices to get off the serial bus so it can be used for other purposes. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item> </itemize> <tag/Availability/cc65 @@ -2070,7 +2059,7 @@ to get off the serial bus so it can be used for other purposes. <tag/Declaration/<tt/void __fastcall__ cclear (unsigned char length);/ <tag/Description/The function clears part of a line by writing <tt/length/ spaces in the current text color. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2094,7 +2083,7 @@ at a specific screen position. <tag/Description/The function moves the cursor to a specific position, and will then clear part of the line by writing <tt/length/ spaces in the current text color. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2118,7 +2107,7 @@ only be used in presence of a prototype. no character available, <tt/cgetc/ waits until the user presses a key. If the cursor is enabled by use of the <tt/cursor/ function, a blinking cursor is displayed while waiting. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>If the system supports a keyboard buffer, <tt/cgetc/ will fetch a key from this buffer and wait only if the buffer is empty. </itemize> @@ -2140,7 +2129,7 @@ from this buffer and wait only if the buffer is empty. <tag/Declaration/<tt/void __fastcall__ chline (unsigned char length);/ <tag/Description/The function outputs a horizontal line with the given length starting at the current cursor position. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The character used to draw the horizontal line is system dependent. If available, a line drawing character is used. Drawing a line that is partially off screen leads to undefined behaviour. @@ -2166,7 +2155,7 @@ used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ chlinexy (unsigned char x, unsigned char y, unsigned char length);/ <tag/Description/The function outputs a horizontal line with the given length starting at a given position. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The character used to draw the horizontal line is system dependent. If available, a line drawing character is used. Drawing a line that is partially off screen leads to undefined behaviour. @@ -2192,7 +2181,7 @@ used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ clearerr (FILE* f);/ <tag/Description/<tt/clearerr/ clears the error and end-of-file status indicators for the stream <tt/f/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2216,7 +2205,7 @@ used in presence of a prototype. time used by the program. The time is returned in implementation defined units. It can be converted to seconds by dividing by the value of the macro <tt/CLOCKS_PER_SEC/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Since the machines, cc65 generated programs run on, cannot run multiple processes, the function will actually return the time since some implementation defined point in the past. @@ -2257,7 +2246,7 @@ the upper left corner. <tag/Description/The function closes the given file descriptor. It returns zero on success and -1 on error. If an error occurs, the cause can be determined by reading the <tt/errno/ variable. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2280,7 +2269,7 @@ be used in presence of a prototype. <tag/Description/The function closes the given directory descriptor. It returns zero on success and -1 on error. If an error occurs, the cause can be determined by reading the <tt/errno/ variable. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2303,7 +2292,7 @@ be used in presence of a prototype. <tag/Description/<tt/creat/ creates a new file and returns the file descriptor associated with it. On error, -1 is returned and an error code is stored in <tt/errno/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item><tt/creat/ is identical to calling <tt/<ref id="open" name="open">/ with <tt/flags/ equal to <tt/O_WRONLY | O_CREAT | O_TRUNC/. <item>The function is only available as fastcall function, so it may only @@ -2329,7 +2318,7 @@ be used in presence of a prototype. formatted according to the format string given. The resulting string is output to the console. <tt/cprintf/ supports the same format specifiers as <tt/printf/. <!-- <tt/<ref id="printf" name="printf">/. --> -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Like all other <tt/conio/ output functions, <tt/cprintf/ distinguishes between <tt/\r/ and <tt/\n/. </itemize> @@ -2354,7 +2343,7 @@ between <tt/\r/ and <tt/\n/. <tag/Declaration/<tt/void __fastcall__ cputc (char c);/ <tag/Description/Output one character to the console at the current cursor position. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Like all other <tt/conio/ output functions, <tt/cputc/ distinguishes between <tt/\r/ and <tt/\n/. <item>The function is only available as fastcall function, so it may only @@ -2381,7 +2370,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c);/ <tag/Description/<tt/cputcxy/ moves the cursor to the given x/y position on the screen and outputs one character. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Like all other <tt/conio/ output functions, <tt/cputcxy/ distinguishes between <tt/\r/ and <tt/\n/. <item>The function is only available as fastcall function, so it may only @@ -2408,7 +2397,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cputs (const char* s);/ <tag/Description/The function outputs the given string on the console at the current cursor position. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Like all other <tt/conio/ output functions, <tt/cputs/ distinguishes between <tt/\r/ and <tt/\n/. <item>The function is only available as fastcall function, so it may only @@ -2435,7 +2424,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cputsxy (unsigned char x, unsigned char y, const char* s);/ <tag/Description/<tt/cputsxy/ moves the cursor to the given x/y position, and outputs the string <tt/s/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Like all other <tt/conio/ output functions, <tt/cputsxy/ distinguishes between <tt/\r/ and <tt/\n/. <item>The function is only available as fastcall function, so it may only @@ -2463,7 +2452,7 @@ be used in presence of a prototype. <tag/Description/If the argument to the function is non zero, a blinking cursor will be enabled when the <tt/cgetc/ function waits for input from the keyboard. If the argument is zero, <tt/cgetc/ will wait without a blinking cursor. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2485,7 +2474,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cvline (unsigned char length);/ <tag/Description/The function outputs a vertical line with the given length starting at the current cursor position. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The character used to draw the vertical line is system dependent. If available, a line drawing character is used. Drawing a line that is partially off screen leads to undefined behaviour. @@ -2511,7 +2500,7 @@ used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ cvlinexy (unsigned char x, unsigned char y, unsigned char length);/ <tag/Description/The function outputs a vertical line with the given length starting at a given position. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The character used to draw the vertical line is system dependent. If available, a line drawing character is used. Drawing a line that is partially off screen leads to undefined behaviour. @@ -2537,8 +2526,7 @@ used in presence of a prototype. <tag/Declaration/<tt/div_t __fastcall__ div (int numer, int denom);/ <tag/Description/<tt/div/ divides <tt/numer/ by <tt/denom/ and returns the quotient and remainder in a <tt/div_t/ structure. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2562,7 +2550,7 @@ the contents of the memory window have been changed, these changes may be lost if <tt/<ref id="em_map" name="em_map">/, <tt/<ref id="em_use" name="em_use">/, <tt/<ref id="em_copyfrom" name="em_copyfrom">/ or <tt/<ref id="em_copyto" name="em_copyto">/ are called without calling <tt/em_commit/ first. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Calling <tt/em_commit/ does not necessarily mean that changes to the memory window are discarded, it does just mean that the drivers is allowed to discard it. @@ -2591,7 +2579,7 @@ loaded. <tag/Description/Copy data from extended memory into linear memory. Source and target addresses as well as the number of bytes to transfer are specified in the <tt/em_copy/ structure that is passed as a parameter. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Calling <tt/em_copyfrom/ will invalidate the memory window, so if you made any changes to the data in the window, call <tt/<ref id="em_commit" name="em_commit">/ first, or the changes are lost. @@ -2620,7 +2608,7 @@ loaded. <tag/Description/Copy data from linear into extended memory. Source and target addresses as well as the number of bytes to transfer are specified in the <tt/em_copy/ structure that is passed as a parameter. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Calling <tt/em_copyto/ will invalidate the memory window, so if you made any changes to the data in the window, call <tt/<ref id="em_commit" name="em_commit">/ first, or the changes are lost. @@ -2649,7 +2637,7 @@ loaded. <tag/Description/The function installs an already loaded extended memory driver and returns an error code. The function may be used to install a driver linked statically to the program. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Not all drivers are able to detect if the supported hardware is really present. <item>The function is only available as fastcall function, so it may only be @@ -2675,7 +2663,7 @@ used in presence of a prototype. <tag/Description/Load an extended memory driver into memory and initialize it. The function returns an error code that tells if all this has been successful. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Not all drivers are able to detect if the supported hardware is really present. <item>The function is only available as fastcall function, so it may only be @@ -2705,7 +2693,7 @@ into a buffer. If you don't need the actual contents of the page (for example because you're going to overwrite it completely), it is better to call <tt/<ref id="em_use" name="em_use">/ instead. <tt/em_use/ will not transfer the data if it is possible to avoid that. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Calling <tt/em_map/ will invalidate the memory window, so if you made any changes to the data in the window, call <tt/<ref id="em_commit" name="em_commit">/ first, or the changes are lost. @@ -2733,7 +2721,7 @@ loaded. <tag/Declaration/<tt/unsigned em_pagecount (void);/ <tag/Description/The function returns the size of the extended memory supported by the driver in 256 byte pages. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function returns zero if no extended memory driver is loaded. <item>The function may return zero if the supported hardware was not detected. </itemize> @@ -2754,7 +2742,7 @@ by the driver in 256 byte pages. <tag/Declaration/<tt/unsigned char em_uninstall (void);/ <tag/Description/The function uninstalls an already loaded extended memory driver but doesn't remove it from memory. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>If the driver has been loaded using <tt/<ref id="em_load_driver" name="em_load_driver">/, <tt/<ref id="em_unload" name="em_unload">/ should be used instead of <tt/em_uninstall/ so the driver is also removed @@ -2779,7 +2767,7 @@ from memory. <tag/Declaration/<tt/unsigned char em_unload (void);/ <tag/Description/The function unloads a loaded extended memory driver and frees all memory allocated for the driver. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function does nothing if no driver is loaded. </itemize> <tag/Availability/cc65 @@ -2802,7 +2790,7 @@ memory and returns a pointer to the page frame. This function is similar to <tt/<ref id="em_map" name="em_map">/, but will not transfer data into the actual memory window in the assumption that the existing data is wrong or will get overwritten. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Calling <tt/em_use/ will invalidate the memory window, so if you made any changes to the data in the window, call <tt/<ref id="em_commit" name="em_commit">/ first, or the changes are lost. @@ -2834,7 +2822,7 @@ output is written and any functions registered with <tt/<ref id="atexit" name="atexit">/ are called. Common values for status are <tt/EXIT_SUCCESS/ and <tt/EXIT_FAILURE/ which are also defined in <tt/<ref id="stdlib.h" name="stdlib.h">/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>It depends on the host machine if the program return code can be @@ -2863,7 +2851,7 @@ the command line specified as second argument. Instead of an empty string, a <tt/NULL/ pointer may be passed as second parameter. On success, the function does not return. On failure, -1 is returned and <tt/errno/ contains an error code. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>On most platforms, the function needs to copy a small stub loader to @@ -2893,7 +2881,7 @@ program, it may not be able to read it. <tag/Declaration/<tt/void fast (void);/ <tag/Description/The function will switch the clock of the C128 to 2MHz. This will nearly double the speed compared to slow mode. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is specific to the C128. <item>2MHz clock will not work in 40 column mode. </itemize> @@ -2916,7 +2904,7 @@ will nearly double the speed compared to slow mode. <tag/Declaration/<tt/int __fastcall__ feof (FILE* f);/ <tag/Description/<tt/feof/ tests the end-of-file indicator ofthe stream <tt/f/, and returns a non zero value if it is set. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The indicator is set only after a read past the end of a file is attempted. <item>The function is only available as fastcall function, so it may only be @@ -2940,7 +2928,7 @@ used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ ferror (FILE* f);/ <tag/Description/<tt/ferror/ tests the error indicator of the stream <tt/f/, and returns a non zero value if it is set. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -2963,7 +2951,7 @@ used in presence of a prototype. <tag/Description/The <tt/fileno/ function returns the file handle used internally by a C stream. This file handle (an integer) can be used as a handle for the POSIX input/output functions. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>Mixing C file I/O functions and POSIX file I/O functions for the same @@ -2991,8 +2979,7 @@ file may have unpredictable results. <tt/<ref id="malloc" name="malloc">/, <tt/<ref id="calloc" name="calloc">/ or <tt/<ref id="realloc" name="realloc">/. As an exception, if the passed pointer is <tt/NULL/, no action is performed. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>Passing an already free'd block to <tt/free/ again will cause undefined behaviour and may crash your program. <item>The function is only available as fastcall function, so it may only @@ -3024,7 +3011,7 @@ be used in presence of a prototype. all supported targets. If it exists, it returns a number that identifies the operating system or machine type, the program runs on. The machine dependent header files define constants that can be used to check the return code. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function does not exist on all platforms. <item>The return codes are platform dependent. </itemize> @@ -3047,7 +3034,7 @@ returns one of the constants<itemize> <item><tt/CPU_65C02/ <item><tt/CPU_65816/ </itemize> -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Other, more exotic CPU types are not disinguished. </itemize> <tag/Availability/cc65 @@ -3067,7 +3054,7 @@ returns one of the constants<itemize> matches <tt/name/ and returns its value. The environment consists of a list of strings in the form <tt/name=value/. If there is no match, <tt/getenv/ returns <tt/NULL/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>What exactly is stored in the environment depends on the machine the program is running on. <item>The function is only available as fastcall function, so it may only @@ -3097,7 +3084,7 @@ preceeded by a '-'. found on the command line and <tt/EOF/ (-1) if there is no other option. An option argument is placed in <tt/optarg/, the index of the next element on the command line to be processed is placed in <tt/optind/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The implementation will not reorder options. A non option on the command line will terminate option processing. All remaining arguments are not recognized as options, even if the start with a '-' character. @@ -3120,7 +3107,7 @@ be used in presence of a prototype. <tag/Description/The function moves the text mode cursor to the specified X position while leaving the Y position untouched. The leftmost position on the screen has the coordinate 0. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>Invalid values for the X position (out of screen coordinates) may @@ -3147,7 +3134,7 @@ lead to undefined behaviour. <tag/Description/The function moves the text mode cursor to the specified position. The leftmost position on the screen has the X coordinate 0, the topmost line has the Y coordinate 0. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>Invalid values for any of both coordinates (out of screen positions) may @@ -3174,7 +3161,7 @@ lead to undefined behaviour. <tag/Description/The function moves the text mode cursor to the specified Y position while leaving the X position untouched. The uppermost position on the screen has the coordinate 0. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>Invalid values for the Y position (out of screen coordinates) may lead @@ -3201,7 +3188,7 @@ to undefined behaviour. <tag/Description/The function returns a non zero value if the given argument is a letter or digit. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3238,7 +3225,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ isalpha (int c);/ <tag/Description/The function returns a non zero value if the given argument is a letter. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3275,7 +3262,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ isascii (int c);/ <tag/Description/The function returns a non zero value if the given argument is in the range 0..127 (the range of valid ASCII characters) and zero if not. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3313,7 +3300,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Description/The function returns a non zero value if the given argument is a space or tab character. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3322,7 +3309,7 @@ macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> -<tag/Availability/cc65 +<tag/Availability/ISO 9899 <tag/See also/ <ref id="isalnum" name="isalnum">, <ref id="isalpha" name="isalpha">, @@ -3351,7 +3338,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Description/The function returns a non zero value if the given argument is a control character. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3388,7 +3375,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ isdigit (int c);/ <tag/Description/The function returns a non zero value if the given argument is a digit. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3427,7 +3414,7 @@ space). <tag/Description/The function returns a non zero value if the given argument is a printable character with the exception of space. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3465,7 +3452,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Description/The function returns a non zero value if the given argument is a lower case letter. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3503,7 +3490,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Description/The function returns a non zero value if the given argument is a printable character (this includes the space character). The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3542,7 +3529,7 @@ space or an alphanumeric character. <tag/Description/The function returns a non zero value if the given argument is a printable character, but not a space or anything alphanumeric. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3582,7 +3569,7 @@ is a white space character. The return value is zero if the character is anything else. The standard white space characters are: space, formfeed ('\f'), newline ('\n'), carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3620,7 +3607,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Description/The function returns a non zero value if the given argument is an upper case letter. The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3658,7 +3645,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Description/The function returns a non zero value if the given argument is a hexadecimal digit (0..9, a..f and A..F). The return value is zero if the character is anything else. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>When compiling with <tt/-Os/ the function is actually a macro. The inline sequence generated by the macro will not work correctly for values outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of @@ -3695,7 +3682,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Declaration/<tt/char* __fastcall__ itoa (int val, char* buf, int radix);/ <tag/Description/<tt/itoa/ converts the integer <tt/val/ into a string using <tt/radix/ as the base. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>There are no provisions to prevent a buffer overflow. <item>If <tt/val/ contains <tt/INT_MIN/, the behaviour is undefined. <item>The function is non standard, so it is not available in strict ANSI mode. @@ -3724,7 +3711,7 @@ used in presence of a prototype. <tag/Declaration/<tt/unsigned char joy_count (void);/ <tag/Description/The function returns a the number of joysticks supported by the current joystick driver. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>A joystick driver must be loaded using <ref id="joy_load_driver" name="joy_load_driver"> before calling this function. <item>The function returns the number of joysticks supported by the driver. @@ -3749,7 +3736,7 @@ There's no way to check for the number of actually connected joysticks. <tag/Description/The function installs a driver that was already loaded into memory (or linked statically to the program). It returns an error code (<tt/JOY_ERR_OK/ in case of success). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -3773,7 +3760,7 @@ used in presence of a prototype. <tag/Description/The function loads a driver with the given name from disk and installs it. An error code is returned, which is <tt/JOY_ERR_OK/ if the driver was successfully loaded and installed. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -3797,7 +3784,7 @@ used in presence of a prototype. <tag/Description/The function reads the status bits for a joystick. The number of the joystick is passed as parameter. The result may be examined by using one of the <tt/JOY_xxx/ macros from <ref id="joystick.h" name="joystick.h">. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>A joystick driver must be loaded using <ref id="joy_load_driver" name="joy_load_driver"> before calling this function. <item>The function is only available as fastcall function, so it may only be @@ -3823,7 +3810,7 @@ used in presence of a prototype. <tag/Description/The function uninstalls the currently installed joystick driver. It does not remove the driver from memory. The function returns an error code, which is <tt/JOY_ERR_OK/ if the driver was successfully uninstalled. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>A joystick driver must be installed using <ref id="joy_install" name="joy_install"> before calling this function. </itemize> @@ -3847,7 +3834,7 @@ name="joy_install"> before calling this function. <tag/Description/The function uninstalls the currently installed joystick driver and removes it from memory. An error code is returned, which is <tt/JOY_ERR_OK/ if the driver was successfully uninstalled. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>A joystick driver must be loaded using <ref id="joy_load_driver" name="joy_load_driver"> before calling this function. </itemize> @@ -3868,7 +3855,7 @@ name="joy_load_driver"> before calling this function. <tag/Declaration/<tt/unsigned char kbhit (void);/ <tag/Description/The function returns a value of zero if there is no character waiting to be read from the keyboard. It returns non zero otherwise. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>If the system does not support a keyboard buffer (most systems do), the function is rather useless. </itemize> @@ -3890,7 +3877,7 @@ do), the function is rather useless. <tag/Declaration/<tt/long __fastcall__ labs (long v);/ <tag/Description/<tt/labs/ returns the absolute value of the argument passed to the function. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The return value is undefined if <tt/LONG_MIN/ is passed to the function. <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. @@ -3912,7 +3899,7 @@ used in presence of a prototype. <tag/Declaration/<tt/char* __fastcall__ ltoa (long val, char* buf, int radix);/ <tag/Description/<tt/itoa/ converts the long integer <tt/val/ into a string using <tt/radix/ as the base. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>There are no provisions to prevent a buffer overflow. <item>If <tt/val/ contains <tt/LONG_MIN/, the behaviour is undefined. <item>The function is non standard, so it is not available in strict ANSI mode. @@ -3941,7 +3928,7 @@ used in presence of a prototype. <tag/Declaration/<tt/struct lconv* localeconv (void);/ <tag/Description/<tt/localeconv/ returns a pointer to the current locale structure. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>cc65 supports only the "C" locale, so even after setting a new locale using <tt/<ref id="setlocale" name="setlocale">/, the structure returned will always be the same. @@ -3966,8 +3953,7 @@ data in <tt/buf/, which must have been set by a preceeding call to <tt/<ref id="setjmp" name="setjmp">/. Program execution continues as if the call to <tt/<ref id="setjmp" name="setjmp">/ has just returned the value <tt/retval/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>If the parameter <tt/retval/ is zero, the function will behave as if it was called with a value of one. <item>The function is only available as fastcall function, so it may only @@ -3991,8 +3977,7 @@ be used in presence of a prototype. <tag/Description/<tt/malloc/ allocates size bytes on the heap and returns a pointer to the allocated memory block. On error (not enough memory available), <tt/malloc/ returns <tt/NULL/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4022,7 +4007,7 @@ be used in presence of a prototype. (converted to a char) in the block of raw memory string pointed to by <tt/mem/ that is of size <tt/count/. Upon completion, the function returns a pointer to the character found, or a null pointer if the character was not found. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4045,8 +4030,7 @@ be used in presence of a prototype. pointed to by <tt/p1/ into the memory area pointed to by <tt/p2/. It returns a value that is less than zero if <tt/p1/ is less than <tt/p2/, zero if <tt/p1/ is the same as <tt/p2/, and a value greater than zero if <tt/p1/ is greater than <tt/p2/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4070,8 +4054,7 @@ be used in presence of a prototype. <tag/Description/<tt/memcpy/ copies <tt/count/ bytes from the memory area pointed to by <tt/src/ into the memory area pointed to by <tt/dest/. It returns <tt/dest/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The result is undefined if the memory areas do overlap. Use <tt/<ref id="memmove" name="memmove">/ to copy overlapping memory areas. <item>The function is only available as fastcall function, so it may only @@ -4097,8 +4080,7 @@ be used in presence of a prototype. <tag/Description/<tt/memmove/ copies <tt/count/ bytes from the memory area pointed to by <tt/src/ into the memory area pointed to by <tt/dest/. It returns <tt/dest/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>While <tt/memmove/ allows the memory areas to overlap, it has some additional overhead compared to <tt/<ref id="memcpy" name="memcpy">/. <item>The function is only available as fastcall function, so it may only @@ -4123,8 +4105,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void* __fastcall__ memset (void* p, int val, size_t count);/ <tag/Description/<tt/memset/ fills the memory area pointed to by <tt/p/ with the value <tt/val/. The function returns <tt/p/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4148,7 +4129,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ mod_free (void* module);/ <tag/Description/The function will free a module loaded into memory by use of the <tt/<ref id="mod_load" name="mod_load">/ function. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The pointer passed as parameter is the pointer to the module memory, not the pointer to the control structure. </itemize> @@ -4179,7 +4160,7 @@ the module just loaded. Possible error codes are: <item><tt/MLOAD_ERR_FMT/ - Data format error <item><tt/MLOAD_ERR_MEM/ - Not enough memory </itemize> -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The <htmlurl url="ld65.html" name="ld65"> linker is needed to create relocatable o65 modules for use with this function. </itemize> @@ -4199,7 +4180,7 @@ relocatable o65 modules for use with this function. <tag/Header/<tt/<ref id="mouse.h" name="mouse.h">/ <tag/Declaration/<tt/void __fastcall__ mouse_setbox (const struct mouse_box* box);/ <tag/Description/The function allows to set a bounding box for mouse movement. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function does not check if the mouse cursor is currently within the given rectangle. Placing the mouse cursor within the bounding box is the responsibility of the programmer. @@ -4228,7 +4209,7 @@ used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ mouse_getbox (struct mouse_box* box);/ <tag/Description/The function queries the current bounding box for mouse movement. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4270,7 +4251,7 @@ return value. code);/ <tag/Description/The function returns an error message (in english) for the error code passed parameter. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function will return "Unknown error" for invalid error codes. <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. @@ -4315,7 +4296,7 @@ mouse. <tag/Declaration/<tt/void __fastcall__ mouse_info (struct mouse_info* info);/ <tag/Description/The function returns the state of the mouse buttons and the position of the mouse in the <tt/mouse_info/ structure passed as parameter. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The <tt/mouse_info/ struct is a superset of the <tt/mouse_pos/ struct, so if you just need the mouse position, call <tt/<ref id="mouse_pos" name="mouse_pos">/ instead. @@ -4346,7 +4327,7 @@ pointer. Defaults for these routines are supplied by the library, so if you can live with these defaults (which are platform specific), just pass a pointer to <tt/mouse_def_callbacks/. The function may be used to install a driver linked statically to the program. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Not all drivers are able to detect if the supported hardware is really present. <item>After installing a driver, the mouse cursor is hidden. @@ -4376,7 +4357,7 @@ different IOCTL functions, and the <tt/data/ depends on code. The function returns an error code. The purpose of this function is to allow for driver specific extensions. See the documentation for a specific mouse driver for supported ioctl calls. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Calling this function is non portable, because each driver may implement different ioctl calls (or none at all). <item>The function is only available as fastcall function, so it may only be @@ -4402,7 +4383,7 @@ function returns an error code that tells if the call has been successful. The routines needed to move or hide/show the mouse pointer. Defaults for these routines are supplied by the library, so if you can live with these defaults (which are platform specific), just pass a pointer to <tt/mouse_def_callbacks/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The driver is loaded by name, so currently you must know the type of mouse that should be supported. There is no autodetect capability. <item>Not all drivers are able to detect if the supported hardware is really @@ -4430,7 +4411,7 @@ used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ mouse_move (int x, int y);/ <tag/Description/The function updates the mouse position. If the mouse cursor is visible, it is shown at the new position. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function does not check if the new position is within the bounding box specified with <tt/<ref id="mouse_setbox" name="mouse_setbox">/. <item>The function is only available as fastcall function, so it may only be @@ -4454,7 +4435,7 @@ used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ mouse_pos (struct mouse_pos* pos);/ <tag/Description/The function returns the position of the mouse in the <tt/mouse_pos/ structure passed as parameter. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The <tt/mouse_pos/ struct is a subset of the <tt/mouse_info/ struct, so if you do also need the mouse buttons, call <tt/<ref id="mouse_info" name="mouse_info">/ instead. @@ -4498,7 +4479,7 @@ that is shared between <tt/<ref id="mouse_hide" name="mouse_hide">/ and <tag/Declaration/<tt/unsigned char mouse_uninstall (void);/ <tag/Description/The function uninstalls an already loaded mouse driver but don't removes it from memory. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>If the driver has been loaded using <tt/<ref id="mouse_load_driver" name="mouse_load_driver">/, <tt/<ref id="mouse_unload" name="mouse_unload">/ should be used instead of <tt/mouse_uninstall/ so the driver is also removed @@ -4523,7 +4504,7 @@ from memory. <tag/Declaration/<tt/unsigned char __fastcall__ mouse_unload (void);/ <tag/Description/The function unloads a loaded mouse driver and frees all memory allocated for the driver. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function does nothing if no driver is loaded. </itemize> <tag/Availability/cc65 @@ -4545,7 +4526,7 @@ memory allocated for the driver. <tag/Declaration/<tt/size_t offsetof (type, member);/ <tag/Description/<tt/offsetof/ calculates the address offset of a <tt/struct/ or <tt/union/ member. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is actually a macro. </itemize> <tag/Availability/ISO 9899 @@ -4564,7 +4545,7 @@ or <tt/union/ member. <tag/Description/<tt/open/ opens a file and returns the file descriptor associated with it. On error, -1 is returned and an error code is stored in <tt/errno/. Several flags may be passed to <tt/open/ that change the behaviour. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>POSIX specifies an additional <tt/mode/ argument that may be passed to open, which is used as the permission mask when a new file is created. While cc65 allows to pass this argument, it is ignored. @@ -4588,7 +4569,7 @@ cc65 allows to pass this argument, it is ignored. <tag/Description/<tt/opendir/ opens a directory and returns the direcory descriptor associated with it. On error, NULL is returned and an error code is stored in <tt/errno/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4611,8 +4592,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/unsigned char __fastcall__ peekbsys (unsigned addr);/ <tag/Description/<tt/peekbsys/ reads one byte from the given address in the system bank (bank 15) of the CBM PET-II machines and returns it. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>This function may be a macro depending on the compiler options. The @@ -4642,8 +4622,7 @@ actual function is accessible by #undef'ing the macro. system bank (bank 15) of the CBM PET-II machines and returns it. Following the usual 6502 conventions, the low byte is read from <tt/addr/, and the high byte is read from <tt/addr+1/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The order in which the two bytes are read is undefined. @@ -4672,8 +4651,7 @@ is not <tt/NULL/ and not an empty string, it is printed followed by a colon and a blank. Then the error message for the current contents of <tt/errno/ is printed followed by a newline. The message output is the same as returned by <tt/<ref id="strerror" name="strerror">/ with an argument of <tt/errno/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4696,8 +4674,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ pokebsys (unsigned addr, unsigned char val);/ <tag/Description/<tt/pokebsys/ writes one byte to the given address in the system bank (bank 15) of the CBM PET-II machines. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4725,8 +4702,7 @@ be used in presence of a prototype. system bank (bank 15) of the CBM PET-II machines. Following the usual 6502 conventions, the low byte of <tt/val/ is written to <tt/addr/, and the high byte is written to <tt/addr+1/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The order in which the two bytes are written is undefined. @@ -4755,8 +4731,7 @@ size_t size, int (*compare) (const void*, const void*));/ function <tt/compare/. <tt/base/ is the address of the array, <tt/count/ is the number of elements, <tt/size/ the size of an element and <tt/compare/ the function used to compare the members. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>If there are multiple members with the same key, the order after calling the function is undefined. <item>The function is only available as fastcall function, so it may only @@ -4782,7 +4757,7 @@ program has installed a signal handler for the signal, this signal handler will be executed. If no handler has been installed, the default action for the raised signal will be taken. The function returns zero on success, nonzero otherwise. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4804,7 +4779,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/int rand (void);/ <tag/Description/The function returns a pseudo random number between 0 and <tt/RAND_MAX/ (exclusive). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Without using <tt><ref id="srand" name="srand"></tt>, always the same flow of numbers is generated. <item>On startup, the function behaves as if <ref id="srand" name="srand"> @@ -4831,7 +4806,7 @@ stream pointed to by <tt/dir/. It stores the data in a <tt/dirent/ structure and returns a pointer to it. If the end of directory is reached, or an error occurs, NULL is returned. In case of errors, an error code is stored into <tt/errno/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The returned pointer may point to a statically allocated instance of @@ -4870,8 +4845,7 @@ by <tt/block/ to <tt/size/ bytes. If <tt/block/ is <tt/NULL/, <tt/realloc/ behaves as if <tt/malloc/ had been called. If <tt/size/ is zero, <tt/realloc/ behaves as if <tt/free/ had been called. On error (not enough memory available), <tt/realloc/ returns <tt/NULL/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The part of the memory block that is returned will have its contents unchanged. <item>This function is somewhat dangerous to use. Be careful to save the @@ -4907,8 +4881,7 @@ be used in presence of a prototype. <tag/Description/<tt/remove/ deletes the file with the given name. On success, zero is returned. On error, -1 is returned and <tt/errno/ is set to an error code describing the reason for the failure. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>This function is not available on all cc65 targets (depends on the availability of file I/O). <item>The function is only available as fastcall function, so it may only @@ -4944,8 +4917,7 @@ if (remove (FILENAME) == 0) { <tag/Description/<tt/rename/ renames a file (gives it a new name). On success, zero is returned. On error, -1 is returned and <tt/errno/ is set to an error code describing the reason for the failure. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>This function is not available on all cc65 targets (depends on the capabilities of the storage devices). <item>The function is only available as fastcall function, so it may only @@ -4980,11 +4952,9 @@ if (rename (OLDNAME, NEWNAME) == 0) { <tag/Declaration/<tt/void reset_brk (void);/ <tag/Description/<tt/reset_brk/ resets the break vector to the value it had before a call to <tt/set_brk/. -<tag/Limits/ -<itemize> -<item>Since <tt/<ref id="set_brk" name="set_brk">/ installs an exit handler, -it is not strictly necessary to call this function as part of the cleanup when -the program ends. +<tag/Notes/<itemize> +<item>The break vector is reset on program termination, so it's not strictly +necessary to call this function as a part of your clean-up when exitting the program. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -5004,10 +4974,9 @@ the program ends. <tag/Header/<tt/<ref id="6502.h" name="6502.h">/ <tag/Declaration/<tt/void reset_irq (void);/ <tag/Description/<tt/reset_irq/ resets the C level interrupt request vector. -<tag/Limits/ -<itemize> -<item>The original IRQ vector is restored on program termination even without -calling this function. +<tag/Notes/<itemize> +<item>The interrupt vector is reset on program termination, so it's not strictly +necessary to call this function as a part of your clean-up when exitting the program. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -5029,7 +4998,7 @@ calling this function. <tag/Description/If the argument is non zero, the function enables reverse character display. If the argument is zero, reverse character display is switched off. The old value of the setting is returned. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function may not be supported by the hardware, in which case the call is ignored. <item>The function is only available as fastcall function, so it may only @@ -5052,7 +5021,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ rewinddir (DIR* dir);/ <tag/Description/<tt/rewinddir/ sets the position of the directory stream pointed to by <tt/dir/ to the start of the directory. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5073,7 +5042,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="conio.h" name="conio.h">/ <tag/Declaration/<tt/void __fastcall__ screensize (unsigned char* x, unsigned char* y);/ <tag/Description/The function returns the dimensions of the text mode screen. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5099,7 +5068,7 @@ be used in presence of a prototype. <tag/Description/<tt/seekdir/ sets the position of the directory stream pointed to by <tt/dir/ to the value given in <tt/offset/, which should be a value returned by <tt/<ref id="telldir" name="telldir">/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5153,7 +5122,7 @@ static void initialize(){ <tag/Description/Get a character from the serial port. If no characters are available, the function will return SER_ERR_NO_DATA, so this is not a fatal error. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5180,7 +5149,7 @@ while (ser_get(&ch) == SER_ERR_NO_DATA) <tag/Description/The function installs a driver that was already loaded into memory (or linked statically to the program). It returns an error code (<tt/SER_ERR_OK/ in case of success). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5206,7 +5175,7 @@ ser_install(lynx_comlynx); //Include the driver statically instead of loading it <tag/Description/Some platforms have extra serial functions that are not supported by standard serial driver functions. You can extend the driver to support this extra functionality bt using ser_ioctl functions. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>These functions are not easily portable to other cc65 platforms. @@ -5226,7 +5195,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/unsigned char __fastcall__ ser_load_driver (const char *name);/ <tag/Description/Load and install the driver by name. Will just load the driver and check if loading was successful. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5245,7 +5214,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="serial.h" name="serial.h">/ <tag/Declaration/<tt/unsigned char __fastcall__ ser_open (const struct ser_params* params);/ <tag/Description/Open the port by setting the port parameters and enable interrupts. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5282,7 +5251,7 @@ static void initialize(){ <tag/Description/Send a character via the serial port. There is a transmit buffer, but transmitting is not done via interrupt. The function returns SER_ERR_OVERFLOW if there is no space left in the transmit buffer. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5304,7 +5273,7 @@ ser_put('A'); <tag/Header/<tt/<ref id="serial.h" name="serial.h">/ <tag/Declaration/<tt/unsigned char __fastcall__ ser_status (unsigned char* status);/ <tag/Description/Return the serial port status. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5355,8 +5324,7 @@ be used in presence of a prototype. program code by letting the vector point to a user written C function. The runtime library installs a small stub that saves the registers into global variables that may be accessed (and changed) by the break handler. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The stub saves the zero page registers used by the C runtime and switches @@ -5367,9 +5335,9 @@ function called from it. <item>The <tt/brk_pc/ variable points to the <tt/BRK/ instruction. If you want the continue with the interrupted code, you have to adjust <tt/brk_pc/, otherwise the <tt/BRK/ instruction will get executed over and over again. -<item>Since <tt/set_brk/ installs an exit handler, it is not strictly necessary -to call <tt/<ref id="reset_brk" name="reset_brk">/ as part of the cleanup when -the program terminates. +<item>The break vector is reset on program termination, so it's not strictly +necessary to call <tt/<ref id="reset_brk" name="reset_brk">/ as a part of your +clean-up when exitting the program. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -5396,8 +5364,7 @@ was set up to handle a "private", "exclusive" interrupt request source it must return the value <tt/IRQ_HANDLED/ if and only if it has verified that the current interrupt request actually stems from that source. In all other cases it must return the value <tt/IRQ_NOT_HANDLED/. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The stub saves the registers and zero page locations used by the C runtime @@ -5406,9 +5373,9 @@ runtime overhead, but it it is safe to execute C code, even if other C code was interrupted. Be careful however not to call C library functions, and do not enable stack checks for the handler function or any other function called from it. -<item>The interrupt vector is reset on function termination, so it's not -strictly necessary to call <tt/<ref id="reset_irq" name="reset_irq">/ as part -of the cleanup when the program terminates. +<item>The interrupt vector is reset on program termination, so it's not strictly +necessary to call <tt/<ref id="reset_irq" name="reset_irq">/ as a part of your +clean-up when exitting the program. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -5430,8 +5397,7 @@ of the cleanup when the program terminates. <tag/Description/The <tt/setjmp/ function saves the current context in <tt/buf/ for subsequent use by the <tt/<ref id="longjmp" name="longjmp">/ function and returns zero. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item><tt/setjmp/ is actually a macro as required by the ISO standard. @@ -5453,8 +5419,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="locale.h" name="locale.h">/ <tag/Declaration/<tt/char* __fastcall__ setlocale (int category, const char* locale);/ <tag/Description/<tt/setlocale/ sets or queries the program's locale. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>cc65 supports only the "C" locale, so calling this function to set a @@ -5482,7 +5447,7 @@ handler may either be a user supplied function, or one of the predefined signal handlers <tt/SIG_IGN/ or <tt/SIG_DFL/. The function returns the previous value if the signal , or the special function vector SIG_ERR in case of an error. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5504,7 +5469,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void __fastcall__ sleep (unsigned seconds);/ <tag/Description/The function will return after the specified number of seconds have elapsed. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5523,7 +5488,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void slow (void);/ <tag/Description/The function will switch the clock of the C128 to 1MHz. This will halve the speed compared to fast mode. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is specific to the C128. </itemize> <tag/Availability/C128 @@ -5546,7 +5511,7 @@ will halve the speed compared to fast mode. <tag/Description/The function initializes the random number generator using the given seed. On program startup, the generator behaves as if <tt/srand/ has been called with an argument of 1. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5570,7 +5535,7 @@ be used in presence of a prototype. as parameters without case sensitivity. It returns a value that is less than zero if <tt/s1/ is less than <tt/s2/, zero if <tt/s1/ is the same as <tt/s2/, and a value greater than zero if <tt/s1/ is greater than <tt/s2/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The function is not available in strict ANSI mode. @@ -5598,7 +5563,7 @@ be used in presence of a prototype. pointed to by s2 (including the terminating null byte) to the end of the string pointed to by s1. The initial byte of s2 overwrites the null byte at the end of s1. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>If copying takes place between objects that overlap, the behaviour @@ -5625,7 +5590,7 @@ is undefined. (converted to a char) in the string pointed to by <tt/s/. The terminating null byte is considered to be part of the string. Upon completion, the function returns a pointer to the byte, or a null pointer if the byte was not found. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5649,7 +5614,7 @@ be used in presence of a prototype. parameters. It returns a value that is less than zero if <tt/s1/ is less than <tt/s2/, zero if <tt/s1/ is the same as <tt/s2/, and a value greater than zero if <tt/s1/ is greater than <tt/s2/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5677,7 +5642,7 @@ parameters, according to the collating sequence set by <tt/<ref id="setlocale" name="setlocale">/. It returns a value that is less than zero if <tt/s1/ is less than <tt/s2/, zero if <tt/s1/ is the same as <tt/s2/, and a value greater than zero if <tt/s1/ is greater than <tt/s2/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5704,7 +5669,7 @@ be used in presence of a prototype. <tag/Description/The <tt/strcpy/ function copies the string pointed to by <tt/s2/ (including the terminating null byte) into the array pointed to by <tt/s1/. The function will always return <tt/s1/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>If copying takes place between objects that overlap, the behaviour @@ -5737,7 +5702,7 @@ strcpy (hello, "Hello world!\n"); <tag/Description/The <tt/strcspn/ function computes and returns the length of the substring pointed to by <tt/s/ which does <em>not</em> consist of characters contained in the string <tt/set/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5763,7 +5728,7 @@ be used in presence of a prototype. to hold a copy of <tt/s/ including the terminating zero. If the allocation fails, <tt/NULL/ is returned, otherwise <tt/s/ is copied into the allocated memory block, and a pointer to the block is returned. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>It is up to the caller to free the allocated memory block. @@ -5788,7 +5753,7 @@ be used in presence of a prototype. given error code. If an invalid error code is passed, the string "Unknown error" is returned, and <tt/errno/ is set to <tt/EINVAL/. In all other cases, <tt/errno/ is left untouched. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>While the return type of the function is a <tt/char*/, the returned @@ -5813,7 +5778,7 @@ string must not be modified by the caller! parameters without case sensitivity. It returns a value that is less than zero if <tt/s1/ is less than <tt/s2/, zero if <tt/s1/ is the same as <tt/s2/, and a value greater than zero if <tt/s1/ is greater than <tt/s2/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The function is not available in strict ANSI mode. @@ -5839,7 +5804,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/size_t __fastcall__ strlen (const char* s);/ <tag/Description/The <tt/strlen/ function computes the number of bytes in the string to which s points, not including the terminating null byte. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>When compiling with <tt/-Os/ (inline known standard functions), the @@ -5862,7 +5827,7 @@ function does not work correctly for strings with more than 255 characters. <tag/Declaration/<tt/char* __fastcall__ strlower (char* s);/ <tag/Description/The <tt/strlower/ function will apply the <tt/tolower/ function to each character of a string. The function will always return <tt/s/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The function prototype is unavailable when compiling in strict ANSI mode. @@ -5895,7 +5860,7 @@ See <tt/strlower/. of the string pointed to by s2 to the end of the string pointed to by s1. The terminating null character at the end of s1 is overwritten. A terminating null character is appended to the result, even if not all of s2 is appended to s1. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>If copying takes place between objects that overlap, the behaviour @@ -5923,7 +5888,7 @@ characters of the two strings passed as parameters. It returns a value that is less than zero if the first <tt/count/ characters of <tt/s1/ are less than <tt/s2/, zero if they are identical, and a value greater than zero they are greater. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -5951,7 +5916,7 @@ the array pointed to by <tt/s2/ to the array pointed to by <tt/s1/. If the array pointed to by <tt/s2/ is a string that is shorter than <tt/n/ bytes, null bytes are appended to the copy in the array pointed to by <tt/s1/, until <tt/n/ bytes are written. The function always will return <tt/s1/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is available only as a fastcall function; so, it may be used only in the presence of a prototype. <item>If there is no null byte in the first <tt/n/ bytes of the array pointed @@ -5991,7 +5956,7 @@ string <tt/s2/. Tokens inside quotation marks may contain characters from <tt/s2 pointer to the first token in the string <tt/s1/. The following calls must pass a <tt/NULL/ pointer as <tt/s1/, in order to get the next token in the string. Different sets of delimiters may be used for the subsequent calls to <tt/strqtok()/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is available only as a fastcall function; so, it may be used only in the presence of a prototype. <item><tt/strqtok()/ will modify the string <tt/s1/. @@ -6020,7 +5985,7 @@ a second <tt/s1/ string before it finishes the first one. (converted to a char) in the string pointed to by <tt/s/. The terminating null byte is considered to be part of the string. Upon completion, the function returns a pointer to the byte, or a null pointer if the byte was not found. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6042,7 +6007,7 @@ be used in presence of a prototype. <tag/Description/The <tt/strspn/ function computes and returns the length of the substring pointed to by <tt/s/ which does consist only of characters contained in the string <tt/set/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6065,7 +6030,7 @@ be used in presence of a prototype. <tag/Description/<tt/strstr/ searches for the first occurance of the string <tt/substr/ within <tt/str/. If found, it returns a pointer to the copy, otherwise it returns <tt/NULL/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6091,7 +6056,7 @@ to <tt/strtok()/ will return a pointer to the first token in the string <tt/s1/. The following calls must pass a <tt/NULL/ pointer as <tt/s1/, in order to get the next token in the string. Different sets of delimiters may be used for the subsequent calls to <tt/strtok()/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item><tt/strtok()/ will modify the string <tt/s1/. @@ -6123,7 +6088,7 @@ transformed strings, it returns a value greater than, equal to, or less than zero, corresponding to the result of the <tt/strcoll/ function applied to the same two original strings. No more than n characters are placed into the resulting array pointed to by s1, including the terminating null character. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item><tt/s1/ and <tt/s2/ must not point to the same memory area, otherwise the behaviour is undefined. <item>If <tt/n/ is zero, <tt/s1/ may be a NULL pointer. @@ -6151,7 +6116,7 @@ just copy s2 to s1 using <tt><ref id="strncpy" name="strncpy"></tt>. <tag/Declaration/<tt/char* __fastcall__ strupper (char* s);/ <tag/Description/The <tt/strupper/ function will apply the <tt/toupper/ function to each character of a string. The function will always return <tt/s/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The function prototype is unavailable when compiling in strict ANSI mode. @@ -6183,7 +6148,7 @@ See <tt/strupper/. <tag/Description/<tt/telldir/ returns the current position of a directory stream. The return value may be used in subsequent calls to <tt/<ref id="seekdir" name="seekdir">/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6206,7 +6171,7 @@ be used in presence of a prototype. <tag/Description/The function will set a new text color. It returns the old (current) text color. Text output using any <tt/conio.h/ function will use the color set by this function. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Text colors are system dependent. The function may have no effect on systems where the text color cannot be changed. <item>The function is only available as fastcall function, so it may only @@ -6233,7 +6198,7 @@ unsigned char rx, unsigned char ry, unsigned sa, unsigned ea);/ radii rx/ry using the current drawing color. The arc covers the angle between sa and ea (startangle and endangle), which must be in the range 0..360. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The function behaves unexpectedly or may crash if the angles are out @@ -6265,7 +6230,7 @@ color. <tag/Declaration/<tt/void __fastcall__ tgi_bar (int x1, int y1, int x2, int y2);/ <tag/Description/The function fills a rectangle on the drawpage with the current color. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6287,7 +6252,7 @@ tgi_bar(10, 10, 100, 60); <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/void __fastcall__ tgi_circle (int x, int y, unsigned char radius);/ <tag/Description/The function draws a circle in the current color. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6347,7 +6312,7 @@ Will NOT uninstall or unload the driver! <tag/Declaration/<tt/void __fastcall__ tgi_ellipse (int x, int y, unsigned char rx, unsigned char ry);/ <tag/Description/The function draws an ellipse at position x/y with radii rx and ry, using the current drawing color. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6374,7 +6339,7 @@ tgi_ellipse (50, 40, 40, 20); <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/void __fastcall__ tgi_free_vectorfont (const tgi_vectorfont* font);/ <tag/Description/Free a vector font that was previously loaded into memory. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6397,7 +6362,7 @@ driver and display as an 8.8 fixed point value. It may be used to correct geometric shapes so they look correct on the display. As an example, a circle with a radius of 100 pixels may look elliptic on some driver/display combinations if the aspect ratio is not 1.00. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The aspect ratio is encoded in the TGI driver which assumes a "standard" monitor for the given platform. The aspect ratio may be wrong if another monitor is used. @@ -6501,7 +6466,7 @@ This will also clear the error. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/const char* __fastcall__ tgi_geterrormsg (unsigned char code);/ <tag/Description/Get an error message describing the error. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6597,7 +6562,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/unsigned char __fastcall__ tgi_getpixel (int x, int y);/ <tag/Description/Get the color of a pixel from the viewpage. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6648,7 +6613,7 @@ This is same as tgi_maxy()+1. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/void __fastcall__ tgi_gotoxy (int x, int y);/ <tag/Description/Set graphics cursor at x, y. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6668,7 +6633,7 @@ be used in presence of a prototype. <tag/Declaration/<tt/void tgi_init (void);/ <tag/Description/The tgi_init function will set the default palette to the hardware. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item><tt/tgi_init/ will not clear the screen. This allows switching between text and graphics mode on platforms that have separate memory areas for the screens. If you want the screen cleared, call <tt/<ref id="tgi_clear" @@ -6694,7 +6659,7 @@ tgi_init(); //Set up the default palette and clear the screen. <tag/Description/The function installs a driver that was already loaded into memory (or linked statically to the program). It returns an error code (<tt/TGI_ERR_OK/ in case of success). -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6722,7 +6687,7 @@ tgi_init(); //Set up the default palette and clear the screen. Install a vector font for use. More than one vector font can be loaded, but only one can be active. This function is used to tell which one. Call with a NULL pointer to uninstall the currently installed font. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6745,7 +6710,7 @@ used in presence of a prototype. <tag/Description/Some platforms have extra display hardware that is not supported by standard tgi functions. You can extend the driver to support this extra hardware using tgi_ioctl functions. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>These functions are not easily portable to other cc65 platforms. @@ -6780,7 +6745,7 @@ The graphics cursor will be set to x2/y2 by this call. <tag/Declaration/<tt/void __fastcall__ tgi_line (int x1, int y1, int x2, int y2);/ <tag/Description/Draw a line in the current drawing color. The graphics cursor will be set to x2/y2 by this call. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6801,7 +6766,7 @@ cursor to the new end point. The graphics cursor will be updated to x2/y2. <tag/Declaration/<tt/void __fastcall__ tgi_lineto (int x2, int y2);/ <tag/Description/Draw a line in the current drawing color from the graphics cursor to the new end point. The graphics cursor will be updated to x2/y2. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6822,7 +6787,7 @@ be used in presence of a prototype. <tag/Description/Load and install the driver by name. Will just load the driver and check if loading was successful. Will not switch to graphics mode. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6844,7 +6809,7 @@ be used in presence of a prototype. Load a vector font into memory and return it. In case of errors, NULL is returned and an error is set, which can be retrieved using tgi_geterror. To use the font, it has to be installed using tgi_install_vectorfont. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6867,7 +6832,7 @@ The graphics cursor is moved to the end of the text. <tag/Declaration/<tt/void __fastcall__ tgi_outtext (const char* s);/ <tag/Description/Output text at the current graphics cursor position. The graphics cursor is moved to the end of the text. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6888,7 +6853,7 @@ The graphics cursor is moved to the end of the text. <tag/Declaration/<tt/void __fastcall__ tgi_outtextxy (int x, int y, const char* s);/ <tag/Description/Output text at the given cursor position. The graphics cursor is moved to the end of the text. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6911,7 +6876,7 @@ unsigned char rx, unsigned char ry, unsigned sa, unsigned ea);/ and radii rx/ry using the current drawing color. The pie slice covers the angle between sa and ea (startangle and endangle), which must be in the range 0..360. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>The function behaves unexpectedly or may crash if the angles are out @@ -6943,7 +6908,7 @@ driver and display. The argument is an 8.8 fixed point value. The aspect ratio may be used to correct geometric shapes so they look correct on a given display. As an example, a circle with a radius of 100 pixels may look elliptic on some driver/display combinations if the aspect ratio is not 1.00. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The aspect ratio is encoded in the TGI driver which assumes a "standard" monitor for the given platform. The aspect ratio may be wrong if another monitor is used. @@ -6971,7 +6936,7 @@ ratio. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/void __fastcall__ tgi_setcolor (unsigned char color);/ <tag/Description/Set color to be used in future draw operations. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -6997,7 +6962,7 @@ tgi_bar(10,10,20,20); is seen immediately as it is drawn. For double buffered games you can set the drawpage to a different page than the viewpage. This lets you draw the next screen in the background and when the screen is ready you display it. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7025,7 +6990,7 @@ Palette is a pointer to as many entries as there are colors. <tag/Declaration/<tt/void __fastcall__ tgi_setpalette (const unsigned char* palette);/ <tag/Description/Set the palette (not available with all drivers/hardware). Palette is a pointer to as many entries as there are colors. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7043,7 +7008,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/void __fastcall__ tgi_setpixel (int x, int y);/ <tag/Description/Plot a pixel on the drawpage with the current color. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7064,7 +7029,7 @@ be used in presence of a prototype. is seen immediately as it is drawn. For double buffered games you can set the drawpage to a different page than the viewpage. This lets you draw the next screen in the background and when the screen is ready you display it. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7092,7 +7057,7 @@ the current text style. <tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextheight (const char* s);/ <tag/Description/Calculate the height of the text in pixels according to the current text style. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7112,7 +7077,7 @@ be used in presence of a prototype. <tag/Description/ Set the scaling for text output. The scaling factors for width and height are 8.8 fixed point values. This means that $100 = 1 $200 = 2 etc. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7131,7 +7096,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/void __fastcall__ tgi_settextstyle (unsigned char magx, unsigned char magy, unsigned char dir, unsigned char font);/ <tag/Description/Set the style for text output. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7150,7 +7115,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextwidth (const char* s);/ <tag/Description/Calculate the width of the text in pixels according to the current text style. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7203,7 +7168,7 @@ Will call tgi_done if necessary. measured in seconds. If the pointer <tt/t/ is not <tt/NULL/, the function result will also be stored there. If no time is available, <tt/(time_t)-1/ is returned and <tt/errno/ is set to <tt/ENOSYS/. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. <item>Many platforms supported by cc65 do not have a realtime clock, so the @@ -7227,7 +7192,7 @@ returned value may not be valid. <tag/Description/Toggle between 40 and 80 column mode. The settings for the old mode (cursor position, color and so on) are saved and restored together with the mode. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is specific to the C128. <item>This function is deprecated. Please use <ref id="videomode" name="videomode"> instead! @@ -7251,7 +7216,7 @@ name="videomode"> instead! <tag/Declaration/<tt/int __fastcall__ tolower (int c);/ <tag/Description/The function returns the given character converted to lower case. If the given character is not a letter, it is returned unchanged. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7274,7 +7239,7 @@ only be used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ toupper (int c);/ <tag/Description/The function returns the given character converted to upper case. If the given character is not a letter, it is returned unchanged. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -7297,7 +7262,7 @@ only be used in presence of a prototype. <tag/Declaration/<tt/char* __fastcall__ ultoa (unsigned long val, char* buf, int radix);/ <tag/Description/<tt/itoa/ converts the unsigned long integer <tt/val/ into a string using <tt/radix/ as the base. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>There are no provisions to prevent a buffer overflow. <item>The function is non standard, so it is not available in strict ANSI mode. You should probably use <tt/sprintf/ instead. @@ -7326,8 +7291,7 @@ used in presence of a prototype. <tag/Description/<tt/unlink/ deletes the file with the given name. On success, zero is returned. On error, -1 is returned and <tt/errno/ is set to an error code describing the reason for the failure. -<tag/Limits/ -<itemize> +<tag/Notes/<itemize> <item>The use of this function is discouraged. Please use <tt/<ref id="remove" name="remove">/ instead, which is a native ANSI C function and does the same. <item>This function is not available on all cc65 targets (depends on the @@ -7367,7 +7331,7 @@ if (unlink (FILENAME) == 0) { <tag/Declaration/<tt/char* __fastcall__ utoa (unsigned val, char* buf, int radix);/ <tag/Description/<tt/itoa/ converts the unsigned integer <tt/val/ into a string using <tt/radix/ as the base. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>There are no provisions to prevent a buffer overflow. <item>The function is non standard, so it is not available in strict ANSI mode. You should probably use <tt/sprintf/ instead. @@ -7397,7 +7361,7 @@ used in presence of a prototype. text where necessary and formatted according to the format string given. The resulting string is output to the console. <tt/vcprintf/ supports the same format specifiers as <tt/vprintf/. <!-- <tt/<ref id="vprintf" name="vprintf">/. --> -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>Like all other <tt/conio/ output functions, <tt/vcprintf/ distinguishes between <tt/\r/ and <tt/\n/. <item>The function is only available as fastcall function, so it may only be @@ -7426,7 +7390,7 @@ used in presence of a prototype. <tag/Description/Switch to 40 or 80 column mode depending on the argument. If the requested mode is already active, nothing happens. The old mode is returned from the call. -<tag/Limits/<itemize> +<tag/Notes/<itemize> <item>The function is specific to the C128 and enhanced Apple //e. <item>This function replaces <ref id="toggle_videomode" name="toggle_videomode">. diff --git a/doc/index.sgml b/doc/index.sgml index 7de8b26ce..921b8c03d 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -134,6 +134,9 @@ <tag><htmlurl url="nes.html" name="nes.html"></tag> Topics specific to the Nintendo Entertainment System. + <tag><htmlurl url="osi.html" name="osi.html"></tag> + Topics specific to the Ohio Scientific machines. + <tag><htmlurl url="pet.html" name="pet.html"></tag> Topics specific to the Commodore PET machines. diff --git a/doc/intro.sgml b/doc/intro.sgml index 02c5c83d5..d92fd1d20 100644 --- a/doc/intro.sgml +++ b/doc/intro.sgml @@ -6,8 +6,9 @@ <author> <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:cbmnut@hushmail.com" name="CbmNut">,<newline> -<url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2014-4-24 +<url url="mailto:greg.king5@verizon.net" name="Greg King">,<newline> +<url url="mailto:stephan.muehlstrasser@web.de" name="Stephan Mühlstrasser"> +<date>2015-03-07 <abstract> How to use the cc65 C language system -- an introduction. @@ -342,8 +343,8 @@ Available at <url url="http://code.google.com/p/oriculator/">: Emulates Oric-1 and Atmos computers, with sound, disk images, -scanline-exact NTSC/PAL video, and movie export. Includes monitor. -Fortunately for all SDL platforms. You will just need the emulator, all +scanline-exact NTSC/PAL video, and movie export. Includes a monitor. +Fortunately, for all SDL platforms. You will need just the emulator; all ROMs are supplied. Compile the tutorial with @@ -353,8 +354,11 @@ cl65 -O -t atmos hello.c text.s -o hello.tap </verb></tscreen> Start the emulator, choose <bf/F1/ and <bf/Insert tape.../, and point to -the "<bf/hello.tap/" executable. The file has an auto start header meant to -be loaded directly from tape. +the "<bf/hello.tap/" executable. After it has finished loading, type + +<tscreen><verb> +RUN +</verb></tscreen> On a real Atmos, you would need a tape drive. Turn on the computer, type @@ -363,7 +367,11 @@ Turn on the computer, type CLOAD"" </verb></tscreen> -at the BASIC prompt. +at the BASIC prompt. After it has finished loading, type + +<tscreen><verb> +RUN +</verb></tscreen> The emulation, also, supports that method. @@ -514,6 +522,127 @@ The output is shown in a GEOS dialog box; click <bf/OK/ when you have finished reading it. +<sect1>Ohio Scientific Challenger 1P<p> +The <tt/osic1p/ runtime library returns to the boot prompt when the main() +program exits. Therefore, the C file in the tutorial must be modified +slightly, in order to see the results on the screen. Otherwise, the program +would print the text string, and then jump to the boot prompt, making it +impossible to see the results of running the tutorial program. + +In addition to that, the <tt/osic1p/ target does not yet have support for stdio +functions. Only the functions from the conio library are available. + +Therefore, modify the "<tt/hello.c/" source file, as follows: + +<tscreen><code> +#include <conio.h> +#include <stdlib.h> + +extern const char text[]; /* In text.s */ + +int main (void) +{ + clrscr (); + cprintf ("%s\r\nPress <RETURN>.\r\n", text); + cgetc (); + return EXIT_SUCCESS; +} +</code></tscreen> + +Compile the tutorial with + +<tscreen><verb> +cl65 -O -t osic1p -u __BOOT__ -o hello.lod hello.c text.s +</verb></tscreen> + +The program is configured for a Challenger 1P computer with, at least, 32 kB +of RAM. See the <url url="osi.html" +name="Ohio Scientifc-specific documentation"> for instructions about how to +compile for other RAM sizes. + +Plug a cassette player into your C1P computer; or, connect an RS-232 cable +between your C1P and a PC (set the PC's serial port to 300 Bits Per Second, +8 data bits, No parity, and 2 stop bits). (Turn on the computers.) + +Tap the "<bf/BREAK/" key, to display the boot prompt; then, tap the "<tt/M/" +key, to enter the 65V PROM monitor. Tap the "<tt/L/" key. Either start the +cassette player (with a tape of the program), or start a transfer of the +program file "<tt/hello.lod/" from the PC. After a while, you should see the +following text on the screen: + +<tscreen><verb> +Hello world! +Press <RETURN>. +</verb></tscreen> + +(Stop the cassette player.) After hitting the RETURN key, you should see the +boot prompt again. + +<sect2>WinOSI<p> +Available at <url +url="http://osi.marks-lab.com/#Emulator">: + +Emulates the Ohio Scientific Challenger computers in different configurations. +Configure it to emulate a C1P (model 600 board) with 32 kB of RAM. + +Compile the tutorial with the same command that is used to make the program +for a real machine. + +Start the emulator. Tap the "<tt/M/" key, to enter the 65V PROM monitor; then, +tap the "<tt/L/" key. If you had configured WinOSI to ask for a file when it +starts to read data from the serial port, then you will see a file dialog box; +otherwise, you must tap your host keyboard's F10 function key. Select the file +"<tt/hello.lod/". After a moment, you should see the following text on the +screen: + +<tscreen><verb> +Hello world! +Press <RETURN>. +</verb></tscreen> + +After hitting the RETURN key, you should see the boot prompt again. + +<sect2>C1Pjs<p> +Available at <url +url="http://www.pcjs.org/docs/c1pjs/">: + +Emulates the Ohio Scientific Challenger 1P computer in different configurations. +The 32 kB RAM machine that must be used with the default compiler settings is +<url url="http://www.pcjs.org/devices/c1p/machine/32kb/" name="here">. + +In addition to cc65, the <bf/srec_cat/ program from <url +url="http://srecord.sourceforge.net/" name="the SRecord tool collection"> +must be installed. Some Linux distributions also provide srecord directly as +an installable package. + +Compile the tutorial with this command line: + +<tscreen><verb> +cl65 -O -t osic1p hello.c text.s +</verb></tscreen> + +Convert the binary file into a text file that can be loaded via +the Ohio Scientific 65V PROM monitor, at start address 0x200: + +<tscreen><verb> +srec_cat hello -binary -offset 0x200 -o hello.c1p -Ohio_Scientific -execution-start-address=0x200 +</verb></tscreen> + +Open the URL that points to the 32 kB machine; and, wait until the emulator +has been loaded. Click on the "<bf/BREAK/" button to display the boot prompt; +then, press the "<tt/M/" key to enter the 65V PROM monitor. Click the +"<bf/Browse.../" button; and, select the file "<tt/hello.c1p/" that was +created as the output of the above invocation of the "<tt/srec_cat/" command. +Press the "<bf/Load/" button. You should see the following text on the screen: + +<tscreen><verb> +Hello world! +Press <RETURN>. +</verb></tscreen> + +After hitting the RETURN key, you should see the boot prompt again. + + <sect1>Contributions wanted<p> We need your help! Recommended emulators and instructions for other targets diff --git a/doc/osi.sgml b/doc/osi.sgml new file mode 100644 index 000000000..ab1b4cee5 --- /dev/null +++ b/doc/osi.sgml @@ -0,0 +1,233 @@ +<!doctype linuxdoc system> + +<article> + +<title>Ohio Scientific-specific information for cc65 +<author> +<url url="mailto:stephan.muehlstrasser@web.de" name="Stephan Mühlstrasser">,<newline> +<url url="mailto:greg.king5@verizon.net" name="Greg King"> +<date>2015-03-17 + +<abstract> +An overview over the Ohio Scientific runtime system as it is implemented for the cc65 C +compiler. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + +This file contains an overview of the Ohio Scientific runtime system as it comes with the +cc65 C compiler. It describes the memory layout, Ohio Scientific-specific header files, +and any pitfalls specific to that platform. + +Please note that Ohio Scientific-specific functions are just mentioned here, they are +described in detail in the separate <url url="funcref.html" name="function +reference">. Even functions marked as "platform dependent" may be available on +more than one platform. Please see the function reference for more +information. + +<sect>Targets<p> + +Currently the target "osic1p" is implemented. This works for the Ohio Scientific +Challenger 1P machine and for the Briel Superboard /// replica. + +<sect>Program file formats<p> + +<descrip> + <tag/Binary, then text/ + The standard binary output format generated by the linker for the osic1p + target is a pure machine language program. + + For uploading into a real machine over its serial port or into an emulator, + that program must be converted into a text file that can be understood by + the 65V PROM monitor. For that purpose, the <bf/srec_cat/ program from <url + url="http://srecord.sourceforge.net/" name="the SRecord tool collection"> + can be used. + + Care must be taken that the <tt/-offset/ and <tt/-execution-start-address/ + options for the <bf/srec_cat/ program correspond to the start address + of the executable. + + Example for converting an executable "hello" file that was built for the + default start address $0200 to an uploadable file "hello.c1p": + + <tscreen><verb> + srec_cat hello -bin -of 0x200 -o hello.c1p -os -esa=0x200 + </verb></tscreen> + + <tag/Hybrid/ + The linker can create an alternate format that contains two parts: + <enum> + <item>A text header that is understood by the 65V PROM monitor. + It is a boot loader that reads the second part. + <item>The default binary code that is described above. + </enum> + + You can make the alternate format by adding the option <tt/-u __BOOT__/ to + <tt/cl65/'s or <tt/ld65/'s command lines. + + This format doesn't need to be converted. It is smaller than the text-only + format. But, it cannot be loaded by <url + url="http://www.pcjs.org/docs/c1pjs/" name="C1Pjs">; you must use the + SRecord-produced text-only format with that emulator. (However, if you know + that you never will use C1Pjs, then you can edit the + <tt>cfg/osic1p*.cfg</tt> files; uncomment the lines that import <tt/__BOOT__/. + Then, you won't need to use <tt/-u __BOOT__/ on your command lines.) + +</descrip> + +<sect>Memory layout<p> + +By default programs compiled for the osic1p target are configured for 32 kB RAM. +The RAM size can be configured via the symbol <tt/__HIMEM__/. + +Special locations: + +<descrip> + <tag/Program start address/ + The default start address is $0200. The start address is configurable + via the linker option <tt/--start-addr/. + + <tag/Stack/ + The C runtime stack is located at the top of RAM and growing downwards. + The size is configurable via the symbol <tt/__STACKSIZE__/. The default + stack size is $0400. + + <tag/Heap/ + The C heap is located at the end of the program and grows towards the C + runtime stack. + + <tag/Video RAM/ + The 1 kB video RAM is located at $D000. On the monitor, only a subset + of the available video RAM is visible. The address of the upper left corner + of the visible area is $D085 and corresponds to conio cursor + position (0, 0). + +</descrip><p> + +Example for building a program with start address $0300, stack size +$0200 and RAM size $2000: + +<tscreen><verb> +cl65 --start-addr 0x300 -Wl -D,__HIMEM__=$2000,-D,__STACKSIZE__=$0200 -t osic1p hello.c +</verb></tscreen> + +<sect>Linker configurations<p> + +The ld65 linker comes with a default config file "osic1p.cfg" for the Ohio Scientific +Challenger 1P, which is implicitly used via <tt/-t osic1p/. The +osic1p package comes with additional secondary linker config files, which are +used via <tt/-t osic1p -C <configfile>/. + +<sect1>Default config file (<tt/osic1p.cfg/)<p> + +The default configuration is tailored to C programs. + +<sect1><tt/osic1p-asm.cfg/<p> + +This configuration is made for assembler programmers who don't need a special +setup. + +To use this config file, assemble with <tt/-t osic1p/ and link with +<tt/-C osic1p-asm.cfg/. The former will make sure that correct runtime library +is used, while the latter supplies the actual config. When using <tt/cl65/, +use both command line options. + +Sample command lines for <tt/cl65/: + +<tscreen><verb> +cl65 -t osic1p -C osic1p-asm.cfg -o program source.s +cl65 -t osic1p -C osic1p-asm.cfg -u __BOOT__ -o program.lod source.s +</verb></tscreen> + +<sect>Platform-specific header files<p> + +Programs containing Ohio Scientific-specific code may use the <tt/osic1p.h/ +header file. + +<sect1>Ohio Scientific-specific functions<p> + +There are currently no special Ohio Scientific functions. + +<sect1>Hardware access<p> + +There is no specific support for direct hardware access. + +<sect>Loadable drivers<p> + +There are no loadable drivers available. + +<sect>Support for different screen layouts<p> + +By default the conio library uses a 24 columns by 24 lines screen layout +for the Challenger 1P, like under BASIC. In addition to that there is support +for other screen layouts with extra modules. + +There is a module <tt/screen-c1p-24x24.o/ in the OSI-specific +cc65 runtime library that contains all conio functions that depend +on the screen layout. No further configuration is needed for using the +default screen layout of the Challenger 1P. + +For other screen layouts additional versions of the screen module are +available. The linker finds these modules without further configuration +if they are specified on the compiler or linker command line. The +extra module then overrides the default module. + +Sample <tt/cl65/ command line to override the default screen +module with the module <tt/osic1p-screen-s3-32x28.o/: + +<tscreen><verb> +cl65 -o hello -t osic1p osic1p-screen-s3-32x28.o hello.c +</verb></tscreen> + +Currently the following extra screen configuration modules are implemented: + +<itemize> +<item><tt>osic1p-screen-s3-32x28.o</tt>: 32 columns by 28 lines mode +for Briel Superboard ///</item> +</itemize> + +<sect>Limitations<p> + +<sect1>stdio implementation<p> + +There is no support for stdio at the moment. + +<sect>Other hints<p> + +<sect1>Passing arguments to the program<p> + +There is currently no support for passing arguments to a program. + +<sect1>Program return code<p> + +The program return code currently has no effect. When the main() function +finishes, the boot prompt is shown again. + +<sect>License<p> + +This software is provided 'as-is', without any expressed or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +<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. +</enum> + +</article> + diff --git a/include/ace.h b/include/ace.h index 8d9130085..fba672227 100644 --- a/include/ace.h +++ b/include/ace.h @@ -2,14 +2,14 @@ /* */ /* ace.h */ /* */ -/* ACE system specific definitions */ +/* ACE system-specific definitions */ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2015, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -61,9 +61,9 @@ struct aceDirentBuf { char ad_name [17]; /* Name itself, ASCIIZ */ }; -int aceDirOpen (char* dir); -int aceDirClose (int handle); -int aceDirRead (int handle, struct aceDirentBuf* buf); +int __cdecl__ aceDirOpen (char* dir); +int __cdecl__ aceDirClose (int handle); +int __cdecl__ aceDirRead (int handle, struct aceDirentBuf* buf); /* Type of an ACE key. Key in low byte, shift mask in high byte */ typedef unsigned int aceKey; @@ -92,23 +92,23 @@ typedef unsigned int aceKey; #define aceOP_RPTRATE 11 /* Key repeat rate */ /* Console functions */ -void aceConWrite (char* buf, size_t count); -void aceConPutLit (int c); -void aceConPos (unsigned x, unsigned y); -void aceConGetPos (unsigned* x, unsigned* y); +void __cdecl__ aceConWrite (char* buf, size_t count); +void __cdecl__ aceConPutLit (int c); +void __cdecl__ aceConPos (unsigned x, unsigned y); +void __cdecl__ aceConGetPos (unsigned* x, unsigned* y); unsigned aceConGetX (void); unsigned aceConGetY (void); -char* aceConInput (char* buf, unsigned initial); +char __cdecl__* aceConInput (char* buf, unsigned initial); int aceConStopKey (void); aceKey aceConGetKey (void); -int aceConKeyAvail (aceKey* key); -void aceConKeyMat (char* matrix); -void aceConSetOpt (unsigned char opt, unsigned char val); -int aceConGetOpt (unsigned char opt); +int __cdecl__ aceConKeyAvail (aceKey* key); +void __cdecl__ aceConKeyMat (char* matrix); +void __cdecl__ aceConSetOpt (unsigned char opt, unsigned char val); +int __cdecl__ aceConGetOpt (unsigned char opt); /* Misc stuff */ -int aceMiscIoPeek (unsigned addr); -void aceMiscIoPoke (unsigned addr, unsigned char val); +int __cdecl__ aceMiscIoPeek (unsigned addr); +void __cdecl__ aceMiscIoPoke (unsigned addr, unsigned char val); diff --git a/include/assert.h b/include/assert.h index 87bc4ff02..504964dc2 100644 --- a/include/assert.h +++ b/include/assert.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2015, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -42,7 +42,7 @@ #ifdef NDEBUG # define assert(expr) #else -extern void _afailed (const char*, unsigned); +extern void __fastcall__ _afailed (const char*, unsigned); # define assert(expr) ((expr)? (void)0 : _afailed(__FILE__, __LINE__)) #endif diff --git a/include/cbm.h b/include/cbm.h index 730b0b49e..701924d57 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -222,7 +222,7 @@ void cbm_k_unlsn (void); -unsigned int cbm_load (const char* name, unsigned char device, void* data); +unsigned int __fastcall__ cbm_load (const char* name, unsigned char device, void* data); /* Loads file "name", from given device, to given address -- or, to the load ** address of the file if "data" is the null pointer (like load"name",8,1 ** in BASIC). diff --git a/include/conio.h b/include/conio.h index f8a880c77..8638e94d4 100644 --- a/include/conio.h +++ b/include/conio.h @@ -77,6 +77,8 @@ # include <lynx.h> #elif defined(__NES__) # include <nes.h> +#elif defined(__OSIC1P__) +# include <osic1p.h> #elif defined(__PCE__) # include <pce.h> #endif diff --git a/include/dbg.h b/include/dbg.h index 734ca06b8..7b4f67e31 100644 --- a/include/dbg.h +++ b/include/dbg.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2000, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -88,7 +88,7 @@ unsigned __fastcall__ DbgDisAsmLen (unsigned Addr); int __fastcall__ DbgIsRAM (unsigned Addr); /* Return true if we can read and write the given address */ -char* DbgMemDump (unsigned Addr, char* Buf, unsigned char Len); +char* __cdecl__ DbgMemDump (unsigned Addr, char* Buf, unsigned char Len); /* Create a line of a memory dump in the given buffer. The buffer contains ** the starting address (4 digits hex), then Len bytes in this format: ** "AAAA__XX_YY_ZZ_...". The passed char buffer must hold Len*3+5 bytes diff --git a/include/lynx.h b/include/lynx.h index e9c702994..72f3d5bfd 100644 --- a/include/lynx.h +++ b/include/lynx.h @@ -2,7 +2,7 @@ /* */ /* lynx.h */ /* */ -/* Lynx system specific definitions */ +/* Lynx system-specific definitions */ /* */ /* */ /* */ @@ -109,25 +109,25 @@ extern void lynx_160_102_16_tgi[]; /* Referred to by tgi_static_stddrv[] */ /* Sound support */ /*****************************************************************************/ -void lynx_snd_init (); +void lynx_snd_init (void); /* Initialize the sound driver */ -void lynx_snd_pause (); +void lynx_snd_pause (void); /* Pause sound */ -void lynx_snd_continue (); +void lynx_snd_continue (void); /* Continue sound after pause */ void __fastcall__ lynx_snd_play (unsigned char channel, unsigned char *music); /* Play tune on channel */ -void lynx_snd_stop (); +void lynx_snd_stop (void); /* Stop sound on all channels */ void __fastcall__ lynx_snd_stop_channel (unsigned char channel); /* Stop sound on all channels */ -unsigned char lynx_snd_active(); +unsigned char lynx_snd_active(void); /* Show which channels are active */ /*****************************************************************************/ diff --git a/include/osic1p.h b/include/osic1p.h new file mode 100644 index 000000000..57fe0cd24 --- /dev/null +++ b/include/osic1p.h @@ -0,0 +1,47 @@ +/*****************************************************************************/ +/* */ +/* osic1p.h */ +/* */ +/* Challenger 1P system specific definitions */ +/* */ +/* */ +/* */ +/* (C) 2015 Stephan Muehlstrasser */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + +#ifndef _OSIC1P_H +#define _OSIC1P_H + +/* Check for errors */ +#if !defined(__OSIC1P__) +# error "This module may only be used when compiling for the Challenger 1P!" +#endif + +/* The following #defines will cause the matching functions calls in conio.h +** to be overlaid by macros with the same names, saving the function call +** overhead. +*/ +#define _textcolor(color) COLOR_WHITE +#define _bgcolor(color) COLOR_BLACK +#define _bordercolor(color) COLOR_BLACK + +#endif diff --git a/include/stdlib.h b/include/stdlib.h index eac5629a8..3103172d8 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -107,12 +107,12 @@ int __fastcall__ atoi (const char* s); long __fastcall__ atol (const char* s); int __fastcall__ atexit (void (*exitfunc) (void)); void* __fastcall__ bsearch (const void* key, const void* base, size_t n, - size_t size, int (*cmp) (const void*, const void*)); + size_t size, int __fastcall__ (* cmp) (const void*, const void*)); div_t __fastcall__ div (int numer, int denom); void __fastcall__ exit (int ret) __attribute__ ((noreturn)); char* __fastcall__ getenv (const char* name); void __fastcall__ qsort (void* base, size_t count, size_t size, - int (*compare) (const void*, const void*)); + int __fastcall__ (* compare) (const void*, const void*)); long __fastcall__ strtol (const char* nptr, char** endptr, int base); unsigned long __fastcall__ strtoul (const char* nptr, char** endptr, int base); int __fastcall__ system (const char* s); diff --git a/include/zlib.h b/include/zlib.h index 9bc5dcb27..8fa6a2bd1 100644 --- a/include/zlib.h +++ b/include/zlib.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2001 Piotr Fusik <fox@scene.pl> */ +/* (C) 2000-2015 Piotr Fusik <fox@scene.pl> */ /* */ /* This file is based on the zlib.h from 'zlib' general purpose compression */ /* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */ @@ -83,8 +83,8 @@ unsigned __fastcall__ inflatemem (char* dest, const char* source); */ -int uncompress (char* dest, unsigned* destLen, - const char* source, unsigned sourceLen); +int __fastcall__ uncompress (char* dest, unsigned* destLen, + const char* source, unsigned sourceLen); /* Original zlib description: diff --git a/libsrc/Makefile b/libsrc/Makefile index dc944ee05..d70ad5a31 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -24,6 +24,7 @@ TARGETS = apple2 \ $(GEOS) \ lynx \ nes \ + osic1p \ pce \ sim6502 \ sim65c02 \ diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 4a7463b27..445039b1e 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -46,9 +46,9 @@ sta $94 sty $95 - ; Call into the Applesoft Block Transfer Utility -- which handles zero- + ; Call into Applesoft Block Transfer Up -- which handles zero- ; sized blocks well -- to move the content of the LC memory area. - jsr $D396 ; BLTU + 3 + jsr $D39A ; BLTU2 ; Set the source start address. lda #<__ZPSAVE_RUN__ @@ -68,9 +68,9 @@ sta $94 sty $95 - ; Call into the Applesoft Block Transfer Utility -- which handles moving + ; Call into Applesoft Block Transfer Up -- which handles moving ; overlapping blocks upwards well -- to move the INIT segment. - jsr $D396 ; BLTU + 3 + jsr $D39A ; BLTU2 ; Delegate all further processing, to keep the STARTUP segment small. jsr init @@ -164,10 +164,6 @@ basic: lda HIMEM : sta sp stx sp+1 - ; Enable interrupts, as old ProDOS versions (i.e. 1.1.1) - ; jump to SYS and BIN programs with interrupts disabled. - cli - ; Call the module constructors. jsr initlib diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index c486306bb..d24de604c 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -23,11 +23,29 @@ oserr: jsr popname ; Preserves A jmp __mappederrno _exec: + ; Save cmdline + sta ptr4 + stx ptr4+1 + ; Get and push name jsr popax jsr pushname bne oserr + ; ProDOS TechRefMan, chapter 5.1.5.1: + ; "The complete or partial pathname of the system program + ; is stored at $280, starting with a length byte." + ; In fact BASIC.SYSTEM does the same for BLOAD and BRUN of + ; binary programs so we should do the same too in any case + ; especially as _we_ rely on it in mainargs.s for argv[0] + ldy #$00 + lda (sp),y + tay +: lda (sp),y + sta $0280,y + dey + bpl :- + ; Set pushed name lda sp ldx sp+1 @@ -52,24 +70,14 @@ _exec: lda mliparam + MLI::INFO::FILE_TYPE cmp #$FF ; SYS file? bne binary ; No, check for BIN file + sta file_type ; Save file type for cmdline handling - ; ProDOS TechRefMan, chapter 5.1.5.1: - ; "The complete or partial pathname of the system program - ; is stored at $280, starting with a length byte." - ldy #$00 - lda (sp),y - tay -: lda (sp),y - sta $0280,y - dey - bpl :- - ; SYS programs replace BASIC.SYSTEM so set in the ProDOS system bit map ; protection for pages $80 - $BF just in case BASIC.SYSTEM is there now ldx #$0F ; Start with protection for pages $B8 - $BF lda #%00000001 ; Protect only system global page : sta $BF60,x ; Set protection for 8 pages - lda #$00 ; Protect no page + lda #%00000000 ; Protect no page dex bpl :- bmi prodos ; Branch always @@ -112,7 +120,7 @@ setbuf: lda #$00 ; Low byte dex dex dex - + ; Set I/O buffer sta mliparam + MLI::OPEN::IO_BUFFER stx mliparam + MLI::OPEN::IO_BUFFER+1 @@ -126,7 +134,7 @@ setbuf: lda #$00 ; Low byte stx level beq :+ dec LEVEL - + ; Open file : lda #OPEN_CALL ldx #OPEN_COUNT @@ -158,8 +166,27 @@ setbuf: lda #$00 ; Low byte bit $C080 .endif + ; Reset stack as we already passed + ; the point of no return anyway + ldx #$FF + txs + + ; Store up to 127 chars of cmdline (if any) + ; including terminating zero in stack page + ldy #$00 + lda ptr4+1 ; NULL? + beq :++ ; Yes, store as '\0' +: lda (ptr4),y +: sta $0100,y + beq :+ ; '\0' stored, done + iny + cpy #$7E + bcc :-- + lda #$00 ; '\0' + beq :- ; Branch always + ; Call loader stub after C libary shutdown - lda #<target +: lda #<target ldx #>target sta done+1 stx done+2 @@ -177,16 +204,58 @@ level : .res 1 source: jsr $BF00 .byte READ_CALL .word read_param - bcs :+ + bcs error ; Close program file jsr $BF00 .byte CLOSE_CALL .word close_param - bcs :+ + bcs error + + ; Check for cmdline handling + lda $0100 ; Valid cmdline? + beq jump ; No, jump to program right away + ldx file_type ; SYS file? + bne system ; Yes, check for startup filename + + ; Store REM and cmdline in BASIC input buffer + lda #$B2 ; REM token + bne :++ ; Branch always +: inx + lda a:$0100-1,x +: sta $0200,x + bne :-- + beq jump ; Branch always + + ; Check for startup filename support + ; ProDOS TechRefMan, chapter 5.1.5.1: + ; "$2000 is a jump instruction. $2003 and $2004 are $EE." +system: lda $2000 + cmp #$4C + bne jump + lda $2003 + cmp #$EE + bne jump + lda $2004 + cmp #$EE + bne jump + + ; Store cmdline in startup filename buffer + ldx #$01 +: lda a:$0100-1,x + beq :+ + sta $2006,x + inx + cpx $2005 ; Buffer full? + bcc :- ; No, continue +: dex + stx $2006 ; Store cmdline length ; Go for it ... - jmp (data_buffer) +jump: jmp (data_buffer) + +file_type = * - source + target + .byte $00 read_param = * - source + target .byte $04 ; PARAM_COUNT @@ -204,7 +273,7 @@ close_ref = * - source + target ; Quit to ProDOS dispatcher quit = * - source + target -: jsr $BF00 +error: jsr $BF00 .byte $65 ; QUIT .word quit_param diff --git a/libsrc/apple2/irq.s b/libsrc/apple2/irq.s index c81fa7108..0b0555695 100644 --- a/libsrc/apple2/irq.s +++ b/libsrc/apple2/irq.s @@ -21,6 +21,10 @@ initirq: .byte $40 ; Alloc interrupt .addr i_param bcs prterr + + ; Enable interrupts, as old ProDOS versions (i.e. 1.1.1) + ; jump to SYS and BIN programs with interrupts disabled. + cli rts ; Print error message and exit diff --git a/libsrc/apple2/mainargs.s b/libsrc/apple2/mainargs.s index 6b0df4ded..2e809dc56 100644 --- a/libsrc/apple2/mainargs.s +++ b/libsrc/apple2/mainargs.s @@ -34,12 +34,12 @@ MAXARGS = 10 ; ProDOS stores the filename in the second half of BASIC's input buffer, so -; there are 128 characters left. At least 7 characters are necessary for the -; CALLxxxx:REM so 121 characters may be used before overwriting the ProDOS -; filename. As we don't want to put further restrictions on the command-line -; length we reserve those 121 characters terminated by a zero. +; there are 128 characters left. At least 1 character is necessary for the +; REM so 127 characters (including the terminating zero) may be used before +; overwriting the ProDOS filename. As we don't want to further restrict the +; command-line length we reserve those 127 characters. -BUF_LEN = 122 +BUF_LEN = 127 BASIC_BUF = $200 FNAM_LEN = $280 @@ -176,4 +176,4 @@ argv: .addr FNAM .bss -buffer: .res BUF_LEN \ No newline at end of file +buffer: .res BUF_LEN diff --git a/libsrc/apple2/targetutil/loader.s b/libsrc/apple2/targetutil/loader.s index 0173f6105..a6cc13cef 100644 --- a/libsrc/apple2/targetutil/loader.s +++ b/libsrc/apple2/targetutil/loader.s @@ -22,14 +22,14 @@ READ_CALL = $CA CLOSE_CALL = $CC FILE_NOT_FOUND_ERR = $46 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ------------------------------------------------------------------------ .import __CODE_0300_SIZE__, __DATA_0300_SIZE__ .import __CODE_0300_LOAD__, __CODE_0300_RUN__ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ------------------------------------------------------------------------ -.segment "DATA_2000" + .segment "DATA_2000" GET_FILE_INFO_PARAM: .byte $0A ;PARAM_COUNT @@ -57,9 +57,9 @@ LOADING: ELLIPSES: .byte " ...", $0D, $0D, $00 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ------------------------------------------------------------------------ -.segment "DATA_0300" + .segment "DATA_0300" READ_PARAM: .byte $04 ;PARAM_COUNT @@ -81,22 +81,22 @@ QUIT_PARAM: FILE_NOT_FOUND: .asciiz "... File Not Found" - + ERROR_NUMBER: .asciiz "... Error $" PRESS_ANY_KEY: .asciiz " - Press Any Key " -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ------------------------------------------------------------------------ -.segment "CODE_2000" + .segment "CODE_2000" jmp :+ .byte $EE .byte $EE - .byte 65 -STARTUP:.res 65 + .byte $7F +STARTUP:.res $7F ; Reset stack : ldx #$FF @@ -104,8 +104,8 @@ STARTUP:.res 65 ; Relocate CODE_0300 and DATA_0300 ldx #<(__CODE_0300_SIZE__ + __DATA_0300_SIZE__) -: lda __CODE_0300_LOAD__ - 1,x - sta __CODE_0300_RUN__ - 1,x +: lda __CODE_0300_LOAD__-1,x + sta __CODE_0300_RUN__-1,x dex bne :- @@ -118,23 +118,23 @@ STARTUP:.res 65 ; Add trailing '\0' to pathname tax lda #$00 - sta PATHNAME + 1,x + sta PATHNAME+1,x ; Copy ProDOS startup filename and trailing '\0' to stack ldx STARTUP lda #$00 - beq :++ ; bra -: lda STARTUP + 1,x + beq :++ ; Branch always +: lda STARTUP+1,x : sta STACK,x dex - bpl :-- + bpl :-- ; Provide some user feedback lda #<LOADING ldx #>LOADING jsr PRINT - lda #<(PATHNAME + 1) - ldx #>(PATHNAME + 1) + lda #<(PATHNAME+1) + ldx #>(PATHNAME+1) jsr PRINT lda #<ELLIPSES ldx #>ELLIPSES @@ -159,16 +159,16 @@ STARTUP:.res 65 ; Get load address from aux-type lda FILE_INFO_ADDR - ldx FILE_INFO_ADDR + 1 + ldx FILE_INFO_ADDR+1 sta READ_ADDR - stx READ_ADDR + 1 + stx READ_ADDR+1 ; It's high time to leave this place jmp __CODE_0300_RUN__ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ------------------------------------------------------------------------ -.segment "CODE_0300" + .segment "CODE_0300" jsr MLI .byte READ_CALL @@ -180,15 +180,15 @@ STARTUP:.res 65 .word CLOSE_PARAM bcs ERROR - ; Copy REM token and startup filename to BASIC input buffer + ; Copy REM and startup filename to BASIC input buffer ldx #$00 - lda #$B2 - bne :++ ; bra + lda #$B2 ; REM token + bne :++ ; Branch always : inx - lda a:STACK - 1,x + lda a:STACK-1,x : sta BUF,x bne :-- - + ; Go for it ... jmp (READ_ADDR) @@ -207,7 +207,7 @@ PRINT: : ora #$80 jsr COUT iny - bne :-- ; bra + bne :-- ; Branch always : rts ERROR: @@ -216,7 +216,7 @@ ERROR: lda #<FILE_NOT_FOUND ldx #>FILE_NOT_FOUND jsr PRINT - beq :++ ; bra + beq :++ ; Branch always : pha lda #<ERROR_NUMBER ldx #>ERROR_NUMBER @@ -230,5 +230,3 @@ ERROR: jsr MLI .byte QUIT_CALL .word QUIT_PARAM - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/libsrc/atmos/bashdr.s b/libsrc/atmos/bashdr.s new file mode 100644 index 000000000..e09bc9fec --- /dev/null +++ b/libsrc/atmos/bashdr.s @@ -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: diff --git a/libsrc/atmos/crt0.s b/libsrc/atmos/crt0.s index 1d919f348..e789b28c2 100644 --- a/libsrc/atmos/crt0.s +++ b/libsrc/atmos/crt0.s @@ -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 ; ------------------------------------------------------------------------ diff --git a/libsrc/atmos/tapehdr.s b/libsrc/atmos/tapehdr.s new file mode 100644 index 000000000..d90c908eb --- /dev/null +++ b/libsrc/atmos/tapehdr.s @@ -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) diff --git a/libsrc/cbm/cbm_load.c b/libsrc/cbm/cbm_load.c index 695af504b..c1c6f568a 100644 --- a/libsrc/cbm/cbm_load.c +++ b/libsrc/cbm/cbm_load.c @@ -1,9 +1,9 @@ /* ** Marc 'BlackJack' Rintsch, 06.03.2001 ** -** unsigned int cbm_load(const char* name, -** unsigned char device, -** const unsigned char* data); +** unsigned int __fastcall__ cbm_load(const char* name, +** unsigned char device, +** const unsigned char* data); */ #include <cbm.h> @@ -11,7 +11,7 @@ /* loads file "name" from given device to given address or to the load address ** of the file if "data" is 0 */ -unsigned int cbm_load(const char* name, unsigned char device, void* data) +unsigned int __fastcall__ cbm_load(const char* name, unsigned char device, void* data) { /* LFN is set to 0; but, it's not needed for loading ** (BASIC V2 sets it to the value of the SA for LOAD). diff --git a/libsrc/common/_afailed.c b/libsrc/common/_afailed.c index 4e56b93f2..7c6df4a2c 100644 --- a/libsrc/common/_afailed.c +++ b/libsrc/common/_afailed.c @@ -1,7 +1,8 @@ /* ** _afailed.c ** -** Ullrich von Bassewitz, 06.06.1998 +** 1998-06-06, Ullrich von Bassewitz +** 2015-03-13, Greg King */ @@ -11,7 +12,7 @@ -void _afailed (char* file, unsigned line) +void __fastcall__ _afailed (char* file, unsigned line) { fprintf (stderr, "ASSERTION FAILED IN %s(%u)\n", file, line); exit (2); diff --git a/libsrc/common/_printf.h b/libsrc/common/_printf.h index ffb2443bd..7914fa870 100644 --- a/libsrc/common/_printf.h +++ b/libsrc/common/_printf.h @@ -16,7 +16,7 @@ struct outdesc; /* Type of the function that is called to output data */ -typedef void (*outfunc) (struct outdesc* desc, const char* buf, unsigned count); +typedef void __cdecl__ (* outfunc) (struct outdesc* desc, const char* buf, unsigned count); diff --git a/libsrc/common/bsearch.c b/libsrc/common/bsearch.c index f6d32a5b5..aafd28592 100644 --- a/libsrc/common/bsearch.c +++ b/libsrc/common/bsearch.c @@ -1,7 +1,8 @@ /* ** bsearch.c ** -** Ullrich von Bassewitz, 17.06.1998 +** 1998-06-17, Ullrich von Bassewitz +** 2015-06-21, Greg King */ @@ -11,7 +12,7 @@ void* __fastcall__ bsearch (const void* key, const void* base, size_t n, - size_t size, int (*cmp) (const void*, const void*)) + size_t size, int __fastcall__ (* cmp) (const void*, const void*)) { int current; int result; diff --git a/libsrc/common/qsort.c b/libsrc/common/qsort.c index df02095ed..991db3ba1 100644 --- a/libsrc/common/qsort.c +++ b/libsrc/common/qsort.c @@ -1,7 +1,8 @@ /* ** qsort.c ** -** Ullrich von Bassewitz, 09.12.1998 +** 1998.12.09, Ullrich von Bassewitz +** 2015-06-21, Greg King */ @@ -12,7 +13,7 @@ static void QuickSort (register unsigned char* Base, int Lo, int Hi, register size_t Size, - int (*Compare)(const void*, const void*)) + int __fastcall__ (* Compare) (const void*, const void*)) /* Internal recursive function. Works with ints, but this shouldn't be ** a problem. */ @@ -52,7 +53,7 @@ static void QuickSort (register unsigned char* Base, int Lo, int Hi, void __fastcall__ qsort (void* base, size_t nmemb, size_t size, - int (*compare)(const void*, const void*)) + int __fastcall__ (* compare) (const void*, const void*)) /* Quicksort implementation */ { if (nmemb > 1) { diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s index 9812f661b..1225bcc47 100644 --- a/libsrc/common/vfprintf.s +++ b/libsrc/common/vfprintf.s @@ -33,7 +33,7 @@ ptr: .res 2 ; Points to output file ; can ignore the passed pointer d, and access the data directly. While this ; is not very clean, it gives better and shorter code. ; -; static void out (struct outdesc* d, const char* buf, unsigned count) +; static void cdecl out (struct outdesc* d, const char* buf, unsigned count) ; /* Routine used for writing */ ; { ; register size_t cnt; @@ -56,7 +56,7 @@ out: ldy #5 ldy #7 jsr pushwysp ; Push count lda ptr - ldx ptr+1 + ldx ptr+1 jsr _fwrite sta ptr1 ; Save function result stx ptr1+1 diff --git a/libsrc/common/vsnprintf.s b/libsrc/common/vsnprintf.s index db82bdaf3..a8ed50e06 100644 --- a/libsrc/common/vsnprintf.s +++ b/libsrc/common/vsnprintf.s @@ -1,5 +1,5 @@ ; -; int vsnprintf (char* Buf, size_t size, const char* Format, va_list ap); +; int __fastcall__ vsnprintf (char* Buf, size_t size, const char* Format, va_list ap); ; ; Ullrich von Bassewitz, 2009-09-26 ; @@ -130,7 +130,7 @@ L9: pla ; ---------------------------------------------------------------------------- ; Callback routine used for the actual output. ; -; static void out (struct outdesc* d, const char* buf, unsigned count) +; static void __cdecl__ out (struct outdesc* d, const char* buf, unsigned count) ; /* Routine used for writing */ ; ; Since we know, we're called with a pointer to our static outdesc structure, diff --git a/libsrc/dbg/dbgdump.s b/libsrc/dbg/dbgdump.s index b2045872f..8ab646d21 100644 --- a/libsrc/dbg/dbgdump.s +++ b/libsrc/dbg/dbgdump.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 11.08.1998 ; -; char* DbgMemDump (unsigend Addr, char* Buf, unsigned char Length); +; char* __cdecl__ DbgMemDump (unsigend Addr, char* Buf, unsigned char Length); ; .export _DbgMemDump diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s new file mode 100644 index 000000000..2a501b980 --- /dev/null +++ b/libsrc/osic1p/bootstrap.s @@ -0,0 +1,153 @@ +; +; 2015-03-08, Greg King +; + +; When you want to create a program with the alternate file format, +; add "-u __BOOT__" to the cl65/ld65 command line. Then, the linker +; will import this symbol name; and, link this module at the front +; of your program file. +; + .export __BOOT__:abs = 1 + + .import __RAM_START__, __RAM_SIZE__, __BSS_RUN__ + +; ------------------------------------------------------------------------ + +load_addr := __RAM_START__ +load_size = __BSS_RUN__ - __RAM_START__ +ram_top := __RAM_START__ + __RAM_SIZE__ + + .segment "BOOT" + +; If you want to change how this bootstrap loader works, then: +; 1. edit this assembly source code, +; 2. define the constant ASM (uncomment the line below), +; 3. assemble this file (and, make a listing of that assembly), +; 4. copy the listing's hex codes into the .byte lines below (notice that most +; of the strings are followed by CR; it's required by the OS65V monitor) +; (be sure to match the listing's lines against the .byte lines), +; 5. undefine ASM (recomment the line), +; 6. assemble this file, again, +; 7. and, add the object file to "osic1p.lib". + +;ASM = 1 + +.ifdef ASM + + .include "osic1p.inc" + .macpack generic + +load := $08 ; private variables +count := $0A + +GETCHAR := $FFBF ; gets one character from ACIA + +FIRSTVISC = $85 ; Offset of first visible character in video RAM +LINEDIST = $20 ; Offset in video RAM between two lines + + ldy #<$0000 + lda #<load_addr + ldx #>load_addr + sta load + stx load+1 + lda #<load_size + eor #$FF + sta count ; store (-size - 1) + lda #>load_size + eor #$FF + sta count+1 + +L1: inc count ; pre-count one's-complement upwards + bnz L2 + inc count+1 + bze L3 +L2: jsr GETCHAR ; (doesn't change .Y) + sta (load),y + +; Show that the file is being loaded by rotating an arrow on the screen. +; + tya + lsr a + lsr a + and #8 - 1 + ora #$10 ; eight arrow characters + sta SCRNBASE + FIRSTVISC + 2 * LINEDIST + 11 + + iny + bnz L1 + inc load+1 + bnz L1 ; branch always + +L3: jmp load_addr + +.else + +.mac hex1 h + .lobytes ((h) & $0F) + (((h) & $0F) > 9) * 7 + '0' +.endmac + +.mac hex2 h + hex1 (h) >> 4 + hex1 (h) >> 0 +.endmac + +.mac hex4 h + hex2 >(h) + hex2 <(h) +.endmac + +CR = $0D + + .byte CR, CR + .byte "." ; set an address + hex4 ram_top ; put loader where stack will sit + .byte "/" ; write bytes into RAM + +; ASCII-coded hexadecimal translation of the above assembly code. +; It was copied from the assembler listing. + + .byte "A0", CR, "00", CR + .byte "A9", CR + hex2 <load_addr + .byte CR, "A2", CR + hex2 >load_addr + .byte CR, "85", CR, "08", CR + .byte "86", CR, "09", CR + .byte "A9", CR + hex2 <load_size + .byte CR, "49", CR, "FF", CR + .byte "85", CR, "0A", CR + .byte "A9", CR + hex2 >load_size + .byte CR, "49", CR, "FF", CR + .byte "85", CR, "0B", CR + + .byte "E6", CR, "0A", CR + .byte "D0", CR, "04", CR + .byte "E6", CR, "0B", CR + .byte "F0", CR, "16", CR + .byte "20", CR, "BF", CR, "FF", CR + .byte "91", CR, "08", CR + + .byte "98", CR + .byte "4A", CR + .byte "4A", CR + .byte "29", CR, "07", CR + .byte "09", CR, "10", CR + .byte "8D", CR, "D0", CR, "D0", CR + + .byte "C8", CR + .byte "D0", CR, "E6", CR + .byte "E6", CR, "09", CR + .byte "D0", CR, "E2", CR + + .byte "4C", CR + hex2 <load_addr + .byte CR + hex2 >load_addr + + .byte CR, "." + hex4 ram_top + .byte "G" ; go to address + +.endif diff --git a/libsrc/osic1p/cclear.s b/libsrc/osic1p/cclear.s new file mode 100644 index 000000000..2036c38e0 --- /dev/null +++ b/libsrc/osic1p/cclear.s @@ -0,0 +1,29 @@ +; +; Copied from CBM implementation +; +; originally by: +; Ullrich von Bassewitz, 08.08.1998 +; +; void cclearxy (unsigned char x, unsigned char y, unsigned char length); +; void cclear (unsigned char length); +; + + .export _cclearxy, _cclear + .import popa, _gotoxy, cputdirect + .importzp tmp1 + +_cclearxy: + pha ; Save the length + jsr popa ; Get y + jsr _gotoxy ; Call this one, will pop params + pla ; Restore the length and run into _cclear + +_cclear: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda #' ' + jsr cputdirect ; Direct output + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s new file mode 100644 index 000000000..0c7c69488 --- /dev/null +++ b/libsrc/osic1p/cgetc.s @@ -0,0 +1,48 @@ +; +; char cgetc (void); +; + + .constructor initcgetc + .export _cgetc + .import cursor + + .include "osic1p.inc" + .include "extzp.inc" + .include "zeropage.inc" + +; Initialize one-character buffer that is filled by kbhit() +initcgetc: + lda #$00 + sta CHARBUF ; No character in buffer initially + rts + +; Input routine from 65V PROM MONITOR, show cursor if enabled +_cgetc: + lda CHARBUF ; character in buffer available? + beq nobuffer + tax ; save character in X + lda #$00 + sta CHARBUF ; empty buffer + beq restorex ; restore X and return +nobuffer: + lda cursor ; show cursor? + beq nocursor + ldy CURS_X + lda (SCREEN_PTR),y ; fetch current character + sta tmp1 ; save it + lda #$A1 ; full white square + sta (SCREEN_PTR),y ; store at cursor position +nocursor: + jsr INPUTC ; get input character in A + ldx cursor + beq done ; was cursor on? + tax ; save A in X + lda tmp1 ; fetch saved character + ldy CURS_X + sta (SCREEN_PTR),y ; store at cursor position + +restorex: + txa ; restore saved character from X +done: + ldx #$00 ; high byte of int return value + rts diff --git a/libsrc/osic1p/chline.s b/libsrc/osic1p/chline.s new file mode 100644 index 000000000..be40d40af --- /dev/null +++ b/libsrc/osic1p/chline.s @@ -0,0 +1,29 @@ +; +; based on CBM implementation +; +; originally by: +; Ullrich von Bassewitz, 08.08.1998 +; +; void chlinexy (unsigned char x, unsigned char y, unsigned char length); +; void chline (unsigned char length); +; + + .export _chlinexy, _chline + .import popa, _gotoxy, cputdirect + .importzp tmp1 + +_chlinexy: + pha ; Save the length + jsr popa ; Get y + jsr _gotoxy ; Call this one, will pop params + pla ; Restore the length + +_chline: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda #$94 ; Horizontal line, screen code + jsr cputdirect ; Direct output + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/osic1p/crt0.s b/libsrc/osic1p/crt0.s new file mode 100644 index 000000000..62342c206 --- /dev/null +++ b/libsrc/osic1p/crt0.s @@ -0,0 +1,55 @@ +; --------------------------------------------------------------------------- +; crt0.s +; --------------------------------------------------------------------------- +; +; Startup code for Ohio Scientific Challenger 1P + +.export _init, _exit +.import _main + +.export __STARTUP__ : absolute = 1 ; Mark as startup +.import __RAM_START__, __RAM_SIZE__ ; Linker generated +.import __STACKSIZE__ + +.import zerobss, initlib, donelib + +.include "zeropage.inc" +.include "extzp.inc" +.include "osic1p.inc" + +; --------------------------------------------------------------------------- +; Place the startup code in a special segment + +.segment "STARTUP" + +; --------------------------------------------------------------------------- +; A little light 6502 housekeeping + +_init: ldx #$FF ; Initialize stack pointer to $01FF + txs + cld ; Clear decimal mode + +; --------------------------------------------------------------------------- +; Set cc65 argument stack pointer + + lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + sta sp + lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + sta sp+1 + +; --------------------------------------------------------------------------- +; Initialize memory storage + + jsr zerobss ; Clear BSS segment + jsr initlib ; Run constructors + +; --------------------------------------------------------------------------- +; Call main() + + jsr _main + +; --------------------------------------------------------------------------- +; Back from main (this is also the _exit entry): + +_exit: jsr donelib ; Run destructors + jmp RESET ; Display boot menu after program exit diff --git a/libsrc/osic1p/ctype.s b/libsrc/osic1p/ctype.s new file mode 100644 index 000000000..fa901c189 --- /dev/null +++ b/libsrc/osic1p/ctype.s @@ -0,0 +1,289 @@ +; +; Character specification table. +; +; Ullrich von Bassewitz, 02.06.1998 +; 2003-05-02, Greg King +; +; Copied from cbm/ctype.s + +; The following 256-byte-wide table specifies attributes for the isxxx type +; of functions. Doing it by a table means some overhead in space, but it +; has major advantages: +; +; * It is fast. If it weren't for the slow parameter-passing of cc65, +; one even could define C-language macroes for the isxxx functions +; (as it usually is done, on other platforms). +; +; * It is highly portable. The only unportable part is the table itself; +; all real code goes into the common library. +; +; * We save some code in the isxxx functions. + +; This table is taken from Craig S. Bruce's technical docs. for the ACE OS. + + .include "ctype.inc" + +; The table is read-only, put it into the RODATA segment. + + .rodata + +__ctype: + .byte CT_CTRL ; 0/00 ___rvs_@___ + .byte CT_CTRL ; 1/01 ___rvs_a___ + .byte CT_CTRL ; 2/02 ___rvs_b___ + .byte CT_CTRL ; 3/03 ___rvs_c___ + .byte CT_CTRL ; 4/04 ___rvs_d___ + .byte CT_CTRL ; 5/05 ___rvs_e___ + .byte CT_CTRL ; 6/06 ___rvs_f___ + .byte CT_CTRL ; 7/07 _BEL/rvs_g_ + .byte CT_CTRL ; 8/08 ___rvs_h___ + .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB ; 9/09 _TAB/rvs_i_ + .byte CT_CTRL | CT_OTHER_WS ; 10/0a _BOL/rvs_j_ + .byte CT_CTRL ; 11/0b ___rvs_k___ + .byte CT_CTRL ; 12/0c ___rvs_l___ + .byte CT_CTRL | CT_OTHER_WS ; 13/0d _CR_/rvs_m_ + .byte CT_CTRL ; 14/0e ___rvs_n___ + .byte CT_CTRL ; 15/0f ___rvs_o___ + .byte CT_CTRL ; 16/10 ___rvs_p___ + .byte CT_CTRL | CT_OTHER_WS ; 17/11 _VT_/rvs_q_ + .byte CT_CTRL ; 18/12 ___rvs_r___ + .byte CT_CTRL | CT_OTHER_WS ; 19/13 HOME/rvs_s_ + .byte CT_CTRL | CT_OTHER_WS ; 20/14 _BS_/rvs_t_ + .byte CT_CTRL ; 21/15 ___rvs_u___ + .byte CT_CTRL ; 22/16 ___rvs_v___ + .byte CT_CTRL ; 23/17 ___rvs_w___ + .byte CT_CTRL ; 24/18 ___rvs_x___ + .byte CT_CTRL ; 25/19 ___rvs_y___ + .byte CT_CTRL ; 26/1a ___rvs_z___ + .byte CT_CTRL ; 27/1b ___rvs_[___ + .byte CT_CTRL ; 28/1c ___rvs_\___ + .byte CT_CTRL | CT_OTHER_WS ; 29/1d cursr-right + .byte CT_CTRL ; 30/1e ___rvs_^___ + .byte CT_CTRL ; 31/1f _rvs_under_ + .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ + .byte $00 ; 33/21 _____!_____ + .byte $00 ; 34/22 _____"_____ + .byte $00 ; 35/23 _____#_____ + .byte $00 ; 36/24 _____$_____ + .byte $00 ; 37/25 _____%_____ + .byte $00 ; 38/26 _____&_____ + .byte $00 ; 39/27 _____'_____ + .byte $00 ; 40/28 _____(_____ + .byte $00 ; 41/29 _____)_____ + .byte $00 ; 42/2a _____*_____ + .byte $00 ; 43/2b _____+_____ + .byte $00 ; 44/2c _____,_____ + .byte $00 ; 45/2d _____-_____ + .byte $00 ; 46/2e _____._____ + .byte $00 ; 47/2f _____/_____ + .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ + .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ + .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ + .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ + .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ + .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ + .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ + .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ + .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ + .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ + .byte $00 ; 58/3a _____:_____ + .byte $00 ; 59/3b _____;_____ + .byte $00 ; 60/3c _____<_____ + .byte $00 ; 61/3d _____=_____ + .byte $00 ; 62/3e _____>_____ + .byte $00 ; 63/3f _____?_____ + + .byte $00 ; 64/40 _____@_____ + .byte CT_LOWER | CT_XDIGIT ; 65/41 _____a_____ + .byte CT_LOWER | CT_XDIGIT ; 66/42 _____b_____ + .byte CT_LOWER | CT_XDIGIT ; 67/43 _____c_____ + .byte CT_LOWER | CT_XDIGIT ; 68/44 _____d_____ + .byte CT_LOWER | CT_XDIGIT ; 69/45 _____e_____ + .byte CT_LOWER | CT_XDIGIT ; 70/46 _____f_____ + .byte CT_LOWER ; 71/47 _____g_____ + .byte CT_LOWER ; 72/48 _____h_____ + .byte CT_LOWER ; 73/49 _____i_____ + .byte CT_LOWER ; 74/4a _____j_____ + .byte CT_LOWER ; 75/4b _____k_____ + .byte CT_LOWER ; 76/4c _____l_____ + .byte CT_LOWER ; 77/4d _____m_____ + .byte CT_LOWER ; 78/4e _____n_____ + .byte CT_LOWER ; 79/4f _____o_____ + .byte CT_LOWER ; 80/50 _____p_____ + .byte CT_LOWER ; 81/51 _____q_____ + .byte CT_LOWER ; 82/52 _____r_____ + .byte CT_LOWER ; 83/53 _____s_____ + .byte CT_LOWER ; 84/54 _____t_____ + .byte CT_LOWER ; 85/55 _____u_____ + .byte CT_LOWER ; 86/56 _____v_____ + .byte CT_LOWER ; 87/57 _____w_____ + .byte CT_LOWER ; 88/58 _____x_____ + .byte CT_LOWER ; 89/59 _____y_____ + .byte CT_LOWER ; 90/5a _____z_____ + .byte $00 ; 91/5b _____[_____ + .byte $00 ; 92/5c _____\_____ + .byte $00 ; 93/5d _____]_____ + .byte $00 ; 94/5e _____^_____ + .byte $00 ; 95/5f _UNDERLINE_ + .byte $00 ; 96/60 _A`_grave__ + .byte $00 ; 97/61 _A'_acute__ + .byte $00 ; 98/62 _A^_circum_ + .byte $00 ; 99/63 _A~_tilde__ + .byte $00 ; 100/64 _A"_dieres_ + .byte $00 ; 101/65 _A__ring___ + .byte $00 ; 102/66 _AE________ + .byte $00 ; 103/67 _C,cedilla_ + .byte $00 ; 104/68 _E`_grave__ + .byte $00 ; 105/69 _E'_acute__ + .byte $00 ; 106/6a _E^_circum_ + .byte $00 ; 107/6b _E"_dieres_ + .byte $00 ; 108/6c _I`_grave__ + .byte $00 ; 109/6d _I'_acute__ + .byte $00 ; 110/6e _I^_circum_ + .byte $00 ; 111/6f _I"_dieres_ + .byte $00 ; 112/70 _D-_Eth_lr_ + .byte $00 ; 113/71 _N~_tilde__ + .byte $00 ; 114/72 _O`_grave__ + .byte $00 ; 115/73 _O'_acute__ + .byte $00 ; 116/74 _O^_circum_ + .byte $00 ; 117/75 _O~_tilde__ + .byte $00 ; 118/76 _O"_dieres_ + .byte $00 ; 119/77 __multiply_ + .byte $00 ; 120/78 _O/_slash__ + .byte $00 ; 121/79 _U`_grave__ + .byte $00 ; 122/7a _U'_acute__ + .byte $00 ; 123/7b _U^_circum_ + .byte $00 ; 124/7c _U"_dieres_ + .byte $00 ; 125/7d _Y'_acute__ + .byte $00 ; 126/7e _cap_thorn_ + .byte $00 ; 127/7f _Es-sed_B__ + + .byte CT_CTRL ; 128/80 __bullet___ + .byte CT_CTRL ; 129/81 __v_line___ + .byte CT_CTRL ; 130/82 __h_line___ + .byte CT_CTRL ; 131/83 ___cross___ + .byte CT_CTRL ; 132/84 _tl_corner_ + .byte CT_CTRL ; 133/85 _tr_corner_ + .byte CT_CTRL ; 134/86 _bl_corner_ + .byte CT_CTRL ; 135/87 _br_corner_ + .byte CT_CTRL ; 136/88 ___l_tee___ + .byte CT_CTRL ; 137/89 ___r_tee___ + .byte CT_CTRL ; 138/8a ___t_tee___ + .byte CT_CTRL ; 139/8b ___b_tee___ + .byte CT_CTRL ; 140/8c ___heart___ + .byte CT_CTRL | CT_OTHER_WS ; 141/8d _CR/diamond + .byte CT_CTRL ; 142/8e ___club____ + .byte CT_CTRL ; 143/8f ___spade___ + .byte CT_CTRL ; 144/90 _s_circle__ + .byte CT_CTRL | CT_OTHER_WS ; 145/91 _cursor-up_ + .byte CT_CTRL ; 146/92 ___pound___ + .byte CT_CTRL | CT_OTHER_WS ; 147/93 _CLS/check_ + .byte CT_CTRL | CT_OTHER_WS ; 148/94 __INSert___ + .byte CT_CTRL ; 149/95 ____+/-____ + .byte CT_CTRL ; 150/96 __divide___ + .byte CT_CTRL ; 151/97 __degree___ + .byte CT_CTRL ; 152/98 _c_checker_ + .byte CT_CTRL ; 153/99 _f_checker_ + .byte CT_CTRL ; 154/9a _solid_sq__ + .byte CT_CTRL ; 155/9b __cr_char__ + .byte CT_CTRL ; 156/9c _up_arrow__ + .byte CT_CTRL | CT_OTHER_WS ; 157/9d cursor-left + .byte CT_CTRL ; 158/9e _left_arro_ + .byte CT_CTRL ; 159/9f _right_arr_ + .byte CT_SPACE | CT_SPACE_TAB ; 160/a0 _req space_ + .byte $00 ; 161/a1 _!_invertd_ + .byte $00 ; 162/a2 ___cent____ + .byte $00 ; 163/a3 ___pound___ + .byte $00 ; 164/a4 __currency_ + .byte $00 ; 165/a5 ____yen____ + .byte $00 ; 166/a6 _|_broken__ + .byte $00 ; 167/a7 __section__ + .byte $00 ; 168/a8 __umulaut__ + .byte $00 ; 169/a9 _copyright_ + .byte $00 ; 170/aa __fem_ord__ + .byte $00 ; 171/ab _l_ang_quo_ + .byte $00 ; 172/ac ____not____ + .byte $00 ; 173/ad _syl_hyphn_ + .byte $00 ; 174/ae _registerd_ + .byte $00 ; 175/af _overline__ + .byte $00 ; 176/b0 __degrees__ + .byte $00 ; 177/b1 ____+/-____ + .byte $00 ; 178/b2 _2_supersc_ + .byte $00 ; 179/b3 _3_supersc_ + .byte $00 ; 180/b4 ___acute___ + .byte $00 ; 181/b5 ____mu_____ + .byte $00 ; 182/b6 _paragraph_ + .byte $00 ; 183/b7 __mid_dot__ + .byte $00 ; 184/b8 __cedilla__ + .byte $00 ; 185/b9 _1_supersc_ + .byte $00 ; 186/ba __mas_ord__ + .byte $00 ; 187/bb _r_ang_quo_ + .byte $00 ; 188/bc ____1/4____ + .byte $00 ; 189/bd ____1/2____ + .byte $00 ; 190/be ____3/4____ + .byte $00 ; 191/bf _?_invertd_ + + .byte $00 ; 192/c0 _____`_____ + .byte CT_UPPER | CT_XDIGIT ; 193/c1 _____A_____ + .byte CT_UPPER | CT_XDIGIT ; 194/c2 _____B_____ + .byte CT_UPPER | CT_XDIGIT ; 195/c3 _____C_____ + .byte CT_UPPER | CT_XDIGIT ; 196/c4 _____D_____ + .byte CT_UPPER | CT_XDIGIT ; 197/c5 _____E_____ + .byte CT_UPPER | CT_XDIGIT ; 198/c6 _____F_____ + .byte CT_UPPER ; 199/c7 _____G_____ + .byte CT_UPPER ; 200/c8 _____H_____ + .byte CT_UPPER ; 201/c9 _____I_____ + .byte CT_UPPER ; 202/ca _____J_____ + .byte CT_UPPER ; 203/cb _____K_____ + .byte CT_UPPER ; 204/cc _____L_____ + .byte CT_UPPER ; 205/cd _____M_____ + .byte CT_UPPER ; 206/ce _____N_____ + .byte CT_UPPER ; 207/cf _____O_____ + .byte CT_UPPER ; 208/d0 _____P_____ + .byte CT_UPPER ; 209/d1 _____Q_____ + .byte CT_UPPER ; 210/d2 _____R_____ + .byte CT_UPPER ; 211/d3 _____S_____ + .byte CT_UPPER ; 212/d4 _____T_____ + .byte CT_UPPER ; 213/d5 _____U_____ + .byte CT_UPPER ; 214/d6 _____V_____ + .byte CT_UPPER ; 215/d7 _____W_____ + .byte CT_UPPER ; 216/d8 _____X_____ + .byte CT_UPPER ; 217/d9 _____Y_____ + .byte CT_UPPER ; 218/da _____Z_____ + .byte $00 ; 219/db _____{_____ + .byte $00 ; 220/dc _____|_____ + .byte $00 ; 221/dd _____}_____ + .byte $00 ; 222/de _____~_____ + .byte $00 ; 223/df ___HOUSE___ + .byte $00 ; 224/e0 _a`_grave__ + .byte $00 ; 225/e1 _a'_acute__ + .byte $00 ; 226/e2 _a^_circum_ + .byte $00 ; 227/e3 _a~_tilde__ + .byte $00 ; 228/e4 _a"_dieres_ + .byte $00 ; 229/e5 _a__ring___ + .byte $00 ; 230/e6 _ae________ + .byte $00 ; 231/e7 _c,cedilla_ + .byte $00 ; 232/e8 _e`_grave__ + .byte $00 ; 233/e9 _e'_acute__ + .byte $00 ; 234/ea _e^_circum_ + .byte $00 ; 235/eb _e"_dieres_ + .byte $00 ; 236/ec _i`_grave__ + .byte $00 ; 237/ed _i'_acute__ + .byte $00 ; 238/ee _i^_circum_ + .byte $00 ; 239/ef _i"_dieres_ + .byte $00 ; 240/f0 _o^x_Eth_s_ + .byte $00 ; 241/f1 _n~_tilda__ + .byte $00 ; 242/f2 _o`_grave__ + .byte $00 ; 243/f3 _o'_acute__ + .byte $00 ; 244/f4 _o^_circum_ + .byte $00 ; 245/f5 _o~_tilde__ + .byte $00 ; 246/f6 _o"_dieres_ + .byte $00 ; 247/f7 __divide___ + .byte $00 ; 248/f8 _o/_slash__ + .byte $00 ; 249/f9 _u`_grave__ + .byte $00 ; 250/fa _u'_acute__ + .byte $00 ; 251/fb _u^_circum_ + .byte $00 ; 252/fc _u"_dieres_ + .byte $00 ; 253/fd _y'_acute__ + .byte $00 ; 254/fe _sm_thorn__ + .byte $00 ; 255/ff _y"_dieres_ diff --git a/libsrc/osic1p/cvline.s b/libsrc/osic1p/cvline.s new file mode 100644 index 000000000..84e5a45bf --- /dev/null +++ b/libsrc/osic1p/cvline.s @@ -0,0 +1,29 @@ +; +; based on CBM version +; originally by: +; Ullrich von Bassewitz, 08.08.1998 +; +; void cvlinexy (unsigned char x, unsigned char y, unsigned char length); +; void cvline (unsigned char length); +; + + .export _cvlinexy, _cvline + .import popa, _gotoxy, putchar, newline + .importzp tmp1 + +_cvlinexy: + pha ; Save the length + jsr popa ; Get y + jsr _gotoxy ; Call this one, will pop params + pla ; Restore the length and run into _cvline + +_cvline: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda #$95 ; Vertical bar + jsr putchar ; Write, no cursor advance + jsr newline ; Advance cursor to next line + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/osic1p/extra/screen-s3-32x28.s b/libsrc/osic1p/extra/screen-s3-32x28.s new file mode 100644 index 000000000..40ed24203 --- /dev/null +++ b/libsrc/osic1p/extra/screen-s3-32x28.s @@ -0,0 +1,16 @@ +; +; Implementation of screen-layout related functions for Superboard /// +; + + .include "../osiscreen.inc" + +S3_SCR_BASE := $D000 ; Base of Superboard /// video RAM +S3_VRAM_SIZE = $0400 ; Size of Superboard /// video RAM (1 kB) +S3_SCR_WIDTH = $20 ; Screen width +S3_SCR_HEIGHT = $1C ; Screen height +S3_SCR_FIRSTCHAR = $80 ; Offset of cursor position (0, 0) from base + ; of video RAM +S3_SCROLL_DIST = $20 ; Memory distance for scrolling by one line + +osi_screen_funcs S3_SCR_BASE, S3_VRAM_SIZE, S3_SCR_FIRSTCHAR, \ + S3_SCR_WIDTH, S3_SCR_HEIGHT, S3_SCROLL_DIST diff --git a/libsrc/osic1p/extzp.inc b/libsrc/osic1p/extzp.inc new file mode 100644 index 000000000..5e85e0b74 --- /dev/null +++ b/libsrc/osic1p/extzp.inc @@ -0,0 +1,7 @@ +; +; Additional zero page locations for the Challenger 1P. +; + +; ------------------------------------------------------------------------ + + .globalzp CURS_X, CURS_Y, SCREEN_PTR, CHARBUF diff --git a/libsrc/osic1p/extzp.s b/libsrc/osic1p/extzp.s new file mode 100644 index 000000000..b3bdaa0b7 --- /dev/null +++ b/libsrc/osic1p/extzp.s @@ -0,0 +1,20 @@ +; +; Additional zero page locations for the Challenger 1P. +; NOTE: The zeropage locations contained in this file get initialized +; in the startup code, so if you change anything here, be sure to check +; not only the linker config, but also the startup file. +; + +; ------------------------------------------------------------------------ + + .include "extzp.inc" + +.segment "EXTZP" : zeropage + +CURS_X: .res 1 +CURS_Y: .res 1 +SCREEN_PTR: .res 2 +CHARBUF: .res 1 + +; size 5 +; Adjust size of the ZP segment in osic1p.cfg if the size changes diff --git a/libsrc/osic1p/gotox.s b/libsrc/osic1p/gotox.s new file mode 100644 index 000000000..0dea72b9a --- /dev/null +++ b/libsrc/osic1p/gotox.s @@ -0,0 +1,13 @@ +; +; copied from CBM implementation +; originally by: +; Ullrich von Bassewitz, 07.08.1998 +; +; void gotox (unsigned char x); +; + .export _gotox + .import plot + .include "extzp.inc" + +_gotox: sta CURS_X ; Set new position + jmp plot ; And activate it diff --git a/libsrc/osic1p/gotoxy.s b/libsrc/osic1p/gotoxy.s new file mode 100644 index 000000000..f76537349 --- /dev/null +++ b/libsrc/osic1p/gotoxy.s @@ -0,0 +1,17 @@ +; +; copied from CBM implementation +; +; originally by: +; Ullrich von Bassewitz, 06.08.1998 +; +; void gotoxy (unsigned char x, unsigned char y); +; + .export _gotoxy + .import popa, plot + .include "extzp.inc" + +_gotoxy: + sta CURS_Y ; Set Y + jsr popa ; Get X + sta CURS_X ; Set X + jmp plot ; Set the cursor position diff --git a/libsrc/osic1p/gotoy.s b/libsrc/osic1p/gotoy.s new file mode 100644 index 000000000..693863d94 --- /dev/null +++ b/libsrc/osic1p/gotoy.s @@ -0,0 +1,13 @@ +; +; copied from CBM implementation +; originally by: +; Ullrich von Bassewitz, 0.08.1998 +; +; void gotoy (unsigned char y); +; + .export _gotoy + .import plot + .include "extzp.inc" + +_gotoy: sta CURS_Y ; Set the new position + jmp plot ; And activate it diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s new file mode 100644 index 000000000..b616b4a3f --- /dev/null +++ b/libsrc/osic1p/kbhit.s @@ -0,0 +1,47 @@ +; +; unsigned char kbhit (void); +; +; The method to detect a pressed key is based on the documentation in +; "Section 3 Programmed Key Functions" in "The Challenger Character Graphics +; Reference Manual" +; We only want to return true for characters that can be returned by cgetc(), +; but not for keys like <Shift> or <Ctrl>. Therefore a special handling is +; needed for the first row. This is implemented by a bit mask that is stored +; in tmp1 and that is set to zero after the first round. +; + + .export _kbhit + .include "osic1p.inc" + .include "extzp.inc" + .include "zeropage.inc" + +_kbhit: + lda #%11011111 ; Mask for only checking the column for the + sta tmp1 ; ESC key in the first keyboard row. + + lda #%11111110 ; Mask for first keyboard row +scan: + sta KBD ; Select keyboard row + tax ; Save A + lda KBD ; Read keyboard columns + ora tmp1 ; Mask out uninteresting keys (only relevant in + ; first row) + cmp #$FF ; No keys pressed? + bne keypressed + lda #$00 ; For remaining rows no keys masked + sta tmp1 + txa ; Restore A + sec ; Want to shift in ones + rol a ; Rotate row select to next bit position + cmp #$FF ; Done? + bne scan ; If not, continue + lda #$00 ; Return false + tax ; High byte of return is also zero + sta CHARBUF ; No character in buffer + rts +keypressed: + jsr INPUTC ; Get input character in A + sta CHARBUF ; Save in buffer + ldx #$00 ; High byte of return is always zero + lda #$01 ; Return true + rts diff --git a/libsrc/osic1p/oserror.s b/libsrc/osic1p/oserror.s new file mode 100644 index 000000000..073691a06 --- /dev/null +++ b/libsrc/osic1p/oserror.s @@ -0,0 +1,20 @@ +; +; dummy implementation for Challenger 1P based on atmos implementation +; +; original by +; Stefan Haubenthal, 2011-04-18 +; +; int __fastcall__ _osmaperrno (unsigned char oserror); +; /* Map a system specific error into a system independent code */ +; + + .include "errno.inc" + .export __osmaperrno + +.proc __osmaperrno + + lda #<EUNKNOWN + ldx #>EUNKNOWN + rts + +.endproc diff --git a/libsrc/osic1p/osic1p.inc b/libsrc/osic1p/osic1p.inc new file mode 100644 index 000000000..eabeaf79e --- /dev/null +++ b/libsrc/osic1p/osic1p.inc @@ -0,0 +1,4 @@ +; Addresses +INPUTC := $FD00 ; Input character from keyboard +RESET := $FF00 ; Reset address, show boot prompt +KBD := $DF00 ; Polled keyboard register diff --git a/libsrc/osic1p/osiscreen.inc b/libsrc/osic1p/osiscreen.inc new file mode 100644 index 000000000..66c5e9fb0 --- /dev/null +++ b/libsrc/osic1p/osiscreen.inc @@ -0,0 +1,184 @@ +; +; Macro definitions for screen layout modules +; + + .include "extzp.inc" + +.linecont + + +; +; Internal function for screensize() +; +.macro osi_screensize ScrWidth, ScrHeight + ; Macro implementation of internal screensize + ; function for given width and height in + ; characters + + .export screensize + +.proc screensize + ldx #ScrWidth + ldy #ScrHeight + rts +.endproc +.endmacro + +; +; void clrscr (void); +; +.macro osi_clrscr ScrBase, ScrRamSize + + .export _clrscr + +.proc _clrscr + lda #<ScrBase ; Fill whole video RAM with blanks by calling + ldx #>ScrBase ; memset appropriately + jsr pushax + + lda #' ' + ldx #$00 + jsr pushax + + lda #<ScrRamSize + ldx #>ScrRamSize + jsr _memset + + lda #$00 ; Cursor in upper left corner + sta CURS_X + sta CURS_Y + + jmp plot ; Set the cursor position +.endproc + +.endmacro + +; +; cputc/cputcxy for Challenger 1P +; Based on PET/CBM implementation +; + +.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \ + ScrollDist, ScrLo, ScrHi + + ; Number of characters to move for scrolling + ; by one line +ScrollLength = (ScrHeight - 1) * ScrollDist + +; +; void cputcxy (unsigned char x, unsigned char y, char c); +; void cputc (char c); +; + .export _cputcxy, _cputc, cputdirect, putchar + .export newline, plot + +_cputcxy: + pha ; Save C + jsr popa ; Get Y + jsr _gotoxy ; Set cursor, drop x + pla ; Restore C + +; Plot a character - also used as internal function + +_cputc: cmp #$0A ; CR? + bne L1 + lda #0 + sta CURS_X + beq plot ; Recalculate pointers + +L1: cmp #$0D ; LF? + beq newline ; Recalculate pointers + +cputdirect: + jsr putchar ; Write the character to the screen + +; Advance cursor position, register Y contains horizontal position after +; putchar + + cpy #(ScrWidth - 1) ; Check whether line is full + bne L3 + jsr newline ; New line + ldy #$FF ; + cr +L3: iny + sty CURS_X + rts + +newline: + inc CURS_Y + lda CURS_Y + cmp #ScrHeight ; Screen height + bne plot + dec CURS_Y ; Bottom of screen reached, scroll + + ; Scroll destination address + lda #<(ScrBase + ScrFirstChar) + ldx #>(ScrBase + ScrFirstChar) + jsr pushax + + ; Scroll source address + lda #<(ScrBase + ScrFirstChar + ScrollDist) + ldx #>(ScrBase + ScrFirstChar + ScrollDist) + jsr pushax + + ; Number of characters to move + lda #<ScrollLength + ldx #>ScrollLength + jsr _memmove + + ; Address of first character in last line + ; of screen + lda #<(ScrBase + ScrFirstChar + ScrollLength) + sta ptr1 + lda #>(ScrBase + ScrFirstChar + ScrollLength) + sta ptr1+1 + + ldy #ScrWidth ; Fill last line with blanks + lda #' ' +clrln: sta (ptr1),y + dey + bpl clrln + +plot: ldy CURS_Y + lda ScrLo,y + sta SCREEN_PTR + lda ScrHi,y + sta SCREEN_PTR+1 + rts + +; Write one character to the screen without doing anything else, return X +; position in register Y + +putchar: + ldy CURS_X + sta (SCREEN_PTR),y ; Set char + rts + +.endmacro + +.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \ + ScrWidth, ScrHeight, ScrollDist + + .import popa, _gotoxy + .import _memmove, _memset, pushax + .importzp ptr1 + +.rodata + +; Screen address tables - offset to real screen +ScrTabLo: + .repeat ScrHeight, I + .byte <(ScrBase + ScrFirstChar + I * ScrollDist) + .endrep + +ScrTabHi: + .repeat ScrHeight, I + .byte >(ScrBase + ScrFirstChar + I * ScrollDist) + .endrep + +.code + +osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \ + ScrollDist, ScrTabLo, ScrTabHi +osi_screensize ScrWidth, ScrHeight +osi_clrscr ScrBase, ScrRamSize + +.endmacro \ No newline at end of file diff --git a/libsrc/osic1p/screen-c1p-24x24.s b/libsrc/osic1p/screen-c1p-24x24.s new file mode 100644 index 000000000..e691c2f1f --- /dev/null +++ b/libsrc/osic1p/screen-c1p-24x24.s @@ -0,0 +1,16 @@ +; +; Implementation of screen-layout related functions for Challenger 1P +; + + .include "osiscreen.inc" + +C1P_SCR_BASE := $D000 ; Base of C1P video RAM +C1P_VRAM_SIZE = $0400 ; Size of C1P video RAM (1 kB) +C1P_SCR_WIDTH = $18 ; Screen width +C1P_SCR_HEIGHT = $18 ; Screen height +C1P_SCR_FIRSTCHAR = $85 ; Offset of cursor position (0, 0) from base + ; of video RAM +C1P_SCROLL_DIST = $20 ; Memory distance for scrolling by one line + +osi_screen_funcs C1P_SCR_BASE, C1P_VRAM_SIZE, C1P_SCR_FIRSTCHAR, \ + C1P_SCR_WIDTH, C1P_SCR_HEIGHT, C1P_SCROLL_DIST diff --git a/libsrc/osic1p/wherex.s b/libsrc/osic1p/wherex.s new file mode 100644 index 000000000..1155a8abd --- /dev/null +++ b/libsrc/osic1p/wherex.s @@ -0,0 +1,14 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; Copied from cbm/wherex.s + +; unsigned char wherex (void); +; + .export _wherex + .include "extzp.inc" + +.proc _wherex + lda CURS_X + ldx #$00 + rts +.endproc diff --git a/libsrc/osic1p/wherey.s b/libsrc/osic1p/wherey.s new file mode 100644 index 000000000..632cf4a15 --- /dev/null +++ b/libsrc/osic1p/wherey.s @@ -0,0 +1,14 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; Copied from cbm/wherey.s +; +; unsigned char wherey (void); +; + .export _wherey + .include "extzp.inc" + +.proc _wherey + lda CURS_Y + ldx #$00 + rts +.endproc diff --git a/libsrc/zlib/uncompress.c b/libsrc/zlib/uncompress.c index 7810eb4f8..4e449a3ef 100644 --- a/libsrc/zlib/uncompress.c +++ b/libsrc/zlib/uncompress.c @@ -6,8 +6,8 @@ #include <zlib.h> -int uncompress (char* dest, unsigned* destLen, - const char* source, unsigned sourceLen) +int __fastcall__ uncompress (char* dest, unsigned* destLen, + const char* source, unsigned sourceLen) { unsigned len; unsigned char* ptr; diff --git a/src/ca65/expr.c b/src/ca65/expr.c index e4d6f7363..c4da32824 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -62,6 +62,7 @@ #include "symtab.h" #include "toklist.h" #include "ulabel.h" +#include "macro.h" @@ -417,6 +418,34 @@ static ExprNode* FuncDefined (void) +static ExprNode* FuncIsMnemonic (void) +/* Handle the .ISMNEMONIC, .ISMNEM builtin function */ +{ + int Instr = -1; + + /* Check for a macro or an instruction depending on UbiquitousIdents */ + + if (CurTok.Tok == TOK_IDENT) { + if (UbiquitousIdents) { + /* Macros CAN be instructions, so check for them first */ + if (FindMacro (&CurTok.SVal) == 0) { + Instr = FindInstruction (&CurTok.SVal); + } + } else { + /* Macros and symbols may NOT use the names of instructions, so just check for the instruction */ + Instr = FindInstruction (&CurTok.SVal); + } + } else { + Error ("Identifier expected."); + } + /* Skip the name */ + NextTok (); + + return GenLiteralExpr (Instr > 0); +} + + + ExprNode* FuncHiByte (void) /* Handle the .HIBYTE builtin function */ { @@ -629,6 +658,85 @@ static ExprNode* FuncReferenced (void) +static ExprNode* FuncAddrSize (void) +/* Handle the .ADDRSIZE function */ +{ + StrBuf ScopeName = STATIC_STRBUF_INITIALIZER; + StrBuf Name = STATIC_STRBUF_INITIALIZER; + SymEntry* Sym; + int AddrSize; + int NoScope; + + + /* Assume we don't know the size */ + AddrSize = 0; + + /* Check for a cheap local which needs special handling */ + if (CurTok.Tok == TOK_LOCAL_IDENT) { + + /* Cheap local symbol */ + Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING); + if (Sym == 0) { + Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal); + } else { + AddrSize = Sym->AddrSize; + } + + /* Remember and skip SVal, terminate ScopeName so it is empty */ + SB_Copy (&Name, &CurTok.SVal); + NextTok (); + SB_Terminate (&ScopeName); + + } else { + + /* Parse the scope and the name */ + SymTable* ParentScope = ParseScopedIdent (&Name, &ScopeName); + + /* Check if the parent scope is valid */ + if (ParentScope == 0) { + /* No such scope */ + SB_Done (&ScopeName); + SB_Done (&Name); + return GenLiteral0 (); + } + + /* If ScopeName is empty, no explicit scope was specified. We have to + ** search upper scope levels in this case. + */ + NoScope = SB_IsEmpty (&ScopeName); + + /* If we did find a scope with the name, read the symbol defining the + ** size, otherwise search for a symbol entry with the name and scope. + */ + if (NoScope) { + Sym = SymFindAny (ParentScope, &Name); + } else { + Sym = SymFind (ParentScope, &Name, SYM_FIND_EXISTING); + } + /* If we found the symbol retrieve the size, otherwise complain */ + if (Sym) { + AddrSize = Sym->AddrSize; + } else { + Error ("Unknown symbol or scope: `%m%p%m%p'", &ScopeName, &Name); + } + + } + + if (AddrSize == 0) { + Warning (1, "Unknown address size: `%m%p%m%p'", &ScopeName, &Name); + } + + /* Free the string buffers */ + SB_Done (&ScopeName); + SB_Done (&Name); + + /* Return the size. */ + + return GenLiteralExpr (AddrSize); +} + + + static ExprNode* FuncSizeOf (void) /* Handle the .SIZEOF function */ { @@ -965,6 +1073,10 @@ static ExprNode* Factor (void) N = Function (FuncBankByte); break; + case TOK_ADDRSIZE: + N = Function (FuncAddrSize); + break; + case TOK_BLANK: N = Function (FuncBlank); break; @@ -982,6 +1094,10 @@ static ExprNode* Factor (void) N = Function (FuncDefined); break; + case TOK_ISMNEMONIC: + N = Function (FuncIsMnemonic); + break; + case TOK_HIBYTE: N = Function (FuncHiByte); break; diff --git a/src/ca65/feature.c b/src/ca65/feature.c index c398d2b37..3462d5501 100644 --- a/src/ca65/feature.c +++ b/src/ca65/feature.c @@ -63,6 +63,7 @@ static const char* FeatureKeys[FEAT_COUNT] = { "c_comments", "force_range", "underline_in_numbers", + "addrsize", }; @@ -119,6 +120,7 @@ feature_t SetFeature (const StrBuf* Key) case FEAT_C_COMMENTS: CComments = 1; break; case FEAT_FORCE_RANGE: ForceRange = 1; break; case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break; + case FEAT_ADDRSIZE: AddrSize = 1; break; default: /* Keep gcc silent */ break; } diff --git a/src/ca65/feature.h b/src/ca65/feature.h index 9682ad9b9..3a520a54a 100644 --- a/src/ca65/feature.h +++ b/src/ca65/feature.h @@ -65,6 +65,7 @@ typedef enum { FEAT_C_COMMENTS, FEAT_FORCE_RANGE, FEAT_UNDERLINE_IN_NUMBERS, + FEAT_ADDRSIZE, /* Special value: Number of features available */ FEAT_COUNT diff --git a/src/ca65/global.c b/src/ca65/global.c index b3d6d6c6e..77ed66e7f 100644 --- a/src/ca65/global.c +++ b/src/ca65/global.c @@ -82,3 +82,4 @@ unsigned char OrgPerSeg = 0; /* Make .org local to current seg */ unsigned char CComments = 0; /* Allow C like comments */ unsigned char ForceRange = 0; /* Force values into expected range */ unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */ +unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */ diff --git a/src/ca65/global.h b/src/ca65/global.h index 378a776e6..fb254f835 100644 --- a/src/ca65/global.h +++ b/src/ca65/global.h @@ -84,6 +84,8 @@ extern unsigned char OrgPerSeg; /* Make .org local to current seg */ extern unsigned char CComments; /* Allow C like comments */ extern unsigned char ForceRange; /* Force values into expected range */ extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */ +extern unsigned char AddrSize; /* Allow .ADDRSIZE function */ + diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 6acf8c94f..500db1985 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -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 }, diff --git a/src/ca65/main.c b/src/ca65/main.c index 4f39eb286..d81a87577 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -303,6 +303,10 @@ static void SetSys (const char* Sys) NewSymbol ("__SIM65C02__", 1); break; + case TGT_OSIC1P: + NewSymbol ("__OSIC1P__", 1); + break; + case TGT_PCENGINE: NewSymbol ("__PCE__", 1); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 0b066c7bd..6d27c05c4 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1964,6 +1964,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoA16 }, { ccNone, DoA8 }, { ccNone, DoAddr }, /* .ADDR */ + { ccNone, DoUnexpected }, /* .ADDRSIZE */ { ccNone, DoAlign }, { ccNone, DoASCIIZ }, { ccNone, DoAssert }, @@ -2039,6 +2040,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoIncBin }, { ccNone, DoInclude }, { ccNone, DoInterruptor }, + { ccNone, DoUnexpected }, /* .ISMNEMONIC */ { ccNone, DoInvalid }, /* .LEFT */ { ccNone, DoLineCont }, { ccNone, DoList }, diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 890e1c7a3..30494b365 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -135,6 +135,7 @@ struct DotKeyword { { ".A16", TOK_A16 }, { ".A8", TOK_A8 }, { ".ADDR", TOK_ADDR }, + { ".ADDRSIZE", TOK_ADDRSIZE }, { ".ALIGN", TOK_ALIGN }, { ".AND", TOK_BOOLAND }, { ".ASCIIZ", TOK_ASCIIZ }, @@ -222,6 +223,8 @@ struct DotKeyword { { ".INCBIN", TOK_INCBIN }, { ".INCLUDE", TOK_INCLUDE }, { ".INTERRUPTOR", TOK_INTERRUPTOR }, + { ".ISMNEM", TOK_ISMNEMONIC }, + { ".ISMNEMONIC", TOK_ISMNEMONIC }, { ".LEFT", TOK_LEFT }, { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, @@ -723,7 +726,24 @@ static token_t FindDotKeyword (void) R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]), sizeof (DotKeywords [0]), CmpDotKeyword); if (R != 0) { + + /* By default, disable any somewhat experiemental DotKeyword. */ + + switch (R->Tok) { + + case TOK_ADDRSIZE: + /* Disallow .ADDRSIZE function by default */ + if (AddrSize == 0) { + return TOK_NONE; + } + break; + + default: + break; + } + return R->Tok; + } else { return TOK_NONE; } diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 7e21dd309..35d5a8066 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -696,10 +696,10 @@ void SymDump (FILE* F) while (S) { /* Ignore unused symbols */ - if ((S->Flags & SF_UNUSED) != 0) { + if ((S->Flags & SF_UNUSED) == 0) { fprintf (F, - "%m%-24p %s %s %s %s %s\n", - GetSymName (S), + "%-24s %s %s %s %s %s\n", + SB_GetConstBuf (GetSymName (S)), (S->Flags & SF_DEFINED)? "DEF" : "---", (S->Flags & SF_REFERENCED)? "REF" : "---", (S->Flags & SF_IMPORT)? "IMP" : "---", diff --git a/src/ca65/token.h b/src/ca65/token.h index 803b12785..5ffe42466 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -123,6 +123,7 @@ typedef enum token_t { TOK_A16 = TOK_FIRSTPSEUDO, TOK_A8, TOK_ADDR, + TOK_ADDRSIZE, TOK_ALIGN, TOK_ASCIIZ, TOK_ASSERT, @@ -198,6 +199,7 @@ typedef enum token_t { TOK_INCBIN, TOK_INCLUDE, TOK_INTERRUPTOR, + TOK_ISMNEMONIC, TOK_LEFT, TOK_LINECONT, TOK_LIST, diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index be80319e7..de51781a6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2001-2012, Ullrich von Bassewitz */ +/* (C) 2001-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "global.h" #include "reginfo.h" #include "symtab.h" #include "codeinfo.h" @@ -386,33 +387,35 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) ** Search for it in the list of builtin functions. */ if (Name[0] == '_') { - /* Search in the symbol table, skip the leading underscore */ SymEntry* E = FindGlobalSym (Name+1); - /* Did we find it in the top level table? */ + /* Did we find it in the top-level table? */ if (E && IsTypeFunc (E->Type)) { - FuncDesc* D = E->V.F.Func; - /* A function may use the A or A/X registers if it is a fastcall - ** function. If it is not a fastcall function but a variadic one, - ** it will use the Y register (the parameter size is passed here). - ** In all other cases, no registers are used. However, we assume - ** that any function will destroy all registers. + /* A variadic function will use the Y register (the parameter list + ** size is passed there). A fastcall function will use the A or A/X + ** registers. In all other cases, no registers are used. However, + ** we assume that any function will destroy all registers. */ - if (IsQualFastcall (E->Type) && D->ParamCount > 0) { - /* Will use registers depending on the last param */ - unsigned LastParamSize = CheckedSizeOf (D->LastParam->Type); - if (LastParamSize == 1) { - *Use = REG_A; - } else if (LastParamSize == 2) { - *Use = REG_AX; - } else { - *Use = REG_EAX; - } - } else if ((D->Flags & FD_VARIADIC) != 0) { + if ((D->Flags & FD_VARIADIC) != 0) { *Use = REG_Y; + } else if (D->ParamCount > 0 && + (AutoCDecl ? + IsQualFastcall (E->Type) : + !IsQualCDecl (E->Type))) { + /* Will use registers depending on the last param. */ + switch (CheckedSizeOf (D->LastParam->Type)) { + case 1u: + *Use = REG_A; + break; + case 2u: + *Use = REG_AX; + break; + default: + *Use = REG_EAX; + } } else { /* Will not use any registers */ *Use = REG_NONE; diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 427d0bd13..cf6392bd3 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -766,12 +766,8 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer InsertEntry (D, X, D->IP++); /* Lhs load entries can be removed */ - if (LoadX->AM != AM65_IMM) { - D->Lhs.X.Flags |= LI_REMOVE; - } - if (LoadA->AM != AM65_IMM) { - D->Lhs.A.Flags |= LI_REMOVE; - } + D->Lhs.X.Flags |= LI_REMOVE; + D->Lhs.A.Flags |= LI_REMOVE; } else if ((D->Rhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT && (D->Rhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT) { @@ -794,12 +790,8 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer InsertEntry (D, X, D->IP++); /* Rhs load entries can be removed */ - if (LoadX->AM != AM65_IMM) { - D->Rhs.X.Flags |= LI_REMOVE; - } - if (LoadA->AM != AM65_IMM) { - D->Rhs.A.Flags |= LI_REMOVE; - } + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; } else if ((D->Rhs.A.Flags & LI_DIRECT) != 0 && (D->Rhs.X.Flags & LI_DIRECT) != 0) { diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 053810b50..9971a9569 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -293,15 +293,15 @@ void PrintType (FILE* F, const Type* T) /* Recursive call */ PrintType (F, T + 1); if (T->A.L == UNSPECIFIED) { - fprintf (F, "[]"); + fprintf (F, " []"); } else { - fprintf (F, "[%ld]", T->A.L); + fprintf (F, " [%ld]", T->A.L); } return; case T_TYPE_PTR: /* Recursive call */ PrintType (F, T + 1); - fprintf (F, "*"); + fprintf (F, " *"); return; case T_TYPE_FUNC: fprintf (F, "function returning "); @@ -659,7 +659,7 @@ Type* GetBaseElementType (Type* T) ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. */ -{ +{ while (IsTypeArray (T)) { ++T; } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 598d0a228..92b3d0122 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -603,6 +603,16 @@ INLINE int IsQualCDecl (const Type* T) # define IsQualCDecl(T) (((T)->C & T_QUAL_CDECL) != 0) #endif +#if defined(HAVE_INLINE) +INLINE int IsQualCConv (const Type* T) +/* Return true if the given type has a calling convention qualifier */ +{ + return (T->C & T_QUAL_CCONV) != 0; +} +#else +# define IsQualCConv(T) (((T)->C & T_QUAL_CCONV) != 0) +#endif + int IsVariadicFunc (const Type* T) attribute ((const)); /* Return true if this is a function type or pointer to function type with ** variable parameter list diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 693c2116e..163084835 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2013, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -85,7 +85,7 @@ struct StructInitData { static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers); -/* Parse a type specificier */ +/* Parse a type specifier */ static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers); /* Parse initialization of variables. Return the number of data bytes. */ @@ -335,18 +335,30 @@ static void FixQualifiers (Type* DataType) T = DataType; while (T->C != T_END) { if (IsTypePtr (T)) { + /* Calling convention qualifier on the pointer? */ + if (IsQualCConv (T)) { + /* Pull the convention off of the pointer */ + Q = T[0].C & T_QUAL_CCONV; + T[0].C &= ~T_QUAL_CCONV; - /* Fastcall qualifier on the pointer? */ - if (IsQualFastcall (T)) { - /* Pointer to function which is not fastcall? */ - if (IsTypeFunc (T+1) && !IsQualFastcall (T+1)) { - /* Move the fastcall qualifier from the pointer to - ** the function. - */ - T[0].C &= ~T_QUAL_FASTCALL; - T[1].C |= T_QUAL_FASTCALL; + /* Pointer to a function which doesn't have an explicit convention? */ + if (IsTypeFunc (T + 1)) { + if (IsQualCConv (T + 1)) { + if ((T[1].C & T_QUAL_CCONV) == Q) { + Warning ("Pointer duplicates function's calling convention"); + } else { + Error ("Function's and pointer's calling conventions are different"); + } + } else { + if (Q == T_QUAL_FASTCALL && IsVariadicFunc (T + 1)) { + Error ("Variadic-function pointers cannot be __fastcall__"); + } else { + /* Move the qualifier from the pointer to the function. */ + T[1].C |= Q; + } + } } else { - Error ("Invalid `_fastcall__' qualifier for pointer"); + Error ("Not pointer to a function; can't use a calling convention"); } } @@ -355,8 +367,8 @@ static void FixQualifiers (Type* DataType) if (Q == T_QUAL_NONE) { /* No address size qualifiers specified */ if (IsTypeFunc (T+1)) { - /* Pointer to function. Use the qualifier from the function - ** or the default if the function don't has one. + /* Pointer to function. Use the qualifier from the function, + ** or the default if the function doesn't have one. */ Q = (T[1].C & T_QUAL_ADDRSIZE); if (Q == T_QUAL_NONE) { @@ -368,7 +380,7 @@ static void FixQualifiers (Type* DataType) T[0].C |= Q; } else { /* We have address size qualifiers. If followed by a function, - ** apply these also to the function. + ** apply them to the function also. */ if (IsTypeFunc (T+1)) { TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE); @@ -489,7 +501,7 @@ static void ParseEnumDecl (void) static int ParseFieldWidth (Declaration* Decl) -/* Parse an optional field width. Returns -1 if no field width is speficied, +/* Parse an optional field width. Returns -1 if no field width is specified, ** otherwise the width of the field. */ { @@ -862,7 +874,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) -/* Parse a type specificier */ +/* Parse a type specifier */ { ident Ident; SymEntry* Entry; @@ -1376,13 +1388,13 @@ static FuncDesc* ParseFuncDecl (void) static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Recursively process declarators. Build a type array in reverse order. */ { - /* Read optional function or pointer qualifiers. These modify the - ** identifier or token to the right. For convenience, we allow the fastcall - ** qualifier also for pointers here. If it is a pointer-to-function, the - ** qualifier will later be transfered to the function itself. If it's a + /* Read optional function or pointer qualifiers. They modify the + ** identifier or token to the right. For convenience, we allow a calling + ** convention also for pointers here. If it's a pointer-to-function, the + ** qualifier later will be transfered to the function itself. If it's a ** pointer to something else, it will be flagged as an error. */ - TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_FASTCALL); + TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_CCONV); /* Pointer to something */ if (CurTok.Tok == TOK_STAR) { @@ -1390,10 +1402,10 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Skip the star */ NextToken (); - /* Allow const, restrict and volatile qualifiers */ + /* Allow const, restrict, and volatile qualifiers */ Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT); - /* Parse the type, the pointer points to */ + /* Parse the type that the pointer points to */ Declarator (Spec, D, Mode); /* Add the type */ @@ -1443,7 +1455,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* We cannot specify fastcall for variadic functions */ if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) { - Error ("Variadic functions cannot be `__fastcall__'"); + Error ("Variadic functions cannot be __fastcall__"); Qualifiers &= ~T_QUAL_FASTCALL; } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 03374a521..7563645ff 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1,6 +1,7 @@ /* expr.c ** -** Ullrich von Bassewitz, 21.06.1998 +** 1998-06-21, Ullrich von Bassewitz +** 2015-06-26, Greg King */ @@ -470,9 +471,11 @@ static void FunctionCall (ExprDesc* Expr) /* Handle function pointers transparently */ IsFuncPtr = IsTypeFuncPtr (Expr->Type); if (IsFuncPtr) { - - /* Check wether it's a fastcall function that has parameters */ - IsFastcall = IsQualFastcall (Expr->Type + 1) && (Func->ParamCount > 0); + /* Check whether it's a fastcall function that has parameters */ + IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && Func->ParamCount > 0 && + (AutoCDecl ? + IsQualFastcall (Expr->Type + 1) : + !IsQualCDecl (Expr->Type + 1)); /* Things may be difficult, depending on where the function pointer ** resides. If the function pointer is an expression of some sort @@ -517,7 +520,10 @@ static void FunctionCall (ExprDesc* Expr) } /* If we didn't inline the function, get fastcall info */ - IsFastcall = IsQualFastcall (Expr->Type); + IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && + (AutoCDecl ? + IsQualFastcall (Expr->Type) : + !IsQualCDecl (Expr->Type)); } /* Parse the parameter list */ @@ -1707,8 +1713,13 @@ void hie10 (ExprDesc* Expr) } else { Error ("Illegal indirection"); } - /* The * operator yields an lvalue */ - ED_MakeLVal (Expr); + /* If the expression points to an array, then don't convert the + ** address -- it already is the location of the first element. + */ + if (!IsTypeArray (Expr->Type)) { + /* The * operator yields an lvalue */ + ED_MakeLVal (Expr); + } } break; diff --git a/src/cc65/function.c b/src/cc65/function.c index d9f1eeac3..22b305739 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2012, Ullrich von Bassewitz */ +/* (C) 2000-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -460,6 +460,9 @@ void NewFunc (SymEntry* Func) */ if (D->ParamCount > 0 || (D->Flags & FD_VARIADIC) != 0) { g_importmainargs (); + + /* The start-up code doesn't fast-call main(). */ + Func->Type->C |= T_QUAL_CDECL; } /* Determine if this is a main function in a C99 environment that @@ -478,13 +481,12 @@ void NewFunc (SymEntry* Func) PushLiteralPool (Func); /* If this is a fastcall function, push the last parameter onto the stack */ - if (IsQualFastcall (Func->Type) && D->ParamCount > 0) { - + if ((D->Flags & FD_VARIADIC) == 0 && D->ParamCount > 0 && + (AutoCDecl ? + IsQualFastcall (Func->Type) : + !IsQualCDecl (Func->Type))) { unsigned Flags; - /* Fastcall functions may never have an ellipsis or the compiler is buggy */ - CHECK ((D->Flags & FD_VARIADIC) == 0); - /* Generate the push */ if (IsTypeFunc (D->LastParam->Type)) { /* Pointer to function */ diff --git a/src/cc65/global.c b/src/cc65/global.c index e2800a65e..dbdd72f3c 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -44,6 +44,7 @@ unsigned char AddSource = 0; /* Add source lines as comments */ +unsigned char AutoCDecl = 0; /* Make functions default to __cdecl__ */ unsigned char DebugInfo = 0; /* Add debug info to the obj */ unsigned char PreprocessOnly = 0; /* Just preprocess the input */ unsigned char DebugOptOutput = 0; /* Output debug stuff */ diff --git a/src/cc65/global.h b/src/cc65/global.h index 2abd78601..8b0af5a83 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -52,6 +52,7 @@ /* Options */ extern unsigned char AddSource; /* Add source lines as comments */ +extern unsigned char AutoCDecl; /* Make functions default to __cdecl__ */ extern unsigned char DebugInfo; /* Add debug info to the obj */ extern unsigned char PreprocessOnly; /* Just preprocess the input */ extern unsigned char DebugOptOutput; /* Output debug stuff */ diff --git a/src/cc65/main.c b/src/cc65/main.c index 13fe76db4..1041b8fa2 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2013, Ullrich von Bassewitz */ +/* (C) 2000-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -104,6 +104,7 @@ static void Usage (void) "\n" "Long options:\n" " --add-source\t\t\tInclude source as comment\n" + " --all-cdecl\t\t\tMake functions default to __cdecl__\n" " --bss-name seg\t\tSet the name of the BSS segment\n" " --check-stack\t\t\tGenerate stack overflow checks\n" " --code-name seg\t\tSet the name of the CODE segment\n" @@ -258,6 +259,10 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__SIM65C02__", 1); break; + case TGT_OSIC1P: + DefineNumericMacro ("__OSIC1P__", 1); + break; + case TGT_PCENGINE: DefineNumericMacro ("__PCE__", 1); break; @@ -350,6 +355,15 @@ static void OptAddSource (const char* Opt attribute ((unused)), +static void OptAllCDecl (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Make functions default to cdecl instead of fastcall. */ +{ + AutoCDecl = 1; +} + + + static void OptBssName (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --bss-name option */ { @@ -790,6 +804,7 @@ int main (int argc, char* argv[]) /* Program long options */ static const LongOpt OptTab[] = { { "--add-source", 0, OptAddSource }, + { "--all-cdecl", 0, OptAllCDecl }, { "--bss-name", 1, OptBssName }, { "--check-stack", 0, OptCheckStack }, { "--code-name", 1, OptCodeName }, diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 67941026b..673dfa163 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2008 Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2015, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -37,6 +37,7 @@ /* cc65 */ #include "funcdesc.h" +#include "global.h" #include "symtab.h" #include "typecmp.h" @@ -245,23 +246,36 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) return; } } + + if (LeftType == T_TYPE_FUNC) { + /* If a calling convention wasn't set explicitly, + ** then assume the default one. + */ + if ((LeftQual & T_QUAL_CCONV) == T_QUAL_NONE) { + LeftQual |= (AutoCDecl || IsVariadicFunc (lhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL; + } + if ((RightQual & T_QUAL_CCONV) == T_QUAL_NONE) { + RightQual |= (AutoCDecl || IsVariadicFunc (rhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL; + } + } + if (LeftQual != RightQual) { /* On the first indirection level, different qualifiers mean - ** that the types are still compatible. On the second level, - ** this is a (maybe minor) error, so we create a special - ** return code, since a qualifier is dropped from a pointer. - ** Starting from the next level, the types are incompatible - ** if the qualifiers differ. + ** that the types still are compatible. On the second level, + ** that is a (maybe minor) error. We create a special return-code + ** if a qualifier is dropped from a pointer. But, different calling + ** conventions are incompatible. Starting from the next level, + ** the types are incompatible if the qualifiers differ. */ + /* (Debugging statement) */ /* printf ("Ind = %d %06X != %06X\n", Indirections, LeftQual, RightQual); */ switch (Indirections) { - case 0: SetResult (Result, TC_STRICT_COMPATIBLE); break; case 1: - /* A non const value on the right is compatible to a + /* A non-const value on the right is compatible to a ** const one to the left, same for volatile. */ if ((LeftQual & T_QUAL_CONST) < (RightQual & T_QUAL_CONST) || @@ -270,7 +284,11 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) } else { SetResult (Result, TC_STRICT_COMPATIBLE); } - break; + + if (LeftType != T_TYPE_FUNC || (LeftQual & T_QUAL_CCONV) == (RightQual & T_QUAL_CCONV)) { + break; + } + /* else fall through */ default: SetResult (Result, TC_INCOMPATIBLE); @@ -280,7 +298,6 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) /* Check for special type elements */ switch (LeftType) { - case T_TYPE_PTR: ++Indirections; break; diff --git a/src/common/target.c b/src/common/target.c index 013afe8ba..60b9af660 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2011, Ullrich von Bassewitz */ +/* (C) 2000-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -50,7 +50,7 @@ /* Translation table with direct (no) translation */ -static unsigned char CTNone[256] = { +static const unsigned char CTNone[256] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -69,8 +69,8 @@ static unsigned char CTNone[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; -/* Translation table ISO-8859-1 -> ATASCII */ -static const unsigned char CTAtari [256] = { +/* Translation table ISO-8859-1 -> AtASCII */ +static const unsigned char CTAtari[256] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0xFD,0x08,0x7F,0x9B,0x0B,0x7D,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -89,8 +89,28 @@ static const unsigned char CTAtari [256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; -/* Translation table ISO-8859-1 -> PETSCII */ -static const unsigned char CTPET [256] = { +/* Translation table ISO-8859-1 -> OSASCII */ +static const unsigned char CTOSI[256] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7D,0x7C,0x7F,0x7E, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, +}; + +/* Translation table ISO-8859-1 -> PetSCII */ +static const unsigned char CTPET[256] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x14,0x09,0x0D,0x11,0x93,0x0A,0x0E,0x0F, 0x10,0x0B,0x12,0x13,0x08,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, @@ -142,6 +162,7 @@ static const TargetEntry TargetMap[] = { { "module", TGT_MODULE }, { "nes", TGT_NES }, { "none", TGT_NONE }, + { "osic1p", TGT_OSIC1P }, { "pce", TGT_PCENGINE }, { "pet", TGT_PET }, { "plus4", TGT_PLUS4 }, @@ -168,6 +189,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "plus4", CPU_6502, BINFMT_BINARY, CTPET }, { "cbm510", CPU_6502, BINFMT_BINARY, CTPET }, { "cbm610", CPU_6502, BINFMT_BINARY, CTPET }, + { "osic1p", CPU_6502, BINFMT_BINARY, CTOSI }, { "pet", CPU_6502, BINFMT_BINARY, CTPET }, { "bbc", CPU_6502, BINFMT_BINARY, CTNone }, { "apple2", CPU_6502, BINFMT_BINARY, CTNone }, diff --git a/src/common/target.h b/src/common/target.h index ae9f931c4..3ea562aa6 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -64,6 +64,7 @@ typedef enum { TGT_PLUS4, TGT_CBM510, TGT_CBM610, + TGT_OSIC1P, TGT_PET, TGT_BBC, TGT_APPLE2, diff --git a/src/common/version.c b/src/common/version.c index d2fcf4f40..4e61a5f83 100644 --- a/src/common/version.c +++ b/src/common/version.c @@ -47,7 +47,7 @@ #define VER_MAJOR 2U -#define VER_MINOR 14U +#define VER_MINOR 15U diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index 1cfb5ba45..a9143584a 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -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 */ { diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h index c9fb9c35f..18515ce49 100644 --- a/src/da65/attrtab.h +++ b/src/da65/attrtab.h @@ -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 diff --git a/src/da65/data.c b/src/da65/data.c index f4c37818f..7355e60d1 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -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; diff --git a/src/da65/infofile.c b/src/da65/infofile.c index 4ee1ffd79..e8ce66cf7 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -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 */ diff --git a/src/da65/main.c b/src/da65/main.c index a819f9771..8c37e1ae2 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -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; + } } } diff --git a/src/da65/output.c b/src/da65/output.c index 9098d7d37..4daacb1ee 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -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 */ { diff --git a/src/da65/output.h b/src/da65/output.h index ad5f8d34e..13ea0cc85 100644 --- a/src/da65/output.h +++ b/src/da65/output.h @@ -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 diff --git a/src/da65/segment.c b/src/da65/segment.c index cad2096ff..12d4cf656 100644 --- a/src/da65/segment.c +++ b/src/da65/segment.c @@ -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; +} diff --git a/src/da65/segment.h b/src/da65/segment.h index 14700ba99..b1423bb41 100644 --- a/src/da65/segment.h +++ b/src/da65/segment.h @@ -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 diff --git a/test/Makefile b/test/Makefile index b942cbcdf..702b332d5 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,41 +1,43 @@ -# 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 + DEL = -del /f $(subst /,\,$1) + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) else - RM := rm -f EXE := - MKDIR = mkdir -p - RMDIR = rmdir + DEL = $(RM) $1 + MKDIR = mkdir $1 + RMDIR = rmdir $1 endif WORKDIR := ../testwrk -.PHONY: dotests clean +CC := gcc + +.PHONY: all dotests continue mostly-clean clean all: dotests $(WORKDIR): - @$(MKDIR) $(WORKDIR) + $(call 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 +45,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 + @$(call DEL,$(WORKDIR)/bdiff$(EXE)) + @$(call RMDIR,$(WORKDIR)) diff --git a/test/err/Makefile b/test/err/Makefile index 40ccfcb59..454a560ce 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -2,51 +2,47 @@ # makefile for the tests that MUST NOT compile ifneq ($(shell echo),) - CMD_EXE = 1 + CMD_EXE := 1 endif -CC65FLAGS = -t sim6502 +ifdef CMD_EXE + NOT := - # Hack + DEL = -del /f $(subst /,\,$1) +else + NOT := ! + DEL = $(RM) $1 +endif + +CC65FLAGS := -t sim6502 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) -ifdef CMD_EXE -RM := del /f -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) $(WORKDIR)/%.prg: %.c - ! $(CL65) $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) $(CC65FLAGS) $< -o $@ $(WORKDIR)/%.o.prg: %.c - ! $(CL65) -O $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) -O $(CC65FLAGS) $< -o $@ $(WORKDIR)/%.os.prg: %.c - ! $(CL65) -Os $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) -Os $(CC65FLAGS) $< -o $@ $(WORKDIR)/%.osi.prg: %.c - ! $(CL65) -Osi $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) -Osi $(CC65FLAGS) $< -o $@ $(WORKDIR)/%.osir.prg: %.c - ! $(CL65) -Osir $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) -Osir $(CC65FLAGS) $< -o $@ $(WORKDIR)/%.oi.prg: %.c - ! $(CL65) -Oi $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) -Oi $(CC65FLAGS) $< -o $@ $(WORKDIR)/%.oir.prg: %.c - ! $(CL65) -Oir $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) -Oir $(CC65FLAGS) $< -o $@ $(WORKDIR)/%.or.prg: %.c - ! $(CL65) -Or $(CC65FLAGS) $< -o $@ + $(NOT) $(CL65) -Or $(CC65FLAGS) $< -o $@ + clean: - @$(RM) $(TESTS) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o) + @$(call DEL,$(TESTS)) + @$(call DEL,$(SOURCES:.c=.o)) diff --git a/test/err/cc65091001.c b/test/err/cc65091001.c index 265df0aac..65ce6ec83 100644 --- a/test/err/cc65091001.c +++ b/test/err/cc65091001.c @@ -9,6 +9,7 @@ #include <assert.h> #include <string.h> +#include <stdio.h> typedef unsigned char U8; char var = 0xf0; char fn(char bar) diff --git a/test/misc/Makefile b/test/misc/Makefile index b18d9165e..918316c6c 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -2,66 +2,62 @@ # 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 - -CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) -SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65) - ifdef CMD_EXE -RM := del /f + S := $(subst /,\,/) + NOT := - # Hack + DEL = -del /f $(subst /,\,$1) else -RM := rm -f + S := / + NOT := ! + DEL = $(RM) $1 endif -WORKDIR := ./../../testwrk +CC65FLAGS := -t sim6502 +SIM65FLAGS := -x 200000000 +CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) +SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) + +WORKDIR := ..$S..$Stestwrk 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 $@ - ! $(SIM65) $(SIM65FLAGS) $@ + $(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ + $(NOT) $(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 $@ + @echo "FIXME: " $@ "currently will fail." + -$(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ +# -$(SIM65) $(SIM65FLAGS) $@ +$(WORKDIR)/cc65141011%prg: cc65141011.c + @echo "FIXME: " $@ "currently can fail." + $(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ -$(SIM65) $(SIM65FLAGS) $@ clean: - @$(RM) $(TESTS) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.out) - - + @$(call DEL,$(TESTS)) + @$(call DEL,$(SOURCES:.c=.o)) + @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.out)) diff --git a/test/misc/cc65141011.c b/test/misc/cc65141011.c new file mode 100755 index 000000000..26cef7099 --- /dev/null +++ b/test/misc/cc65141011.c @@ -0,0 +1,59 @@ +/* + !!DESCRIPTION!! equality problem + !!ORIGIN!! Testsuite + !!LICENCE!! Public Domain +*/ + +/* + Different results, depending on whether constant is on left or right side. + + The optimizer sometimes makes code that executes the right-side expression + as eight bits; but then, tests it against the left-side zero as 16 bits. + The high-byte is garbage; therefore, that test might, or might not, work. + It depends on the platform and the amount of optimization. + + http://www.cc65.org/mailarchive/2014-10/11680.html + http://www.cc65.org/mailarchive/2014-10/11682.html + http://www.cc65.org/mailarchive/2014-10/11683.html +*/ + +#include <stdio.h> + +static unsigned char fails = 4; +static unsigned char bad[3], good[3]; + +int main(void) +{ + unsigned char joy_state = 0x7e; + unsigned a, b; + + /* NOTE: It fails in only the printf() statements, the other stuff + below works! */ + printf("bad: %u, ", 0 == (joy_state & 1) ); + printf("good: %u\n", (joy_state & 1) == 0 ); + + sprintf(bad, "%u", 0 == (joy_state & 1) ); + sprintf(good, "%u", (joy_state & 1) == 0 ); + + printf("bad: %u, ", bad[0] - '0' ); + printf("good: %u\n", good[0] - '0' ); + + fails -= bad[0] - '0'; + fails -= good[0] - '0'; + + if (0 == (joy_state & 1)) fails--; + if ((joy_state & 1) == 0) fails--; + + printf("failures: %u\n", fails ); + + /* The above printf() returns a value with a zero high-byte. + ** Therefore, the next (broken) statement works (by accident). + */ + a = 0 == (joy_state & 1); + b = (joy_state & 1) == 0; + + printf("a: %u, ", a ); + printf("b: %u\n", b ); + + return fails; +} diff --git a/test/ref/Makefile b/test/ref/Makefile index b752adc1d..09dd96d44 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -3,46 +3,50 @@ # compared with reference output ifneq ($(shell echo),) - CMD_EXE = 1 + CMD_EXE := 1 endif -CC65FLAGS = -t sim6502 -SIM65FLAGS = -x 200000000 - -CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) -SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65) - ifdef CMD_EXE -RM := del /f + S := $(subst /,\,/) + DEL = -del /f $(subst /,\,$1) else -RM := rm -f + S := / + DEL = $(RM) $1 endif -WORKDIR := ./../../testwrk +CC65FLAGS := -t sim6502 +SIM65FLAGS := -x 200000000 +CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) +SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) + +WORKDIR := ..$S..$Stestwrk DIFF := $(WORKDIR)/bdiff +CC := gcc 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) $(WORKDIR)/%.ref: %.c $(CC) $(CFLAGS) $< -o $(WORKDIR)/$*.host - $(WORKDIR)/$*.host > $@ + $(WORKDIR)$S$*.host > $@ + +# Some files have "K & R"-style syntax. Therefore, some forward +# function-declarations don't match the later function definitions. +# Those programs fail when fastcall is used; but, the cdecl calling convention +# tolerates those conflicts. Therefore, make their functions default to cdecl. +# +$(WORKDIR)/init%prg: CC65FLAGS += -Wc --all-cdecl +$(WORKDIR)/switch.%rg: CC65FLAGS += -Wc --all-cdecl +$(WORKDIR)/yacc.%rg: CC65FLAGS += -Wc --all-cdecl +$(WORKDIR)/yaccdbg%prg: CC65FLAGS += -Wc --all-cdecl $(WORKDIR)/%.prg: %.c $(WORKDIR)/%.ref $(CL65) $(CC65FLAGS) $< -o $@ @@ -85,8 +89,8 @@ $(WORKDIR)/%.or.prg: %.c $(WORKDIR)/%.ref $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref clean: - @$(RM) $(TESTS) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.out) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.ref) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.host) + @$(call DEL,$(TESTS)) + @$(call DEL,$(SOURCES:.c=.o)) + @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.out)) + @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.ref)) + @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.host)) diff --git a/test/ref/otccex.c b/test/ref/otccex.c index f3d6c71ec..aa5df158f 100644 --- a/test/ref/otccex.c +++ b/test/ref/otccex.c @@ -126,7 +126,7 @@ mymain(int argc,char **argv) } else { /* why not using a function pointer ? */ f = &fact; - print_num((*(long (*)())f)(n), base); + print_num((*(long (*)(int))f)(n), base); } printf("\n"); return 0; diff --git a/test/val/Makefile b/test/val/Makefile index 2e0aca278..4ad8160ef 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -2,37 +2,37 @@ # 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 +ifdef CMD_EXE + DEL = -del /f $(subst /,\,$1) +else + DEL = $(RM) $1 +endif + +CC65FLAGS := -t sim6502 +SIM65FLAGS := -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65) -ifdef CMD_EXE -RM := del /f -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) +# Some files have "K & R"-style syntax. Therefore, some forward +# function-declarations don't match the later function definitions. +# Those programs fail when fastcall is used; but, the cdecl calling convention +# tolerates those conflicts. Therefore, make their functions default to cdecl. +# +$(WORKDIR)/cq4%prg $(WORKDIR)/cq71.%rg $(WORKDIR)/cq81%prg $(WORKDIR)/cq84%prg: CC65FLAGS += -Wc --all-cdecl + $(WORKDIR)/%.prg: %.c $(CL65) $(CC65FLAGS) $< -o $@ $(SIM65) $(SIM65FLAGS) $@ @@ -66,5 +66,5 @@ $(WORKDIR)/%.or.prg: %.c $(SIM65) $(SIM65FLAGS) $@ clean: - @$(RM) $(TESTS) - @$(RM) $(SOURCES:%.c=$(WORKDIR)/%.o) + @$(call DEL,$(TESTS)) + @$(call DEL,$(SOURCES:.c=.o)) diff --git a/test/val/add3a.c b/test/val/add3a.c new file mode 100755 index 000000000..4ca32d06b --- /dev/null +++ b/test/val/add3a.c @@ -0,0 +1,73 @@ + +/* + !!DESCRIPTION!! Addition tests - mostly int's + !!ORIGIN!! SDCC regression tests + !!LICENCE!! GPL, read COPYING.GPL +*/ + +#include <stdio.h> +#include <stdlib.h> + +static unsigned int failures = 0; + +/* + this test assumes: + sizeof(long) == 4 + + CAUTION: the wraparound behaviour is actually undefined, to get the "expected" + behaviour with GCC, use -fwrapv or -fno-strict-overflow + + see: https://gcc.gnu.org/wiki/FAQ#signed_overflow +*/ + +#ifdef REFERENCE + +/* + make sure the reference output uses types with + proper size +*/ + +#include <stdint.h> + +int32_t long0 = 0; + +#else + +long long0 = 0; + +#endif + +void print(void) +{ +#if defined(REFERENCE) && defined(REFCC_SIZEOF_LONG_64BIT) + printf("long0: %d\n", long0); +#else + printf("long0: %ld\n", long0); +#endif +} + +int main(void) +{ + long0 = 0x7f000000L; + /* wrap around zero */ + print(); + long0 = long0 + 0x2000000L; + if(long0 != -0x7f000000L) { + printf("failed!\n"); + failures++; + } + print(); + + long0 = 0x7f000000L; + /* wrap around zero */ + print(); + long0 = long0 + 0x2000000L; + print(); + if(long0 != -0x7f000000L) { + printf("failed!\n"); + failures++; + } + print(); + + return failures; +} diff --git a/test/val/casttochar.c b/test/val/casttochar.c new file mode 100755 index 000000000..d492f6bb8 --- /dev/null +++ b/test/val/casttochar.c @@ -0,0 +1,49 @@ + +/* + !!DESCRIPTION!! Cast to char + !!ORIGIN!! Piotr Fusik + !!LICENCE!! PD +*/ + +#include <stdio.h> +#include <stdlib.h> + +static unsigned int failures = 0; + +int f1(int i, int j) { + return (signed char) (i + 1) == j; +} + +int f2(int i, int j) { + return (unsigned char) (i + 1) == j; +} + +int f3(int i, int j) { + return (char) (i + 1) == j; +} + +int main(void) +{ + printf("f1: got :%04x ", f1(0x1234, 0x35)); + if(f1(0x1234, 0x35) == 0) { + printf("- failed"); + failures++; + } + printf("\n"); + + printf("f2: got :%04x ", f2(0x1234, 0x35)); + if(f2(0x1234, 0x35) == 0) { + printf("- failed"); + failures++; + } + printf("\n"); + + printf("f3: got :%04x ", f3(0x1234, 0x35)); + if(f3(0x1234, 0x35) == 0) { + printf("- failed"); + failures++; + } + printf("\n"); + + return failures; +} diff --git a/test/val/cc65141002.c b/test/val/cc65141002.c new file mode 100755 index 000000000..ae5cd3d5f --- /dev/null +++ b/test/val/cc65141002.c @@ -0,0 +1,45 @@ + +/* + !!DESCRIPTION!! forgetting to emit labels + !!ORIGIN!! Testsuite + !!LICENCE!! Public Domain +*/ + +/* + http://www.cc65.org/mailarchive/2014-10/11673.html + http://www.cc65.org/mailarchive/2014-10/11675.html +*/ + +#include <stdlib.h> +#include <stdio.h> + +struct udata { + int (*u_sigvec[16])(); + int u_argn; + int u_argn1; +}; + +struct udata udata; + +#define sig (int)udata.u_argn +#define func (int (*)())udata.u_argn1 + +int _signal(void) +{ + if (func != 0) { + goto nogood; + } + udata.u_sigvec[sig] = func; + return 0; + +nogood: + return (-1); +} + +int main(int n,char **args) +{ + _signal(); + printf("it works\n"); + + return 0; +} diff --git a/test/val/cc65141022.c b/test/val/cc65141022.c new file mode 100755 index 000000000..1d7792cf2 --- /dev/null +++ b/test/val/cc65141022.c @@ -0,0 +1,57 @@ + +/* + !!DESCRIPTION!! struct base address dereferencing bug + !!ORIGIN!! Testsuite + !!LICENCE!! Public Domain +*/ + +#include <stdlib.h> +#include <stdio.h> + +struct yywork +{ + char verify, advance; +} yycrank[] = +{ + {0,0} +}; + +struct yysvf +{ + struct yywork *yystoff; +} yysvec[1]; + +unsigned char fails = 0; + +int main(int n, char **args) +{ + struct yysvf *yystate = yysvec; + struct yywork *yyt; + + yystate->yystoff = yycrank; + yyt = yystate->yystoff; + + if(yyt == yycrank) { + printf("yyt == yycrank (ok)\n"); + } else { + printf("yyt != yycrank (fail)\n"); + ++fails; + } + + if(yyt == yystate->yystoff) { + printf("yyt == yystate->yystoff (ok)\n"); + } else { + printf("yyt != yystate->yystoff (fail)\n"); + ++fails; + } + + if(yycrank == yystate->yystoff) { + printf("yycrank == yystate->yystoff (ok)\n"); + } else { + printf("yycrank != yystate->yystoff (fail)\n"); + ++fails; + } + + printf("fails: %d\n", fails); + return fails; +} diff --git a/test/val/pointed-array.c b/test/val/pointed-array.c new file mode 100644 index 000000000..3390ac94b --- /dev/null +++ b/test/val/pointed-array.c @@ -0,0 +1,91 @@ +/* +** !!DESCRIPTION!! Simple tests of pointer-to-array dereferences +** !!ORIGIN!! cc65 regression tests +** !!LICENCE!! Public Domain +** !!AUTHOR!! 2015-06-29, Greg King +*/ + +#include <stdio.h> + +static unsigned char failures = 0; +static size_t Size; + +typedef unsigned char array_t[4][4]; + +static array_t table = { + {12, 13, 14, 15}, + { 8, 9, 10, 11}, + { 4, 5, 6, 7}, + { 0, 1, 2, 3} +}; +static array_t *tablePtr = &table; + +static unsigned (*vector)[2]; + +static unsigned char y = 0, x; + +int main(void) +{ + /* The indirection must convert the expression-type (from Pointer into + ** Array); but, it must not convert the value, because it already points + ** to the start of the array. + */ + /* (Note: I reduce output clutter by using a variable to prevent + ** compiler warnings about constant comparisons and unreachable code. + */ + if ((Size = sizeof *tablePtr) != sizeof table) { + ++failures; + } + if (*tablePtr != table) { + ++failures; + } + + /* Test fetching. */ + do { + x = 0; + do { + if ((*tablePtr)[y][x] != table[y][x]) { + ++failures; + printf("(*tableptr)[%u][%u] (%u) != table[%u][%u] (%u).\n", + y, x, (*tablePtr)[y][x], + y, x, table[y][x]); + } + } while (++x < sizeof table[0]); + } while (++y < sizeof table / sizeof table[0]); + + vector = (unsigned (*)[])table[1]; + if ((*vector)[1] != 0x0B0A) { + ++failures; + } + + /* Test storing. */ + (*tablePtr)[2][1] = 42; + if (table[2][1] != 42) { + ++failures; + printf("table[2][1] == %u (should have changed from 5 to 42).\n", + table[2][1]); + } + x = 3; + y = 1; + (*tablePtr)[y][x] = 83; + if (table[1][3] != 83) { + ++failures; + printf("table[y][x] == %u (should have changed from 11 to 83).\n", + table[1][3]); + } + + /* Test triple indirection. It should compile to two indirection + ** operations. + */ + --***tablePtr; + if (**table != 11) { + ++failures; + printf("**table == %u (should have changed from 12 to 11).\n", + table[0][0]); + } + + if (failures != 0) { + printf("failures: %u\n", failures); + } + return failures; +} diff --git a/test/val/ptrfunc.c b/test/val/ptrfunc.c index e1682507a..55503e176 100644 --- a/test/val/ptrfunc.c +++ b/test/val/ptrfunc.c @@ -5,7 +5,8 @@ */ #include <stdio.h> -#include <limits.h> + +#define NO_IMPLICIT_FUNCPTR_CONV unsigned char success=0; unsigned char failures=0;