1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 06:25:17 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
mrdudz
2022-02-20 18:07:57 +01:00
19 changed files with 416 additions and 204 deletions

View File

@@ -23,9 +23,10 @@ jobs:
- name: Build the tools. - name: Build the tools.
shell: bash shell: bash
run: | run: make -j2 bin USER_CFLAGS=-Werror
make -j2 bin USER_CFLAGS=-Werror - name: Build the utilities.
make -j2 util shell: bash
run: make -j2 util
- name: Build the platform libraries. - name: Build the platform libraries.
shell: bash shell: bash
run: make -j2 lib QUIET=1 run: make -j2 lib QUIET=1
@@ -33,135 +34,9 @@ jobs:
shell: bash shell: bash
run: make test QUIET=1 run: make test QUIET=1
- name: Test that the samples can be built. - name: Test that the samples can be built.
shell: bash run: make -C samples platforms
run: |
make SYS=apple2 -C samples
make SYS=apple2 -C samples clean
make SYS=apple2enh -C samples
make SYS=apple2enh -C samples clean
make SYS=atari -C samples
make SYS=atari -C samples clean
make SYS=atarixl -C samples
make SYS=atarixl -C samples clean
make SYS=atari2600 -C samples
make SYS=atari2600 -C samples clean
make SYS=atari5200 -C samples
make SYS=atari5200 -C samples clean
make SYS=atmos -C samples
make SYS=atmos -C samples clean
make SYS=bbc -C samples
make SYS=bbc -C samples clean
make SYS=c128 -C samples
make SYS=c128 -C samples clean
make SYS=c16 -C samples
make SYS=c16 -C samples clean
make SYS=c64 -C samples
make SYS=c64 -C samples clean
make SYS=cbm510 -C samples
make SYS=cbm510 -C samples clean
make SYS=cbm610 -C samples
make SYS=cbm610 -C samples clean
make SYS=creativision -C samples
make SYS=creativision -C samples clean
make SYS=cx16 -C samples
make SYS=cx16 -C samples clean
make SYS=gamate -C samples
make SYS=gamate -C samples clean
make SYS=geos-apple -C samples
make SYS=geos-apple -C samples clean
make SYS=geos-cbm -C samples
make SYS=geos-cbm -C samples clean
make SYS=lunix -C samples
make SYS=lunix -C samples clean
make SYS=lynx -C samples
make SYS=lynx -C samples clean
make SYS=nes -C samples
make SYS=nes -C samples clean
make SYS=osic1p -C samples
make SYS=osic1p -C samples clean
make SYS=pce -C samples
make SYS=pce -C samples clean
make SYS=pet -C samples
make SYS=pet -C samples clean
make SYS=plus4 -C samples
make SYS=plus4 -C samples clean
make SYS=sim6502 -C samples
make SYS=sim6502 -C samples clean
make SYS=sim65c02 -C samples
make SYS=sim65c02 -C samples clean
make SYS=supervision -C samples
make SYS=supervision -C samples clean
make SYS=sym1 -C samples
make SYS=sym1 -C samples clean
make SYS=telestrat -C samples
make SYS=telestrat -C samples clean
make SYS=vic20 -C samples
make SYS=vic20 -C samples clean
- name: Test that the targettest programs can be built. - name: Test that the targettest programs can be built.
shell: bash run: make -C targettest platforms
run: |
make SYS=apple2 -C targettest
make SYS=apple2 -C targettest clean
make SYS=apple2enh -C targettest
make SYS=apple2enh -C targettest clean
make SYS=atari -C targettest
make SYS=atari -C targettest clean
make SYS=atarixl -C targettest
make SYS=atarixl -C targettest clean
make SYS=atari2600 -C targettest
make SYS=atari2600 -C targettest clean
make SYS=atari5200 -C targettest
make SYS=atari5200 -C targettest clean
make SYS=atmos -C targettest
make SYS=atmos -C targettest clean
make SYS=bbc -C targettest
make SYS=bbc -C targettest clean
make SYS=c128 -C targettest
make SYS=c128 -C targettest clean
make SYS=c16 -C targettest
make SYS=c16 -C targettest clean
make SYS=c64 -C targettest
make SYS=c64 -C targettest clean
make SYS=cbm510 -C targettest
make SYS=cbm510 -C targettest clean
make SYS=cbm610 -C targettest
make SYS=cbm610 -C targettest clean
make SYS=creativision -C targettest
make SYS=creativision -C targettest clean
make SYS=cx16 -C targettest
make SYS=cx16 -C targettest clean
make SYS=gamate -C targettest
make SYS=gamate -C targettest clean
make SYS=geos-apple -C targettest
make SYS=geos-apple -C targettest clean
make SYS=geos-cbm -C targettest
make SYS=geos-cbm -C targettest clean
make SYS=lunix -C targettest
make SYS=lunix -C targettest clean
make SYS=lynx -C targettest
make SYS=lynx -C targettest clean
make SYS=nes -C targettest
make SYS=nes -C targettest clean
make SYS=osic1p -C targettest
make SYS=osic1p -C targettest clean
make SYS=pce -C targettest
make SYS=pce -C targettest clean
make SYS=pet -C targettest
make SYS=pet -C targettest clean
make SYS=plus4 -C targettest
make SYS=plus4 -C targettest clean
make SYS=sim6502 -C targettest
make SYS=sim6502 -C targettest clean
make SYS=sim65c02 -C targettest
make SYS=sim65c02 -C targettest clean
make SYS=supervision -C targettest
make SYS=supervision -C targettest clean
make SYS=sym1 -C targettest
make SYS=sym1 -C targettest clean
make SYS=telestrat -C targettest
make SYS=telestrat -C targettest clean
make SYS=vic20 -C targettest
make SYS=vic20 -C targettest clean
- name: Build the document files. - name: Build the document files.
shell: bash shell: bash
run: make -j2 doc run: make -j2 doc

