mirror of
https://github.com/cc65/cc65.git
synced 2025-01-11 11:30:13 +00:00
Merge branch 'cc65:master' into master
This commit is contained in:
commit
4865caa593
@ -90,7 +90,7 @@ VIA1_T1LH := VIA1+$7 ; Timer 1 latch, high byte
|
||||
VIA1_T2CL := VIA1+$8 ; Timer 2, low byte
|
||||
VIA1_T2CH := VIA1+$9 ; Timer 2, high byte
|
||||
VIA1_SR := VIA1+$A ; Shift register
|
||||
VIA1_CR := VIA1+$B ; Auxiliary control register
|
||||
VIA1_ACR := VIA1+$B ; Auxiliary control register
|
||||
VIA1_PCR := VIA1+$C ; Peripheral control register
|
||||
VIA1_IFR := VIA1+$D ; Interrupt flag register
|
||||
VIA1_IER := VIA1+$E ; Interrupt enable register
|
||||
@ -112,7 +112,7 @@ VIA2_T1LH := VIA2+$7 ; Timer 1 latch, high byte
|
||||
VIA2_T2CL := VIA2+$8 ; Timer 2, low byte
|
||||
VIA2_T2CH := VIA2+$9 ; Timer 2, high byte
|
||||
VIA2_SR := VIA2+$A ; Shift register
|
||||
VIA2_CR := VIA2+$B ; Auxiliary control register
|
||||
VIA2_ACR := VIA2+$B ; Auxiliary control register
|
||||
VIA2_PCR := VIA2+$C ; Peripheral control register
|
||||
VIA2_IFR := VIA2+$D ; Interrupt flag register
|
||||
VIA2_IER := VIA2+$E ; Interrupt enable register
|
||||
|
@ -3410,7 +3410,7 @@ loaded.
|
||||
<descrip>
|
||||
<tag/Function/Install an already loaded extended memory driver.
|
||||
<tag/Header/<tt/<ref id="em.h" name="em.h">/
|
||||
<tag/Declaration/<tt/unsigned char _fastcall__ em_install (void* driver);/
|
||||
<tag/Declaration/<tt/unsigned char _fastcall__ em_install (const void* driver);/
|
||||
<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.
|
||||
@ -4733,7 +4733,7 @@ There's no way to check for the number of actually connected joysticks.
|
||||
<descrip>
|
||||
<tag/Function/Install an already loaded driver and return an error code.
|
||||
<tag/Header/<tt/<ref id="joystick.h" name="joystick.h">/
|
||||
<tag/Declaration/<tt/unsigned char __fastcall__ joy_install (void* driver);/
|
||||
<tag/Declaration/<tt/unsigned char __fastcall__ joy_install (const void* driver);/
|
||||
<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).
|
||||
@ -6198,7 +6198,7 @@ while (ser_get(&ch) == SER_ERR_NO_DATA)
|
||||
<descrip>
|
||||
<tag/Function/Install an already loaded driver and return an error code.
|
||||
<tag/Header/<tt/<ref id="serial.h" name="serial.h">/
|
||||
<tag/Declaration/<tt/unsigned char __fastcall__ ser_install (void* driver);/
|
||||
<tag/Declaration/<tt/unsigned char __fastcall__ ser_install (const void* driver);/
|
||||
<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).
|
||||
|
@ -205,7 +205,7 @@ see them together in the filling box in GeoPaint.
|
||||
|
||||
<sect2>GraphicsString
|
||||
<p>
|
||||
<tt/void GraphicsString (char *myGString)/
|
||||
<tt/void GraphicsString (const void *myGString)/
|
||||
<p>
|
||||
One of the more powerfull routines of GEOS. This function calls other graphic functions depending
|
||||
on the given command string. See the structures chapter for a more detailed description.
|
||||
|
@ -555,7 +555,7 @@ tgi_init(); //Set up the default palette and clear the screen.
|
||||
<descrip>
|
||||
<tag/Function/Install an already loaded driver and return an error code.
|
||||
<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/
|
||||
<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (void* driver);/
|
||||
<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (const void* driver);/
|
||||
<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).
|
||||
|
@ -82,7 +82,7 @@ unsigned char __fastcall__ em_load_driver (const char* driver);
|
||||
unsigned char em_unload (void);
|
||||
/* Uninstall, then unload the currently loaded driver. */
|
||||
|
||||
unsigned char __fastcall__ em_install (void* driver);
|
||||
unsigned char __fastcall__ em_install (const void* driver);
|
||||
/* Install an already loaded driver. Return an error code. */
|
||||
|
||||
unsigned char em_uninstall (void);
|
||||
|
@ -43,7 +43,7 @@ void __fastcall__ BitOtherClip(void *proc1, void *proc2, char skipl,
|
||||
char skipr, unsigned skiptop,
|
||||
struct iconpic *myIcon);
|
||||
|
||||
void __fastcall__ GraphicsString(char *myGfxString);
|
||||
void __fastcall__ GraphicsString(const void *myGfxString);
|
||||
|
||||
#ifdef __GEOS_CBM__
|
||||
void SetNewMode(void);
|
||||
|
@ -89,7 +89,7 @@ unsigned char __fastcall__ joy_load_driver (const char* driver);
|
||||
unsigned char joy_unload (void);
|
||||
/* Uninstall, then unload the currently loaded driver. */
|
||||
|
||||
unsigned char __fastcall__ joy_install (void* driver);
|
||||
unsigned char __fastcall__ joy_install (const void* driver);
|
||||
/* Install an already loaded driver. Return an error code. */
|
||||
|
||||
unsigned char joy_uninstall (void);
|
||||
|
@ -136,7 +136,7 @@ unsigned char __fastcall__ ser_load_driver (const char* driver);
|
||||
unsigned char ser_unload (void);
|
||||
/* Uninstall, then unload the currently loaded driver. */
|
||||
|
||||
unsigned char __fastcall__ ser_install (void* driver);
|
||||
unsigned char __fastcall__ ser_install (const void* driver);
|
||||
/* Install an already loaded driver. Return an error code. */
|
||||
|
||||
unsigned char ser_uninstall (void);
|
||||
|
@ -82,7 +82,7 @@ void tgi_unload (void);
|
||||
** necessary.
|
||||
*/
|
||||
|
||||
void __fastcall__ tgi_install (void* driver);
|
||||
void __fastcall__ tgi_install (const void* driver);
|
||||
/* Install an already loaded driver. */
|
||||
|
||||
void tgi_uninstall (void);
|
||||
|
@ -44,4 +44,4 @@ _exit: jsr donelib ; Run module destructors
|
||||
|
||||
; A 5200 program isn't supposed to exit.
|
||||
|
||||
halt: jmp halt
|
||||
halt: jmp halt
|
||||
|
@ -36,7 +36,7 @@ emd_sig: .byte $65, $6d, $64, EMD_API_VERSION ; "emd", version
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; unsigned char __fastcall__ em_install (void* driver);
|
||||
; unsigned char __fastcall__ em_install (const void* driver);
|
||||
; /* Install the driver once it is loaded */
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
;
|
||||
; 25.12.99
|
||||
|
||||
; void GraphicsString (char *myString);
|
||||
; void GraphicsString (const void *myString);
|
||||
|
||||
.export _GraphicsString
|
||||
|
||||
|
@ -33,7 +33,7 @@ joy_sig: .byte $6A, $6F, $79, JOY_API_VERSION ; "joy", version
|
||||
|
||||
.code
|
||||
;----------------------------------------------------------------------------
|
||||
; unsigned char __fastcall__ joy_install (void* driver);
|
||||
; unsigned char __fastcall__ joy_install (const void* driver);
|
||||
; /* Install the driver once it is loaded */
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ ser_sig: .byte $73, $65, $72, SER_API_VERSION ; "ser", version
|
||||
|
||||
.code
|
||||
;----------------------------------------------------------------------------
|
||||
; unsigned char __fastcall__ ser_install (void* driver);
|
||||
; unsigned char __fastcall__ ser_install (const void* driver);
|
||||
; /* Install the driver once it is loaded */
|
||||
|
||||
|
||||
|
@ -67,13 +67,13 @@ not_dma:
|
||||
; Removing this segment gives only a warning.
|
||||
.segment "FFF0"
|
||||
.proc reset32kcode
|
||||
lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON
|
||||
lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON
|
||||
sta sv_bank
|
||||
; Now, the 32Kbyte image can reside in the top of 64Kbyte and 128Kbyte ROMs.
|
||||
jmp reset
|
||||
.endproc
|
||||
|
||||
.segment "VECTOR"
|
||||
.segment "VECTORS"
|
||||
|
||||
.word nmi
|
||||
.word reset32kcode
|
||||
|
@ -88,7 +88,7 @@ tgi_sig: .byte $74, $67, $69, TGI_API_VERSION ; "tgi", version
|
||||
|
||||
.code
|
||||
;----------------------------------------------------------------------------
|
||||
; void __fastcall__ tgi_install (void* driver);
|
||||
; void __fastcall__ tgi_install (const void* driver);
|
||||
; /* Install an already loaded driver. */
|
||||
|
||||
|
||||
|
153
samples/Makefile
153
samples/Makefile
@ -159,21 +159,6 @@ DIRLIST = tutorial geos
|
||||
# --------------------------------------------------------------------------
|
||||
# Lists of executables
|
||||
|
||||
EXELIST_c64 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
fire \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
multdemo \
|
||||
nachtm \
|
||||
ovrldemo \
|
||||
plasma \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_apple2 = \
|
||||
ascii \
|
||||
diodemo \
|
||||
@ -204,10 +189,140 @@ EXELIST_atarixl = $(EXELIST_atari)
|
||||
|
||||
EXELIST_atari2600 = \
|
||||
atari2600hello
|
||||
|
||||
|
||||
EXELIST_atmos = \
|
||||
ascii \
|
||||
hello \
|
||||
mandelbrot \
|
||||
sieve
|
||||
|
||||
EXELIST_bbc = \
|
||||
notavailable
|
||||
|
||||
EXELIST_c64 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
fire \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
multdemo \
|
||||
nachtm \
|
||||
ovrldemo \
|
||||
plasma \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_c128 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
fire \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
nachtm \
|
||||
plasma \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_c16 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
hello
|
||||
|
||||
EXELIST_cbm510 = \
|
||||
ascii \
|
||||
fire \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mousedemo \
|
||||
nachtm \
|
||||
plasma \
|
||||
sieve
|
||||
|
||||
EXELIST_cbm610 = \
|
||||
ascii \
|
||||
gunzip65 \
|
||||
hello \
|
||||
nachtm \
|
||||
sieve
|
||||
|
||||
EXELIST_creativision = \
|
||||
ascii \
|
||||
hello
|
||||
|
||||
EXELIST_cx16 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_gamate = \
|
||||
hello
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
ascii \
|
||||
diodemo
|
||||
|
||||
EXELIST_geos-apple = \
|
||||
ascii
|
||||
|
||||
EXELIST_lunix = \
|
||||
notavailable
|
||||
|
||||
EXELIST_lynx = \
|
||||
notavailable
|
||||
|
||||
EXELIST_nes = \
|
||||
hello
|
||||
|
||||
EXELIST_osic1p = \
|
||||
notavailable
|
||||
|
||||
EXELIST_pce = \
|
||||
hello
|
||||
|
||||
EXELIST_pet = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
hello \
|
||||
sieve
|
||||
|
||||
EXELIST_plus4 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
plasma \
|
||||
sieve
|
||||
|
||||
EXELIST_sim6502 = \
|
||||
gunzip65
|
||||
|
||||
EXELIST_sim65c02 = $(EXELIST_sim6502)
|
||||
|
||||
EXELIST_supervision = \
|
||||
supervisionhello
|
||||
|
||||
EXELIST_telestrat = \
|
||||
ascii \
|
||||
gunzip65 \
|
||||
hello
|
||||
|
||||
EXELIST_vic20 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
hello \
|
||||
mandelbrot \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
# Unlisted targets will try to build everything.
|
||||
# That lets us learn what they cannot build, and what settings
|
||||
# we need to use for programs that can be built and run.
|
||||
@ -227,6 +342,12 @@ endef # SUBDIR_recipe
|
||||
samples: $(EXELIST_$(SYS))
|
||||
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: generic samples not available for" $(SYS)
|
||||
endif
|
||||
|
||||
disk: $(DISK_$(SYS))
|
||||
|
||||
all:
|
||||
|
@ -3,6 +3,19 @@
|
||||
# var. to build for another target system.
|
||||
SYS ?= geos-cbm
|
||||
|
||||
# If SYS was given on the commandline, redirect "c64" to "geos-cbm" and
|
||||
# "apple2enh" to "geos-apple"
|
||||
ifeq ($(origin SYS),command line)
|
||||
ifeq ($(SYS),c64)
|
||||
override SYS = geos-cbm
|
||||
$(info GEOS: c64 -> geos-cbm)
|
||||
endif
|
||||
ifeq ($(SYS),apple2enh)
|
||||
override SYS = geos-apple
|
||||
$(info GEOS: apple2enh -> geos-apple)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
@ -37,16 +50,45 @@ DIRLIST = grc
|
||||
|
||||
define SUBDIR_recipe
|
||||
|
||||
@$(MAKE) -C $(dir) --no-print-directory $@
|
||||
@$(MAKE) SYS=$(SYS) -C $(dir) --no-print-directory $@
|
||||
|
||||
endef # SUBDIR_recipe
|
||||
|
||||
# omitted: dialog.c grphstr.c inittab.c menu.c
|
||||
EXELIST_geos-cbm = \
|
||||
bitmap-demo.cvt \
|
||||
filesel.cvt \
|
||||
geosver.cvt \
|
||||
getid.cvt \
|
||||
hello1.cvt \
|
||||
hello2.cvt \
|
||||
overlay-demo.cvt \
|
||||
vector-demo.cvt \
|
||||
yesno.cvt
|
||||
|
||||
EXELIST_geos-apple = \
|
||||
bitmap-demo.cvt \
|
||||
filesel.cvt \
|
||||
hello1.cvt \
|
||||
hello2.cvt \
|
||||
overlay-demo.cvt \
|
||||
vector-demo.cvt \
|
||||
yesno.cvt
|
||||
|
||||
# omitted: dialog.c grphstr.c inittab.c menu.c
|
||||
# TODO: geosconio.cvt rmvprot.cvt
|
||||
samples: bitmap-demo.cvt filesel.cvt geosver.cvt getid.cvt hello1.cvt hello2.cvt \
|
||||
overlay-demo.cvt vector-demo.cvt yesno.cvt
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
|
||||
else
|
||||
samples:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: geos samples not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
endif
|
||||
|
||||
bitmap.c: logo.pcx
|
||||
$(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap
|
||||
|
@ -8,8 +8,8 @@ struct window wholeScreen = {0, SC_PIX_HEIGHT-1, 0, SC_PIX_WIDTH-1};
|
||||
void main (void)
|
||||
{
|
||||
unsigned char os = get_ostype();
|
||||
unsigned char *machine = NULL;
|
||||
unsigned char *version = NULL;
|
||||
char *machine = NULL;
|
||||
char *version = NULL;
|
||||
unsigned char good = 1;
|
||||
|
||||
SetPattern(0);
|
||||
|
@ -1,4 +1,8 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= geos-cbm
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
@ -29,22 +33,36 @@ else
|
||||
GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65)
|
||||
endif
|
||||
|
||||
samples: test.s vlir.cvt
|
||||
EXELIST_geos-cbm = \
|
||||
test.s \
|
||||
vlir.cvt
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: grc sample not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
endif
|
||||
|
||||
test.s: test.grc
|
||||
$(GRC) -s test.s test.grc
|
||||
|
||||
vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s
|
||||
# using seperate calls here for demonstration purposes:
|
||||
$(GRC) -t geos-cbm -s vlir.s vlir.grc
|
||||
$(AS) -t geos-cbm vlir.s
|
||||
$(AS) -t geos-cbm vlir0.s
|
||||
$(AS) -t geos-cbm vlir1.s
|
||||
$(AS) -t geos-cbm vlir2.s
|
||||
$(LD) -t geos-cbm -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o geos-cbm.lib
|
||||
$(GRC) -t $(SYS) -s vlir.s vlir.grc
|
||||
$(AS) -t $(SYS) vlir.s
|
||||
$(AS) -t $(SYS) vlir0.s
|
||||
$(AS) -t $(SYS) vlir1.s
|
||||
$(AS) -t $(SYS) vlir2.s
|
||||
$(LD) -t $(SYS) -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o $(SYS).lib
|
||||
|
||||
# you can also do the above in one command:
|
||||
# $(CL) -t geos-cbm -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s
|
||||
# $(CL) -t $(SYS) -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s
|
||||
|
||||
clean:
|
||||
@$(DEL) test.s test.h 2>$(NULLDEV)
|
||||
|
@ -972,12 +972,12 @@ static void MakeNiceScreen (void)
|
||||
|
||||
/* Clear the screen hide the cursor, set colors */
|
||||
#ifdef __CBM610__
|
||||
textcolor (COLOR_WHITE);
|
||||
(void)textcolor (COLOR_WHITE);
|
||||
#else
|
||||
textcolor (COLOR_GRAY3);
|
||||
(void)textcolor (COLOR_GRAY3);
|
||||
#endif
|
||||
bordercolor (COLOR_BLACK);
|
||||
bgcolor (COLOR_BLACK);
|
||||
(void)bordercolor (COLOR_BLACK);
|
||||
(void)bgcolor (COLOR_BLACK);
|
||||
clrscr ();
|
||||
cursor (0);
|
||||
|
||||
|
@ -31,10 +31,62 @@ else
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
samples: hello
|
||||
EXELIST_atari2600 = \
|
||||
notavailable
|
||||
|
||||
EXELIST_bbc = \
|
||||
notavailable
|
||||
|
||||
EXELIST_creativision = \
|
||||
notavailable
|
||||
|
||||
EXELIST_gamate = \
|
||||
notavailable
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
notavailable
|
||||
|
||||
EXELIST_geos-apple = \
|
||||
notavailable
|
||||
|
||||
EXELIST_lunix = \
|
||||
notavailable
|
||||
|
||||
EXELIST_lynx = \
|
||||
notavailable
|
||||
|
||||
EXELIST_nes = \
|
||||
notavailable
|
||||
|
||||
EXELIST_osic1p = \
|
||||
notavailable
|
||||
|
||||
EXELIST_pce = \
|
||||
notavailable
|
||||
|
||||
EXELIST_supervision = \
|
||||
notavailable
|
||||
|
||||
# Unlisted targets will try to build everything.
|
||||
# That lets us learn what they cannot build, and what settings
|
||||
# we need to use for programs that can be built and run.
|
||||
ifndef EXELIST_$(SYS)
|
||||
EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)}
|
||||
endif
|
||||
|
||||
samples: $(EXELIST_$(SYS))
|
||||
|
||||
hello: hello.c text.s
|
||||
$(CL) -t $(SYS) -o hello hello.c text.s
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: tutorial sample not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
clean:
|
||||
@$(DEL) hello 2>$(NULLDEV)
|
||||
|
@ -438,9 +438,7 @@ void MacDef (unsigned Style)
|
||||
|
||||
/* Parse the parameter list */
|
||||
if (HaveParams) {
|
||||
|
||||
while (CurTok.Tok == TOK_IDENT) {
|
||||
|
||||
/* Create a struct holding the identifier */
|
||||
IdDesc* I = NewIdDesc (&CurTok.SVal);
|
||||
|
||||
@ -449,6 +447,7 @@ void MacDef (unsigned Style)
|
||||
M->Params = I;
|
||||
} else {
|
||||
IdDesc* List = M->Params;
|
||||
|
||||
while (1) {
|
||||
if (SB_Compare (&List->Id, &CurTok.SVal) == 0) {
|
||||
Error ("Duplicate symbol '%m%p'", &CurTok.SVal);
|
||||
@ -490,9 +489,8 @@ void MacDef (unsigned Style)
|
||||
** the .LOCAL command is detected and removed, at this time.
|
||||
*/
|
||||
while (1) {
|
||||
|
||||
/* Check for include */
|
||||
if (CurTok.Tok == TOK_INCLUDE) {
|
||||
if (CurTok.Tok == TOK_INCLUDE && Style == MAC_STYLE_CLASSIC) {
|
||||
/* Include another file */
|
||||
NextTok ();
|
||||
/* Name must follow */
|
||||
@ -529,9 +527,7 @@ void MacDef (unsigned Style)
|
||||
|
||||
/* Check for a .LOCAL declaration */
|
||||
if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) {
|
||||
|
||||
while (1) {
|
||||
|
||||
IdDesc* I;
|
||||
|
||||
/* Skip .local or comma */
|
||||
@ -570,6 +566,7 @@ void MacDef (unsigned Style)
|
||||
if (CurTok.Tok == TOK_IDENT) {
|
||||
unsigned Count = 0;
|
||||
IdDesc* I = M->Params;
|
||||
|
||||
while (I) {
|
||||
if (SB_Compare (&I->Id, &CurTok.SVal) == 0) {
|
||||
/* Local param name, replace it */
|
||||
|
@ -80,6 +80,8 @@ static GenDesc GenOASGN = { TOK_OR_ASSIGN, GEN_NOPUSH, g_or };
|
||||
|
||||
|
||||
static void parseadd (ExprDesc* Expr, int DoArrayRef);
|
||||
static void PostInc (ExprDesc* Expr);
|
||||
static void PostDec (ExprDesc* Expr);
|
||||
|
||||
|
||||
|
||||
@ -88,6 +90,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef);
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static unsigned GlobalModeFlags (const ExprDesc* Expr)
|
||||
/* Return the addressing mode flags for the given expression */
|
||||
{
|
||||
@ -1510,7 +1513,8 @@ static void hie11 (ExprDesc *Expr)
|
||||
Primary (Expr);
|
||||
|
||||
/* Check for a rhs */
|
||||
while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN ||
|
||||
while (CurTok.Tok == TOK_INC || CurTok.Tok == TOK_DEC ||
|
||||
CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN ||
|
||||
CurTok.Tok == TOK_DOT || CurTok.Tok == TOK_PTR_REF) {
|
||||
|
||||
switch (CurTok.Tok) {
|
||||
@ -1554,6 +1558,14 @@ static void hie11 (ExprDesc *Expr)
|
||||
StructRef (Expr);
|
||||
break;
|
||||
|
||||
case TOK_INC:
|
||||
PostInc (Expr);
|
||||
break;
|
||||
|
||||
case TOK_DEC:
|
||||
PostDec (Expr);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid token in hie11: %d", CurTok.Tok);
|
||||
|
||||
@ -2106,13 +2118,6 @@ void hie10 (ExprDesc* Expr)
|
||||
/* An expression */
|
||||
hie11 (Expr);
|
||||
|
||||
/* Handle post increment */
|
||||
switch (CurTok.Tok) {
|
||||
case TOK_INC: PostInc (Expr); break;
|
||||
case TOK_DEC: PostDec (Expr); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
|
||||
|
||||
/* Now process statements in this block */
|
||||
while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) {
|
||||
Statement (0);
|
||||
AnyStatement (0);
|
||||
}
|
||||
|
||||
/* If this is not a void function, and not the main function in a C99
|
||||
|
177
src/cc65/stmt.c
177
src/cc65/stmt.c
@ -163,7 +163,7 @@ static int IfStatement (void)
|
||||
TestResult = TestInParens (Label1, 0);
|
||||
|
||||
/* Parse the if body */
|
||||
GotBreak = Statement (0);
|
||||
GotBreak = AnyStatement (0);
|
||||
|
||||
/* Else clause present? */
|
||||
if (CurTok.Tok != TOK_ELSE) {
|
||||
@ -195,7 +195,7 @@ static int IfStatement (void)
|
||||
g_defcodelabel (Label1);
|
||||
|
||||
/* Total break only if both branches had a break. */
|
||||
GotBreak &= Statement (0);
|
||||
GotBreak &= AnyStatement (0);
|
||||
|
||||
/* Generate the label for the else clause */
|
||||
g_defcodelabel (Label2);
|
||||
@ -225,7 +225,7 @@ static void DoStatement (void)
|
||||
g_defcodelabel (LoopLabel);
|
||||
|
||||
/* Parse the loop body */
|
||||
Statement (0);
|
||||
AnyStatement (0);
|
||||
|
||||
/* Output the label for a continue */
|
||||
g_defcodelabel (ContinueLabel);
|
||||
@ -283,7 +283,7 @@ static void WhileStatement (void)
|
||||
g_defcodelabel (LoopLabel);
|
||||
|
||||
/* Loop body */
|
||||
Statement (&PendingToken);
|
||||
AnyStatement (&PendingToken);
|
||||
|
||||
/* Emit the while condition label */
|
||||
g_defcodelabel (CondLabel);
|
||||
@ -509,7 +509,7 @@ static void ForStatement (void)
|
||||
|
||||
/* Loop body */
|
||||
g_defcodelabel (BodyLabel);
|
||||
Statement (&PendingToken);
|
||||
AnyStatement (&PendingToken);
|
||||
|
||||
/* If we had an increment expression, move the code to the bottom of
|
||||
** the loop. In this case we don't need to jump there at the end of
|
||||
@ -536,17 +536,20 @@ static void ForStatement (void)
|
||||
|
||||
|
||||
|
||||
static int CompoundStatement (void)
|
||||
static int CompoundStatement (int* PendingToken)
|
||||
/* Compound statement. Allow any number of statements inside braces. The
|
||||
** function returns true if the last statement was a break or return.
|
||||
*/
|
||||
{
|
||||
int GotBreak;
|
||||
int GotBreak = 0;
|
||||
|
||||
/* Remember the stack at block entry */
|
||||
int OldStack = StackPtr;
|
||||
unsigned OldBlockStackSize = CollCount (&CurrentFunc->LocalsBlockStack);
|
||||
|
||||
/* Skip '{' */
|
||||
NextToken ();
|
||||
|
||||
/* Enter a new lexical level */
|
||||
EnterBlockLevel ();
|
||||
|
||||
@ -554,16 +557,15 @@ static int CompoundStatement (void)
|
||||
DeclareLocals ();
|
||||
|
||||
/* Now process statements in this block */
|
||||
GotBreak = 0;
|
||||
while (CurTok.Tok != TOK_RCURLY) {
|
||||
if (CurTok.Tok != TOK_CEOF) {
|
||||
GotBreak = Statement (0);
|
||||
GotBreak = AnyStatement (0);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up the stack. */
|
||||
/* Clean up the stack if the codeflow may reach the end */
|
||||
if (!GotBreak) {
|
||||
g_space (StackPtr - OldStack);
|
||||
}
|
||||
@ -583,12 +585,80 @@ static int CompoundStatement (void)
|
||||
/* Leave the lexical level */
|
||||
LeaveBlockLevel ();
|
||||
|
||||
/* Skip '}' */
|
||||
CheckTok (TOK_RCURLY, "'}' expected", PendingToken);
|
||||
|
||||
return GotBreak;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Statement (int* PendingToken)
|
||||
static void Statement (int* PendingToken)
|
||||
/* Single-line statement */
|
||||
{
|
||||
ExprDesc Expr;
|
||||
unsigned PrevErrorCount;
|
||||
CodeMark Start, End;
|
||||
|
||||
/* Remember the current error count and code position */
|
||||
PrevErrorCount = ErrorCount;
|
||||
GetCodePos (&Start);
|
||||
|
||||
/* Actual statement */
|
||||
ED_Init (&Expr);
|
||||
Expr.Flags |= E_NEED_NONE;
|
||||
Expression0 (&Expr);
|
||||
|
||||
/* If the statement didn't generate code, and is not of type
|
||||
** void, emit a warning.
|
||||
*/
|
||||
GetCodePos (&End);
|
||||
if (!ED_YetToLoad (&Expr) &&
|
||||
!ED_MayHaveNoEffect (&Expr) &&
|
||||
CodeRangeIsEmpty (&Start, &End) &&
|
||||
IS_Get (&WarnNoEffect) &&
|
||||
PrevErrorCount == ErrorCount) {
|
||||
Warning ("Expression result unused");
|
||||
}
|
||||
CheckSemi (PendingToken);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int ParseAnyLabels (void)
|
||||
/* Return -1 if there are any labels with a statement */
|
||||
{
|
||||
unsigned PrevErrorCount = ErrorCount;
|
||||
int HasLabels = 0;
|
||||
for (;;) {
|
||||
if (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) {
|
||||
/* C 'goto' label */
|
||||
DoLabel ();
|
||||
} else if (CurTok.Tok == TOK_CASE) {
|
||||
/* C 'case' label */
|
||||
CaseLabel ();
|
||||
} else if (CurTok.Tok == TOK_DEFAULT) {
|
||||
/* C 'default' label */
|
||||
DefaultLabel ();
|
||||
} else {
|
||||
/* No labels */
|
||||
break;
|
||||
}
|
||||
HasLabels = 1;
|
||||
}
|
||||
|
||||
if (HasLabels) {
|
||||
if (PrevErrorCount != ErrorCount || CheckLabelWithoutStatement ()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AnyStatement (int* PendingToken)
|
||||
/* Statement parser. Returns 1 if the statement does a return/break, returns
|
||||
** 0 otherwise. If the PendingToken pointer is not NULL, the function will
|
||||
** not skip the terminating token of the statement (closing brace or
|
||||
@ -598,40 +668,27 @@ int Statement (int* PendingToken)
|
||||
** NULL, the function will skip the token.
|
||||
*/
|
||||
{
|
||||
ExprDesc Expr;
|
||||
int GotBreak;
|
||||
unsigned PrevErrorCount;
|
||||
CodeMark Start, End;
|
||||
|
||||
ED_Init (&Expr);
|
||||
|
||||
/* Assume no pending token */
|
||||
if (PendingToken) {
|
||||
*PendingToken = 0;
|
||||
}
|
||||
|
||||
/* Check for a label. A label is always part of a statement, it does not
|
||||
/* Handle any labels. A label is always part of a statement, it does not
|
||||
** replace one.
|
||||
*/
|
||||
while (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) {
|
||||
/* Handle the label */
|
||||
DoLabel ();
|
||||
if (CheckLabelWithoutStatement ()) {
|
||||
return 0;
|
||||
}
|
||||
if (ParseAnyLabels ()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (CurTok.Tok) {
|
||||
|
||||
case TOK_LCURLY:
|
||||
NextToken ();
|
||||
GotBreak = CompoundStatement ();
|
||||
CheckTok (TOK_RCURLY, "'{' expected", PendingToken);
|
||||
return GotBreak;
|
||||
|
||||
case TOK_IF:
|
||||
return IfStatement ();
|
||||
|
||||
case TOK_SWITCH:
|
||||
SwitchStatement ();
|
||||
break;
|
||||
|
||||
case TOK_WHILE:
|
||||
WhileStatement ();
|
||||
break;
|
||||
@ -640,10 +697,15 @@ int Statement (int* PendingToken)
|
||||
DoStatement ();
|
||||
break;
|
||||
|
||||
case TOK_SWITCH:
|
||||
SwitchStatement ();
|
||||
case TOK_FOR:
|
||||
ForStatement ();
|
||||
break;
|
||||
|
||||
case TOK_GOTO:
|
||||
GotoStatement ();
|
||||
CheckSemi (PendingToken);
|
||||
return 1;
|
||||
|
||||
case TOK_RETURN:
|
||||
ReturnStatement ();
|
||||
CheckSemi (PendingToken);
|
||||
@ -659,55 +721,22 @@ int Statement (int* PendingToken)
|
||||
CheckSemi (PendingToken);
|
||||
return 1;
|
||||
|
||||
case TOK_FOR:
|
||||
ForStatement ();
|
||||
break;
|
||||
|
||||
case TOK_GOTO:
|
||||
GotoStatement ();
|
||||
CheckSemi (PendingToken);
|
||||
return 1;
|
||||
|
||||
case TOK_SEMI:
|
||||
/* Ignore it */
|
||||
CheckSemi (PendingToken);
|
||||
break;
|
||||
|
||||
case TOK_PRAGMA:
|
||||
DoPragma ();
|
||||
break;
|
||||
|
||||
case TOK_CASE:
|
||||
CaseLabel ();
|
||||
CheckLabelWithoutStatement ();
|
||||
case TOK_SEMI:
|
||||
/* Empty statement. Ignore it */
|
||||
CheckSemi (PendingToken);
|
||||
break;
|
||||
|
||||
case TOK_DEFAULT:
|
||||
DefaultLabel ();
|
||||
CheckLabelWithoutStatement ();
|
||||
break;
|
||||
case TOK_LCURLY:
|
||||
return CompoundStatement (PendingToken);
|
||||
|
||||
default:
|
||||
/* Remember the current error count and code position */
|
||||
PrevErrorCount = ErrorCount;
|
||||
GetCodePos (&Start);
|
||||
|
||||
/* Actual statement */
|
||||
Expr.Flags |= E_NEED_NONE;
|
||||
Expression0 (&Expr);
|
||||
|
||||
/* If the statement didn't generate code, and is not of type
|
||||
** void, emit a warning.
|
||||
*/
|
||||
GetCodePos (&End);
|
||||
if (!ED_YetToLoad (&Expr) &&
|
||||
!ED_MayHaveNoEffect (&Expr) &&
|
||||
CodeRangeIsEmpty (&Start, &End) &&
|
||||
IS_Get (&WarnNoEffect) &&
|
||||
PrevErrorCount == ErrorCount) {
|
||||
Warning ("Expression result unused");
|
||||
}
|
||||
CheckSemi (PendingToken);
|
||||
/* Simple statement */
|
||||
Statement (PendingToken);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
|
||||
int Statement (int* PendingToken);
|
||||
int AnyStatement (int* PendingToken);
|
||||
/* Statement parser. Returns 1 if the statement does a return/break, returns
|
||||
** 0 otherwise. If the PendingToken pointer is not NULL, the function will
|
||||
** not skip the terminating token of the statement (closing brace or
|
||||
|
@ -148,7 +148,7 @@ void SwitchStatement (void)
|
||||
/* Parse the following statement, which may actually be a compound
|
||||
** statement if there is a curly brace at the current input position
|
||||
*/
|
||||
HaveBreak = Statement (&RCurlyBrace);
|
||||
HaveBreak = AnyStatement (&RCurlyBrace);
|
||||
|
||||
/* Check if we had any labels */
|
||||
if (CollCount (SwitchData.Nodes) == 0 && SwitchData.DefaultLabel == 0) {
|
||||
|
@ -64,6 +64,7 @@ $(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/bug760.$1.$2.prg)
|
||||
$(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR)
|
||||
|
||||
# should compile, but gives an error
|
||||
$(WORKDIR)/bug1437.$1.$2.prg: bug1437.c | $(WORKDIR)
|
||||
@echo "FIXME: " $$@ "currently does not compile."
|
||||
$(if $(QUIET),echo misc/bug1437.$1.$2.prg)
|
||||
|
51
test/todo/bug1462-2.c
Normal file
51
test/todo/bug1462-2.c
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
/* issue #1462 - Bit-fields are still broken */
|
||||
/* even the = operation is buggy in certain ways */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
signed int a : 3;
|
||||
signed int b : 3;
|
||||
signed int c : 3;
|
||||
} T;
|
||||
|
||||
int failures = 0;
|
||||
|
||||
T *f(T *t)
|
||||
{
|
||||
t->a = 0;
|
||||
t->c = 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
void test(void)
|
||||
{
|
||||
T a = { 7, 0, 7 };
|
||||
T *p = &a;
|
||||
|
||||
a.b = f(p)->a;
|
||||
|
||||
if (a.a != 0) {
|
||||
++failures;
|
||||
}
|
||||
printf("%d\n", a.a);
|
||||
|
||||
if (p->b != 0) {
|
||||
++failures;
|
||||
}
|
||||
printf("%d\n", p->b);
|
||||
|
||||
if ((&a)->c != 0) {
|
||||
++failures;
|
||||
}
|
||||
printf("%d\n", (&a)->c);
|
||||
|
||||
printf("Failures: %d\n", failures);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test();
|
||||
return failures;
|
||||
}
|
95
test/todo/bug1462-3.c
Normal file
95
test/todo/bug1462-3.c
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
/* issue #1462 - Bit-fields are still broken */
|
||||
/* More testson "op= expression result value" that a naive fix might fail with */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
signed int a : 3;
|
||||
unsigned int b : 3;
|
||||
signed int c : 3;
|
||||
unsigned int d : 3;
|
||||
} T1;
|
||||
|
||||
typedef struct {
|
||||
signed int a : 3;
|
||||
signed int b : 3;
|
||||
signed int c : 3;
|
||||
signed int d : 3;
|
||||
} T2;
|
||||
|
||||
|
||||
int failures1 = 0;
|
||||
int failures2 = 0;
|
||||
|
||||
void test1(void)
|
||||
{
|
||||
T1 a = { 3, 3, 3, 3 };
|
||||
int i;
|
||||
|
||||
i = a.a += a.b + a.c;
|
||||
if (i != 1) {
|
||||
++failures1;
|
||||
}
|
||||
printf("i = %d, a.a = %d\n", i, a.a);
|
||||
|
||||
i = a.b *= -1;
|
||||
if (i != 5 || a.b != 5) {
|
||||
++failures1;
|
||||
}
|
||||
printf("i = %d, a.b = %d\n", i, a.b);
|
||||
|
||||
i = a.c * -1;
|
||||
if (i != -3) {
|
||||
++failures1;
|
||||
}
|
||||
printf("i = %d, a.c = %d\n", i, a.c);
|
||||
|
||||
i = a.d ^= -1;
|
||||
if (i != 4 || a.d != 4) {
|
||||
++failures1;
|
||||
}
|
||||
printf("i = %d, a.d = %d\n", i, a.d);
|
||||
|
||||
printf("Failures: %d\n", failures1);
|
||||
}
|
||||
|
||||
void test2(void)
|
||||
{
|
||||
T2 b = { 3, 3, 4, 4 };
|
||||
int i;
|
||||
|
||||
i = b.a++;
|
||||
if (i != 3 || b.a != -4) {
|
||||
++failures2;
|
||||
}
|
||||
printf("i = %d, b.a = %d\n", i, b.a);
|
||||
|
||||
i = ++b.b;
|
||||
if (i != -4 || b.b != -4) {
|
||||
++failures2;
|
||||
}
|
||||
printf("i = %d, b.b = %d\n", i, b.b);
|
||||
|
||||
i = b.c--;
|
||||
if (i != -4 || b.c != 3) {
|
||||
++failures2;
|
||||
}
|
||||
printf("i = %d, b.c = %d\n", i, b.c);
|
||||
|
||||
i = --b.d;
|
||||
if (i != 3 || b.d != 3) {
|
||||
++failures2;
|
||||
}
|
||||
printf("i = %d, b.d = %d\n", i, b.d);
|
||||
|
||||
printf("Failures: %d\n", failures2);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test1();
|
||||
test2();
|
||||
return failures1 + failures2;
|
||||
}
|
||||
|
13
test/val/bug1504.c
Normal file
13
test/val/bug1504.c
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
/* bug #1504 - Some compilation failures */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = 0, *p = &i;
|
||||
switch (i) case 0: case 1: i = 21; /* Should be OK but fails */
|
||||
p++[0] += 21; /* Should be OK but fails */
|
||||
printf("%d\n", i);
|
||||
return i != 42;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user