View File

@@ -10,6 +10,7 @@ concurrency:
jobs: jobs:
build_windows: build_windows:
name: Build (Windows) name: Build (Windows)
if: github.repository == 'cc65/cc65'
runs-on: windows-latest runs-on: windows-latest
steps: steps:
@@ -29,9 +30,9 @@ jobs:
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release
build_linux: build_linux:
name: Build, Test and Snaphot (Linux) name: Build, Test, and Snapshot (Linux)
if: github.repository == 'cc65/cc65'
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build_windows
steps: steps:
- name: Install Dependencies - name: Install Dependencies

View File

@@ -1,5 +1,7 @@
[Windows Snapshot](https://sourceforge.net/projects/cc65/files/cc65-snapshot-win32.zip) [Windows Snapshot](https://sourceforge.net/projects/cc65/files/cc65-snapshot-win32.zip)
[Linux Snapshot DEB and RPM](https://software.opensuse.org//download.html?project=home%3Astrik&package=cc65)
[Documentation](https://cc65.github.io/doc) [Documentation](https://cc65.github.io/doc)
[Wiki](https://github.com/cc65/wiki/wiki) [Wiki](https://github.com/cc65/wiki/wiki)

View File

@@ -16,7 +16,7 @@ How to debug your code using the VICE and Oricutron emulators.
<sect>Overview<p> <sect>Overview<p>
This document describes how to debug your programs using the cc65 development This document describes how to debug your programs using the cc65 development
tools and the VICE CBM emulator. tools and the VICE or Oricutron emulator.
@@ -126,6 +126,12 @@ and you may use them wherever you need to specify an address. Try
as an example (note that VICE needs a leading dot before all labels, and that as an example (note that VICE needs a leading dot before all labels, and that
the compiler prepends an underline under most named labels). the compiler prepends an underline under most named labels).
If you start the emulator from the commandline, you can also load the labels
directly using something like this:
<tscreen><verb>
x64sc -moncommands hello.lbl hello.prg
</verb></tscreen>
<sect>How to use the label file with Oricutron<p> <sect>How to use the label file with Oricutron<p>
@@ -144,8 +150,7 @@ and you may use them wherever you need to specify an address. Try
d ._main d ._main
</verb></tscreen> </verb></tscreen>
as an example (note that VICE needs a leading dot before all labels, and that as an example.
the compiler prepends an underline under most named labels).

View File

@@ -754,6 +754,16 @@ communication, see also <tt>testcode/lib/ser-test.c</tt>.
</itemize> </itemize>
<sect1><tt/sym1.h/<label id="sym1.h"><p>
<itemize>
<item><ref id="beep" name="beep">
<item><ref id="fdisp" name="fdisp">
<item><ref id="loadt" name="loadt">
<item><ref id="dumpt" name="dumpt">
</itemize>
<sect1><tt/telestrat.h/<label id="telestrat.h"><p> <sect1><tt/telestrat.h/<label id="telestrat.h"><p>
<itemize> <itemize>
@@ -1669,6 +1679,27 @@ used in presence of a prototype.
</quote> </quote>
<sect1>beep<label id="beep"><p>
<quote>
<descrip>
<tag/Function/Beep sound.
<tag/Header/<tt/<ref id="sym1.h" name="sym1.h">/
<tag/Declaration/<tt/void beep(void);/
<tag/Description/<tt/beep/ makes a brief tone.
<tag/Notes/<itemize>
<item>The function is specific to the Sym-1.
</itemize>
<tag/Availability/cc65
<tag/See also/
<ref id="fdisp" name="fdisp">,
<ref id="loadt" name="loadt">,
<ref id="dumpt" name="dumpt">,
<tag/Example/None.
</descrip>
</quote>
<sect1>bgcolor<label id="bgcolor"><p> <sect1>bgcolor<label id="bgcolor"><p>
<quote> <quote>
@@ -3363,6 +3394,30 @@ int main(void)
</quote> </quote>
<sect1>dumpt<label id="dumpt"><p>
<quote>
<descrip>
<tag/Function/Dump memory to tape.
<tag/Header/<tt/<ref id="sym1.h" name="sym1.h">/
<tag/Declaration/<tt/int __fastcall__ dumpt (unsigned char id, const void* start, const void* end);/
<tag/Description/<tt/dumpt/ saves memory onto data tape.
<tag/Notes/<itemize>
<item>The function is specific to the Sym-1.
<item>The return value is status. Non-zero status indicates an error.
<item>The function is only available as fastcall function, so it may only
be used in presence of a prototype.
</itemize>
<tag/Availability/cc65
<tag/See also/
<ref id="beep" name="beep">,
<ref id="fdisp" name="fdisp">,
<ref id="loadt" name="loadt">,
<tag/Example/None.
</descrip>
</quote>
<sect1>em_commit<label id="em_commit"><p> <sect1>em_commit<label id="em_commit"><p>
<quote> <quote>
@@ -3721,6 +3776,28 @@ switching the CPU into double clock mode.
</quote> </quote>
<sect1>fdisp<label id="fdisp"><p>
<quote>
<descrip>
<tag/Function/Flash front-panel display.
<tag/Header/<tt/<ref id="sym1.h" name="sym1.h">/
<tag/Declaration/<tt/void fdisp(void);/
<tag/Description/<tt/fdisp/ flashes front-panel display.
<tag/Notes/<itemize>
<item>The function is specific to the Sym-1.
<item>The front-panel display buffer must be loaded prior to calling fdisp. See the DISPLAY struct definition in sym1.h.
</itemize>
<tag/Availability/cc65
<tag/See also/
<ref id="beep" name="beep">,
<ref id="loadt" name="loadt">,
<ref id="dumpt" name="dumpt">,
<tag/Example/None.
</descrip>
</quote>
<sect1>feof<label id="feof"><p> <sect1>feof<label id="feof"><p>
<quote> <quote>
@@ -4961,6 +5038,30 @@ used in presence of a prototype.
</quote> </quote>
<sect1>loadt<label id="loadt"><p>
<quote>
<descrip>
<tag/Function/Load memory from tape.
<tag/Header/<tt/<ref id="sym1.h" name="sym1.h">/
<tag/Declaration/<tt/int __fastcall__ loadt (unsigned char id);/
<tag/Description/<tt/loadt/ loads memory from data tape.
<tag/Notes/<itemize>
<item>The function is specific to the Sym-1.
<item>The return value is status. Non-zero status indicates an error.
<item>The function is only available as fastcall function, so it may only
be used in presence of a prototype.
</itemize>
<tag/Availability/cc65
<tag/See also/
<ref id="beep" name="beep">,
<ref id="fdisp" name="fdisp">,
<ref id="dumpt" name="dumpt">,
<tag/Example/None.
</descrip>
</quote>
<sect1>ltoa<label id="ltoa"><p> <sect1>ltoa<label id="ltoa"><p>
<quote> <quote>

View File

@@ -38,7 +38,7 @@ Special locations:
Conio support is not currently available for the Sym-1. But stdio console functions are available. Conio support is not currently available for the Sym-1. But stdio console functions are available.
<tag/Stack/ <tag/Stack/
The C runtime stack is located at &dollar;0FFF on 4KB Syms, or at &dollar;7FFFfor 32KB systems. The stack always grows downwards. The C runtime stack is located at &dollar;0FFF on 4KB Syms, or at &dollar;7FFF for 32KB systems. The stack always grows downwards.
<tag/Heap/ <tag/Heap/
The C heap is located at the end of the program and grows towards the C runtime stack. The C heap is located at the end of the program and grows towards the C runtime stack.
@@ -102,7 +102,7 @@ As stated earlier, there are config files for 4KB and 32KB systems. If you have
<sect3>Sample programs<p> <sect3>Sample programs<p>
All the samples will run on the &quot;stock&quot; 4KB Sym-1, except for symIO and symNotepad, which require 32KB. These sample programs can be found in the targettest/sym1 directory: All the samples will run on the &quot;stock&quot; 4KB Sym-1, except for symIO and symNotepad, which require 32KB. These sample programs can be found in the samples/sym1 directory:
<itemize> <itemize>
<item>symHello prints &quot;Hello World!&quot; and then inputs characters, which are echoed on the screen. It also makes a &quot;beep&quot; sound.</item> <item>symHello prints &quot;Hello World!&quot; and then inputs characters, which are echoed on the screen. It also makes a &quot;beep&quot; sound.</item>

View File

@@ -129,7 +129,7 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Generic rules # Generic rules
.PHONY: all mostlyclean clean install zip samples disk .PHONY: samples all mostlyclean clean install zip disk platforms
%: %.c %: %.c
%: %.s %: %.s
@@ -340,7 +340,7 @@ endif
define SUBDIR_recipe define SUBDIR_recipe
@$(MAKE) -C $(dir) --no-print-directory $@ @+$(MAKE) -C $(dir) --no-print-directory $@
endef # SUBDIR_recipe endef # SUBDIR_recipe
@@ -360,6 +360,52 @@ disk: $(DISK_$(SYS))
all: all:
# --------------------------------------------------------------------------
# List of every supported platform
TARGETS := \
apple2 \
apple2enh \
atari \
atarixl \
atari2600 \
atari5200 \
atmos \
bbc \
c128 \
c16 \
c64 \
cbm510 \
cbm610 \
creativision \
cx16 \
gamate \
lunix \
lynx \
nes \
osic1p \
pce \
pet \
plus4 \
sim6502 \
sim65c02 \
supervision \
sym1 \
telestrat \
vic20
# --------------------------------------------------------------------------
# Rule to make the binaries for every platform
define TARGET_recipe
@$(MAKE) -j2 SYS:=$(T)
@$(MAKE) --no-print-directory clean SYS:=$(T)
endef # TARGET_recipe
platforms:
$(foreach T,$(TARGETS),$(TARGET_recipe))
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Overlay rules. Overlays need special ld65 configuration files. Also, the # Overlay rules. Overlays need special ld65 configuration files. Also, the
# overlay file-names are shortenned to fit the Atari's 8.3-character limit. # overlay file-names are shortenned to fit the Atari's 8.3-character limit.

View File

@@ -50,7 +50,7 @@ DIRLIST = grc
define SUBDIR_recipe define SUBDIR_recipe
@$(MAKE) SYS=$(SYS) -C $(dir) --no-print-directory $@ @+$(MAKE) SYS=$(SYS) -C $(dir) --no-print-directory $@
endef # SUBDIR_recipe endef # SUBDIR_recipe

View File

@@ -171,6 +171,25 @@ int IsFarRange (long Val)
static const ExprNode* ResolveSymbolChain(const ExprNode* E)
/* Recursive helper function for IsEasyConst */
{
if (E->Op == EXPR_SYMBOL) {
SymEntry* Sym = E->V.Sym;
if (Sym == 0 || Sym->Expr == 0 || SymHasUserMark (Sym)) {
return 0;
} else {
SymMarkUser (Sym);
E = ResolveSymbolChain (Sym->Expr);
SymUnmarkUser (Sym);
}
}
return E;
}
int IsEasyConst (const ExprNode* E, long* Val) int IsEasyConst (const ExprNode* E, long* Val)
/* Do some light checking if the given node is a constant. Don't care if E is /* Do some light checking if the given node is a constant. Don't care if E is
** a complex expression. If E is a constant, return true and place its value ** a complex expression. If E is a constant, return true and place its value
@@ -178,12 +197,10 @@ int IsEasyConst (const ExprNode* E, long* Val)
*/ */
{ {
/* Resolve symbols, follow symbol chains */ /* Resolve symbols, follow symbol chains */
while (E->Op == EXPR_SYMBOL) { E = ResolveSymbolChain (E);
E = SymResolve (E->V.Sym); if (E == 0) {
if (E == 0) { /* Could not resolve */
/* Could not resolve */ return 0;
return 0;
}
} }
/* Symbols resolved, check for a literal */ /* Symbols resolved, check for a literal */
@@ -1209,11 +1226,11 @@ static ExprNode* Factor (void)
SB_GetLen (&CurTok.SVal) == 1) { SB_GetLen (&CurTok.SVal) == 1) {
/* A character constant */ /* A character constant */
N = GenLiteralExpr (TgtTranslateChar (SB_At (&CurTok.SVal, 0))); N = GenLiteralExpr (TgtTranslateChar (SB_At (&CurTok.SVal, 0)));
NextTok ();
} else { } else {
N = GenLiteral0 (); /* Dummy */ N = GenLiteral0 (); /* Dummy */
Error ("Syntax error"); Error ("Syntax error");
} }
NextTok ();
break; break;
} }
return N; return N;

View File

@@ -546,6 +546,18 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
return; return;
} }
/* If the symbol is already defined, check symbol size against the
** exported size.
*/
if (S->Flags & SF_DEFINED) {
if (AddrSize == ADDR_SIZE_DEFAULT) {
/* Use the real size of the symbol */
AddrSize = S->AddrSize;
} else if (S->AddrSize != AddrSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S));
}
}
/* If the symbol was already marked as an export or global, check if /* If the symbol was already marked as an export or global, check if
** this was done specifiying the same address size. In case of a global ** this was done specifiying the same address size. In case of a global
** declaration, silently remove the global flag. ** declaration, silently remove the global flag.
@@ -558,18 +570,6 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
} }
S->ExportSize = AddrSize; S->ExportSize = AddrSize;
/* If the symbol is already defined, check symbol size against the
** exported size.
*/
if (S->Flags & SF_DEFINED) {
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
/* Use the real size of the symbol */
S->ExportSize = S->AddrSize;
} else if (S->AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S));
}
}
/* If the symbol already was declared as a condes of this type, /* If the symbol already was declared as a condes of this type,
** check if the new priority value is the same as the old one. ** check if the new priority value is the same as the old one.
*/ */

View File

@@ -1462,7 +1462,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
case TOK_IDENT: case TOK_IDENT:
/* This could be a label */ /* This could be a label */
if (NextTok.Tok != TOK_COLON) { if (NextTok.Tok != TOK_COLON || GetLexicalLevel () == LEX_LEVEL_STRUCT) {
Entry = FindSym (CurTok.Ident); Entry = FindSym (CurTok.Ident);
if (Entry && SymIsTypeDef (Entry)) { if (Entry && SymIsTypeDef (Entry)) {
/* It's a typedef */ /* It's a typedef */
@@ -1485,7 +1485,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
** long as it has no qualifiers. ** long as it has no qualifiers.
*/ */
D->Flags |= DS_DEF_TYPE; D->Flags |= DS_DEF_TYPE;
D->Type[0].C = T_QUAL_NONE; D->Type[0].C = T_INT;
D->Type[1].C = T_END; D->Type[1].C = T_END;
break; break;
} }

View File

@@ -88,7 +88,8 @@ SymTable EmptySymTab = {
#define SYMTAB_SIZE_LABEL 7U #define SYMTAB_SIZE_LABEL 7U
/* The current and root symbol tables */ /* The current and root symbol tables */
static unsigned LexicalLevel = 0; /* For safety checks */ static unsigned LexLevelDepth = 0; /* For safety checks */
static LexicalLevel* CurrentLex = 0;
static SymTable* SymTab0 = 0; static SymTable* SymTab0 = 0;
static SymTable* SymTab = 0; static SymTable* SymTab = 0;
static SymTable* TagTab0 = 0; static SymTable* TagTab0 = 0;
@@ -213,10 +214,46 @@ static void CheckSymTable (SymTable* Tab)
unsigned GetLexicalLevelDepth (void)
/* Return the current lexical level depth */
{
return LexLevelDepth;
}
unsigned GetLexicalLevel (void) unsigned GetLexicalLevel (void)
/* Return the current lexical level */ /* Return the current lexical level */
{ {
return LexicalLevel; if (CurrentLex != 0) {
return CurrentLex->CurrentLevel;
}
return LEX_LEVEL_NONE;
}
void PushLexicalLevel (unsigned NewLevel)
/* Enter the specified lexical level */
{
LexicalLevel* L = xmalloc (sizeof (LexicalLevel));
L->PrevLex = CurrentLex;
CurrentLex = L;
CurrentLex->CurrentLevel = NewLevel;
++LexLevelDepth;
}
void PopLexicalLevel (void)
/* Exit the current lexical level */
{
LexicalLevel* L;
PRECONDITION (CurrentLex != 0 && LexLevelDepth > 0);
L = CurrentLex;
CurrentLex = L->PrevLex;
xfree (L);
--LexLevelDepth;
} }
@@ -225,7 +262,10 @@ void EnterGlobalLevel (void)
/* Enter the program global lexical level */ /* Enter the program global lexical level */
{ {
/* Safety */ /* Safety */
PRECONDITION (++LexicalLevel == LEX_LEVEL_GLOBAL); PRECONDITION (GetLexicalLevel () == LEX_LEVEL_NONE);
/* Enter global lexical level */
PushLexicalLevel (LEX_LEVEL_GLOBAL);
/* Create and assign the symbol table */ /* Create and assign the symbol table */
SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL); SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
@@ -246,7 +286,7 @@ void LeaveGlobalLevel (void)
/* Leave the program global lexical level */ /* Leave the program global lexical level */
{ {
/* Safety */ /* Safety */
PRECONDITION (LexicalLevel-- == LEX_LEVEL_GLOBAL); PRECONDITION (GetLexicalLevel () == LEX_LEVEL_GLOBAL);
/* Check the tables */ /* Check the tables */
CheckSymTable (SymTab0); CheckSymTable (SymTab0);
@@ -260,6 +300,9 @@ void LeaveGlobalLevel (void)
/* Don't delete the symbol and struct tables! */ /* Don't delete the symbol and struct tables! */
SymTab = 0; SymTab = 0;
TagTab = 0; TagTab = 0;
/* Exit global lexical level */
PopLexicalLevel ();
} }
@@ -269,8 +312,8 @@ void EnterFunctionLevel (void)
{ {
SymTable* S; SymTable* S;
/* New lexical level */ /* Enter function lexical level */
++LexicalLevel; PushLexicalLevel (LEX_LEVEL_FUNCTION);
/* Get a new symbol table and make it current */ /* Get a new symbol table and make it current */
S = NewSymTable (SYMTAB_SIZE_FUNCTION); S = NewSymTable (SYMTAB_SIZE_FUNCTION);
@@ -293,8 +336,11 @@ void EnterFunctionLevel (void)
void RememberFunctionLevel (struct FuncDesc* F) void RememberFunctionLevel (struct FuncDesc* F)
/* Remember the symbol tables for the level and leave the level without checks */ /* Remember the symbol tables for the level and leave the level without checks */
{ {
/* Leave the lexical level */ /* Safety */
--LexicalLevel; PRECONDITION (GetLexicalLevel () == LEX_LEVEL_FUNCTION);
/* Leave function lexical level */
PopLexicalLevel ();
/* Remember the tables */ /* Remember the tables */
F->SymTab = SymTab; F->SymTab = SymTab;
@@ -311,8 +357,8 @@ void RememberFunctionLevel (struct FuncDesc* F)
void ReenterFunctionLevel (struct FuncDesc* F) void ReenterFunctionLevel (struct FuncDesc* F)
/* Reenter the function lexical level using the existing tables from F */ /* Reenter the function lexical level using the existing tables from F */
{ {
/* New lexical level */ /* Enter function lexical level */
++LexicalLevel; PushLexicalLevel (LEX_LEVEL_FUNCTION);
/* Make the tables current again */ /* Make the tables current again */
F->SymTab->PrevTab = SymTab; F->SymTab->PrevTab = SymTab;
@@ -330,8 +376,11 @@ void ReenterFunctionLevel (struct FuncDesc* F)
void LeaveFunctionLevel (void) void LeaveFunctionLevel (void)
/* Leave function lexical level */ /* Leave function lexical level */
{ {
/* Leave the lexical level */ /* Safety */
--LexicalLevel; PRECONDITION (GetLexicalLevel () == LEX_LEVEL_FUNCTION);
/* Leave function lexical level */
PopLexicalLevel ();
/* Check the tables */ /* Check the tables */
CheckSymTable (SymTab); CheckSymTable (SymTab);
@@ -355,8 +404,8 @@ void EnterBlockLevel (void)
{ {
SymTable* S; SymTable* S;
/* New lexical level */ /* Enter block lexical level */
++LexicalLevel; PushLexicalLevel (LEX_LEVEL_BLOCK);
/* Get a new symbol table and make it current */ /* Get a new symbol table and make it current */
S = NewSymTable (SYMTAB_SIZE_BLOCK); S = NewSymTable (SYMTAB_SIZE_BLOCK);
@@ -374,8 +423,11 @@ void EnterBlockLevel (void)
void LeaveBlockLevel (void) void LeaveBlockLevel (void)
/* Leave a nested block in a function */ /* Leave a nested block in a function */
{ {
/* Leave the lexical level */ /* Safety */
--LexicalLevel; PRECONDITION (GetLexicalLevel () == LEX_LEVEL_BLOCK);
/* Leave block lexical level */
PopLexicalLevel ();
/* Check the tables */ /* Check the tables */
CheckSymTable (SymTab); CheckSymTable (SymTab);
@@ -392,6 +444,9 @@ void EnterStructLevel (void)
{ {
SymTable* S; SymTable* S;
/* Enter struct lexical level */
PushLexicalLevel (LEX_LEVEL_STRUCT);
/* Get a new symbol table and make it current. Note: Structs and enums /* Get a new symbol table and make it current. Note: Structs and enums
** nested in struct scope are NOT local to the struct but visible in the ** nested in struct scope are NOT local to the struct but visible in the
** outside scope. So we will NOT create a new struct or enum table. ** outside scope. So we will NOT create a new struct or enum table.
@@ -406,6 +461,12 @@ void EnterStructLevel (void)
void LeaveStructLevel (void) void LeaveStructLevel (void)
/* Leave a nested block for a struct definition */ /* Leave a nested block for a struct definition */
{ {
/* Safety */
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_STRUCT);
/* Leave struct lexical level */
PopLexicalLevel ();
/* Don't delete the table */ /* Don't delete the table */
FieldTab = FieldTab->PrevTab; FieldTab = FieldTab->PrevTab;
} }
@@ -1398,7 +1459,7 @@ void EmitDebugInfo (void)
/* For cosmetic reasons in the output file, we will insert two tabs /* For cosmetic reasons in the output file, we will insert two tabs
** on global level and just one on local level. ** on global level and just one on local level.
*/ */
if (LexicalLevel == LEX_LEVEL_GLOBAL) { if (GetLexicalLevel () == LEX_LEVEL_GLOBAL) {
Head = "\t.dbg\t\tsym"; Head = "\t.dbg\t\tsym";
} else { } else {
Head = "\t.dbg\tsym"; Head = "\t.dbg\tsym";

View File

@@ -65,12 +65,22 @@ struct SymTable {
/* An empty symbol table */ /* An empty symbol table */
extern SymTable EmptySymTab; extern SymTable EmptySymTab;
/* Forwards */ /* Lexical level linked list node type */
struct FuncDesc; typedef struct LexicalLevel LexicalLevel;
struct LexicalLevel {
LexicalLevel* PrevLex;
unsigned CurrentLevel;
};
/* Predefined lexical levels */ /* Predefined lexical levels */
#define LEX_LEVEL_NONE 0U
#define LEX_LEVEL_GLOBAL 1U #define LEX_LEVEL_GLOBAL 1U
#define LEX_LEVEL_FUNCTION 2U #define LEX_LEVEL_FUNCTION 2U
#define LEX_LEVEL_BLOCK 3U
#define LEX_LEVEL_STRUCT 4U
/* Forwards */
struct FuncDesc;
@@ -80,9 +90,18 @@ struct FuncDesc;
unsigned GetLexicalLevelDepth (void);
/* Return the current lexical level depth */
unsigned GetLexicalLevel (void); unsigned GetLexicalLevel (void);
/* Return the current lexical level */ /* Return the current lexical level */
void PushLexicalLevel (unsigned NewLevel);
/* Enter the specified lexical level */
void PopLexicalLevel (void);
/* Exit the current lexical level */
void EnterGlobalLevel (void); void EnterGlobalLevel (void);
/* Enter the program global lexical level */ /* Enter the program global lexical level */

View File

@@ -108,7 +108,7 @@ DISK_atarixl = testcode.atr
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Generic rules # Generic rules
.PHONY: all mostlyclean clean zip testcode disk .PHONY: testcode all mostlyclean clean zip disk platforms
%: %.c %: %.c
%: %.s %: %.s
@@ -404,7 +404,7 @@ EXELIST_plus4 = \
strqtok-test \ strqtok-test \
uname-test uname-test
# omitted: seek clock-test mouse-test ser-test # omitted: seek clock-test mouse-test ser-test
EXELIST_vic20 = \ EXELIST_vic20 = \
minimal \ minimal \
arg-test \ arg-test \
@@ -616,7 +616,7 @@ EXELIST_nes = \
EXELIST_pce = \ EXELIST_pce = \
minimal \ minimal \
conio conio
# omitted: arg-test clock-test clock cpeek-test conio cprintf deb dir-test div-test # omitted: arg-test clock-test clock cpeek-test conio cprintf deb dir-test div-test
# em-test exec-test1 exec-test2 fileio-test ft getopt-test heaptest joy-test moddiv-test # em-test exec-test1 exec-test2 fileio-test ft getopt-test heaptest joy-test moddiv-test
# mouse-test posixio-test rename-test scanf-test seek ser-test strdup-test strnlen # mouse-test posixio-test rename-test scanf-test seek ser-test strdup-test strnlen
@@ -659,7 +659,7 @@ EXELIST_sim6502 = \
scanf-test \ scanf-test \
strnlen \ strnlen \
strqtok-test strqtok-test
EXELIST_sim65c02 = $(EXELIST_sim6502) EXELIST_sim65c02 = $(EXELIST_sim6502)
@@ -699,7 +699,7 @@ endif
define SUBDIR_recipe define SUBDIR_recipe
@$(MAKE) -C $(dir) --no-print-directory $@ @+$(MAKE) -C $(dir) --no-print-directory $@
endef # SUBDIR_recipe endef # SUBDIR_recipe
@@ -719,6 +719,52 @@ disk: $(DISK_$(SYS))
all: all:
# --------------------------------------------------------------------------
# List of every supported platform
TARGETS := \
apple2 \
apple2enh \
atari \
atarixl \
atari2600 \
atari5200 \
atmos \
bbc \
c128 \
c16 \
c64 \
cbm510 \
cbm610 \
creativision \
cx16 \
gamate \
lunix \
lynx \
nes \
osic1p \
pce \
pet \
plus4 \
sim6502 \
sim65c02 \
supervision \
sym1 \
telestrat \
vic20
# --------------------------------------------------------------------------
# Rule to make the binaries for every platform
define TARGET_recipe
@$(MAKE) -j2 SYS:=$(T)
@$(MAKE) --no-print-directory clean SYS:=$(T)
endef # TARGET_recipe
platforms:
$(foreach T,$(TARGETS),$(TARGET_recipe))
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# some programs link against getsp.o # some programs link against getsp.o

View File

@@ -1,3 +1,7 @@
# Run 'make SYS=<target>'; or, set a SYS env.
# var. to build for another target system.
SYS ?= c64
# Just the usual way to find out if we're # Just the usual way to find out if we're
# using cmd.exe to execute make rules. # using cmd.exe to execute make rules.
ifneq ($(shell echo),) ifneq ($(shell echo),)
@@ -54,10 +58,18 @@ else
endif endif
c64-scpu-test.prg: c64-c128-scpu-test.c c64-scpu-test.prg: c64-c128-scpu-test.c
$(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg # do not use cl65 to prevent tests from failing randomly because of one process
# deleting the temp files from another
# $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg
$(CC) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.s
$(CL) -t c64 c64-scpu-test.s -o c64-scpu-test.prg
c128-scpu-test.prg: c64-c128-scpu-test.c c128-scpu-test.prg: c64-c128-scpu-test.c
$(CL) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.prg # do not use cl65 to prevent tests from failing randomly because of one process
# deleting the temp files from another
# $(CL) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.prg
$(CC) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.s
$(CL) -t c128 c128-scpu-test.s -o c128-scpu-test.prg
c64dtv-test.prg: c64dtv-test.c c64dtv-test.prg: c64dtv-test.c
$(CL) -t c64 c64dtv-test.c -o c64dtv-test.prg $(CL) -t c64 c64dtv-test.c -o c64dtv-test.prg
@@ -79,3 +91,4 @@ turbomaster-test.prg: turbomaster-test.c
clean: clean:
@$(DEL) *.prg 2>$(NULLDEV) @$(DEL) *.prg 2>$(NULLDEV)
@$(DEL) *.s 2>$(NULLDEV)

View File

@@ -26,8 +26,10 @@
static unsigned char failures = 0; static unsigned char failures = 0;
typedef unsigned int field_type;
static struct four_bits { static struct four_bits {
unsigned int x : 4; field_type x : 4;
} fb = {1}; } fb = {1};
static void test_four_bits(void) static void test_four_bits(void)
@@ -57,8 +59,8 @@ static void test_four_bits(void)
*/ */
static struct four_bits_with_int { static struct four_bits_with_int {
unsigned int x : 4; field_type x : 4;
unsigned int y; field_type y;
} fbi = {1, 2}; } fbi = {1, 2};
static void test_four_bits_with_int(void) static void test_four_bits_with_int(void)
@@ -95,8 +97,8 @@ static void test_four_bits_with_int(void)
} }
static struct overlap { static struct overlap {
unsigned int x : 10; field_type x : 10;
unsigned int y : 10; field_type y : 10;
} o = {11, 22}; } o = {11, 22};
/* Tests that bit-fields can share allocation units. */ /* Tests that bit-fields can share allocation units. */
@@ -133,9 +135,9 @@ static void test_overlap(void)
} }
static struct overlap_with_int { static struct overlap_with_int {
unsigned int x : 10; field_type x : 10;
unsigned int y : 10; field_type y : 10;
unsigned int z; field_type z;
} oi = {111, 222, 333}; } oi = {111, 222, 333};
static void test_overlap_with_int(void) static void test_overlap_with_int(void)
@@ -183,8 +185,8 @@ static void test_overlap_with_int(void)
} }
static struct full_width { static struct full_width {
unsigned int x : 8; field_type x : 8;
unsigned int y : 16; field_type y : 16;
} fw = {255, 17}; } fw = {255, 17};
static void test_full_width(void) static void test_full_width(void)
@@ -220,13 +222,13 @@ static void test_full_width(void)
} }
static struct aligned_end { static struct aligned_end {
unsigned int : 2; field_type : 2;
unsigned int x : 6; field_type x : 6;
unsigned int : 3; field_type : 3;
unsigned int y : 13; field_type y : 13;
/* z crosses a byte boundary, but fits in a byte when shifted. */ /* z crosses a byte boundary, but fits in a byte when shifted. */
unsigned int : 6; field_type : 6;
unsigned int z : 7; field_type z : 7;
} ae = {63, 17, 100}; } ae = {63, 17, 100};
static void test_aligned_end(void) static void test_aligned_end(void)

View File

@@ -1,4 +1,12 @@
CC = $(CROSS_COMPILE)gcc
ifdef CROSS_COMPILE
$(info CC: $(CC))
endif
CFLAGS += -O3 -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS)
.PHONY: mostlyclean clean .PHONY: mostlyclean clean
atari: ataricvt atari: ataricvt

View File

@@ -1,4 +1,12 @@
CC = $(CROSS_COMPILE)gcc
ifdef CROSS_COMPILE
$(info CC: $(CC))
endif
CFLAGS += -O3 -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS)
.PHONY: mostlyclean clean .PHONY: mostlyclean clean
gamate: gamate-fixcart gamate: gamate-fixcart

View File

@@ -1,4 +1,12 @@
CC = $(CROSS_COMPILE)gcc
ifdef CROSS_COMPILE
$(info CC: $(CC))
endif
CFLAGS += -O3 -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS)
.PHONY: mostlyclean clean .PHONY: mostlyclean clean
zlib: warning zlib: warning