Compare commits

..

No commits in common. "main" and "v1.27.235" have entirely different histories.

151 changed files with 14010 additions and 42511 deletions

1
.gitignore vendored
View File

@ -353,4 +353,3 @@ make/oscar64
*.mapd
*.idb
oscar64/Releasex64/oscar64.vcxproj.FileListAbsolute.txt
/oscar64/Debugx64

View File

@ -1,67 +0,0 @@
cmake_minimum_required(VERSION 3.15)
# Project name and version
project(oscar64 VERSION 1.0 LANGUAGES CXX)
# Define the executable
add_executable(oscar64)
# Glob all source files in the oscar64/ directory
file(GLOB OSCAR64_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.h")
# Add the sources to the target
target_sources(${PROJECT_NAME} PRIVATE ${OSCAR64_SOURCES})
# Add header files
target_include_directories(oscar64 PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
# Compiler settings based on configuration
set_target_properties(oscar64 PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
)
# Set debug and release configurations
target_compile_definitions(oscar64 PRIVATE $<$<CONFIG:Debug>:_DEBUG;_CONSOLE> $<$<CONFIG:Release>:NDEBUG;_CONSOLE>)
target_compile_options(oscar64 PRIVATE $<$<CONFIG:Debug>:/W3 /WX> $<$<CONFIG:Release>:/O2 /W3>)
# Post-build steps (only for Release builds)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_custom_command(TARGET oscar64 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:oscar64> ${CMAKE_BINARY_DIR}/bin
)
endif()
if (WIN32)
target_link_libraries(oscar64 PRIVATE kernel32 user32 gdi32 winspool comdlg32 advapi32 shell32 ole32 oleaut32 uuid odbc32 odbccp32 version)
elseif (APPLE)
# Add macOS-specific frameworks to replace Windows libraries
target_link_libraries(${PROJECT_NAME}
"-framework Cocoa" # For GUI and application support
"-framework CoreFoundation" # For Core Foundation utilities (similar to advapi32 or shell32)
"-framework CoreGraphics" # For graphics and rendering (similar to gdi32)
"-framework IOKit" # For hardware interaction
"-framework AppKit" # For GUI (equivalent to user32)
)
elseif (UNIX)
# Add Linux-specific libraries for equivalent functionality
target_link_libraries(${PROJECT_NAME}
pthread # For threading (similar to kernel32)
dl # For dynamic library loading (similar to LoadLibrary)
m # For math library (optional but common on Linux)
X11 # For X Window System (similar to user32 for GUI support)
)
endif()
# Output directories
set_target_properties(oscar64 PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release
)

1483
README.md

File diff suppressed because it is too large Load Diff

View File

@ -1,77 +0,0 @@
#include <stdio.h>
#include <assert.h>
struct X
{
char t;
long l;
};
__striped X xs[16];
X xf[16];
char xp;
__noinline long tt(long n)
{
return n;
}
inline auto & tas(void)
{
return xs[xp].l;
}
inline auto & taf(void)
{
return xf[xp].l;
}
long ts(char n)
{
return tt(tas());
}
long tf(char n)
{
return tt(taf());
}
inline auto bas(void)
{
return xs[xp].l;
}
inline auto baf(void)
{
return xs[xp].l;
}
long bs(char n)
{
return tt(bas());
}
long bf(char n)
{
return tt(baf());
}
int main(void)
{
for(char i=0; i<16; i++)
{
xs[i].l = i * i;
xf[i].l = i * i;
}
for(char i=0; i<16; i++)
{
xp = i;
assert(ts(0) == i * i);
assert(tf(0) == i * i);
assert(bs(0) == i * i);
assert(bf(0) == i * i);
}
return 0;
}

View File

@ -1,14 +1,8 @@
rem @echo off
@call :test rolrortest.cpp
@if %errorlevel% neq 0 goto :error
@call :test bitfields.cpp
@if %errorlevel% neq 0 goto :error
@call :testn autorefreturn.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_string.cpp
@if %errorlevel% neq 0 goto :error
@ -18,15 +12,9 @@ rem @echo off
@call :testh opp_vector.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_static_vector.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_vector_string.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_string_init.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_streamtest.cpp
@if %errorlevel% neq 0 goto :error
@ -39,9 +27,6 @@ rem @echo off
@call :testh opp_list.cpp
@if %errorlevel% neq 0 goto :error
@call :testn opp_functional.cpp
@if %errorlevel% neq 0 goto :error
@call :testh operatoroverload.cpp
@if %errorlevel% neq 0 goto :error
@ -57,7 +42,7 @@ rem @echo off
@call :testh constructortest.cpp
@if %errorlevel% neq 0 goto :error
@call :testn copyconstructor.cpp
@call :testh copyconstructor.cpp
@if %errorlevel% neq 0 goto :error
@call :testh copyassign.cpp
@ -96,9 +81,6 @@ rem @echo off
@call :test fastcalltest.c
@if %errorlevel% neq 0 goto :error
@call :test strlen.c
@if %errorlevel% neq 0 goto :error
@call :test strcmptest.c
@if %errorlevel% neq 0 goto :error
@ -123,9 +105,6 @@ rem @echo off
@call :test floatmultest.c
@if %errorlevel% neq 0 goto :error
@call :test floatinttest.c
@if %errorlevel% neq 0 goto :error
@call :test staticconsttest.c
@if %errorlevel% neq 0 goto :error
@ -165,9 +144,6 @@ rem @echo off
@call :test qsorttest.c
@if %errorlevel% neq 0 goto :error
@call :testn plasma.c
@if %errorlevel% neq 0 goto :error
@call :test loopdomtest.c
@if %errorlevel% neq 0 goto :error
@ -195,12 +171,6 @@ rem @echo off
@call :test divmodtest.c
@if %errorlevel% neq 0 goto :error
@call :test divmod32test.c
@if %errorlevel% neq 0 goto :error
@call :test fixmathtest.c
@if %errorlevel% neq 0 goto :error
@call :test enumswitch.c
@if %errorlevel% neq 0 goto :error
@ -255,9 +225,6 @@ rem @echo off
@call :testn mmultest.c
@if %errorlevel% neq 0 goto :error
@call :test tileexpand.cpp
@if %errorlevel% neq 0 goto :error
@exit /b 0
:error
@ -265,136 +232,115 @@ echo Failed with error #%errorlevel%.
exit /b %errorlevel%
:testh
..\bin\oscar64 -e -bc %~1
..\release\oscar64 -e -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -n %~1
..\release\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -bc %~1
..\release\oscar64 -e -O2 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -n %~1
..\release\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
..\release\oscar64 -e -O2 -n -dHEAPCHECK %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
..\release\oscar64 -e -O0 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Oo -n %~1
..\release\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Ox -n %~1
..\release\oscar64 -e -Os -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -bc %~1
..\release\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -n %~1
..\release\oscar64 -e -O3 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -bc %~1
..\release\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n -dHEAPCHECK %~1
..\release\oscar64 -e -O3 -n -dHEAPCHECK %~1
@if %errorlevel% neq 0 goto :error
@exit /b 0
:test
..\bin\oscar64 -e -bc %~1
..\release\oscar64 -e -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -n %~1
..\release\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -bc %~1
..\release\oscar64 -e -O2 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -n %~1
..\release\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -bc %~1
..\release\oscar64 -e -O0 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -n %~1
..\release\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -bc %~1
..\release\oscar64 -e -Os -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -n %~1
..\release\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -bc %~1
..\release\oscar64 -e -O3 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n %~1
..\release\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Oo -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Ox -n %~1
..\release\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error
@exit /b 0
:testb
..\bin\oscar64 -e -bc %~1
..\release\oscar64 -e -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -O2 %~1
..\release\oscar64 -e -bc -O2 %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -O0 %~1
..\release\oscar64 -e -bc -O0 %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -Os %~1
..\release\oscar64 -e -bc -Os %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -O3 %~1
..\release\oscar64 -e -bc -O3 %~1
@if %errorlevel% neq 0 goto :error
@exit /b 0
:testn
..\bin\oscar64 -e -n %~1
..\release\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -n %~1
..\release\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -n %~1
..\release\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -n %~1
..\release\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n %~1
..\release\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Oo -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Ox -n %~1
..\release\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error
@exit /b 0

View File

@ -334,6 +334,7 @@ void test_add_word_cross(void)
}
int main(void)
{
test_char_fit();
test_char_cross();
test_word_fit();

View File

@ -303,18 +303,6 @@ void shr32n(unsigned long xu, long xi)
}
}
void shl1_32n(void)
{
static const unsigned long m[] = {
#for(i, 32) 1ul << i,
};
for(int i=0; i<32; i++)
{
assert(1ul << i == m[i]);
}
}
#pragma native(shl32n)
#pragma native(shr32n)
@ -385,30 +373,24 @@ int main(void)
shr16n(0xfedc, 0xfedc);
shl32b(0x00000000UL, 0x00000000L);
shl32b(0x00000001UL, 0x00000001L);
shl32b(0xffffffffUL, 0xffffffffL);
shl32b(0x12345678UL, 0x12345678L);
shl32b(0xfedcba98UL, 0xfedcba98L);
shr32b(0x00000000UL, 0x00000000L);
shr32b(0x00000001UL, 0x00000001L);
shr32b(0xffffffffUL, 0xffffffffL);
shr32b(0x12345678UL, 0x12345678L);
shr32b(0xfedcba98UL, 0xfedcba98L);
shl32n(0x00000000UL, 0x00000000L);
shl32n(0x00000001UL, 0x00000001L);
shl32n(0xffffffffUL, 0xffffffffL);
shl32n(0x12345678UL, 0x12345678L);
shl32n(0xfedcba98UL, 0xfedcba98L);
shr32n(0x00000000UL, 0x00000000L);
shr32n(0x00000001UL, 0x00000001L);
shr32n(0xffffffffUL, 0xffffffffL);
shr32n(0x12345678UL, 0x12345678L);
shr32n(0xfedcba98UL, 0xfedcba98L);
shl1_32n();
return 0;
}

View File

@ -1,5 +1,4 @@
#include <assert.h>
#include <stdio.h>
int t, n;
@ -162,7 +161,7 @@ void test_return_value(void)
C2 c(test_ret_v());
}
assert(n == 6 && t == 0);
assert(n == 4 && t == 0);
}
void test_return_reference(void)
@ -185,7 +184,7 @@ void test_retparam_value(void)
test_param_fv(test_ret_v());
}
assert(n == 6 && t == 0);
assert(n == 4 && t == 0);
}
void test_retparam_reference(void)
@ -201,6 +200,7 @@ void test_retparam_reference(void)
int main(void)
{
#if 0
test_dcopy_init();
test_copy_init();
test_minit();
@ -208,8 +208,9 @@ int main(void)
test_param_value();
test_param_ref();
test_return_value();
#endif
test_retparam_value();
test_retparam_reference();
// test_retparam_reference();
return 0;
}

View File

@ -1,36 +0,0 @@
#include <assert.h>
void check(unsigned long l, unsigned long r)
{
unsigned long d = l / r, m = l % r;
assert(d * r + m == l);
assert(m < r);
}
int main(void)
{
for(char i=0; i<28; i++)
{
for(char j=0; j<28; j++)
{
check(0xb3ul << i, 0x2bul << j);
check(0xb3ul << i, 0x01ul << j);
check(0x01ul << i, 0xc2ul << j);
check(0xb31ful << i, 0x2bul << j);
check(0xb354ul << i, 0x01ul << j);
check(0xb3ul << i, 0x2b1cul << j);
check(0xb3ul << i, 0x013ful << j);
check(0xb31ful << i, 0x2b23ul << j);
check(0xb354ul << i, 0x0145ul << j);
check(0xb31f24ul << i, 0x2bul << j);
check(0xb35421ul << i, 0x01ul << j);
check(0xb31f24ul << i, 0x2b23ul << j);
check(0xb35421ul << i, 0x0145ul << j);
check(0xb31f24ul << i, 0x2b2356ul << j);
check(0xb35421ul << i, 0x0145a7ul << j);
}
}
return 0;
}

View File

@ -1,90 +0,0 @@
#include <fixmath.h>
#include <assert.h>
#include <stdlib.h>
unsigned tval[] = {
1, 2, 16, 128, 255, 256, 4096, 32768, 65535
};
void testmuldiv16u(void)
{
for (char i=0; i<9; i++)
{
assert(lmuldiv16u(tval[i], 0, tval[i]) == 0);
assert(lmuldiv16u(0, tval[i], tval[i]) == 0);
for(char j=0; j<9; j++)
{
assert(lmuldiv16u(tval[i], tval[j], tval[i]) == tval[j]);
assert(lmuldiv16u(tval[j], tval[i], tval[i]) == tval[j]);
}
}
for(int i=0; i<10000; i++)
{
unsigned a = rand();
unsigned b = rand();
unsigned c = rand();
if (c > 0)
{
unsigned long d = (unsigned long)a * (unsigned long) b / c;
if (d < 0x10000l)
assert(lmuldiv16u(a, b, c) == d);
}
}
}
unsigned ival[] = {
1, 2, 16, 128, 255, 256, 4096, 32767,
-1, -2, -16, -128, -255, -256, -4096, -32767
};
void testmuldiv16s(void)
{
for (char i=0; i<16; i++)
{
assert(lmuldiv16s(ival[i], 0, ival[i]) == 0);
assert(lmuldiv16s(0, ival[i], ival[i]) == 0);
for(char j=0; j<16; j++)
{
assert(lmuldiv16s(ival[i], ival[j], ival[i]) == ival[j]);
assert(lmuldiv16s(ival[j], ival[i], ival[i]) == ival[j]);
}
}
for(int i=0; i<10000; i++)
{
int a = rand();
int b = rand();
int c = rand();
if (c > 0)
{
long d = (long)a * (long)b / c;
if (d >= -32768 && d <= 32767)
assert(lmuldiv16s(a, b, c) == d);
}
}
}
void testlmul4f12s(void)
{
for(int i=0; i<20000; i++)
{
int a = rand();
int b = rand();
long d = ((long)a * (long)b) >> 12;
if (d >= -32768 && d <= 32767)
assert(lmul4f12s(a, b) == d);
}
}
int main(void)
{
testlmul4f12s();
testmuldiv16u();
testmuldiv16s();
return 0;
}

View File

@ -1,75 +0,0 @@
#include <assert.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
float a;
int i;
long li;
unsigned u;
unsigned long lu;
a = 1.0;
i = 1;
for(int j=0; j<15; j++)
{
assert(i == (int)a);
assert(a == (float)i);
a *= 2.0;
i <<= 1;
}
a = -1.0;
i = -1;
for(int j=0; j<15; j++)
{
assert(i == (int)a);
assert(a == (float)i);
a *= 2.0;
i <<= 1;
}
a = 1.0;
u = 1;
for(int j=0; j<16; j++)
{
assert(u == (unsigned)a);
assert(a == (float)u);
a *= 2.0;
u <<= 1;
}
a = 1.0;
li = 1;
for(int j=0; j<31; j++)
{
assert(li == (long)a);
assert(a == (float)li);
a *= 2.0;
li <<= 1;
}
a = -1.0;
li = -1;
for(int j=0; j<31; j++)
{
assert(li == (long)a);
assert(a == (float)li);
a *= 2.0;
li <<= 1;
}
a = 1.0;
lu = 1;
for(int j=0; j<32; j++)
{
assert(lu == (unsigned long)a);
assert(a == (float)lu);
a *= 2.0;
lu <<= 1;
}
return 0;
}

View File

@ -1,3 +1,5 @@
CC=../bin/oscar64
CXX=$(CC)
SRCS=$(filter-out opp_part1.cpp opp_part2.cpp, $(wildcard *.c *.cpp))
EXES=$(patsubst %.c,%,$(SRCS))
EXES:=$(patsubst %.cpp,%,$(EXES))
@ -5,56 +7,44 @@ EXES:=$(patsubst %.cpp,%,$(EXES))
all: $(EXES)
%: %.c
$(OSCAR64_CC) -e -bc $<
$(OSCAR64_CC) -e -n $<
$(OSCAR64_CC) -e -O2 -bc $<
$(OSCAR64_CC) -e -O2 -n $<
$(OSCAR64_CC) -e -O0 -bc $<
$(OSCAR64_CC) -e -O0 -n $<
$(OSCAR64_CC) -e -Os -bc $<
$(OSCAR64_CC) -e -Os -n $<
$(OSCAR64_CC) -e -O3 -bc $<
$(OSCAR64_CC) -e -O3 -n $<
$(CC) -e -bc $<
$(CC) -e -n $<
$(CC) -e -O2 -bc $<
$(CC) -e -O2 -n $<
$(CC) -e -O0 -bc $<
$(CC) -e -O0 -n $<
$(CC) -e -Os -bc $<
$(CC) -e -Os -n $<
$(CC) -e -O3 -bc $<
$(CC) -e -O3 -n $<
%: %.cpp
$(OSCAR64_CXX) -e -bc $<
$(OSCAR64_CXX) -e -n $<
$(OSCAR64_CXX) -e -O2 -bc $<
$(OSCAR64_CXX) -e -O2 -n $<
$(OSCAR64_CXX) -e -O0 -bc $<
$(OSCAR64_CXX) -e -O0 -n $<
$(OSCAR64_CXX) -e -Os -bc $<
$(OSCAR64_CXX) -e -Os -n $<
$(OSCAR64_CXX) -e -O3 -bc $<
$(OSCAR64_CXX) -e -O3 -n $<
$(CXX) -e -bc $<
$(CXX) -e -n $<
$(CXX) -e -O2 -bc $<
$(CXX) -e -O2 -n $<
$(CXX) -e -O0 -bc $<
$(CXX) -e -O0 -n $<
$(CXX) -e -Os -bc $<
$(CXX) -e -Os -n $<
$(CXX) -e -O3 -bc $<
$(CXX) -e -O3 -n $<
# testb
bitshifttest: bitshifttest.c
$(OSCAR64_CC) -e -bc $<
$(OSCAR64_CC) -e -bc -O2 $<
$(OSCAR64_CC) -e -bc -O0 $<
$(OSCAR64_CC) -e -bc -Os $<
$(OSCAR64_CC) -e -bc -O3 $<
$(OSCAR64_CC) -e -n $<
$(CC) -e -bc $<
$(CC) -e -bc -O2 $<
$(CC) -e -bc -O0 $<
$(CC) -e -bc -Os $<
$(CC) -e -bc -O3 $<
$(CC) -e -n $<
# testn
stripedarraytest: stripedarraytest.c
$(OSCAR64_CC) -e -O2 -n $<
$(OSCAR64_CC) -e -O0 -n $<
$(OSCAR64_CC) -e -Os -n $<
$(OSCAR64_CC) -e -O3 -n $<
autorefreturn: autorefreturn.cpp
$(OSCAR64_CC) -e -O2 -n $<
$(OSCAR64_CC) -e -O0 -n $<
$(OSCAR64_CC) -e -Os -n $<
$(OSCAR64_CC) -e -O3 -n $<
copyconstructor: copyconstructor.cpp
$(OSCAR64_CC) -e -O2 -n $<
$(OSCAR64_CC) -e -O0 -n $<
$(OSCAR64_CC) -e -Os -n $<
$(OSCAR64_CC) -e -O3 -n $<
$(CC) -e -O2 -n $<
$(CC) -e -O0 -n $<
$(CC) -e -Os -n $<
$(CC) -e -O3 -n $<
clean:
@$(RM) *.asm *.bcs *.int *.lbl *.map *.prg
$(RM) *.asm *.bcs *.int *.lbl *.map *.prg

View File

@ -1,46 +0,0 @@
#include <opp/functional.h>
class Node
{
public:
virtual int eval(void) const = 0;
};
class ConstNode : public Node
{
private:
int v;
public:
ConstNode(int v_) : v(v_) {}
virtual int eval(void) const
{
return v;
}
};
class BinaryNode : public Node
{
private:
opp::function<int(int, int)> op;
Node * left, * right;
public:
BinaryNode(opp::function<int(int, int)> op_, Node * left_, Node * right_);
virtual int eval(void) const
{
return op(left->eval(), right->eval());
}
};
inline BinaryNode::BinaryNode(opp::function<int(int, int)> op_, Node * left_, Node * right_)
: op(op_), left(left_), right(right_) {}
int main(void)
{
Node * s1 =
new BinaryNode([=](int a, int b){return a + b;},
new ConstNode(7), new ConstNode(11)
);
return s1->eval() - 18;
}

View File

@ -1,78 +0,0 @@
#include <opp/static_vector.h>
#include <opp/algorithm.h>
#include <assert.h>
#include <opp/iostream.h>
int main(void)
{
opp::static_vector<int, 20> a;
for(int i=0; i<10; i++)
a.push_back(i);
int s = 0;
for(int i=0; i<a.size(); i++)
s += a[i];
assert(s == 45);
for(int i=0; i<5; i++)
a.erase(i);
s = 0;
for(int i=0; i<a.size(); i++)
s += a[i];
assert(s == 1 + 3 + 5 + 7 + 9);
opp::static_vector<int, 100> v;
for(int i=0; i<10; i++)
v.push_back(i);
assert(v.size() == 10);
v.insert(0, 20);
assert(v.size() == 11);
v.insert(6, 21);
assert(v.size() == 12);
v.insert(12, 22);
int * fi = opp::find(v.begin(), v.end(), 21);
fi = v.insert(fi, 30);
fi = v.insert(fi, 31);
fi = v.insert(fi, 32);
assert(v.size() == 16);
assert(v[0] == 20);
assert(v[15] == 22);
assert(v[8] == 32);
fi = opp::find(v.begin(), v.end(), 32);
for(int i=0; i<30; i++)
{
fi = v.insert(fi, i + 40);
}
assert(v.size() == 46);
assert(v[28] == 60);
v.erase(10, 10);
for(int i : v)
opp::cout << i << ", ";
opp::cout << "\n";
assert(v.size() == 36);
assert(v[18] == 60);
v.assign(42, 11);
assert(v.size() == 42);
assert(v[0] == 11);
assert(v[15] == 11);
assert(v[41] == 11);
return 0;
}

View File

@ -1,193 +0,0 @@
#include <opp/string.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
using opp::string;
const string s1;
const string s2 = "Hello";
const string s3{"World"};
const string a1[2];
const string a2[2] = {"Hello", "World"};
const string a3[2] = {opp::string("Hello"), opp::string("World")};
const string d1[3][2];
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
const string d3[3][2] =
{{opp::string("Hello"), opp::string("World")},
{opp::string("aaa"), opp::string("bbb")},
{opp::string("ccc"), opp::string("ddd")}};
void test_global_init(void)
{
assert(!strcmp(s1.tocstr(), ""));
assert(!strcmp(s2.tocstr(), "Hello"));
assert(!strcmp(s3.tocstr(), "World"));
}
void test_global_ainit(void)
{
assert(!strcmp(a1[0].tocstr(), ""));
assert(!strcmp(a1[1].tocstr(), ""));
assert(!strcmp(a2[0].tocstr(), "Hello"));
assert(!strcmp(a2[1].tocstr(), "World"));
assert(!strcmp(a3[0].tocstr(), "Hello"));
assert(!strcmp(a3[1].tocstr(), "World"));
}
void test_global_dinit(void)
{
assert(!strcmp(d1[0][0].tocstr(), ""));
assert(!strcmp(d1[2][1].tocstr(), ""));
assert(!strcmp(d2[0][0].tocstr(), "Hello"));
assert(!strcmp(d2[2][1].tocstr(), "ddd"));
assert(!strcmp(d3[0][0].tocstr(), "Hello"));
assert(!strcmp(d3[2][1].tocstr(), "ddd"));
}
void test_local_init(void)
{
const string s1;
const string s2 = "Hello";
const string s3{"World"};
assert(!strcmp(s1.tocstr(), ""));
assert(!strcmp(s2.tocstr(), "Hello"));
assert(!strcmp(s3.tocstr(), "World"));
}
void test_local_ainit(void)
{
const string a1[2];
const string a2[2] = {"Hello", "World"};
const string a3[2] = {opp::string("Hello"), opp::string("World")};
assert(!strcmp(a1[0].tocstr(), ""));
assert(!strcmp(a1[1].tocstr(), ""));
assert(!strcmp(a2[0].tocstr(), "Hello"));
assert(!strcmp(a2[1].tocstr(), "World"));
assert(!strcmp(a3[0].tocstr(), "Hello"));
assert(!strcmp(a3[1].tocstr(), "World"));
}
void test_local_dinit(void)
{
const string d1[3][2];
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
const string d3[3][2] =
{{opp::string("Hello"), opp::string("World")},
{opp::string("aaa"), opp::string("bbb")},
{opp::string("ccc"), opp::string("ddd")}};
assert(!strcmp(d1[0][0].tocstr(), ""));
assert(!strcmp(d1[2][1].tocstr(), ""));
assert(!strcmp(d2[0][0].tocstr(), "Hello"));
assert(!strcmp(d2[2][1].tocstr(), "ddd"));
assert(!strcmp(d3[0][0].tocstr(), "Hello"));
assert(!strcmp(d3[2][1].tocstr(), "ddd"));
}
class X
{
public:
const string s1;
const string s2 = "Hello";
const string s3;
const string a1[2];
const string a2[2] = {"Hello", "World"};
const string d1[3][2];
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
X() : s3("World") {}
};
void test_member_init(void)
{
X x;
assert(!strcmp(x.s1.tocstr(), ""));
assert(!strcmp(x.s2.tocstr(), "Hello"));
assert(!strcmp(x.s3.tocstr(), "World"));
}
void test_member_ainit(void)
{
X x;
assert(!strcmp(x.a1[0].tocstr(), ""));
assert(!strcmp(x.a1[1].tocstr(), ""));
assert(!strcmp(x.a2[0].tocstr(), "Hello"));
assert(!strcmp(x.a2[1].tocstr(), "World"));
}
void test_member_dinit(void)
{
X x;
assert(!strcmp(x.d1[0][0].tocstr(), ""));
assert(!strcmp(x.d1[2][1].tocstr(), ""));
assert(!strcmp(x.d2[0][0].tocstr(), "Hello"));
assert(!strcmp(x.d2[2][1].tocstr(), "ddd"));
}
void test_copy_init(void)
{
X x;
X y(x);
assert(!strcmp(y.s1.tocstr(), ""));
assert(!strcmp(y.s2.tocstr(), "Hello"));
assert(!strcmp(y.s3.tocstr(), "World"));
}
void test_copy_ainit(void)
{
X x;
X y(x);
assert(!strcmp(y.a1[0].tocstr(), ""));
assert(!strcmp(y.a1[1].tocstr(), ""));
assert(!strcmp(y.a2[0].tocstr(), "Hello"));
assert(!strcmp(y.a2[1].tocstr(), "World"));
}
int main(void)
{
test_global_init();
test_global_ainit();
test_global_dinit();
for(int i=0; i<10000; i++)
{
test_local_init();
test_local_ainit();
}
test_member_init();
test_member_ainit();
test_copy_init();
test_copy_ainit();
return 0;
}

View File

@ -64,15 +64,5 @@ int main(void)
opp::cout << i << ", ";
opp::cout << "\n";
assert(v.size() == 36);
assert(v[18] == 60);
v.assign(42, 11);
assert(v.size() == 42);
assert(v[0] == 11);
assert(v[15] == 11);
assert(v[41] == 11);
return 0;
}

View File

@ -1,145 +0,0 @@
#include <stdlib.h>
static const char sintab[] = {
128, 131, 134, 137, 140, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 179, 182, 185, 188, 191, 193, 196, 199, 201, 204, 206, 209, 211, 213, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 239, 240, 241, 243, 244, 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255,
255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246, 245, 244, 243, 241, 240, 239, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220, 218, 216, 213, 211, 209, 206, 204, 201, 199, 196, 193, 191, 188, 185, 182, 179, 177, 174, 171, 168, 165, 162, 159, 156, 153, 150, 147, 144, 140, 137, 134, 131,
128, 125, 122, 119, 116, 112, 109, 106, 103, 100, 97, 94, 91, 88, 85, 82, 79, 77, 74, 71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 43, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 21, 19, 17, 16, 15, 13, 12, 11, 10, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 19, 21, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 45, 47, 50, 52, 55, 57, 60, 63, 65, 68, 71, 74, 77, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 116, 119, 122, 125
};
char Screen0[1024], Screen1[1024];
char colormap0[256], colormap1[256];
char colors0[] = {0, 6, 14, 1, 13, 5, 0};
char colors1[] = {0, 9, 7, 1, 15, 12, 0};
unsigned c1A, c1B, c2A, c2B, c3A, c3B;
int d1A, d1B, d2A, d2B, d3A, d3B;
void inithires(void)
{
for(int i=0; i<256; i++)
{
colormap0[i] = colors0[i / 37];
colormap1[i] = colors1[i / 37] << 4;
}
}
inline void doplasma(char * scrn)
{
char xbuf0[40], xbuf1[40];
char ybuf0[25], ybuf1[25];
char c2a = c2A >> 8;
char c2b = c2B >> 8;
char c1a = c1A >> 8;
char c1b = c1B >> 8;
for (char i = 0; i < 25; i++) {
ybuf0[i] = sintab[(c1a + c2a) & 0xff] + sintab[c1b];
c1a += 13;
c1b -= 5;
}
for (char i = 0; i < 40; i++) {
xbuf0[i] = sintab[(c2a + c1b) & 0xff] + sintab[c2b];
c2a += 11;
c2b -= 7;
}
c2a = c2B >> 8;
c2b = c3A >> 8;
c1a = c1B >> 8;
c1b = c3B >> 8;
for (char i = 0; i < 25; i++) {
ybuf1[i] = sintab[(c1b + c2a) & 0xff] + sintab[c1a];
c1a += 4;
c1b -= 6;
}
for (char i = 0; i < 40; i++) {
xbuf1[i] = sintab[(c2b + c1a) & 0xff] + sintab[c2a];
c2a += 7;
c2b -= 9;
}
#pragma unroll(full)
for (char k=0; k<5; k++)
{
char tbuf0[5], tbuf1[5];
#pragma unroll(full)
for (char i = 0; i < 4; i++)
{
tbuf0[i] = ybuf0[5 * k + i + 1] - ybuf0[5 * k + i];
tbuf1[i] = ybuf1[5 * k + i + 1] - ybuf1[5 * k + i];
}
for (signed char i = 39; i >= 0; i--)
{
char t = xbuf0[i] + ybuf0[5 * k];
char u = xbuf1[i] + ybuf1[5 * k];
#pragma unroll(full)
for (char j = 0; j < 5; j++)
{
scrn[40 * j + 200 * k + i] = colormap0[u] | colormap1[u];
t += tbuf0[j];
u += tbuf1[j];
}
}
}
c1A += 8 * ((int)sintab[d1A] - 128);
c1B += 16 * ((int)sintab[d1B] - 128);
c2A += 8 * ((int)sintab[d2A] - 128);
c2B += 16 * ((int)sintab[d2B] - 128);
c3A += 6 * ((int)sintab[d3A] - 128);
c3B += 12 * ((int)sintab[d3B] - 128);
d1A += 3;
d1B += rand() & 3;
d2A += 5;
d2B += rand() & 3;
d3A += 2;
d3B += rand() & 3;
}
void doplasma0(void)
{
doplasma(Screen0);
}
void doplasma1(void)
{
doplasma(Screen1);
}
unsigned checksum(const char * scr)
{
unsigned s = 0x1234;
for(int i=0; i<1024; i++)
{
unsigned m = s & 1;
s >>= 1;
if (m)
s ^= 0x2152;
s ^= scr[i];
}
return s;
}
int main(void)
{
inithires();
doplasma0();
doplasma1();
doplasma0();
doplasma1();
doplasma0();
doplasma1();
return checksum(Screen0) + checksum(Screen1) - 16337;
}

View File

@ -1,76 +0,0 @@
#include <assert.h>
__noinline unsigned long rollright32(unsigned long a) {
unsigned long tmp = a & 1;
return ( a >> 1) + (tmp << 31);
}
__noinline unsigned rollright16(unsigned a) {
unsigned tmp = a & 1;
return ( a >> 1) + (tmp << 15);
}
__noinline char rollright8(char a) {
char tmp = a & 1;
return ( a >> 1) + (tmp << 7);
}
__noinline unsigned long rollleft32(unsigned long a) {
unsigned long tmp = (a >> 31) & 1;
return ( a << 1) + tmp;
}
__noinline unsigned rollleft16(unsigned a) {
unsigned tmp = (a >> 15) & 1;
return ( a << 1) + tmp;
}
__noinline char rollleft8(char a) {
char tmp = (a >> 7) & 1;
return ( a << 1) + tmp;
}
int main() {
unsigned long lv = 0x12345678ul;
unsigned val = 0x1234;
char c=0x12;
unsigned long lvt[33];
unsigned valt[17];
char ct[9];
lvt[0] = lv;
valt[0] = val;
ct[0] = c;
assert(rollleft8(rollright8(c)) == c);
assert(rollleft16(rollright16(val)) == val);
assert(rollleft32(rollright32(lv)) == lv);
for(int i=0; i<32; i++)
lvt[i + 1] = rollright32(lvt[i]);
for(int i=0; i<16; i++)
valt[i + 1] = rollright16(valt[i]);
for(int i=0; i<8; i++)
ct[i + 1] = rollright8(ct[i]);
for(int i=0; i<=32; i++)
{
assert(lvt[32 - i] == lv);
lv = rollleft32(lv);
}
for(int i=0; i<=16; i++)
{
assert(valt[16 - i] == val);
val = rollleft16(val);
}
for(int i=0; i<=8; i++)
{
assert(ct[8 - i] == c);
c = rollleft8(c);
}
return 0;
}

View File

@ -1,27 +0,0 @@
#include <string.h>
#include <assert.h>
char lstr[1025];
int main(void)
{
#if 1
assert(strlen("") == 0);
assert(strlen("1") == 1);
assert(strlen("12") == 2);
assert(strlen("123") == 3);
assert(strlen("1234") == 4);
assert(strlen("12345") == 5);
assert(strlen("123456") == 6);
#endif
#if 1
char * dp = lstr;
for(int i=0; i<1024; i++)
{
*dp = 0;
assert(strlen(lstr) == i);
*dp++ = 'a';
}
#endif
return 0;
}

View File

@ -5,11 +5,6 @@ void testmuli(long a, long b, long ab)
assert (a * b == ab);
}
void testmulu(unsigned long a, unsigned long b, unsigned long ab)
{
assert (a * b == ab);
}
void testdivi(long a, long b, long ab)
{
assert (a / b == ab);
@ -85,26 +80,6 @@ int main(void)
testmuli( -1024, 1237, -1266688l);
testmuli( -1024,-1237, 1266688l);
testmulu(0x00000001, 0x0000003c, 0x0000003c);
testmulu(0x00000100, 0x0000003c, 0x00003c00);
testmulu(0x00010000, 0x0000003c, 0x003c0000);
testmulu(0x01000000, 0x0000003c, 0x3c000000);
testmulu(0x0000003c, 0x00000001, 0x0000003c);
testmulu(0x0000003c, 0x00000100, 0x00003c00);
testmulu(0x0000003c, 0x00010000, 0x003c0000);
testmulu(0x0000003c, 0x01000000, 0x3c000000);
testmulu(0x0000004b, 0x0000003c, 0x00001194);
testmulu(0x00004b00, 0x0000003c, 0x00119400);
testmulu(0x004b0000, 0x0000003c, 0x11940000);
testmulu(0x4b000000, 0x0000003c, 0x94000000);
testmulu(0x0000003c, 0x0000004b, 0x00001194);
testmulu(0x0000003c, 0x00004b00, 0x00119400);
testmulu(0x0000003c, 0x004b0000, 0x11940000);
testmulu(0x0000003c, 0x4b000000, 0x94000000);
testdivi( 1, 1, 1);
testdivi(-1, 1, -1);
testdivi( 1, -1, -1);

View File

@ -63,33 +63,6 @@ bool nge(long a, long b)
inline bool ieq(long a, long b)
{
return a == b;
}
inline bool ilt(long a, long b)
{
return a < b;
}
inline bool igt(long a, long b)
{
return a > b;
}
inline bool ile(long a, long b)
{
return a <= b;
}
inline bool ige(long a, long b)
{
return a >= b;
}
bool beqz(long a)
{
return a == 0;
@ -215,71 +188,7 @@ bool nge1(long a)
bool beqm(long a)
{
return a == -1;
}
bool bltm(long a)
{
return a < -1;
}
bool bgtm(long a)
{
return a > -1;
}
bool blem(long a)
{
return a <= -1;
}
bool bgem(long a)
{
return a >= -1;
}
bool neqm(long a)
{
return a == -1;
}
#pragma native(neqm)
bool nltm(long a)
{
return a < -1;
}
#pragma native(nltm)
bool ngtm(long a)
{
return a > -1;
}
#pragma native(ngtm)
bool nlem(long a)
{
return a <= -1;
}
#pragma native(nlem)
bool ngem(long a)
{
return a >= -1;
}
#pragma native(ngem)
void cmpc(long a, long b)
void cmp(long a, long b)
{
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b);
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
@ -294,27 +203,6 @@ void cmpc(long a, long b)
assert(bgef == ngef);
}
void cmpi(long a, long b)
{
bool ieqf = ieq(a, b), iltf = ilt(a, b), igtf = igt(a, b), ilef = ile(a, b), igef = ige(a, b);
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
printf("INLINE %ld, %ld : EQ %d LT %d GT %d\r", a, b, ieqf, iltf, igtf);
printf("NATIVE %ld, %ld : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
assert(ieqf == neqf);
assert(iltf == nltf);
assert(igtf == ngtf);
assert(ilef == nlef);
assert(igef == ngef);
}
void cmp(long a, long b)
{
cmpc(a, b);
cmpi(a, b);
}
void cmpz(long a)
{
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
@ -345,21 +233,6 @@ void cmp1(long a)
assert(bgef == ngef);
}
void cmpm(long a)
{
bool beqf = beqm(a), bltf = bltm(a), bgtf = bgtm(a), blef = blem(a), bgef = bgem(a);
bool neqf = neqm(a), nltf = nltm(a), ngtf = ngtm(a), nlef = nlem(a), ngef = ngem(a);
printf("BYTE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
printf("NATIVE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, neqf, nltf, ngtf, nlef, ngef);
assert(beqf == neqf);
assert(bltf == nltf);
assert(bgtf == ngtf);
assert(blef == nlef);
assert(bgef == ngef);
}
int main(void)
{
cmp( 0, 1);
@ -454,10 +327,6 @@ int main(void)
cmp1(256);
cmp1(10000);
cmp1(20000);
cmp1(1000000l);
cmp1(2000000l);
cmp1(100000000l);
cmp1(200000000l);
cmp1(-1);
cmp1(-2);
cmp1(-3);
@ -465,34 +334,6 @@ int main(void)
cmp1(-256);
cmp1(-10000);
cmp1(-20000);
cmp1(-1000000l);
cmp1(-2000000l);
cmp1(-100000000l);
cmp1(-200000000l);
cmpm(0);
cmpm(1);
cmpm(2);
cmpm(3);
cmpm(255);
cmpm(256);
cmpm(10000);
cmpm(20000);
cmpm(1000000l);
cmpm(2000000l);
cmpm(100000000l);
cmpm(200000000l);
cmpm(-1);
cmpm(-2);
cmpm(-3);
cmpm(-255);
cmpm(-256);
cmpm(-10000);
cmpm(-20000);
cmpm(-1000000l);
cmpm(-2000000l);
cmpm(-100000000l);
cmpm(-200000000l);
return 0;

View File

@ -1,83 +0,0 @@
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#define MAP_WIDTH 10
#define MAP_HEIGHT 2
#define TITLE_TILE_WIDTH 4
#define TITLE_TILE_HEIGHT 4
#define PTR_SCREEN ((char *)0xc000)
#define PTR_BUFFER ((char *)0xc400)
#define PTR_COLOR ((char *)0xd800)
#define PTR_FONTCHARSET ((char *)0xd800)
const char TitleMap[1024] = {
#for(i, 1024) i * 17,
};
const char TitleTiles[4096] = {
#for(i, 4096) i * 31,
};
// Custom screen address
extern char* const Screen = PTR_SCREEN;
// Color mem address
extern char* const Color = PTR_COLOR;
void RenderLogo(char screenY)
{
char * sp = Screen;
char * cp = Color;
const char * mp = TitleMap;
for(char ty=0; ty < MAP_HEIGHT; ty++)
{
for(char tx=0; tx< MAP_WIDTH; tx++)
{
char ti = mp[tx];
const char* tp = TitleTiles + (TITLE_TILE_WIDTH * TITLE_TILE_HEIGHT) * ti;
for(char y=0; y<TITLE_TILE_HEIGHT; y++)
{
for(char x=0; x<TITLE_TILE_WIDTH; x++)
{
char c = tp[TITLE_TILE_WIDTH * y + x];
sp[40 * (y + screenY) + x] = c;
cp[40 * (y + screenY) + x] = 1;
}
}
sp += TITLE_TILE_WIDTH;
cp += TITLE_TILE_WIDTH;
}
sp += 120;
cp += 120;
mp += MAP_WIDTH;
}
}
void VerifyLogo(char screenY)
{
for(char dy=0; dy<MAP_HEIGHT * TITLE_TILE_HEIGHT; dy++)
{
for(char dx=0; dx<MAP_WIDTH * TITLE_TILE_WIDTH; dx++)
{
char ty = dy / TITLE_TILE_HEIGHT, iy = dy % TITLE_TILE_HEIGHT;
char tx = dx / TITLE_TILE_WIDTH, ix = dx % TITLE_TILE_WIDTH;
int si = TitleMap[MAP_WIDTH * ty + tx] * TITLE_TILE_WIDTH * TITLE_TILE_HEIGHT + TITLE_TILE_WIDTH * iy + ix;
int di = 40 * (dy + screenY) + dx;
assert(Screen[di] == TitleTiles[si]);
}
}
}
int main(void)
{
RenderLogo(1);
VerifyLogo(1);
return 0;
}

View File

@ -10,13 +10,12 @@ enum SIDFXState
SIDFX_WAIT
};
__striped static struct SIDFXChannel
static struct SIDFXChannel
{
const SIDFX * volatile com;
byte delay, priority;
volatile byte cnt;
volatile SIDFXState state;
unsigned freq, pwm;
const SIDFX * com;
byte delay, cnt, priority;
volatile SIDFXState state;
unsigned freq, pwm;
} channels[3];
@ -27,20 +26,9 @@ void sidfx_init(void)
channels[i].com = nullptr;
channels[i].state = SIDFX_IDLE;
channels[i].priority = 0;
channels[i].delay = 1;
}
}
bool sidfx_idle(byte chn)
{
return channels[chn].state == SIDFX_IDLE;
}
char sidfx_cnt(byte chn)
{
return channels[chn].cnt;
}
void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
{
SIDFXState ns = channels[chn].state;
@ -53,7 +41,6 @@ void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
return;
channels[chn].state = SIDFX_IDLE;
channels[chn].delay = 1;
channels[chn].com = fx;
channels[chn].cnt = cnt - 1;
@ -66,126 +53,103 @@ void sidfx_stop(byte chn)
{
channels[chn].com = nullptr;
if (channels[chn].state != SIDFX_IDLE)
{
channels[chn].state = SIDFX_RESET_0;
channels[chn].delay = 1;
}
}
inline void sidfx_loop_ch(byte ch)
{
if (channels[ch].state)
switch (channels[ch].state)
{
const SIDFX * com = channels[ch].com;
channels[ch].delay--;
if (channels[ch].delay)
{
if (com->dfreq)
case SIDFX_IDLE:
break;
case SIDFX_RESET_0:
sid.voices[ch].ctrl = 0;
sid.voices[ch].attdec = 0;
sid.voices[ch].susrel = 0;
channels[ch].state = SIDFX_RESET_1;
break;
case SIDFX_RESET_1:
sid.voices[ch].ctrl = SID_CTRL_TEST;
channels[ch].state = SIDFX_READY;
break;
case SIDFX_READY:
if (channels[ch].com)
{
channels[ch].freq += com->dfreq;
channels[ch].freq = channels[ch].com->freq;
channels[ch].pwm = channels[ch].com->pwm;
sid.voices[ch].freq = channels[ch].com->freq;
sid.voices[ch].pwm = channels[ch].com->pwm;
sid.voices[ch].attdec = channels[ch].com->attdec;
sid.voices[ch].susrel = channels[ch].com->susrel;
sid.voices[ch].ctrl = channels[ch].com->ctrl;
channels[ch].delay = channels[ch].com->time1;
channels[ch].state = SIDFX_PLAY;
}
else
channels[ch].state = SIDFX_IDLE;
break;
case SIDFX_PLAY:
if (channels[ch].com->dfreq)
{
channels[ch].freq += channels[ch].com->dfreq;
sid.voices[ch].freq = channels[ch].freq;
}
if (com->dpwm)
if (channels[ch].com->dpwm)
{
channels[ch].pwm += com->dpwm;
channels[ch].pwm += channels[ch].com->dpwm;
sid.voices[ch].pwm = channels[ch].pwm;
}
}
while (!channels[ch].delay)
{
switch (channels[ch].state)
if (channels[ch].delay)
channels[ch].delay--;
else if (channels[ch].com->time0)
{
case SIDFX_IDLE:
channels[ch].delay = 1;
break;
case SIDFX_RESET_0:
sid.voices[ch].ctrl = 0;
sid.voices[ch].attdec = 0;
sid.voices[ch].susrel = 0;
if (com)
channels[ch].state = SIDFX_READY;
else
channels[ch].state = SIDFX_IDLE;
channels[ch].delay = 1;
break;
case SIDFX_RESET_1:
sid.voices[ch].ctrl = SID_CTRL_TEST;
sid.voices[ch].ctrl = 0;
sid.voices[ch].attdec = 0;
sid.voices[ch].susrel = 0;
channels[ch].state = SIDFX_READY;
break;
case SIDFX_READY:
channels[ch].freq = com->freq;
channels[ch].pwm = com->pwm;
sid.voices[ch].freq = com->freq;
sid.voices[ch].pwm = com->pwm;
sid.voices[ch].attdec = com->attdec;
sid.voices[ch].susrel = com->susrel;
sid.voices[ch].ctrl = com->ctrl;
if (com->ctrl & SID_CTRL_GATE)
{
channels[ch].delay = com->time1;
channels[ch].state = SIDFX_PLAY;
}
else
{
channels[ch].delay = com->time0;
channels[ch].state = SIDFX_PLAY;
}
break;
case SIDFX_PLAY:
if (com->time0)
{
sid.voices[ch].ctrl = com->ctrl & ~SID_CTRL_GATE;
channels[ch].delay = com->time0 - 1;
channels[ch].state = SIDFX_WAIT;
}
else if (channels[ch].cnt)
{
char sr = com->susrel & 0xf0;
com++;
char ctrl = com->ctrl;
if ((com->attdec & 0xef) == 0 && (ctrl & SID_CTRL_GATE) && (com->susrel & 0xf0) > sr)
{
sid.voices[ch].ctrl = ctrl & ~SID_CTRL_GATE;
sid.voices[ch].ctrl = ctrl | SID_CTRL_GATE;
}
channels[ch].cnt--;
channels[ch].com = com;
channels[ch].priority = com->priority;
channels[ch].state = SIDFX_READY;
}
else
{
com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
case SIDFX_WAIT:
if (channels[ch].cnt)
{
com++;
channels[ch].cnt--;
channels[ch].com = com;
channels[ch].priority = com->priority;
if (com->ctrl & SID_CTRL_GATE)
channels[ch].state = SIDFX_RESET_0;
else
channels[ch].state = SIDFX_READY;
}
else
{
com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
sid.voices[ch].ctrl = channels[ch].com->ctrl & ~SID_CTRL_GATE;
channels[ch].delay = channels[ch].com->time0;
channels[ch].state = SIDFX_WAIT;
}
}
else if (channels[ch].cnt)
{
channels[ch].cnt--;
channels[ch].com++;
channels[ch].priority = channels[ch].com->priority;
channels[ch].state = SIDFX_READY;
}
else
{
channels[ch].com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
case SIDFX_WAIT:
if (channels[ch].com->dfreq)
{
channels[ch].freq += channels[ch].com->dfreq;
sid.voices[ch].freq = channels[ch].freq;
}
if (channels[ch].com->dpwm)
{
channels[ch].pwm += channels[ch].com->dpwm;
sid.voices[ch].pwm = channels[ch].pwm;
}
if (channels[ch].delay)
channels[ch].delay--;
else if (channels[ch].cnt)
{
channels[ch].cnt--;
channels[ch].com++;
channels[ch].priority = channels[ch].com->priority;
channels[ch].state = SIDFX_RESET_0;
}
else
{
channels[ch].com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
}
}

View File

@ -14,14 +14,10 @@ struct SIDFX
void sidfx_init(void);
inline bool sidfx_idle(byte chn);
inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
void sidfx_stop(byte chn);
char sidfx_cnt(byte chn);
void sidfx_loop(void);
void sidfx_loop_2(void);

View File

@ -27,7 +27,6 @@ struct XMMU
#define xmmu (*((struct XMMU *)0xd500))
inline char mmu_set(char cr);
#pragma compile("mmu.c")

View File

@ -34,11 +34,8 @@ byte vdc_reg_read(VDCRegister reg)
void vdc_mem_addr(unsigned addr)
{
#pragma callinline()
vdc_reg_write(VDCR_ADDRH, addr >> 8);
#pragma callinline()
vdc_reg_write(VDCR_ADDRL, addr);
#pragma callinline()
vdc_reg(VDCR_DATA);
}
@ -55,14 +52,12 @@ inline char vdc_mem_read(void)
void vdc_mem_write_at(unsigned addr, char data)
{
#pragma callinline()
vdc_mem_addr(addr);
vdc_write(data);
}
char vdc_mem_read_at(unsigned addr)
{
#pragma callinline()
vdc_mem_addr(addr);
return vdc_read();
}

View File

@ -16,7 +16,7 @@ void cia_init(void)
cia2.ddrb = 0x00;
cia1.ddra = 0xff;
cia2.pra = 0x07;
cia2.prb = 0x07;
cia2.ddra = 0x3f;
char i0 = cia1.icr;

View File

@ -18,46 +18,6 @@ struct EasyFlash
#define eflash (*(EasyFlash *)0xde00)
#ifdef __cplusplus
#ifdef EFPROX_SECTION
#pragma code(EFPROX_SECTION)
#endif
template<int back, class fn, class ... P>
__noinline auto ef_call_p(P... p)
{
if (back != __bankof(fn))
eflash.bank = __bankof(fn);
auto r = fn(p...);
if (back != 0xff && back != __bankof(fn))
eflash.bank = back;
return r;
}
#ifdef EFPROX_SECTION
#pragma code(code)
#endif
template<class fn>
class EFlashCall
{
public:
template<class ... P>
__forceinline auto operator()(P ... p) const
{
switch(__bankof(0))
{
#for(i,64) case i: return ef_call_p<i, fn, P...>(p...);
default:
return ef_call_p<0xff, fn, P...>(p...);
}
}
};
#define EF_CALL(fn) EFlashCall<fn##_p> fn
#endif
#endif

View File

@ -1,608 +0,0 @@
#include "flossiec.h"
#include <c64/iecbus.h>
#include <c64/vic.h>
#include <c64/cia.h>
#include <c64/kernalio.h>
#ifndef FLOSSIEC_NODISPLAY
#define FLOSSIEC_NODISPLAY 0
#endif
#ifndef FLOSSIEC_NOIRQ
#define FLOSSIEC_NOIRQ 0
#endif
#ifndef FLOSSIEC_BORDER
#define FLOSSIEC_BORDER 0
#endif
#define VIA_ATNIN 0x80
#define VIA_ATNOUT 0x10
#define VIA_CLKOUT 0x08
#define VIA_DATAOUT 0x02
#define VIA_CLKIN 0x04
#define VIA_DATAIN 0x01
#define PORTB1 0x1800
#define PORTB2 0x1c00
#define WR 0x1d
#ifdef FLOSSIEC_CODE
#pragma code(FLOSSIEC_CODE)
#endif
#ifdef FLOSSIEC_BSS
#pragma bss(FLOSSIEC_BSS)
#endif
__asm diskcode
{
nop
nop
lda #VIA_CLKOUT
sta PORTB1
lda 0x0202
sta 0x0c
lda 0x0203
sta 0x0d
lda #$80
sta 0x03
ldx #0
l0:
txa
lsr
lsr
lsr
lsr
sta 0x0700,x
inx
bne l0
lr:
lda 0x03
bmi lr
sei
ldx #0
l2:
lda #0
sta PORTB1
lda 0x0600, x
tay
and #0x0f
ora #VIA_DATAIN
l1:
bit PORTB1
bne l1
l3:
sta PORTB1
tya
asl
and #0x0a
sta PORTB1
lda 0x0700,y
nop
sta PORTB1
asl
nop
and #0x0a
sta PORTB1
inx
bne l2
lda #VIA_CLKOUT
sta PORTB1
lda 0x0600
beq w1
sta 0x0c
lda 0x0601
sta 0x0d
lda #$80
sta 0x03
cli
bne lr
w1:
sta PORTB1
cli
rts
}
#define CIA2B_ATNOUT 0x08
#define CIA2B_CLKOUT 0x10
#define CIA2B_DATAOUT 0x20
#define CIA2B_CLKIN 0x40
#define CIA2B_DATAIN 0x80
#define CIA2PRA 0xdd00
static char remap[256];
static char rbuffer[256];
static char xbuffer[256];
static char flpos;
static char xcmd;
static char xi, xj;
static char fldrive;
static char flvxor;
__noinline void fl_read_buf(void)
{
__asm
{
#if FLOSSIEC_NOIRQ
php
sei
#endif
lda CIA2PRA
and #~CIA2B_CLKOUT
sta accu
sta CIA2PRA
and #~CIA2B_DATAOUT
sta accu + 1
l0:
lda CIA2PRA
and #CIA2B_CLKIN
beq l0
#if !FLOSSIEC_NOIRQ
php
pla
and #$04
beq iq
#endif
ldy #0
sec
l1:
ldx accu + 1
#if !FLOSSIEC_NODISPLAY
l2:
lda 0xd012
sbc #50
bcc w1
and #7
beq l2
#endif
w1:
stx CIA2PRA
#if FLOSSIEC_BORDER
inc 0xd020
#else
nop
nop
nop
#endif
ldx accu
nop
lda CIA2PRA
lsr
lsr
nop
eor CIA2PRA
lsr
lsr
nop
eor CIA2PRA
lsr
lsr
sec
eor CIA2PRA
stx CIA2PRA
sta rbuffer, y
iny
bne l1
jmp done
#if !FLOSSIEC_NOIRQ
iq:
ldy #0
sec
l1i:
ldx accu + 1
l2i:
cli
sei
#if !FLOSSIEC_NODISPLAY
lda 0xd012
sbc #50
bcc w1i
and #7
beq l2i
w1i:
#endif
stx CIA2PRA
#if FLOSSIEC_BORDER
inc 0xd020
#else
nop
nop
nop
#endif
ldx accu
nop
lda CIA2PRA
lsr
lsr
nop
eor CIA2PRA
lsr
lsr
nop
eor CIA2PRA
lsr
lsr
sec
eor CIA2PRA
stx CIA2PRA
sta rbuffer, y
iny
bne l1i
cli
#endif
done:
#if FLOSSIEC_NOIRQ
plp
#endif
}
}
inline char flossiec_get(void)
{
if (!flpos)
{
fl_read_buf();
flpos = 2;
}
return remap[rbuffer[flpos++]];
}
void flossiec_decompress(void)
{
char i = 0, j = xj, cmd = xcmd;
xi = 0;
for(;;)
{
if (cmd & 0x80)
{
if (i < cmd)
{
char t = i - cmd;
do {
char ch = xbuffer[j++];
xbuffer[i++] = ch;
} while (i != t);
cmd = 0;
}
else
{
cmd -= i;
do {
char ch = xbuffer[j++];
xbuffer[i++] = ch;
} while (i);
break;
}
}
else
{
char ch = flossiec_get();
if (cmd)
{
xbuffer[i++] = ch;
cmd--;
if (!i)
break;
}
else
{
cmd = ch;
if (!cmd)
break;
if (cmd & 0x80)
{
cmd ^= 0x7f;
cmd++;
j = i - flossiec_get();
}
}
}
}
xj = j;
xcmd = cmd;
}
inline char flossiec_get_lzo(void)
{
if (!xi)
flossiec_decompress();
return xbuffer[xi++];
}
inline bool flossiec_eof(void)
{
return !remap[rbuffer[0]] && flpos >= remap[rbuffer[1]];
}
char * flossiec_read(char * dp, unsigned size)
{
while (size)
{
*dp++ = flossiec_get();
size--;
}
return dp;
}
char * flossiec_read_lzo(char * dp, unsigned size)
{
char i = xi;
dp -= i;
size += i;
while (size)
{
if (!i)
flossiec_decompress();
if (size >= 256)
{
do {
dp[i] = xbuffer[i];
i++;
} while (i);
dp += 256;
size -= 256;
}
else
{
do {
dp[i] = xbuffer[i];
i++;
} while (i != (char)size);
dp += i;
break;
}
}
xi = i;
return dp;
}
static void vxorcheck(void)
{
char vxor = cia2.pra & 7;
vxor ^= vxor >> 2;
vxor ^= 0xff;
if (vxor != flvxor)
{
flvxor = vxor;
for(int i=0; i<256; i++)
{
char j = i ^ vxor;
char d = ((j & 0x11) << 3) |
(j & 0x66) |
((j & 0x88) >> 3);
remap[i] = d;
}
}
}
bool flossiec_init(char drive)
{
fldrive = drive;
flvxor = 0;
iec_open(drive, 2, "#2");
iec_listen(drive, 2);
for(char j=0; j<127; j++)
iec_write(((char *)diskcode)[j]);
iec_unlisten();
iec_close(drive, 2);
iec_open(drive, 15, "");
return true;
}
void flossiec_shutdown(void)
{
iec_close(fldrive, 15);
}
bool flossiec_open(char track, char sector)
{
iec_listen(fldrive, 15);
iec_write(P'U');
iec_write(P'4');
iec_write(track);
iec_write(sector);
iec_unlisten();
cia2.pra |= CIA2B_DATAOUT;
#if FLOSSIEC_NODISPLAY
vic.ctrl1 &= ~VIC_CTRL1_DEN;
#endif
vic_waitFrame();
vxorcheck();
vic_waitFrame();
flpos = 0;
xi = 0;
return true;
}
void flossiec_close(void)
{
cia2.pra |= CIA2B_DATAOUT;
#if FLOSSIEC_NODISPLAY
vic.ctrl1 |= VIC_CTRL1_DEN;
#endif
}
bool flosskio_init(char drive)
{
fldrive = drive;
flvxor = 0;
krnio_setnam_n("#2", 2);
krnio_open(2, drive, 2);
krnio_write(2, (char *)diskcode, 128);
krnio_close(2);
krnio_setnam_n(nullptr, 0);
krnio_open(15, drive, 15);
return true;
}
void flosskio_shutdown(void)
{
krnio_close(15);
}
bool flosskio_open(char track, char sector)
{
krnio_chkout(15);
krnio_chrout(P'U');
krnio_chrout(P'4');
krnio_chrout(track);
krnio_chrout(sector);
krnio_clrchn();
cia2.pra |= CIA2B_DATAOUT;
#if FLOSSIEC_NODISPLAY
vic.ctrl1 &= ~VIC_CTRL1_DEN;
#endif
vic_waitFrame();
vxorcheck();
vic_waitFrame();
flpos = 0;
xi = 0;
return true;
}
void flosskio_close(void)
{
cia2.pra |= CIA2B_DATAOUT;
#if FLOSSIEC_NODISPLAY
vic.ctrl1 |= VIC_CTRL1_DEN;
#endif
}
static bool mapdir(const char * fnames, floss_blk * blks)
{
do {
fl_read_buf();
char si = 0;
do
{
if (remap[rbuffer[si + 2]] == 0x82)
{
char fname[17];
char j = 0;
while (j < 16 && remap[rbuffer[si + j + 5]] != 0xa0)
{
fname[j] = remap[rbuffer[si + j + 5]];
j++;
}
fname[j] = 0;
char sj = 0;
char k = 0;
while (fnames[sj])
{
j = 0;
while (fname[j] && fname[j] == fnames[sj])
{
j++;
sj++;
}
if (!fname[j] && (!fnames[sj] || fnames[sj] == ','))
{
__assume(k < 128);
blks[k].track = remap[rbuffer[si + 3]];
blks[k].sector = remap[rbuffer[si + 4]];
break;
}
while (fnames[sj] && fnames[sj++] != ',')
;
k++;
}
}
si += 32;
} while (si);
} while (remap[rbuffer[0]]);
return true;
}
bool flosskio_mapdir(const char * fnames, floss_blk * blks)
{
if (flosskio_open(18, 1))
{
mapdir(fnames, blks);
flosskio_close();
return true;
}
return false;
}
bool flossiec_mapdir(const char * fnames, floss_blk * blks)
{
if (flossiec_open(18, 1))
{
mapdir(fnames, blks);
flossiec_close();
return true;
}
return false;
}

View File

@ -1,79 +0,0 @@
#ifndef FLOSSIEC_H
#define FLOSSIEC_H
// When building you can use various defines to change the behaviour
// FLOSSIEC_BORDER=1 Enable border flashing while loading
// FLOSSIEC_NODISPLAY=1 Disable the display while loading
// FLOSSIEC_NOIRQ=1 Disable IRQ during load
// FLOSSIEC_CODE=cseg Code segment to be used, when defined
// FLOSSIEC_BSS=bseg BSS segment to be used, when defined
// Initialize the fastloader to be used without the kernal
bool flossiec_init(char drive);
// Shutdown the fastloader when used without the kernal
void flossiec_shutdown(void);
// Open a file for read with the fastloader without the kernal.
// The file has to be read to completion before you can close
// it again,
bool flossiec_open(char track, char sector);
// Close a file after reading
void flossiec_close(void);
// Initialize the fastloader to be used with the kernal
bool flosskio_init(char drive);
// Shutdown the fastloader when used with the kernal
void flosskio_shutdown(void);
// Open a file for read with the fastloader with the kernal
// The file has to be read to completion before you can close
// it again,
bool flosskio_open(char track, char sector);
// Close a file after reading
void flosskio_close(void);
// Track and sector start of a file
struct floss_blk
{
char track, sector;
};
// Map a comma separated list of filenames to an array of
// block start positions by reading the directory, using the
// kernal.
bool flosskio_mapdir(const char * fnames, floss_blk * blks);
// Map a comma separated list of filenames to an array of
// block start positions by reading the directory, without the
// kernal.
bool flossiec_mapdir(const char * fnames, floss_blk * blks);
// Check for end of file while reading
inline bool flossiec_eof(void);
// Get one char from uncompressed file
inline char flossiec_get(void);
// Get one char from compressed file
inline char flossiec_get_lzo(void);
// Read a section of a file into memory up to size bytes,
// returns the first address after the read
char * flossiec_read(char * dp, unsigned size);
// Read and expand section of a file into memory up to size
// bytes, returns the first address after the read
char * flossiec_read_lzo(char * dp, unsigned size);
#pragma compile("flossiec.c")
#endif

View File

@ -2,8 +2,7 @@
#include <c64/cia.h>
#include <c64/vic.h>
IEC_STATUS iec_status;
char iec_queue;
IEC_STATUS iec_status;
#define CIA2B_ATNOUT 0x08
#define CIA2B_CLKOUT 0x10
@ -26,59 +25,46 @@ static void delay(char n)
}
}
static inline void data_true(void)
static inline void data_low(void)
{
cia2.pra &= ~CIA2B_DATAOUT;
}
static inline void data_false(void)
static inline void data_high(void)
{
cia2.pra |= CIA2B_DATAOUT;
}
static inline void clock_true(void)
static inline void clock_low(void)
{
cia2.pra &= ~CIA2B_CLKOUT;
}
static inline void cdata_true(void)
static inline void cdata_low(void)
{
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
}
static inline void clock_false(void)
static inline void clock_high(void)
{
cia2.pra |= CIA2B_CLKOUT;
}
static inline void atn_true(void)
static inline void atn_low(void)
{
cia2.pra &= ~CIA2B_ATNOUT;
}
static inline void atn_false(void)
static inline void atn_high(void)
{
cia2.pra |= CIA2B_ATNOUT;
}
static inline bool data_in(void)
{
return (cia2.pra & CIA2B_DATAIN) != 0;
}
static inline bool clock_in(void)
{
return (cia2.pra & CIA2B_CLKIN) != 0;
}
static bool data_check(void)
{
char cnt = 200;
while (cnt > 0 && data_in())
{
delay(5);
char cnt = 100;
while (cnt > 0 && (cia2.pra & CIA2B_DATAIN))
cnt--;
}
if (cnt)
return true;
@ -89,106 +75,68 @@ static bool data_check(void)
}
}
static bool iec_eoib(void)
bool iec_eoi(void)
{
clock_true();
while (!data_in());
cdata_low();
while (!(cia2.pra & CIA2B_DATAIN))
;
delay(40);
return data_check();
}
static void iec_writeb(char b)
{
clock_true();
while (!data_in());
delay(5);
for(char i=0; i<8; i++)
{
clock_false();
delay(5);
if (b & 1)
data_true();
else
data_false();
clock_true();
b >>= 1;
delay(5);
}
clock_false();
data_true();
}
bool iec_write(char b)
{
if (iec_status == IEC_QUEUED)
cdata_low();
while (!(cia2.pra & CIA2B_DATAIN))
;
clock_high();
for(char i=0; i<8; i++)
{
__asm
{
php
sei
}
iec_status = IEC_OK;
iec_writeb(iec_queue);
__asm
{
plp
}
data_check();
}
if (iec_status < IEC_ERROR)
{
iec_queue = b;
iec_status = IEC_QUEUED;
return true;
if (b & 1)
data_low();
else
data_high();
delay(5);
clock_low();
b >>= 1;
delay(5);
clock_high();
data_low();
}
return false;
return data_check();
}
char iec_read(void)
{
while (!clock_in());
while (!(cia2.pra & CIA2B_CLKIN))
;
__asm
{
php
sei
}
data_true();
data_low();
char cnt = 100;
while (cnt > 0 && clock_in())
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
cnt--;
if (cnt == 0)
{
iec_status = IEC_EOF;
data_false();
delay(10);
data_true();
data_high();
delay(4);
data_low();
cnt = 200;
while (cnt > 0 && clock_in())
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
cnt--;
if (cnt == 0)
{
iec_status = IEC_TIMEOUT;
__asm
{
plp
}
return 0;
}
}
@ -207,36 +155,25 @@ char iec_read(void)
;
}
data_false();
data_high();
__asm
{
plp
}
return b;
}
void iec_atn(char dev, char sec)
{
clock_true();
data_true();
atn_false();
clock_false();
{
cdata_low();
atn_high();
clock_high();
delay(200);
while (data_in());
iec_writeb(dev);
data_check();
iec_write(dev);
if (sec != 0xff)
{
iec_writeb(sec);
data_check();
}
iec_write(sec);
atn_true();
data_high();
atn_low();
}
@ -245,23 +182,7 @@ void iec_talk(char dev, char sec)
iec_status = IEC_OK;
iec_atn(dev | 0x40, sec | 0x60);
data_false();
__asm
{
php
sei
}
clock_true();
char cnt = 200;
while (cnt > 0 && clock_in())
cnt--;
__asm
{
plp
}
clock_low();
delay(10);
}
@ -280,27 +201,7 @@ void iec_listen(char dev, char sec)
void iec_unlisten(void)
{
__asm
{
php
sei
}
if (iec_status == IEC_QUEUED)
{
iec_status = IEC_OK;
iec_eoib();
iec_writeb(iec_queue);
data_check();
}
iec_atn(0x3f, 0xff);
clock_true();
__asm
{
plp
}
}
void iec_open(char dev, char sec, const char * fname)
@ -312,6 +213,8 @@ void iec_open(char dev, char sec, const char * fname)
char i = 0;
while (fname[i])
{
if (!fname[i + 1])
iec_eoi();
iec_write(fname[i]);
i++;
}
@ -336,7 +239,7 @@ int iec_write_bytes(const char * data, int num)
int iec_read_bytes(char * data, int num)
{
int i = 0;
char i = 0;
while (i < num)
{
char ch = iec_read();

View File

@ -5,7 +5,6 @@ enum IEC_STATUS
{
IEC_OK = 0x00,
IEC_EOF = 0x01,
IEC_QUEUED = 0x02,
IEC_ERROR = 0x80,
IEC_TIMEOUT,
@ -14,6 +13,8 @@ enum IEC_STATUS
extern IEC_STATUS iec_status;
bool iec_eoi(void);
bool iec_write(char b);
char iec_read(void);

View File

@ -16,18 +16,7 @@ void krnio_setbnk(char filebank, char namebank)
#pragma native(krnio_setbnk)
#endif
#if defined(__PLUS4__)
#pragma code(lowcode)
#define BANKIN sta 0xff3e
#define BANKOUT sta 0xff3f
#define BANKINLINE __noinline
#else
#define BANKIN
#define BANKOUT
#define BANKINLINE
#endif
BANKINLINE void krnio_setnam(const char * name)
void krnio_setnam(const char * name)
{
__asm
{
@ -42,41 +31,35 @@ BANKINLINE void krnio_setnam(const char * name)
tya
W1: ldx name
ldy name + 1
BANKIN
jsr $ffbd // setnam
BANKOUT
}
}
#pragma native(krnio_setnam)
BANKINLINE void krnio_setnam_n(const char * name, char len)
void krnio_setnam_n(const char * name, char len)
{
__asm
{
lda len
ldx name
ldy name + 1
BANKIN
jsr $ffbd // setnam
BANKOUT
}
}
#pragma native(krnio_setnam_n)
BANKINLINE bool krnio_open(char fnum, char device, char channel)
bool krnio_open(char fnum, char device, char channel)
{
krnio_pstatus[fnum] = KRNIO_OK;
return char(__asm
__asm
{
lda #0
sta accu
sta accu + 1
BANKIN
lda fnum
ldx device
ldy channel
@ -91,48 +74,42 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
W1:
lda #1
sta accu
BANKOUT
E2:
});
}
}
#pragma native(krnio_open)
BANKINLINE void krnio_close(char fnum)
void krnio_close(char fnum)
{
__asm
{
BANKIN
lda fnum
jsr $ffc3 // close
BANKOUT
}
}
#pragma native(krnio_close)
BANKINLINE krnioerr krnio_status(void)
krnioerr krnio_status(void)
{
return __asm
__asm
{
BANKIN
jsr $ffb7 // readst
BANKOUT
sta accu
lda #0
sta accu + 1
};
}
}
#pragma native(krnio_status)
BANKINLINE bool krnio_load(char fnum, char device, char channel)
bool krnio_load(char fnum, char device, char channel)
{
return char(__asm
__asm
{
BANKIN
lda fnum
ldx device
ldy channel
@ -142,22 +119,20 @@ BANKINLINE bool krnio_load(char fnum, char device, char channel)
ldx #0
ldy #0
jsr $FFD5 // load
BANKOUT
lda #0
rol
eor #1
sta accu
});
bcs W1
lda #1
W1: sta accu
}
}
#pragma native(krnio_load)
BANKINLINE bool krnio_save(char device, const char* start, const char* end)
bool krnio_save(char device, const char* start, const char* end)
{
return char(__asm
__asm
{
BANKIN
lda #0
ldx device
ldy #0
@ -168,96 +143,83 @@ BANKINLINE bool krnio_save(char device, const char* start, const char* end)
ldy end+1
jsr $FFD8 // save
BANKOUT
lda #0
rol
eor #1
sta accu
});
bcs W1
lda #1
W1: sta accu
}
}
#pragma native(krnio_save)
BANKINLINE bool krnio_chkout(char fnum)
bool krnio_chkout(char fnum)
{
return char(__asm
__asm
{
BANKIN
ldx fnum
jsr $ffc9 // chkout
BANKOUT
lda #0
rol
eor #1
sta accu
});
bcs W1
lda #1
W1: sta accu
}
}
#pragma native(krnio_chkout)
BANKINLINE bool krnio_chkin(char fnum)
bool krnio_chkin(char fnum)
{
return char(__asm
__asm
{
BANKIN
ldx fnum
jsr $ffc6 // chkin
BANKOUT
lda #0
rol
eor #1
sta accu
});
sta accu + 1
bcs W1
lda #1
W1: sta accu
}
}
#pragma native(krnio_chkin)
BANKINLINE void krnio_clrchn(void)
void krnio_clrchn(void)
{
__asm
{
BANKIN
jsr $ffcc // clrchn
BANKOUT
}
}
#pragma native(krnio_clrchn)
BANKINLINE bool krnio_chrout(char ch)
bool krnio_chrout(char ch)
{
return char(__asm
__asm
{
BANKIN
lda ch
jsr $ffd2 // chrout
sta accu
BANKOUT
});
lda #0
sta accu + 1
}
}
#pragma native(krnio_chrout)
BANKINLINE char krnio_chrin(void)
int krnio_chrin(void)
{
return __asm
__asm
{
BANKIN
jsr $ffcf // chrin
sta accu
BANKOUT
};
lda #0
sta accu + 1
}
}
#pragma native(krnio_chrin)
#if defined(__PLUS4__)
#pragma code(code)
#endif
int krnio_getch(char fnum)
{
if (krnio_pstatus[fnum] == KRNIO_EOF)
@ -421,7 +383,7 @@ int krnio_gets(char fnum, char * data, int num)
if (krnio_chkin(fnum))
{
krnioerr err = KRNIO_OK;
krnioerr err;
int i = 0;
int ch;
while (i + 1 < num)

View File

@ -1,5 +1,5 @@
#ifndef C64_KERNALIO_H
#define C64_KERNALIO_H
#ifndef C64_KERNALIO_H
// Error and status codes returned by krnio_status
@ -64,7 +64,7 @@ bool krnio_chrout(char ch);
// read a single byte from the current input channel
char krnio_chrin(void);
int krnio_chrin(void);
// read a single byte from the given file/channel, returns
// a negative result on failure. If this was the last byte

View File

@ -5,16 +5,16 @@
#include <c64/asm6502.h>
#include <stdlib.h>
volatile char npos = 1, tpos = 0;
volatile byte rirq_count;
static byte rirq_pcount;
byte rasterIRQRows[NUM_IRQS + 1];
byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one
byte rasterIRQRows[NUM_IRQS + 1];
byte rasterIRQIndex[NUM_IRQS + 1];
#ifdef ZPAGE_IRQS
__zeropage
#endif
byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff
byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code
byte rasterIRQNext[NUM_IRQS + 1];
byte rasterIRQLow[NUM_IRQS];
byte rasterIRQHigh[NUM_IRQS];
#ifdef ZPAGE_IRQS
@ -22,87 +22,28 @@ __zeropage
#endif
byte nextIRQ;
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
__asm rirq_isr_ram_io
{
stx plrx + 1
ldx nextIRQ
bmi exi
sta plra + 1
sty plry + 1
l1:
lda rasterIRQNext, x
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
ji:
jsr $0000
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
beq e2
dey
sty $d012
dey
cpy $d012
bcc l1
plry:
ldy #0
plra:
lda #0
plrx:
ldx #0
rti
exi:
asl $d019
jmp plrx
// No more interrupts to service
e2:
inc rirq_count
ldy rasterIRQNext
dey
sty $d012
ldx #0
stx nextIRQ
beq plry
}
__asm rirq_isr_io
__asm irq0
{
pha
txa
pha
tya
pha
kentry:
asl $d019
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
@ -110,20 +51,20 @@ ji:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
lda rasterIRQNext, x
cmp #$ff
beq e2
// carry is cleared at this point
tay
dey
sbc #2
cmp $d012
bcc l1
sty $d012
dey
cpy $d012
bcc l1
exd:
ex:
pla
tay
pla
@ -131,44 +72,56 @@ exd:
pla
rti
exi:
asl $d019
jmp exd
e2:
ldx npos
stx tpos
inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext
dey
sty $d012
ldx #0
stx nextIRQ
beq exd
jmp ex
}
__asm rirq_isr_noio
__asm irq2
{
pha
txa
pha
tya
pha
kentry:
lda $01
pha
lda #$35
sta $01
asl $d019
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
@ -176,20 +129,21 @@ ji:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
lda rasterIRQNext, x
cmp #$ff
beq e2
// carry is cleared at this point
tay
dey
sbc #2
cmp $d012
bcc l1
sty $d012
dey
cpy $d012
bcc l1
exd:
ex:
pla
sta $01
@ -200,35 +154,45 @@ exd:
pla
rti
exi:
asl $d019
jmp exd
e2:
ldx npos
stx tpos
inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext
dey
sty $d012
ldx #0
stx nextIRQ
beq exd
jmp ex
}
__asm rirq_isr_kernal_io
__asm irq1
{
lda $d019
bpl ex2
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
@ -237,111 +201,50 @@ jx:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
beq e2
dey
dey
sty $d012
dey
cpy $d012
bcc l1
exd:
jmp $ea81
exi:
asl $d019
jmp $ea81
e2:
inc rirq_count
ldy rasterIRQNext
dey
dey
sty $d012
ldx #0
stx nextIRQ
jmp $ea81
ex2:
LDA $DC0D
cli
jmp $ea31
}
__asm rirq_isr_kernal_noio
{
lda $01
pha
lda #$36
sta $01
lda $d019
bpl ex2
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
ji:
jsr $0000
jx:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
cmp #$ff
beq e2
dey
tay
sec
sbc #4
cmp $d012
bcc l1
dey
sty $d012
dey
cpy $d012
bcc l1
exd:
pla
sta $01
jmp $ea81
exi:
asl $d019
jmp exd
w1:
jmp ex
e2:
ldx npos
stx tpos
inc rirq_count
ldy rasterIRQNext
dey
dey
sty $d012
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
beq exd
lda rasterIRQNext, x
sec
sbc #1
sta $d012
ex:
asl $d019
jmp $ea81
ex2:
LDA $DC0D
cli
pla
sta $01
jmp $ea31
}
@ -365,8 +268,8 @@ void rirq_build(RIRQCode * ic, byte size)
ic->size = size;
asm_im(ic->code + 0, ASM_LDY, 0);
asm_im(ic->code + 2, ASM_LDX, 0);
asm_ab(ic->code + 4, ASM_CMP, 0xd012);
asm_im(ic->code + 2, ASM_LDA, 0);
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
asm_rl(ic->code + 7, ASM_BCS, -5);
asm_ab(ic->code + 9, ASM_STY, 0x0000);
@ -380,7 +283,7 @@ void rirq_build(RIRQCode * ic, byte size)
}
else
{
asm_ab(ic->code + 12, ASM_STX, 0x0000);
asm_ab(ic->code + 12, ASM_STA, 0x0000);
byte p = 15;
for(byte i=2; i<size; i++)
@ -439,8 +342,7 @@ void rirq_addrhi(RIRQCode * ic, byte n, byte hi)
void rirq_data(RIRQCode * ic, byte n, byte data)
{
byte p = irqdi[n];
// ic->code[p] = data;
(volatile char *)(ic->code)[p] = data;
ic->code[p] = data;
}
void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
@ -500,60 +402,7 @@ void rirq_init_kernal(void)
sei
}
*(void **)0x0314 = rirq_isr_kernal_io;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
vic.raster = 255;
}
void rirq_init_kernal_noio(void)
{
rirq_init_tables();
__asm
{
sei
}
*(void **)0x0314 = rirq_isr_kernal_noio;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
vic.raster = 255;
}
void rirq_init_crt(void)
{
rirq_init_tables();
__asm
{
sei
}
*(void **)0x0314 = rirq_isr_io.kentry;
*(void **)0xfffe = rirq_isr_io;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
vic.raster = 255;
}
void rirq_init_crt_noio(void)
{
rirq_init_tables();
__asm
{
sei
}
*(void **)0x0314 = rirq_isr_noio.kentry;
*(void **)0xfffe = rirq_isr_noio;
*(void **)0x0314 = irq1;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -570,7 +419,7 @@ void rirq_init_io(void)
sei
}
*(void **)0xfffe = rirq_isr_ram_io;
*(void **)0xfffe = irq0;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -587,7 +436,7 @@ void rirq_init_memmap(void)
sei
}
*(void **)0xfffe = rirq_isr_noio;
*(void **)0xfffe = irq2;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -605,18 +454,12 @@ void rirq_init(bool kernalIRQ)
void rirq_wait(void)
{
char i0 = rirq_pcount;
char i1;
do {
i1 = rirq_count;
} while (i0 == i1);
rirq_pcount = i1;
while (tpos != npos) ;
npos++;
}
void rirq_sort(bool inirq)
void rirq_sort(void)
{
// disable raster interrupts while sorting
nextIRQ = 0xff;
#if 1
byte maxr = rasterIRQRows[rasterIRQIndex[1]];
for(byte i = 2; i<NUM_IRQS + 1; i++)
@ -651,31 +494,13 @@ void rirq_sort(bool inirq)
rasterIRQIndex[j] = ri;
}
#endif
#if NUM_IRQS & 3
for(sbyte i=NUM_IRQS-1; i>=0; i--)
rasterIRQNext[i] = rasterIRQRows[rasterIRQIndex[i + 1]];
#else
for(sbyte i=NUM_IRQS/4-1; i>=0; i--)
{
#pragma unroll(full)
for(int j=0; j<4; j++)
rasterIRQNext[i + j * NUM_IRQS / 4] = rasterIRQRows[rasterIRQIndex[i + j * NUM_IRQS / 4 + 1]];
}
#endif
rirq_pcount = rirq_count;
if (inirq)
nextIRQ = NUM_IRQS - 1;
else
{
byte yp = rasterIRQNext[0];
if (yp != 0xff)
{
vic.raster = yp - 1;
nextIRQ = 0;
}
}
npos++;
byte yp = rasterIRQNext[nextIRQ];
if (yp != 0xff)
vic.raster = yp - 1;
}
void rirq_start(void)
@ -689,7 +514,6 @@ void rirq_start(void)
lda #100
sta $d012
asl $d019
cli
}
}

View File

@ -132,8 +132,7 @@ inline void rirq_data(RIRQCode * ic, byte n, byte data);
// Add a delay of 5 * cycles to a raster IRQ
inline void rirq_delay(RIRQCode * ic, byte cycles);
// Place a raster IRQ into one of the 16 slots, the interrupt will fire
// one line below the given row
// Place a raster IRQ into one of the 16 slots
inline void rirq_set(byte n, byte row, RIRQCode * write);
// Remove a raster IRQ from one of the 16 slots
@ -148,28 +147,10 @@ inline void rirq_move(byte n, byte row);
// the less resource hungry option)
inline void rirq_init(bool kernalIRQ);
// Raster IRQ through kernal, with IO range always enabled
// calls kernal continuation
void rirq_init_kernal(void);
// Raster IRQ through kernal, with IO range not always enabled
// calls kernal continuation
void rirq_init_kernal_noio(void);
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range always enabled
// does not call kernal continuation
void rirq_init_crt(void);
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range not always enabled
// does not call kernal continuation
void rirq_init_crt_noio(void);
// Raster IRQ through RAM vector, with ROM disabled and IO range always enabled
// does not call kernal continuation
void rirq_init_io(void);
// Raster IRQ through RAM vector, with ROM disabled and IO range not always enabled
// does not call kernal continuation
void rirq_init_memmap(void);
// Start raster IRQ
@ -179,9 +160,8 @@ void rirq_start(void);
void rirq_stop(void);
// Sort the raster IRQ, must be performed at the end of the frame after changing
// the vertical position of one of the interrupt operations.
// Set the inirq flag to true when calling this from an interrupt
void rirq_sort(bool inirq = false);
// the vertical position of one of the interrupt operatins.
void rirq_sort(void);
// Wait for the last raster IRQ op to have completed. Must be called before a
// sort if the raster IRQ system is active

View File

@ -3,9 +3,6 @@
static volatile char * vspriteScreen;
#ifdef VSPRITE_BSS
#pragma bss(VSPRITE_BSS)
#endif
void spr_init(char * screen)
{
@ -171,12 +168,6 @@ void vspr_init(char * screen)
}
}
void vspr_shutdown(void)
{
for(int i=0; i<VSPRITES_MAX - 7; i++)
rirq_clear(i);
}
void vspr_screen(char * screen)
{
vspriteScreen = screen + 0x3f8;
@ -214,21 +205,6 @@ void vspr_move(char sp, int xpos, int ypos)
vspriteXHigh[sp] = (char)(xpos >> 8);
}
void vspr_movex(char sp, int xpos)
{
vspriteXLow[sp] = (char)xpos;
vspriteXHigh[sp] = (char)(xpos >> 8);
}
void vspr_movey(char sp, int ypos)
{
char yp = (char)ypos;
if (ypos & 0xff00)
yp = 0xff;
vspriteYLow[sp] = yp;
}
void vspr_image(char sp, char image)
{
vspriteImage[sp] = image;
@ -279,7 +255,7 @@ void vspr_update(void)
{
char xymask = 0;
volatile char * vsprs = vspriteScreen;
// char sypos[VSPRITES_MAX];
char sypos[VSPRITES_MAX];
#pragma unroll(full)
@ -300,9 +276,9 @@ void vspr_update(void)
xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1;
#endif
vic.spr_pos[uj].x = vspriteXLow[ri];
vic.spr_pos[uj].y = spriteYPos[ui + 1];
vic.spr_pos[uj].y = vspriteYLow[ri];
// sypos[ui] = vspriteYLow[ri];
sypos[ui] = vspriteYLow[ri];
}
vic.spr_msbx = xymask;
@ -312,11 +288,9 @@ void vspr_update(void)
for(char ti=0; ti<VSPRITES_MAX - 8; ti++)
{
if (!done && spriteYPos[ti + 9] < 250)
byte ri = spriteOrder[ti + 8];
if (!done && vspriteYLow[ri] < 250)
{
byte ri = spriteOrder[ti + 8];
rirq_move(ti, spriteYPos[ti + 1] + 23);
#ifdef VSPRITE_REVERSE
char m = 0x80 >> (ti & 7);
#else
@ -327,13 +301,14 @@ void vspr_update(void)
if (!(vspriteXHigh[ri] & 1))
xymask ^= m;
rirq_data(spirq + ti, 2, spriteYPos[ti + 9]);
rirq_data(spirq + ti, 2, vspriteYLow[ri]);
rirq_data(spirq + ti, 0, vspriteColor[ri]);
rirq_data(spirq + ti, 1, vspriteXLow[ri]);
rirq_data(spirq + ti, 3, vspriteImage[ri]);
rirq_data(spirq + ti, 4, xymask);
// spriteYPos[ti + 9] = vspriteYLow[ri];
rirq_move(ti, sypos[ti] + 23);
sypos[ti + 8] = vspriteYLow[ri];
}
else
{

View File

@ -68,8 +68,6 @@ inline void spr_expand(char sp, bool xexpand, bool yexpand);
void vspr_init(char * screen);
void vspr_shutdown(void);
void vspr_screen(char * screen);
// set one sprite with the given attribute
@ -80,11 +78,6 @@ void vspr_set(char sp, int xpos, int ypos, char image, char color);
inline void vspr_move(char sp, int xpos, int ypos);
inline void vspr_movex(char sp, int xpos);
inline void vspr_movey(char sp, int ypos);
// change the image of a virtual sprite
inline void vspr_image(char sp, char image);

View File

@ -114,21 +114,4 @@ void vic_waitBelow(int line)
}
}
void vic_waitRange(char below, char above)
{
while (vic.ctrl1 & VIC_CTRL1_RST8)
;
if (vic.raster >= above)
{
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
;
while (vic.ctrl1 & VIC_CTRL1_RST8)
;
}
while (vic.raster < below)
;
}
#pragma native(vic_waitLine)

View File

@ -118,9 +118,6 @@ void vic_waitLine(int line);
// wait for beam to be below a line
void vic_waitBelow(int line);
// wait for beam to be in a given range on screen
void vic_waitRange(char below, char above);
// reference to the VIC chip
#define vic (*((struct VIC *)0xd000))

View File

@ -18,13 +18,6 @@ __asm bsin
jsr 0xffe4
sta 0xff01
}
__asm bsget
{
lda #0
sta 0xff00
jsr 0xffcf
sta 0xff01
}
__asm bsplot
{
lda #0
@ -50,7 +43,6 @@ __asm dswap
#define dswap 0xff5f
#define bsout 0xffd2
#define bsin 0xffe4
#define bsget 0xffcf
#define bsplot 0xfff0
#define bsinit 0xff81
#elif defined(__PLUS4__)
@ -67,12 +59,6 @@ __asm bsin
jsr 0xffe4
sta 0xff3f
}
__asm bsget
{
sta 0xff3e
jsr 0xffcf
sta 0xff3f
}
__asm bsplot
{
sta 0xff3e
@ -105,14 +91,6 @@ __asm bsin
pha
}
__asm bsget
{
lda 0xe405
pha
lda 0xe404
pha
}
__asm bsplot
{
@ -121,34 +99,11 @@ __asm bsinit
{
}
#elif defined(__VIC20__)
#define bsout 0xffd2
#define bsin 0xffe4
#define bsplot 0xfff0
#define bsget 0xffcf
__asm bsinit
{
lda #147
jmp $ffd2
}
#elif defined(__CBMPET__)
#define bsout 0xffd2
#define bsin 0xffe4
__asm bsplot
{
/* no equivalent on PET */
}
__asm bsinit
{
/* no equivalent on PET */
}
#define bsget 0xffcf
#else
#define bsout 0xffd2
#define bsin 0xffe4
#define bsplot 0xfff0
#define bsinit 0xff81
#define bsget 0xffcf
#endif
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
@ -181,246 +136,192 @@ void iocharmap(IOCharMap chmap)
giocharmap = chmap;
#if !defined(__ATARI__)
if (chmap == IOCHM_PETSCII_1)
putrch(128 + 14);
putch(128 + 14);
else if (chmap == IOCHM_PETSCII_2)
putrch(14);
putch(14);
#endif
}
void putrch(char c)
__asm putpch
{
__asm {
lda c
jsr bsout
}
}
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
cmp #10
bne w1
lda #13
w1:
cpx #IOCHM_PETSCII_1
bcc w3
cmp #65
bcc w3
cmp #123
bcs w3
void putpch(char c)
{
#if defined(__ATARI__)
if (c == 10)
c = 0x9b;
#else
if (giocharmap >= IOCHM_ASCII)
{
if (c == '\n')
c = 13;
else if (c == '\t')
{
char n = wherex() & 3;
do {
putrch(' ');
} while (++n < 4);
return;
}
else if (giocharmap >= IOCHM_PETSCII_1)
{
if (c >= 65 && c < 123)
{
if (c >= 97 || c < 91)
{
#if defined(__CBMPET__)
if (c >= 97)
c ^= 0xa0;
c ^= 0x20;
cmp #97
bcs w4
cmp #91
bcs w3
w2:
eor #$a0
w4:
eor #$20
#else
c ^= 0x20;
#endif
if (giocharmap == IOCHM_PETSCII_1)
c &= 0xdf;
}
}
}
}
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
#endif
putrch(c);
cpx #IOCHM_PETSCII_2
beq w3
and #$df
w3:
jmp bsout
}
static char convch(char ch)
__asm getpch
{
#if !defined(__ATARI__)
jsr bsin
if (giocharmap >= IOCHM_ASCII)
{
if (ch == 13)
ch = 10;
else if (giocharmap >= IOCHM_PETSCII_1)
{
if (ch >= 65 && ch < 219)
{
if (ch >= 193)
ch ^= 0xa0;
if (ch < 123 && (ch >= 97 || ch < 91))
ch ^= 0x20;
}
}
}
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
#endif
return ch;
}
cmp #13
bne w1
lda #10
w1:
cpx #IOCHM_PETSCII_1
bcc w3
char getrch(void)
{
return __asm {
jsr bsget
sta accu
};
}
cmp #219
bcs w3
cmp #65
bcc w3
char getpch(void)
{
return convch(getrch());
cmp #193
bcc w4
eor #$a0
w4:
cmp #123
bcs w3
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
w3:
}
char kbhit(void)
{
#if defined(__CBMPET__)
return __asm
{
lda $9e
sta accu
};
#else
return __asm
__asm
{
lda $c6
sta accu
};
#endif
}
}
char getche(void)
{
char ch;
do {
ch = __asm {
jsr bsin
sta accu
};
} while (!ch);
__asm
{
L1:
jsr getpch
cmp #0
beq L1
__asm {
lda ch
jsr bsout
sta accu
jsr putpch
}
return convch(ch);
}
char getch(void)
{
char ch;
do {
ch = __asm {
jsr bsin
sta accu
};
} while (!ch);
__asm
{
L1:
jsr getpch
cmp #0
beq L1
return convch(ch);
sta accu
}
}
char getchx(void)
{
char ch = __asm {
jsr bsin
sta accu
};
return convch(ch);
__asm
{
jsr getpch
sta accu
}
}
void putch(char c)
{
putpch(c);
__asm {
lda c
jsr bsout
}
}
void clrscr(void)
{
putrch(147);
__asm
{
jsr bsinit
}
}
void textcursor(bool show)
{
*(volatile char *)0xcc = show ? 0 : 1;
*(char *)0xcc = show ? 0 : 1;
}
void gotoxy(char cx, char cy)
{
#if defined(__CBMPET__)
#define CURS_X 0xc6
#define CURS_Y 0xd8
#define SCREEN_PTR 0xc4
#define SCR_LINELEN 0xd5
__assume(cy < 25);
*(volatile char *)CURS_X = cx;
*(volatile char *)CURS_Y = cy;
if (*(volatile char *)SCR_LINELEN > 40)
cy <<= 1;
const unsigned off = cy * 40;
* (volatile unsigned *)SCREEN_PTR = off + 0x8000;
#else
__asm
{
ldx cy
ldy cx
clc
jsr bsplot
}
#endif
}
}
void textcolor(char c)
{
*(volatile char *)0x0286 = c;
}
void bgcolor(char c)
{
*(volatile char *)0xd021 = c;
}
void bordercolor(char c)
{
*(volatile char *)0xd020 = c;
}
void revers(char r)
{
if (r)
putrch(18);
else
putrch(18 + 128);
__asm
{
lda c
sta $0286
}
}
char wherex(void)
{
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
return *(volatile char *)0xec;
#elif defined(__PLUS4__)
return *(volatile char *)0xca;
#else
return *(volatile char *)0xd3;
#endif
__asm
{
lda $d3
sta accu
}
}
char wherey(void)
{
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
return *(volatile char *)0xeb;
#elif defined(__PLUS4__)
return *(volatile char *)0xcd;
#else
return *(volatile char *)0xd6;
#endif
__asm
{
lda $d6
sta accu
}
}

View File

@ -31,7 +31,7 @@ void dispmode80col(void);
#define PETSCII_CLEAR 0x94
#define PETSCII_DEL 0x14
#define PETSCII_INSERT 0x94
#define PETSCII_STOP 0x03
#define PETSCII_STOP 0x0c
#define PETSCII_RETURN 0x0d
#define PETSCII_F1 0x85
@ -43,39 +43,6 @@ void dispmode80col(void);
#define PETSCII_F7 0x88
#define PETSCII_F8 0x8c
enum ConioColors
{
COLOR_BLACK,
COLOR_WHITE,
COLOR_RED,
COLOR_CYAN,
COLOR_PURPLE,
COLOR_GREEN,
COLOR_BLUE,
COLOR_YELLOW,
COLOR_ORANGE,
COLOR_BROWN,
COLOR_LT_RED,
COLOR_DARK_GREY,
COLOR_MED_GREY,
COLOR_LT_GREEN,
COLOR_LT_BLUE,
COLOR_LT_GREY
};
// Lowlevel console in/out
// using petscii translation
void putpch(char c);
char getpch(void);
// using no translation
inline void putrch(char c);
inline char getrch(void);
// Standard console in/out
char kbhit(void);
char getche(void);
@ -92,21 +59,15 @@ void clrscr(void);
void gotoxy(char x, char y);
inline void textcolor(char c);
void textcolor(char c);
inline void bgcolor(char c);
char wherex(void);
inline void bordercolor(char c);
inline void revers(char r);
inline char wherex(void);
inline char wherey(void);
char wherey(void);
// show or hide the text cursor
inline void textcursor(bool show);
void textcursor(bool show);
#pragma compile("conio.c")

File diff suppressed because it is too large Load Diff

View File

@ -144,8 +144,8 @@ enum ByteCode
BC_LOOP_U8,
BC_MALLOC,
BC_FREE,
BC_FILL,
BC_FILL_LONG,
BC_UNUSED_4,
BC_UNUSED_5,
BC_UNUSED_6,
BC_JSR,
@ -186,11 +186,6 @@ enum ByteCode
BC_BINOP_SHR_I32,
BC_BINOP_CMP_U32,
BC_BINOP_CMP_S32,
BC_CONV_U32_F32,
BC_CONV_I32_F32,
BC_CONV_F32_U32,
BC_CONV_F32_I32,
};
#endif

View File

@ -116,38 +116,31 @@ int lmul4f12s(int x, int y)
{
__asm
{
sec
lda x
ror
sta accu
bit y + 1
bpl W0
sec
lda #0
sbc y
sta y
lda #0
sbc y + 1
sta y + 1
sec
lda #0
sbc x
sta x
lda #0
sbc x + 1
sta x + 1
W0:
ldx #15
lda #0
sta accu + 1
bcc W4
L2:
tay
clc
lda accu + 1
adc y
sta accu + 1
tya
adc y + 1
W4:
ror
ror accu + 1
lsr accu
bcc W4
bne L2
ldx x + 1
stx accu
ldx #7
lsr accu
L1:
L1: lsr x + 1
ror x
bcc W1
tay
clc
@ -163,31 +156,23 @@ W1:
dex
bne L1
lsr x
bcc W2
tay
// sec ; we know it is set here
sec
lda accu + 1
sbc y
sta accu + 1
tya
sbc y + 1
sec
W2:
ror
ror accu + 1
ror accu
bit y + 1
bpl W3
tax
sec
lda accu + 1
sbc x
sta accu + 1
txa
sbc x + 1
W3:
lsr
ror accu + 1
ror accu
@ -285,17 +270,15 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
__asm
{
lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2
sta __tmp + 3
lda a
sec
T1:
ldy #8
L1:
ror
ldx #16
L1: lsr a + 1
ror a
bcc W1
tax
clc
lda __tmp + 2
adc b
@ -303,38 +286,20 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3
adc b + 1
sta __tmp + 3
txa
W1:
ror __tmp + 3
ror __tmp + 2
dey
ror __tmp + 1
ror __tmp
dex
bne L1
ror
bcc T2
sta __tmp + 0
lda a + 1
clc
bcc T1
lda #0
sta accu
sta accu + 1
T2:
sec
L3:
sta __tmp + 1
ldx #8
ldx #17
L2:
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
bcc W3
lda __tmp + 2
sbc c
tay
lda __tmp + 3
sbc c + 1
sec
bcs W4
W3:
sec
lda __tmp + 2
sbc c
@ -342,23 +307,33 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3
sbc c + 1
bcc W2
W4:
sta __tmp + 3
sty __tmp + 2
W2:
dex
bne L2
lda __tmp + 1
rol
bcc T3
rol accu
rol accu + 1
asl __tmp
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
dex
beq E2
bcc L2
lda __tmp + 2
sbc c
sta __tmp + 2
lda __tmp + 3
sbc c + 1
sta __tmp + 3
sec
bcs W2
E2:
sta accu + 1
lda __tmp + 0
clc
bcc L3
T3:
sta accu
}
}
int lmuldiv16s(int a, int b, int c)
@ -383,17 +358,15 @@ int lmuldiv16s(int a, int b, int c)
__asm
{
lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2
sta __tmp + 3
lda a
sec
T1:
ldy #8
L1:
ror
ldx #16
L1: lsr a + 1
ror a
bcc W1
tax
clc
lda __tmp + 2
adc b
@ -401,38 +374,20 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3
adc b + 1
sta __tmp + 3
txa
W1:
ror __tmp + 3
ror __tmp + 2
dey
ror __tmp + 1
ror __tmp
dex
bne L1
ror
bcc T2
sta __tmp + 0
lda a + 1
clc
bcc T1
lda #0
sta accu
sta accu + 1
T2:
sec
L3:
sta __tmp + 1
ldx #8
ldx #17
L2:
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
bcc W3
lda __tmp + 2
sbc c
tay
lda __tmp + 3
sbc c + 1
sec
bcs W4
W3:
sec
lda __tmp + 2
sbc c
@ -440,23 +395,30 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3
sbc c + 1
bcc W2
W4:
sta __tmp + 3
sty __tmp + 2
W2:
rol accu
rol accu + 1
asl __tmp
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
dex
bne L2
lda __tmp + 1
rol
bcc T3
sta accu + 1
lda __tmp + 0
clc
bcc L3
T3:
sta accu
beq E2
bcc L2
lda __tmp + 2
sbc c
sta __tmp + 2
lda __tmp + 3
sbc c + 1
sta __tmp + 3
sec
bcs W2
E2:
lda sign
beq E1

View File

@ -525,7 +525,7 @@ void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int
static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
{
char ip = 0;
bool delta16 =((dx | dy) & 0xff80) != 0;
bool delta16 = ((dx | dy) & 0xff80) != 0;
// ylow
ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly);
@ -579,105 +579,59 @@ static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool
break;
}
if (dy)
// m >= 0
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, delta16 ? 5 + 15 + 13 + 2 : 5 + 15 + 7 + 2);
ip += asm_np(BLIT_CODE + ip, up ? ASM_DEY : ASM_INY);
ip += asm_im(BLIT_CODE + ip, ASM_CPY, up ? 0xff : 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 15);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, up ? 0x07 : 0x00);
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{
bool delta8 = false;
if (dx)
{
// m >= 0
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
char n = delta16 ? 18 + 13 + 2 : 18 + 7 + 2;
if (!up) n++;
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, n);
delta8 = !delta16;
}
if (up)
{
ip += asm_np(BLIT_CODE + ip, ASM_DEY);
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta8 ? 17 : 15);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x07);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
}
else
{
ip += asm_np(BLIT_CODE + ip, ASM_INY);
ip += asm_im(BLIT_CODE + ip, ASM_CPY, 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, delta8 ? 16 : 14);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x00);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
}
if (dx)
{
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 13 + 4 + 12);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
}
else
{
// We know regdp to be in the accu at this point
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 5 + 4 + 12);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
}
}
// m < 0
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
}
if (dx)
// m < 0
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta16 ? 4 + 15 + 13 : 4 + 15 + 7);
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 15);
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xf8 : 0x08);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xff : 0x00);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 12);
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
if (left)
{
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0xf8);
ip += asm_rl(BLIT_CODE + ip, ASM_BCS, 2);
ip += asm_zp(BLIT_CODE + ip, ASM_DEC, REG_SP + 1);
}
else
{
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 2);
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_SP + 1);
}
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
}
// l --
@ -695,7 +649,6 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern)
{
__asm
{
lda dst
sta REG_SP
lda dst + 1

View File

@ -1,26 +0,0 @@
#include "inttypes.h"
#include "stdlib.h"
intmax_t imaxabs(intmax_t n)
{
return n < 0 ? -n : n;
}
imaxdiv_t imaxdiv(intmax_t l, intmax_t r)
{
imaxdiv_t t;
t.quot = l / r;
t.rem = l % r;
return t;
}
inline intmax_t strtoimax(const char * s, char ** endp, int base)
{
return strtol(s, endp, base);
}
inline uintmax_t strtoumax(const char * s, char ** endp, int base)
{
return strtoul(s, endp, base);
}

View File

@ -1,98 +0,0 @@
#ifndef INTTYPES_H
#define INTTYPES_H
#include <stdint.h>
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "ld"
#define PRIdLEAST8 "d"
#define PRIdLEAST16 "d"
#define PRIdLEAST32 "ld"
#define PRIdFAST8 "d"
#define PRIdFAST16 "d"
#define PRIdFAST32 "ld"
#define PRIdMAX "ld"
#define PRIdPTR "d"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "lo"
#define PRIoLEAST8 "o"
#define PRIoLEAST16 "o"
#define PRIoLEAST32 "lo"
#define PRIoFAST8 "o"
#define PRIoFAST16 "o"
#define PRIoFAST32 "lo"
#define PRIoMAX "lo"
#define PRIoPTR "o"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "lu"
#define PRIuLEAST8 "u"
#define PRIuLEAST16 "u"
#define PRIuLEAST32 "lu"
#define PRIuFAST8 "u"
#define PRIuFAST16 "u"
#define PRIuFAST32 "lu"
#define PRIuMAX "lu"
#define PRIuPTR "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "lx"
#define PRIxLEAST8 "x"
#define PRIxLEAST16 "x"
#define PRIxLEAST32 "lx"
#define PRIxFAST8 "x"
#define PRIxFAST16 "x"
#define PRIxFAST32 "lx"
#define PRIxMAX "lx"
#define PRIxPTR "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "lX"
#define PRIXLEAST8 "X"
#define PRIXLEAST16 "X"
#define PRIXLEAST32 "lX"
#define PRIXFAST8 "X"
#define PRIXFAST16 "X"
#define PRIXFAST32 "lX"
#define PRIXMAX "lX"
#define PRIXPTR "X"
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
intmax_t imaxabs(intmax_t n);
imaxdiv_t imaxdiv(intmax_t l, intmax_t r);
intmax_t strtoimax(const char * s, char ** endp, int base);
uintmax_t strtoumax(const char * s, char ** endp, int base);
#pragma compile("inttypes.c")
#endif

View File

@ -1,16 +0,0 @@
#ifndef ISO646_H
#define ISO646_H
#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=
#endif

View File

@ -11,7 +11,7 @@
#define CHAR_MIN SCHAR_MIN
#define CHAR_MAX SCHAR_MAX
#define INT_MIN (-32767-1)
#define INT_MIN -32767
#define INT_MAX 32767
#define UINT_MAX 65535

View File

@ -110,12 +110,12 @@ float atan2(float p, float q)
return s;
}
#define F_EXP_0 1.0
#define F_EXP_1 0.69315668
#define F_EXP_2 0.240132068
#define F_EXP_3 0.055876024
#define F_EXP_4 0.008940801
#define F_EXP_5 0.001894414
#define F_EXP_0 1.0000003
#define F_EXP_1 0.693147059
#define F_EXP_2 0.240173099
#define F_EXP_3 0.055816392
#define F_EXP_4 0.008965036
#define F_EXP_5 0.001898429
float exp(float f)
{
@ -143,12 +143,12 @@ float exp(float f)
return s * x.f;
}
#define F_LOG_0 -3.78717706
#define F_LOG_1 10.0960498
#define F_LOG_2 -13.975654
#define F_LOG_3 12.7580616
#define F_LOG_4 -6.48190725
#define F_LOG_5 1.39064767
#define F_LOG_0 -3.78712618
#define F_LOG_1 10.0957081
#define F_LOG_2 -13.9747486
#define F_LOG_3 12.7568806
#define F_LOG_4 -6.48114552
#define F_LOG_5 1.39045416
float log(float f)
{

View File

@ -32,15 +32,6 @@ bool isfinite(float f);
#pragma intrinsic(sin)
#pragma intrinsic(cos)
#pragma intrinsic(tan)
#pragma intrinsic(atan)
#pragma intrinsic(atan2)
#pragma intrinsic(log)
#pragma intrinsic(exp)
#pragma intrinsic(pow)
#pragma intrinsic(sqrt)
#pragma compile("math.c")

View File

@ -1,59 +0,0 @@
#ifndef OPP_BOUNDINT_H
#define OPP_BOUNDINT_H
namespace opp {
template<int tmin, int tmax>
constexpr auto boundinttype(void)
{
if constexpr (tmin >= 0 && tmax <= 255)
return (char)0;
else if constexpr (tmin >= -128 && tmax <= 127)
return (signed char)0;
else
return (int)0;
}
template<int tmin, int tmax>
class boundint
{
protected:
decltype(boundinttype<tmin, tmax>()) v;
public:
boundint(int i)
: v(i)
{
}
void operator=(int k)
{
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator+=(int k)
{
k += v;
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator-=(int k)
{
k = v - k;
__assume(k >= tmin && k <= tmax);
v = k;
}
operator int() const
{
int k = v;
__assume(k >= tmin && k <= tmax);
return k;
}
};
}
#endif

View File

@ -1,93 +0,0 @@
#ifndef OPP_FUNCTIONAL_H
#define OPP_FUNCTIONAL_H
namespace opp
{
template <class F>
class function;
template <class R, class ... P>
class function<R(P...)>
{
private:
struct callif
{
virtual R call(P...) = 0;
virtual ~callif() {}
virtual callif * clone(void) const = 0;
};
template<class CA>
struct callable : callif
{
CA ca;
callable(CA ca_) : ca(ca_) {}
R call(P... p) {return ca(p...);}
callif * clone(void) const
{
return new callable(ca);
}
};
callif * c;
public:
template <class F>
function(F f)
{
c = new callable<F>(f);
}
function(const function & f)
{
c = f.c->clone();
}
function(function && f)
{
c = f.c;
f.c = nullptr;
}
function(void)
{
c = nullptr;
}
function & operator=(const function & f)
{
if (c != f.c)
{
delete c;
c = f.c;
}
return *this;
}
function & operator=(function && f)
{
if (c != f.c)
{
c = f.c;
f.c = nullptr;
}
return *this;
}
~function(void)
{
delete c;
}
R operator()(P ... p) const
{
return c->call(p...);
}
};
}
#endif

View File

@ -952,13 +952,6 @@ istream & istream::operator>>(float & val)
return *this;
}
istream & istream::operator>>(char & val)
{
doskipws();
val = get();
return *this;
}
istream & istream::operator>>(char * p)
{
doskipws();

View File

@ -37,7 +37,7 @@ public:
showpos = 0x0800,
skipws = 0x1000,
unitbuf = 0x2000,
uppercase = 0x4000,
uppercase = 0x3000,
adjustfield = 0x00b0,
basefield = 0x004a,
@ -124,7 +124,6 @@ public:
istream & putback(char c);
istream & unget(void);
istream & operator>>(char & val);
istream & operator>>(bool & val);
istream & operator>>(int & val);
istream & operator>>(unsigned & val);

View File

@ -124,8 +124,8 @@ public:
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
head.succ->pred = head;
head.pred->succ = head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
}
@ -136,8 +136,8 @@ public:
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
head.succ->pred = head;
head.pred->succ = head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
return *this;

View File

@ -20,12 +20,12 @@ void ostringstream::bput(char ch)
{
mBSize = 15;
mBFill = 0;
mBuffer = (char *)malloc(15);
mBuffer = malloc(15);
}
else if (mBFill == mBSize)
{
mBSize *= 2;
char * b = (char *)malloc(mBSize);
char * b = malloc(mBSize);
for(char i=0; i<mBFill; i++)
b[i] = mBuffer[i];
free(mBuffer);
@ -46,7 +46,7 @@ void ostringstream::str(const string & str)
{
free(mBuffer);
mBSize = mBFill;
mBuffer = (char *)malloc(mBSize);
mBuffer = malloc(mBSize);
}
str.copyseg(mBuffer, 0, mBFill);
}

View File

@ -4,7 +4,6 @@
#include <new>
#include <stdlib.h>
#include <opp/utility.h>
#include <oscar.h>
namespace opp {
@ -12,8 +11,8 @@ template <class T, int N>
class static_vector
{
protected:
enum { m = N } _size;
char _space[N * sizeof(T)];
enum { m = N } _size;
public:
typedef T element_type;
@ -21,28 +20,23 @@ public:
static_vector(size_t n) : _size(n)
{
#ifdef CAPACITYCHECK
if (n > N) debugcrash();
#endif
T * data = (T*)_space;
for(size_t i=0; i<n; i++)
new (data + i) T();
new (data + i) T;
}
static_vector(const static_vector & v)
: _size(v._size)
{
size_t n = _size;
T * data = (T*)_space, * vdata = (T*)(v._space);
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
new (data + i)T(vdata[i]);
}
~static_vector(void)
{
T * data = (T*)_space;
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
data[i].~T();
}
@ -51,12 +45,10 @@ public:
if (this != &v)
{
T * data = (T*)_space, * vdata = (T*)(v._space);
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
data[i].~T();
_size = v._size;
n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
new (data + i)T(vdata[i]);
}
return *this;
@ -77,11 +69,6 @@ public:
return _size == 0;
}
bool full(void) const
{
return _size == N;
}
size_t capacity(void) const
{
return N;
@ -89,8 +76,6 @@ public:
void resize(size_t n);
void clear(void);
T & at(size_t at)
{
return ((T*)_space)[at];
@ -181,8 +166,6 @@ public:
((T*)_space)[_size].~T();
}
void assign(size_t count, const T & t);
void insert(size_t at, const T & t);
void erase(size_t at, size_t n = 1);
@ -194,50 +177,34 @@ public:
};
template <class T, int N>
void static_vector<T, N>::clear(void)
{
T * data = (T*)_space;
for(size_t i=0; i<_size; i++)
data[i].~T();
_size = 0;
}
template <class T, int N>
void static_vector<T, N>::resize(size_t n)
{
#ifdef CAPACITYCHECK
if (n > N) debugcrash();
#endif
T * data = (T*)_space;
if (n < _size)
{
for(size_t i=n; i<_size; i++)
data[i].~T();
_size = n;
}
else if (n > 0)
else
{
for(size_t i=_size; i<n; i++)
new(data + i)T();
new(data + i)T;
_size = n;
}
_size = n;
}
template <class T, int N>
void static_vector<T, N>::push_back(const T & t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(t);
}
template <class T, int N>
void static_vector<T, N>::push_back(T && t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(t);
}
@ -245,28 +212,14 @@ template <class T, int N>
template <typename ...P>
void static_vector<T, N>::emplace_back(const P&... p)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(p...);
}
template <class T, int N>
void static_vector<T, N>::assign(size_t count, const T & t)
{
T * data = (T*)_space;
for(size_t i=0; i<_size; i++)
data[i].~T();
for(size_t i=0; i<count; i++)
new (data + i)T(t);
_size = count;
}
template <class T, int N>
void static_vector<T, N>::insert(size_t at, const T & t)
{
T * data = (T*)_space;
new (data + _size)T();
new (data + _size)T;
for(size_t i=_size; i>at; i--)
data[i] = move(data[i - 1]);
data[at] = t;
@ -287,12 +240,9 @@ void static_vector<T, N>::erase(size_t at, size_t n)
template <class T, int N>
T * static_vector<T, N>::insert(T * at, const T & t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
T * data = (T*)_space;
T * dp = data + _size;
new (dp)T();
new (dp)T;
while (dp != at)
{
dp--;

View File

@ -32,7 +32,7 @@ string::string(const string & s)
if (s.cstr)
{
char l = s.cstr[0];
cstr = (char *)malloc(char(l + 2));
cstr = malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2);
}
else
@ -52,7 +52,7 @@ string::string(const char * s)
char l = sstrlen(s);
if (l)
{
cstr = (char *)malloc(char(l + 2));
cstr = malloc(char(l + 2));
cstr[0] = l;
smemcpy(cstr + 1, s, l + 1);
}
@ -67,10 +67,9 @@ string::string(const char * s, char size)
{
if (size)
{
cstr = (char *)malloc(char(size + 2));
cstr = malloc(char(size + 2));
cstr[0] = size;
smemcpy(cstr + 1, s, size);
cstr[size + 1] = 0;
smemcpy(cstr + 1, s, size + 1);
}
else
cstr = nullptr;
@ -78,7 +77,7 @@ string::string(const char * s, char size)
string::string(char c)
{
cstr = (char *)malloc(3);
cstr = malloc(3);
cstr[0] = 1;
cstr[1] = c;
cstr[2] = 0;
@ -115,7 +114,7 @@ string & string::operator=(const string & s)
if (s.cstr)
{
char l = s.cstr[0];
cstr = (char *)malloc(char(l + 2));
cstr = malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2);
}
else
@ -145,7 +144,7 @@ string & string::operator=(const char * s)
char l = sstrlen(s);
if (l)
{
cstr = (char *)malloc(char(l + 2));
cstr = malloc(char(l + 2));
cstr[0] = l;
smemcpy(cstr + 1, s, l + 1);
}
@ -167,7 +166,7 @@ string & string::operator+=(const string & s)
d = cstr[0];
char l = s.cstr[0] + d;
char * c = (char *)malloc(char(l + 2));
char * c = malloc(char(l + 2));
c[0] = l;
if (d)
@ -189,7 +188,7 @@ string & string::operator+=(const char * s)
if (cstr)
{
char l = sl + cstr[0];
char * c = (char *)malloc(char(l + 2));
char * c = malloc(char(l + 2));
c[0] = l;
smemcpy(c + 1, cstr + 1, cstr[0]);
smemcpy(c + 1 + cstr[0], s, sl + 1);
@ -198,7 +197,7 @@ string & string::operator+=(const char * s)
}
else
{
cstr = (char *)malloc(char(sl + 2));
cstr = malloc(char(sl + 2));
cstr[0] = sl;
smemcpy(cstr + 1, s, sl + 1);
}
@ -212,7 +211,7 @@ string & string::operator+=(char c)
if (cstr)
{
char l = cstr[0] + 1;
char * p = (char *)malloc(char(l + 2));
char * p = malloc(char(l + 2));
p[0] = l;
smemcpy(p + 1, cstr + 1, cstr[0]);
p[l] = c;
@ -222,7 +221,7 @@ string & string::operator+=(char c)
}
else
{
cstr = (char *)malloc(3);
cstr = malloc(3);
cstr[0] = 1;
cstr[1] = c;
cstr[2] = 0;
@ -230,10 +229,6 @@ string & string::operator+=(char c)
return *this;
}
inline const char * string::c_str(void) const
{
return this->tocstr();
}
inline const char * string::tocstr(void) const
{
@ -258,7 +253,7 @@ string string::operator+(const string & s) const
if (s.cstr)
{
char l = cstr[0] + s.cstr[0];
char * p = (char *)malloc(char(l + 2));
char * p = malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]);
smemcpy(p + 1 + cstr[0], s.cstr + 1, s.cstr[0]);
return string(l, p);
@ -280,7 +275,7 @@ string string::operator+(const char * s) const
if (sl)
{
char l = cstr[0] + sl;
char * p = (char *)malloc(char(l + 2));
char * p = malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]);
smemcpy(p + 1 + cstr[0], s, sl);
return string(l, p);
@ -300,7 +295,7 @@ string string::operator+(char c) const
if (cstr)
{
char l = cstr[0] + 1;
char * p = (char *)malloc(char(l + 2));
char * p = malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]);
p[l] = c;
return string(l, p);
@ -528,7 +523,7 @@ string string::substr(char pos, char len) const
if (pos + len > l)
len = l - pos;
char * p = (char *)malloc(len + 2);
char * p = malloc(len + 2);
memcpy(p + 1, cstr + 1 + pos, len);
return string(len, p);
}

View File

@ -67,7 +67,6 @@ public:
const char * end(void) const;
const char * cend(void) const;
const char * c_str(void) const;
const char * tocstr(void) const;
string substr(char pos, char len) const;

View File

@ -21,14 +21,13 @@ public:
vector(size_t n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
{
for(size_t i=0; i<n; i++)
new (_data + i) T();
new (_data + i) T;
}
vector(const vector & v)
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
new (_data + i)T(v._data[i]);
}
@ -51,16 +50,14 @@ public:
{
if (this != &v)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
_data[i].~T();
free(_data);
_data = (T*)malloc(v._size * sizeof(T));
_size = v._size;
_capacity = v._size;
n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
new (_data + i)T(v._data[i]);
}
return *this;
@ -97,8 +94,6 @@ public:
return _capacity;
}
void clear(void);
void resize(size_t n);
void reserve(size_t n);
@ -195,8 +190,6 @@ public:
_data[_size].~T();
}
void assign(size_t count, const T & t);
void insert(size_t at, const T & t);
void erase(size_t at, size_t n = 1);
@ -211,7 +204,7 @@ protected:
template <class T>
__noinline void vector<T>::reserve(size_t n)
void vector<T>::reserve(size_t n)
{
if (n > _capacity)
{
@ -228,15 +221,7 @@ __noinline void vector<T>::reserve(size_t n)
}
template <class T>
void vector<T>::clear(void)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
_size = 0;
}
template <class T>
__noinline void vector<T>::resize(size_t n)
void vector<T>::resize(size_t n)
{
if (n < _size)
{
@ -247,7 +232,7 @@ __noinline void vector<T>::resize(size_t n)
else if (n < _capacity)
{
for(size_t i=_size; i<n; i++)
new(_data + i)T();
new(_data + i)T;
_size = n;
}
else
@ -301,27 +286,12 @@ void vector<T>::emplace_back(const P&... p)
new (add_back())T(p...);
}
template <class T>
void vector<T>::assign(size_t count, const T & t)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
if (count > _capacity)
{
_size = 0;
reserve(count);
}
for(size_t i=0; i<count; i++)
new (_data + i)T(t);
_size = count;
}
template <class T>
void vector<T>::insert(size_t at, const T & t)
{
if (_size == _capacity)
reserve(_size + 1 + (_size >> 1));
new (_data + _size)T();
new (_data + _size)T;
for(size_t i=_size; i>at; i--)
_data[i] = move(_data[i - 1]);
_data[at] = t;
@ -348,7 +318,7 @@ T * vector<T>::insert(T * at, const T & t)
at = (T *)(f + unsigned(_data));
}
T * dp = _data + _size;
new (dp)T();
new (dp)T;
while (dp != at)
{
dp--;

View File

@ -86,53 +86,3 @@ const char * oscar_expand_rle(char * dp, const char * sp)
return sp + 1;
}
__native const char * oscar_expand_lzo_buf(char * dp, const char * sp)
{
char buf[256];
char b = 0;
char cmd = sp[0];
do
{
if (cmd & 0x80)
{
char i = b - sp[1];
cmd &= 0x7f;
sp += 2;
char n = 0;
do {
buf[b] = dp[n] = buf[i];
b++;
i++;
n++;
} while (n != cmd);
}
else
{
sp += 1;
char n = 0;
do {
buf[b] = dp[n] = sp[n];
b++;
n++;
} while (n != cmd);
sp += cmd;
}
dp += cmd;
cmd = sp[0];
} while (cmd);
return sp + 1;
}
void debugcrash(void)
{
__asm volatile {
byt $02
}
}

View File

@ -6,19 +6,6 @@ __native const char * oscar_expand_lzo(char * dp, const char * sp);
__native const char * oscar_expand_rle(char * dp, const char * sp);
// Same as oscar_expand_lzo, but does not need read access to the
// target memory area. On the downside, it uses 256 bytes of stack
// memory as buffer
__native const char * oscar_expand_lzo_buf(char * dp, const char * sp);
// Write a breakpoint instruction into the .lbl file for vice. This
// intrinsic function will change the behaviour of the optimizer to ensure
// that the breakpoint is not move around into wild places.
void breakpoint(void);
#pragma intrinsic(breakpoint)
void debugcrash(void);
#pragma compile("oscar.c")

View File

@ -2,50 +2,237 @@
#include "conio.h"
#include "stdlib.h"
#if defined(__C128__)
#pragma code(lowcode)
__asm bsout
{
ldx #0
stx 0xff00
jsr 0xffd2
sta 0xff01
}
__asm bsplot
{
lda #0
sta 0xff00
jsr 0xfff0
sta 0xff01
}
__asm bsin
{
lda #0
sta 0xff00
jsr 0xffcf
sta 0xff01
}
#pragma code(code)
#elif defined(__PLUS4__)
#pragma code(lowcode)
__asm bsout
{
sta 0xff3e
jsr 0xffd2
sta 0xff3f
}
__asm bsin
{
sta 0xff3e
jsr 0xffe4
sta 0xff3f
}
__asm bsplot
{
sta 0xff3e
jsr 0xfff0
sta 0xff3f
}
#pragma code(code)
#elif defined(__ATARI__)
__asm bsout
{
tax
lda 0xe407
pha
lda 0xe406
pha
txa
}
__asm bsin
{
lda 0xe405
pha
lda 0xe404
pha
}
__asm bsplot
{
}
#else
#define bsout 0xffd2
#define bsplot 0xfff0
#define bsin 0xffcf
#endif
__asm putpch
{
#if defined(__ATARI__)
cmp #10
bne w1
lda #0x9b
w1:
jmp bsout
#else
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
cmp #10
bne w1
lda #13
w1:
cmp #9
beq t1
cpx #IOCHM_PETSCII_1
bcc w3
cmp #65
bcc w3
cmp #123
bcs w3
#if defined(__CBMPET__)
cmp #97
bcs w4
cmp #91
bcs w3
w2:
eor #$a0
w4:
eor #$20
#else
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
#endif
cpx #IOCHM_PETSCII_2
beq w3
and #$df
w3:
jmp bsout
t1:
sec
jsr bsplot
tya
and #3
eor #3
tax
lda #$20
l1:
jsr bsout
dex
bpl l1
#endif
}
__asm getpch
{
jsr bsin
#if !defined(__ATARI__)
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
cmp #13
bne w1
lda #10
w1:
cpx #IOCHM_PETSCII_1
bcc w3
cmp #219
bcs w3
cmp #65
bcc w3
cmp #193
bcc w4
eor #$a0
w4:
cmp #123
bcs w3
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
w3:
#endif
}
void putchar(char c)
{
putpch(c);
__asm {
lda c
jsr putpch
}
}
char getchar(void)
{
return getpch();
__asm {
jsr getpch
sta accu
lda #0
sta accu + 1
}
}
void puts(const char * str)
{
while (char ch = *str++)
putpch(ch);
__asm {
ploop:
ldy #0
lda (str), y
beq pdone
jsr putpch
inc str
bne ploop
inc str + 1
bne ploop
pdone:
}
}
char * gets(char * str)
{
char i = 0;
while ((char ch = getpch()) != '\n')
str[i++] = ch;
str[i] = 0;
return str;
}
char * gets_s(char * str, size_t n)
{
if (str == NULL)
return NULL;
if (n < 2)
return NULL;
char i = 0, t = n - 1;
while ((char ch = getpch()) != '\n')
{
if (i < t)
str[i] = ch;
++i;
__asm {
gloop:
jsr getpch
ldy #0
cmp #10
beq gdone
sta (str), y
inc str
bne gloop
inc str + 1
bne gloop
gdone:
lda #0
sta (str), y
}
str[(i < t) ? i : t] = '\0';
if (i > t)
return NULL;
return str;
}
@ -396,7 +583,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
if (c >= '0' && c <='9')
{
char i = 0;
int i = 0;
while (c >= '0' && c <='9')
{
i = i * 10 + c - '0';
@ -407,7 +594,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
if (c == '.')
{
char i = 0;
int i = 0;
c = *p++;
while (c >= '0' && c <='9')
{
@ -417,7 +604,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
si.precision = i;
}
if (c == 'd' || c == p'd' || c == 'i' || c == p'i')
if (c == 'd' || c == p'd')
{
bi = nformi(&si, bp, *fps++, true);
}
@ -556,17 +743,6 @@ int sprintf(char * str, const char * fmt, ...)
return d - str;
}
void vprintf(const char * fmt, va_list vlist)
{
char buff[50];
sformat(buff, fmt, (int *)vlist, true);
}
int vsprintf(char * str, const char * fmt, va_list vlist)
{
char * d = sformat(str, fmt, (int *)vlist, false);
return d - str;
}
static inline bool isspace(char c)
{

View File

@ -2,8 +2,7 @@
#define STDIO_H
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
void putchar(char c);
@ -13,16 +12,10 @@ void puts(const char * str);
char * gets(char * str);
char * gets_s(char * str, size_t n);
void printf(const char * fmt, ...);
int sprintf(char * str, const char * fmt, ...);
void vprintf(const char * fmt, va_list vlist);
int vsprintf(char * str, const char * fmt, va_list vlist);
int scanf(const char * fmt, ...);
int sscanf(const char * str, const char * fmt, ...);

View File

@ -7,17 +7,20 @@
void itoa(int n, char * s, unsigned radix)
{
bool neg = n < 0;
unsigned un = neg ? -n : n;
if (neg)
{
n = - n;
}
char i = 0;
do {
unsigned d = un % radix;
int d = n % radix;
if (d < 10)
d += '0';
else
d += 'A' - 10;
s[i++] = d;
} while ((un /= radix) > 0);
} while ((n /= radix) > 0);
if (neg)
{
@ -521,12 +524,6 @@ void exit(int status)
}
}
void abort(void)
{
exit(-1);
}
extern struct Heap {
Heap * next, * end;
} HeapNode;
@ -544,7 +541,7 @@ unsigned heapfree(void)
}
#if 0
struct Heap {q
struct Heap {
unsigned int size;
Heap * next;
} * freeHeap;
@ -667,97 +664,6 @@ void * calloc(int num, int size)
return p;
}
void * realloc(void * ptr, unsigned size)
{
if (ptr)
{
#ifdef HEAPCHECK
Heap * pheap = (Heap *)((char *)ptr - 6);
Heap * eheap = pheap->next;
unsigned psize = (char *)eheap - (char *)pheap;
void * nptr = malloc(size);
memcpy(nptr, ptr, psize - 6);
free(ptr);
return nptr;
#else
unsigned nsize = (size + 5) & ~3;
// Get heap info
Heap * pheap = (Heap *)((char *)ptr - 2);
Heap * eheap = pheap->next;
unsigned psize = (char *)eheap - (char *)pheap;
Heap * h = HeapNode.next;
Heap * hp = &HeapNode;
while (h && h < pheap)
{
hp = h;
h = h->next;
}
if (nsize <= psize)
{
// check if we should free some memory
if (nsize + sizeof(HeapNode) < psize)
{
Heap * nheap = (Heap *)((char *)pheap + nsize);
pheap->next = nheap;
if (h == eheap)
{
nheap->end = h->end;
nheap->next = h->next;
}
else
{
nheap->end = eheap;
nheap->next = h;
}
hp->next = nheap;
}
return ptr;
}
else if (h == eheap)
{
// Free space after this
// Check if enough space if extending
unsigned xsize = (char *)h->end - (char *)pheap;
if (xsize >= nsize)
{
if (xsize > nsize + sizeof(HeapNode))
{
Heap * nheap = (Heap *)((char *)pheap + nsize);
pheap->next = nheap;
nheap->end = h->end;
nheap->next = h->next;
hp->next = nheap;
}
else
{
pheap->next = h->end;
hp->next = h->next;
}
return ptr;
}
}
void * nptr = malloc(size);
memcpy(nptr, ptr, psize - 2);
free(ptr);
return nptr;
#endif
}
else
return malloc(size);
}
static unsigned seed = 31232;
unsigned int rand(void)

View File

@ -37,16 +37,12 @@ long labs(long n);
void exit(int status);
void abort(void);
void * malloc(unsigned int size);
void free(void * ptr);
void * calloc(int num, int size);
void * realloc(void * ptr, unsigned size);
unsigned heapfree(void);
unsigned int rand(void);

View File

@ -138,20 +138,6 @@ char * cpycat(char * dst, const char * src)
#pragma native(cpycat)
char* strchr( const char* str, int ch )
{
char * p = (char *)str;
while (*p != (char)ch)
{
if (!*p)
return nullptr;
p++;
}
return p;
}
void * memset(void * dst, int value, int size)
{
__asm
@ -237,8 +223,8 @@ void * memmove(void * dst, const void * src, int size)
int sz = size;
if (sz > 0)
{
char * d = (char *)dst;
const char * s = (const char *)src;
char * d = dst;
const char * s = src;
if (d < s)
{
do {
@ -259,7 +245,7 @@ void * memmove(void * dst, const void * src, int size)
int memcmp(const void * ptr1, const void * ptr2, int size)
{
const char * p = (const char *)ptr1, * q = (const char *)ptr2;
const char * p = ptr1, * q = ptr2;
char c, d;
while (size--)

View File

@ -21,16 +21,10 @@ int memcmp(const void * ptr1, const void * ptr2, int size);
void * memmove(void * dst, const void * src, int size);
char* strchr( const char* str, int ch );
#pragma intrinsic(strcpy)
#pragma intrinsic(memcpy)
#pragma intrinsic(memset)
#pragma intrinsic(memclr)
#pragma compile("string.c")
#endif

View File

@ -1,25 +1,12 @@
project_dir := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))/../)
sources = $(wildcard $(project_dir)/oscar64/*.cpp)
srcdir := $(if $(srcdir),$(srcdir),$(project_dir)/build)
objects = $(patsubst $(project_dir)/oscar64/%.cpp,$(srcdir)/%.o,$(sources))
sources = $(wildcard ../oscar64/*.cpp)
objects = $(patsubst ../oscar64/%.cpp,%.o,$(sources))
CXX = c++
CPPFLAGS = -g -O2 -std=c++11 -Wno-switch
SED = /usr/bin/sed
REMOVE_FORCE_ALL = $(RM) --recursive --dir
export OSCAR64_CC = $(project_dir)/bin/oscar64
export OSCAR64_CFLAGS =
export OSCAR64_CXX = $(project_dir)/bin/oscar64
MKDIR_PARENT = /bin/mkdir -p -m 755
INSTALL = /usr/bin/install
INSTALL_PROGRAM = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644
DESTDIR =
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
includedir = $(prefix)/include
$(shell mkdir -p ../bin)
ifdef WINDIR
linklibs = -lpthread
@ -29,87 +16,26 @@ else
ifeq ($(UNAME_S), Darwin)
linklibs = -lpthread
else
# MSVC
else
linklibs = -lrt -lpthread
# MinGW
#linklibs = -lversion -lpthread
endif
endif
%.o: ../oscar64/%.cpp
$(CXX) -c $(CPPFLAGS) $< -o $@
%.d: ../oscar64/%.cpp
@set -e; rm -f $@; \
$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
all: compiler samples check
$(srcdir)/%.o: $(project_dir)/oscar64/%.cpp
@echo "Compiling compiler file" $@ "..." $<
@$(CXX) -c $(CPPFLAGS) $< -o $@
$(srcdir)/%.d: $(project_dir)/oscar64/%.cpp
@$(MKDIR_PARENT) $(srcdir)
@echo "Transforming file" $@ "..." $<
@set -e; \
$(RM) $@; \
$(CC) -MM -MT $(patsubst %.d,%.o,$@) $(CPPFLAGS) $< > $@.$$$$; \
$(SED) 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
$(RM) $@.$$$$
compiler: --prep-build-dir $(objects)
@$(MKDIR_PARENT) $(srcdir)
@echo "Linking compiler..."
$(CXX) $(CPPFLAGS) $(objects) $(linklibs) -o $(project_dir)/bin/oscar64
../bin/oscar64 : $(objects)
$(CXX) $(CPPFLAGS) $(linklibs) $(objects) -o ../bin/oscar64
.PHONY : clean
clean :
@echo "Cleaning compiler..."
@$(RM) $(srcdir)/*.o
@$(RM) $(srcdir)/*.d
@$(RM) $(project_dir)/bin/oscar64
@$(MAKE) -C $(project_dir)/samples clean
@$(MAKE) -C $(project_dir)/autotest clean
.PHONY : distclean
distclean :
@echo "Distribution cleaning compiler..."
@$(REMOVE_FORCE_ALL) $(srcdir)
@$(REMOVE_FORCE_ALL) $(project_dir)/bin
@$(MAKE) -C $(project_dir)/samples clean
@$(MAKE) -C $(project_dir)/autotest clean
samples: compiler
@$(MAKE) -C $(project_dir)/samples all
check: compiler
@$(MAKE) -C $(project_dir)/autotest all
install: compiler
@echo "Installing to" $(DESTDIR)$(prefix)
@$(MKDIR_PARENT) $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) $(project_dir)/bin/oscar64 $(DESTDIR)$(bindir)
@$(MKDIR_PARENT) $(DESTDIR)$(includedir)/oscar64/{audio,c64,c128,cx16,gfx,nes,opp,plus4,vic20}
$(INSTALL_DATA) $(wildcard $(project_dir)/include/*.h $(project_dir)/include/*.c) $(DESTDIR)$(includedir)/oscar64
$(INSTALL_DATA) $(wildcard $(project_dir)/include/audio/*.h $(project_dir)/include/audio/*.c) $(DESTDIR)$(includedir)/oscar64/audio
$(INSTALL_DATA) $(wildcard $(project_dir)/include/c64/*.h $(project_dir)/include/c64/*.c) $(DESTDIR)$(includedir)/oscar64/c64
$(INSTALL_DATA) $(wildcard $(project_dir)/include/c128/*.h $(project_dir)/include/c128/*.c) $(DESTDIR)$(includedir)/oscar64/c128
$(INSTALL_DATA) $(wildcard $(project_dir)/include/cx16/*.h $(project_dir)/include/cx16/*.c) $(DESTDIR)$(includedir)/oscar64/cx16
$(INSTALL_DATA) $(wildcard $(project_dir)/include/gfx/*.h $(project_dir)/include/gfx/*.c) $(DESTDIR)$(includedir)/oscar64/gfx
$(INSTALL_DATA) $(wildcard $(project_dir)/include/nes/*.h $(project_dir)/include/nes/*.c) $(DESTDIR)$(includedir)/oscar64/nes
$(INSTALL_DATA) $(wildcard $(project_dir)/include/opp/*.h $(project_dir)/include/opp/*.cpp) $(DESTDIR)$(includedir)/oscar64/opp
$(INSTALL_DATA) $(wildcard $(project_dir)/include/plus4/*.h $(project_dir)/include/plus4/*.c) $(DESTDIR)$(includedir)/oscar64/plus4
$(INSTALL_DATA) $(wildcard $(project_dir)/include/vic20/*.h $(project_dir)/include/vic20/*.c) $(DESTDIR)$(includedir)/oscar64/vic20
uninstall:
@echo "Uninstalling..."
@$(RM) $(DESTDIR)$(bindir)/oscar64
@$(REMOVE_FORCE_ALL) $(DESTDIR)$(includedir)/oscar64/
-rm *.o *.d ../bin/oscar64
ifeq ($(UNAME_S), Darwin)
@ -118,9 +44,3 @@ else
include $(objects:.o=.d)
endif
--prep-build-dir:
echo "makedir"
@if [ ! -d $(srcdir) ]; then $(MKDIR_PARENT) $(srcdir); fi
@if [ ! -d $(project_dir)/bin ]; then $(MKDIR_PARENT) $(project_dir)/bin; fi

View File

@ -1,11 +0,0 @@
mkdir r:\oscar64
mkdir r:\oscar64\bin
mkdir r:\oscar64\include
xcopy /y bin\oscar64.exe r:\oscar64\bin
xcopy /y /e include r:\oscar64\include
tar -caf r:\oscar64.zip r:\oscar64

1630
oscar64.md

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35931.197
# Visual Studio Version 16
VisualStudioVersion = 16.0.31624.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}"
EndProject
@ -23,14 +23,10 @@ Global
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x64.Build.0 = Release|x64
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.ActiveCfg = Release|Win32
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.Build.0 = Release|Win32
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.Build.0 = Debug|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug|x86
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.Build.0 = Debug|x86
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.Build.0 = Release|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release|x86
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.Build.0 = Release|x86
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -421,33 +421,9 @@ protected:
array = a2;
}
for (int i = size; i < to; i++) array[i] = T{};
size = to;
}
template<typename F>
void Partition(const F & f, int l, int r)
{
if (r > l + 1)
{
int pi = l;
T p(array[pi]);
for (int i = l + 1; i < r; i++)
{
if (f(array[i], p))
{
array[pi++] = array[i];
array[i] = array[pi];
}
}
array[pi] = p;
Partition(f, l, pi);
Partition(f, pi + 1, r);
}
}
public:
ExpandingArray(void)
{
@ -620,24 +596,6 @@ public:
return false;
}
void Fill(const T& t)
{
for (int i = 0; i < size; i++)
array[i] = t;
}
void Clear(void)
{
for (int i = 0; i < size; i++)
array[i] = T{};
}
template<typename F>
void Sort(const F & f)
{
Partition(f, 0, size);
}
__forceinline T& operator[](int n)
{
assert(n >= 0 && n < size);

View File

@ -293,7 +293,7 @@ const char* AsmInstructionNames[NUM_ASM_INS_TYPES] = {
"INV", "BYT"
};
int AsmInsModeSize[NUM_ASM_INS_MODES_X] = {
int AsmInsModeSize[NUM_ASM_INS_MODES] = {
1,
2,
2,
@ -306,8 +306,6 @@ int AsmInsModeSize[NUM_ASM_INS_MODES_X] = {
2,
2,
2,
0,
2
};
void InitAssembler(void)

View File

@ -31,9 +31,7 @@ enum AsmInsMode
NUM_ASM_INS_MODES,
ASMIM_IMMEDIATE_ADDRESS,
NUM_ASM_INS_MODES_X,
ASMIM_IMMEDIATE_ADDRESS
};
struct AsmInsData
@ -47,8 +45,6 @@ extern AsmInsData DecInsData[256];
extern short AsmInsOpcodes[NUM_ASM_INS_TYPES][NUM_ASM_INS_MODES];
extern int AsmInsModeSize[NUM_ASM_INS_MODES_X];
extern const char* AsmInstructionNames[NUM_ASM_INS_TYPES];
AsmInsType FindAsmInstruction(const char * ins);

View File

@ -3,7 +3,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
class BitVector
{

View File

@ -144,8 +144,8 @@ static const char* ByteCodeNames[] = {
"LOOP_U8",
"MALLOC",
"FREE",
"FILL",
"FILL_LONG",
nullptr,
nullptr,
nullptr,
"JSR", //114
@ -623,10 +623,6 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
case BC_OP_CEIL_F32:
case BC_CONV_F32_U16:
case BC_CONV_F32_I16:
case BC_CONV_U32_F32:
case BC_CONV_I32_F32:
case BC_CONV_F32_U32:
case BC_CONV_F32_I32:
used = 0xffffffff;
break;
@ -684,8 +680,6 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
used = 0xffffffff;
break;
case BC_FILL:
case BC_FILL_LONG:
case BC_COPY:
case BC_COPY_LONG:
case BC_STRCPY:
@ -786,7 +780,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
return true;
if (mCode == BC_LEA_ACCU_INDEX)
return true;
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL)
if (mCode == BC_COPY || mCode == BC_STRCPY)
return true;
if (mCode == BC_BINOP_ADDA_16)
return true;
@ -799,7 +793,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_STORE_ADDR_32)
return true;
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL)
if (mCode == BC_COPY || mCode == BC_STRCPY)
return true;
if (mCode == BC_JSR || mCode == BC_CALL_ADDR || mCode == BC_CALL_ABS)
@ -1218,20 +1212,6 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
block->PutByte(mValue);
break;
case BC_FILL:
case BC_FILL_LONG:
if (mValue < 256)
{
block->PutCode(generator, BC_FILL);
block->PutByte(uint8(mValue));
}
else
{
block->PutCode(generator, BC_FILL_LONG);
block->PutWord(uint16(mValue));
}
break;
case BC_COPY:
case BC_COPY_LONG:
if (mValue < 256)
@ -1282,23 +1262,6 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
block->PutByte(mRegister);
break;
}
case BC_CONV_U32_F32:
case BC_CONV_I32_F32:
case BC_CONV_F32_U32:
case BC_CONV_F32_I32:
{
block->PutCode(generator, BC_EXTRT);
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
rl.mRefObject = generator->mExtByteCodes[mCode - 128];
rl.mRefOffset = 0;
block->mRelocations.Push(rl);
block->PutWord(0);
block->PutByte(mRegister);
break;
}
default:
assert(false);
@ -1604,30 +1567,6 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
}
void ByteCodeBasicBlock::FillValue(InterCodeProcedure* proc, const InterInstruction* ins)
{
LoadOperandAddress(proc, ins->mSrc[1], BC_REG_ADDR);
if (ins->mSrc[0].mTemp < 0)
{
ByteCodeInstruction cins(BC_CONST_8);
cins.mRegister = BC_REG_ACCU;
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
else
{
ByteCodeInstruction lins(BC_LOAD_REG_8);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
}
ByteCodeInstruction cins(BC_FILL);
cins.mValue = ins->mConst.mOperandSize;
mIns.Push(cins);
}
void ByteCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins)
{
LoadOperandAddress(proc, ins->mSrc[0], BC_REG_ACCU);
@ -3462,151 +3401,94 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
{
if (ins->mSrc[1].mTemp < 0)
{
if (ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mMemory == IM_ABSOLUTE)
ByteCodeInstruction lins(BC_LOAD_REG_16);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
if (csigned)
{
ByteCodeInstruction lins(BC_LOAD_REG_16);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
if (csigned)
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
cins.mValue = int(ins->mSrc[1].mIntConst);
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
cins.mValue = int(ins->mSrc[1].mIntConst);
mIns.Push(cins);
}
}
else if (ins->mSrc[0].mTemp < 0)
{
ByteCodeInstruction lins(BC_LOAD_REG_16);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
lins.mRegisterFinal = ins->mSrc[1].mFinal;
mIns.Push(lins);
if (csigned)
{
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
case IA_CMPEQ:
return BC_BRANCHS_EQ;
case IA_CMPNE:
return BC_BRANCHS_NE;
case IA_CMPLES:
return BC_BRANCHS_LE;
case IA_CMPGS:
return BC_BRANCHS_GT;
case IA_CMPGES:
return BC_BRANCHS_GE;
case IA_CMPLS:
return BC_BRANCHS_LT;
}
}
else if (ins->mSrc[1].IsUByte())
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
cins.mValue = int(ins->mSrc[1].mIntConst);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
}
else
{
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
case IA_CMPEQ:
case IA_CMPLEU:
return BC_BRANCHS_EQ;
case IA_CMPNE:
case IA_CMPGU:
return BC_BRANCHS_NE;
case IA_CMPGEU:
return BC_JUMPS;
case IA_CMPLU:
return BC_NOP;
}
}
else if (ins->mSrc[1].IsUByte())
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
cins.mValue = int(ins->mSrc[1].mIntConst);
mIns.Push(cins);
}
}
else
{
ByteCodeInstruction bins(BC_LEA_ABS);
bins.mRegister = BC_REG_ACCU;
bins.mLinkerObject = ins->mSrc[1].mLinkerObject;
bins.mValue = int(ins->mSrc[1].mIntConst);
bins.mRelocate = true;
mIns.Push(bins);
if (csigned)
{
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
cins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
cins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(cins);
}
code = TransposeBranchCondition(code);
}
}
else if (ins->mSrc[0].mTemp < 0)
{
if (ins->mSrc[0].mType == IT_INT16 || ins->mSrc[0].mMemory == IM_ABSOLUTE)
{
ByteCodeInstruction lins(BC_LOAD_REG_16);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
lins.mRegisterFinal = ins->mSrc[1].mFinal;
mIns.Push(lins);
if (csigned)
{
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
case IA_CMPEQ:
return BC_BRANCHS_EQ;
case IA_CMPNE:
return BC_BRANCHS_NE;
case IA_CMPLES:
return BC_BRANCHS_LE;
case IA_CMPGS:
return BC_BRANCHS_GT;
case IA_CMPGES:
return BC_BRANCHS_GE;
case IA_CMPLS:
return BC_BRANCHS_LT;
}
}
else if (ins->mSrc[1].IsUByte())
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
}
else
{
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
case IA_CMPEQ:
case IA_CMPLEU:
return BC_BRANCHS_EQ;
case IA_CMPNE:
case IA_CMPGU:
return BC_BRANCHS_NE;
case IA_CMPGEU:
return BC_JUMPS;
case IA_CMPLU:
return BC_NOP;
}
}
else if (ins->mSrc[1].IsUByte())
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
}
code = TransposeBranchCondition(code);
}
else
{
ByteCodeInstruction bins(BC_LEA_ABS);
bins.mRegister = BC_REG_ACCU;
bins.mLinkerObject = ins->mSrc[0].mLinkerObject;
bins.mValue = int(ins->mSrc[0].mIntConst);
bins.mRelocate = true;
mIns.Push(bins);
if (csigned)
{
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
cins.mRegisterFinal = ins->mSrc[1].mFinal;
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
cins.mRegisterFinal = ins->mSrc[1].mFinal;
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
}
code = TransposeBranchCondition(code);
}
else
{
@ -3799,67 +3681,6 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
} break;
case IA_FLOAT2LINT:
{
ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_F32_I32);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_32);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_LINT2FLOAT:
{
ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_I32_F32);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_32);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_FLOAT2LUINT:
{
ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_F32_U32);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_32);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_LUINT2FLOAT:
{
ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_U32_F32);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_32);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_EXT8TO16S:
{
if (ins->mSrc[0].mTemp == ins->mDst.mTemp)
@ -4499,9 +4320,6 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
else
LoadDirectValue(iproc, ins);
break;
case IC_FILL:
FillValue(iproc, ins);
break;
case IC_COPY:
CopyValue(iproc, ins);
break;
@ -6605,7 +6423,7 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
{
mID = proc->mID;
mNumBlocks = proc->mNumBlocks;
mNumBlocks = proc->mBlocks.Size();
tblocks = new ByteCodeBasicBlock * [mNumBlocks];
for (int i = 0; i < mNumBlocks; i++)

View File

@ -145,8 +145,8 @@ enum ByteCode
BC_LOOP_U8,
BC_MALLOC,
BC_FREE,
BC_FILL,
BC_FILL_LONG,
BC_UNUSED_4,
BC_UNUSED_5,
BC_UNUSED_6,
BC_JSR,
@ -186,12 +186,7 @@ enum ByteCode
BC_BINOP_SHR_U32,
BC_BINOP_SHR_I32,
BC_BINOP_CMP_U32,
BC_BINOP_CMP_S32,
BC_CONV_U32_F32,
BC_CONV_I32_F32,
BC_CONV_F32_U32,
BC_CONV_F32_I32,
BC_BINOP_CMP_S32
};
class ByteCodeProcedure;
@ -286,7 +281,6 @@ public:
void IntConstToAddr(int64 val);
void FloatConstToAccu(double val);
void FloatConstToWork(double val);
void FillValue(InterCodeProcedure* proc, const InterInstruction* ins);
void CopyValue(InterCodeProcedure* proc, const InterInstruction * ins);
void StrcpyValue(InterCodeProcedure* proc, const InterInstruction* ins);
void CallMalloc(InterCodeProcedure* proc, const InterInstruction* ins);

View File

@ -174,13 +174,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
if (bcdec->mType == DT_CONST_ASSEMBLER)
{
if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
linkerObject = bcdec->mLinkerObject;
}
else if (bcdec->mType == DT_LABEL)
{
if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
linkerObject = bcdec->mBase->mLinkerObject;
offset = int(bcdec->mInteger);
@ -466,7 +466,7 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
printf("Generate native code <%s>\n", proc->mIdent->mString);
ncproc->Compile(proc);
mNativeCodeGenerator->mProcedures.Push(ncproc);
mNativeProcedures.Push(ncproc);
}
else
{
@ -508,8 +508,6 @@ bool Compiler::GenerateCode(void)
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES))
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
else if (mTargetMachine == TMACH_PET_8K || mTargetMachine == TMACH_PET_16K || mTargetMachine == TMACH_PET_32K)
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00ed, 0x00f7);
else
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff);
}
@ -523,12 +521,6 @@ bool Compiler::GenerateCode(void)
{
switch (mTargetMachine)
{
case TMACH_MEGA65:
if (mCompilerOptions & COPT_NATIVE)
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2080);
else
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2100);
break;
case TMACH_C64:
case TMACH_X16:
if (mCompilerOptions & COPT_NATIVE)
@ -560,12 +552,12 @@ bool Compiler::GenerateCode(void)
if (mCompilerOptions & COPT_NATIVE)
{
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1180);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1100);
}
else
{
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1180);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1000);
}
regionLowcode->mSections.Push(mCompilationUnits->mSectionLowCode);
break;
@ -631,9 +623,6 @@ bool Compiler::GenerateCode(void)
{
switch (mTargetMachine)
{
case TMACH_MEGA65:
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
break;
case TMACH_C64:
case TMACH_X16:
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
@ -644,8 +633,6 @@ bool Compiler::GenerateCode(void)
regionBytecode = mLinker->AddRegion(identBytecode, 0x1d00, 0x1e00);
break;
case TMACH_PLUS4:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1200, 0x1300);
break;
case TMACH_VIC20:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1100, 0x1200);
break;
@ -695,9 +682,6 @@ bool Compiler::GenerateCode(void)
{
switch (mTargetMachine)
{
case TMACH_MEGA65:
regionMain = mLinker->AddRegion(identMain, 0x2300, 0xc000);
break;
case TMACH_C64:
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
break;
@ -714,7 +698,7 @@ bool Compiler::GenerateCode(void)
regionMain = mLinker->AddRegion(identMain, 0x1e00, 0xc000);
break;
case TMACH_PLUS4:
regionMain = mLinker->AddRegion(identMain, 0x1300, 0xfc00);
regionMain = mLinker->AddRegion(identMain, 0x1200, 0xfc00);
break;
case TMACH_VIC20:
regionMain = mLinker->AddRegion(identMain, 0x1200, 0x1e00);
@ -749,14 +733,6 @@ bool Compiler::GenerateCode(void)
{
switch (mTargetMachine)
{
case TMACH_MEGA65:
// TODO: Disable M65 cartridges for now.
//
// if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
// regionMain = mLinker->AddRegion(identMain, 0x2666, 0xff00);
// else
regionMain = mLinker->AddRegion(identMain, 0x2080, 0xc000);
break;
case TMACH_C64:
if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
@ -777,7 +753,7 @@ bool Compiler::GenerateCode(void)
regionMain = mLinker->AddRegion(identMain, 0x1c80, 0xc000);
break;
case TMACH_PLUS4:
regionMain = mLinker->AddRegion(identMain, 0x1180, 0xfc00);
regionMain = mLinker->AddRegion(identMain, 0x1100, 0xfc00);
break;
case TMACH_VIC20:
regionMain = mLinker->AddRegion(identMain, 0x1080, 0x1e00);
@ -932,7 +908,7 @@ bool Compiler::GenerateCode(void)
if (mCompilerOptions & COPT_VERBOSE)
printf("Generate intermediate code\n");
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart, nullptr);
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
{
Declaration* dec = mCompilationUnits->mReferenced[i];
@ -941,19 +917,13 @@ bool Compiler::GenerateCode(void)
if (!dec->mLinkerObject)
mInterCodeGenerator->TranslateProcedure(mInterCodeModule, dec->mValue, dec);
}
}
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
{
Declaration* dec = mCompilationUnits->mReferenced[i];
if (dec->mType != DT_CONST_FUNCTION)
else
{
if (!dec->mLinkerObject)
mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, dec);
}
}
mInterCodeGenerator->CompleteMainInit();
if (mErrors->mErrorCount != 0)
return false;
@ -965,8 +935,7 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("fsplitt"));
RegisterRuntime(loc, Ident::Unique("fsplitx"));
RegisterRuntime(loc, Ident::Unique("fsplita"));
RegisterRuntime(loc, Ident::Unique("fadd"));
RegisterRuntime(loc, Ident::Unique("fsub"));
RegisterRuntime(loc, Ident::Unique("faddsub"));
RegisterRuntime(loc, Ident::Unique("fmul"));
RegisterRuntime(loc, Ident::Unique("fdiv"));
RegisterRuntime(loc, Ident::Unique("mul16"));
@ -979,12 +948,8 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("fceil"));
RegisterRuntime(loc, Ident::Unique("ftoi"));
RegisterRuntime(loc, Ident::Unique("ftou"));
RegisterRuntime(loc, Ident::Unique("ftoli"));
RegisterRuntime(loc, Ident::Unique("ftolu"));
RegisterRuntime(loc, Ident::Unique("ffromi"));
RegisterRuntime(loc, Ident::Unique("ffromu"));
RegisterRuntime(loc, Ident::Unique("ffromli"));
RegisterRuntime(loc, Ident::Unique("ffromlu"));
RegisterRuntime(loc, Ident::Unique("fcmp"));
RegisterRuntime(loc, Ident::Unique("bcexec"));
RegisterRuntime(loc, Ident::Unique("jmpaddr"));
@ -994,12 +959,8 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("divu32"));
RegisterRuntime(loc, Ident::Unique("modu32"));
RegisterRuntime(loc, Ident::Unique("store32"));
RegisterRuntime(loc, Ident::Unique("load32"));
RegisterRuntime(loc, Ident::Unique("malloc"));
RegisterRuntime(loc, Ident::Unique("free"));
RegisterRuntime(loc, Ident::Unique("breakpoint"));
}
// Register extended byte code functions
@ -1015,7 +976,7 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER)
{
if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
}
}
@ -1058,18 +1019,13 @@ bool Compiler::GenerateCode(void)
mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection);
}
mNativeCodeGenerator->OutlineFunctions();
mNativeCodeGenerator->BuildFunctionProxies();
for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++)
for (int i = 0; i < mNativeProcedures.Size(); i++)
{
if (mCompilerOptions & COPT_VERBOSE2)
{
if (mNativeCodeGenerator->mProcedures[i]->mInterProc)
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
}
mNativeCodeGenerator->mProcedures[i]->Assemble();
printf("Assemble native code <%s>\n", mNativeProcedures[i]->mInterProc->mIdent->mString);
mNativeProcedures[i]->Assemble();
}
LinkerObject* byteCodeObject = nullptr;
@ -1095,13 +1051,13 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER)
{
if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
linkerObject = bcdec->mLinkerObject;
}
else if (bcdec->mType == DT_LABEL)
{
if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
linkerObject = bcdec->mBase->mLinkerObject;
offset = int(bcdec->mInteger);
}
@ -1219,85 +1175,9 @@ bool Compiler::BuildLZO(const char* targetPath)
}
}
bool Compiler::RemoveErrorFile(const char* targetPath)
{
char prgPath[200], mapPath[200], asmPath[200], intPath[200];
char basePath[200];
strcpy_s(basePath, targetPath);
ptrdiff_t i = strlen(basePath);
while (i > 0 && basePath[i - 1] != '/' && basePath[i - 1] != '\\' && basePath[i - 1] != ':')
i--;
if (i > 0)
basePath[i] = 0;
strcpy_s(prgPath, targetPath);
i = strlen(prgPath);
while (i > 0 && prgPath[i - 1] != '.')
i--;
if (i > 0)
prgPath[i] = 0;
strcpy_s(mapPath, prgPath);
strcpy_s(asmPath, prgPath);
strcpy_s(intPath, prgPath);
strcat_s(mapPath, "error.map");
strcat_s(asmPath, "error.asm");
strcat_s(intPath, "error.int");
remove(mapPath);
remove(asmPath);
remove(intPath);
return true;
}
bool Compiler::WriteErrorFile(const char* targetPath)
{
char prgPath[200], mapPath[200], asmPath[200], intPath[200];
char basePath[200];
strcpy_s(basePath, targetPath);
ptrdiff_t i = strlen(basePath);
while (i > 0 && basePath[i - 1] != '/' && basePath[i - 1] != '\\' && basePath[i - 1] != ':')
i--;
if (i > 0)
basePath[i] = 0;
strcpy_s(prgPath, targetPath);
i = strlen(prgPath);
while (i > 0 && prgPath[i - 1] != '.')
i--;
if (i > 0)
prgPath[i] = 0;
strcpy_s(mapPath, prgPath);
strcpy_s(asmPath, prgPath);
strcpy_s(intPath, prgPath);
strcat_s(mapPath, "error.map");
strcat_s(asmPath, "error.asm");
strcat_s(intPath, "error.int");
if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", mapPath);
mLinker->WriteMapFile(mapPath);
if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", asmPath);
mLinker->WriteAsmFile(asmPath, mVersion);
if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", intPath);
mInterCodeModule->Disassemble(intPath);
return true;
}
bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
{
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200], cszPath[200];
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200];
char basePath[200];
strcpy_s(basePath, targetPath);
@ -1320,7 +1200,6 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcpy_s(intPath, prgPath);
strcpy_s(bcsPath, prgPath);
strcpy_s(dbjPath, prgPath);
strcpy_s(cszPath, prgPath);
strcat_s(mapPath, "map");
strcat_s(asmPath, "asm");
@ -1328,7 +1207,6 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcat_s(intPath, "int");
strcat_s(bcsPath, "bcs");
strcat_s(dbjPath, "dbj");
strcat_s(cszPath, "csz");
if (mCompilerOptions & COPT_TARGET_PRG)
{
@ -1411,9 +1289,6 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
if (mCompilerOptions & COPT_DEBUGINFO)
WriteDbjFile(dbjPath);
if (mCompilerOptions & COPT_PROFILEINFO)
WriteCszFile(cszPath);
if (!(mCompilerOptions & COPT_NATIVE))
{
if (mCompilerOptions & COPT_VERBOSE)
@ -1480,111 +1355,6 @@ static void DumpReferences(FILE* file, Declaration* dec)
}
bool Compiler::WriteCszFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
{
InterCodeProcedure* p(mInterCodeModule->mProcedures[i]);
if (p->mLinkerObject && p->mIdent && p->mDeclaration)
{
LinkerObject* lo = p->mLinkerObject;
struct SourceCount
{
const char* mFileName;
int mLine, mAddress;
int mBytes;
};
ExpandingArray<SourceCount> ea;
for (int j = 0; j < lo->mCodeLocations.Size(); j++)
{
const CodeLocation& co(lo->mCodeLocations[j]);
const Location* ls = &(co.mLocation);
while (ls->mFrom)
ls = ls->mFrom;
int k = 0;
while (k < ea.Size() && (ea[k].mFileName != ls->mFileName || ea[k].mLine != ls->mLine))
k++;
if (k == ea.Size())
{
SourceCount sc;
sc.mFileName = ls->mFileName;
sc.mLine = ls->mLine;
sc.mBytes = 0;
sc.mAddress = co.mStart + lo->mAddress;
ea.Push(sc);
}
ea[k].mBytes += co.mEnd - co.mStart;
}
if (ea.Size())
{
ea.Sort([](const SourceCount& l, const SourceCount& r)->bool {
return l.mFileName == r.mFileName ? l.mLine < r.mLine : l.mAddress < r.mAddress;
});
FILE* fsrc;
fopen_s(&fsrc, ea[0].mFileName, "r");
if (fsrc)
{
fprintf(file, "<%s, %s>\n", p->mDeclaration->mQualIdent->mString, ea[0].mFileName);
#if 0
for (int i = 0; i < ea.Size(); i++)
{
fprintf(file, "%s:%d : %d\n", ea[i].mFileName, ea[i].mLine, ea[i].mBytes);
}
#endif
int k = 0, l = 1;
char line[1024];
while (k < ea.Size() && fgets(line, 1024, fsrc))
{
size_t ll = strlen(line);
while (ll > 0 && (line[ll - 1] == '\r' || line[ll - 1] == '\n'))
ll--;
line[ll] = 0;
if (l < ea[k].mLine)
{
if (k > 0)
fprintf(file, "%5d,---- ( ) : %s\n", l, line);
}
else
{
int ks = k, sum = 0;
do {
sum += ea[ks].mBytes;
ks++;
} while (ks < ea.Size() && ea[ks].mFileName != ea[0].mFileName);
fprintf(file, "%5d,%04x (%3d) : %s\n", l, ea[k].mAddress, ea[k].mBytes, line);
k = ks;
}
l++;
}
fclose(fsrc);
fprintf(file, "\n");
}
}
}
}
fclose(file);
return true;
}
else
return false;
}
bool Compiler::WriteDbjFile(const char* filename)
{
FILE* file;

View File

@ -29,6 +29,7 @@ public:
GlobalOptimizer* mGlobalOptimizer;
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
ExpandingArray<NativeCodeProcedure*> mNativeProcedures;
TargetMachine mTargetMachine;
uint64 mCompilerOptions;
@ -47,8 +48,6 @@ public:
bool ParseSource(void);
bool GenerateCode(void);
bool WriteOutputFile(const char* targetPath, DiskImage * d64);
bool WriteErrorFile(const char* targetPath);
bool RemoveErrorFile(const char* targetPath);
int ExecuteCode(bool profile, int trace);
void AddDefine(const Ident* ident, const char* value);
@ -60,5 +59,4 @@ public:
void CompleteTemplateExpansion(void);
bool WriteDbjFile(const char* filename);
bool WriteCszFile(const char* filename);
};

View File

@ -14,8 +14,6 @@ static const uint64 COPT_OPTIMIZE_AUTO_ZEROPAGE = 1ULL << 8;
static const uint64 COPT_OPTIMIZE_CONST_PARAMS = 1ULL << 9;
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11;
static const uint64 COPT_OPTIMIZE_OUTLINE = 1ULL << 12;
static const uint64 COPT_OPTIMIZE_PAGE_CROSSING = 1ULL << 13;
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 1ULL << 16;
static const uint64 COPT_NATIVE = 1ULL << 17;
@ -40,11 +38,6 @@ static const uint64 COPT_VERBOSE3 = 1ULL << 50;
static const uint64 COPT_DEBUGINFO = 1ULL << 51;
static const uint64 COPT_CPLUSPLUS = 1ULL << 52;
static const uint64 COPT_PETSCII = 1ULL << 53;
static const uint64 COPT_ERROR_FILES = 1ULL << 54;
static const uint64 COPT_PROFILEINFO = 1ULL << 55;
static const uint64 COPT_STRICT = 1ULL << 56;
@ -52,7 +45,7 @@ static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE |
static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;// | COPT_OPTIMIZE_OUTLINE;
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_UNROLL | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_ASSEMBLER | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
@ -79,8 +72,7 @@ enum TargetMachine
TMACH_NES_MMC1,
TMACH_NES_MMC3,
TMACH_ATARI,
TMACH_X16,
TMACH_MEGA65
TMACH_X16
};

View File

@ -11,7 +11,7 @@ int CompressLZO(uint8* dst, const uint8* source, int size)
while (pi < 127 && pos < size)
{
int bi = pi, bj = 0;
for (int i = 1; i <= (pos < 255 ? pos : 255); i++)
for (int i = 1; i < (pos < 255 ? pos : 255); i++)
{
int j = 0;
while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j])

View File

@ -2,7 +2,7 @@
#include <math.h>
ConstexprInterpreter::Value::Value(void)
: mDecType(TheVoidTypeDeclaration), mDecValue(nullptr),
: mDecType(TheVoidTypeDeclaration),
mBaseValue(nullptr), mOffset(0),
mData(mShortData), mDataSize(0)
{
@ -10,7 +10,7 @@ ConstexprInterpreter::Value::Value(void)
ConstexprInterpreter::Value::Value(const Location & location)
: mLocation(location),
mDecType(TheVoidTypeDeclaration), mDecValue(nullptr),
mDecType(TheVoidTypeDeclaration),
mBaseValue(nullptr), mOffset(0),
mData(mShortData), mDataSize(0)
{
@ -18,7 +18,7 @@ ConstexprInterpreter::Value::Value(const Location & location)
ConstexprInterpreter::Value::Value(Expression* exp)
: mLocation(exp->mLocation),
mDecType(exp->mDecType), mDecValue(nullptr),
mDecType(exp->mDecType),
mBaseValue(nullptr), mOffset(0),
mDataSize(exp->mDecType->mSize)
{
@ -51,15 +51,12 @@ void ConstexprInterpreter::Value::PutConst(int offset, Declaration* dec)
for (int i = 0; i < dec->mBase->mSize; i++)
PutIntAt(dec->mData[i], offset + i, TheConstCharTypeDeclaration);
break;
case DT_CONST_POINTER:
PutPtrAt(new Value(mLocation, dec->mValue->mDecValue, dec->mBase, 0), offset, dec);
break;
}
}
ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec)
: mLocation(location),
mDecType(dec), mDecValue(nullptr),
mDecType(dec),
mBaseValue(nullptr), mOffset(0),
mDataSize(dec->mSize)
{
@ -71,7 +68,7 @@ ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec)
ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec, int size)
: mLocation(location),
mDecType(dec), mDecValue(nullptr),
mDecType(dec),
mBaseValue(nullptr), mOffset(0),
mDataSize(size)
{
@ -83,7 +80,7 @@ ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec, i
ConstexprInterpreter::Value::Value(const Value& value)
: mLocation(value.mLocation),
mDecType(value.mDecType), mDecValue(nullptr),
mDecType(value.mDecType),
mBaseValue(value.mBaseValue), mOffset(value.mOffset),
mDataSize(value.mDataSize)
@ -99,7 +96,7 @@ ConstexprInterpreter::Value::Value(const Value& value)
ConstexprInterpreter::Value::Value(Value&& value)
: mLocation(value.mLocation),
mDecType(value.mDecType), mDecValue(nullptr),
mDecType(value.mDecType),
mBaseValue(value.mBaseValue), mOffset(value.mOffset),
mDataSize(value.mDataSize)
{
@ -118,7 +115,7 @@ ConstexprInterpreter::Value::Value(Value&& value)
ConstexprInterpreter::Value::Value(Value* value)
: mLocation(value->mLocation),
mDecType(value->mDecType), mDecValue(value->mDecValue),
mDecType(value->mDecType),
mBaseValue(value), mOffset(0),
mDataSize(0), mData(mShortData)
{
@ -126,23 +123,15 @@ ConstexprInterpreter::Value::Value(Value* value)
ConstexprInterpreter::Value::Value(const Location& location, Value* value, Declaration* type, int offset)
: mLocation(location),
mDecType(type), mDecValue(nullptr),
mDecType(type),
mBaseValue(value), mOffset(offset),
mDataSize(0), mData(mShortData)
{
}
ConstexprInterpreter::Value::Value(const Location& location, Declaration* value, Declaration* type, int offset)
: mLocation(location),
mDecType(type), mDecValue(value),
mBaseValue(nullptr), mOffset(offset),
mDataSize(0), mData(mShortData)
{
}
ConstexprInterpreter::Value::Value(const Location& location, const uint8* data, Declaration* type)
: mLocation(location),
mDecType(type), mDecValue(nullptr),
mDecType(type),
mBaseValue(nullptr), mOffset(0),
mDataSize(type->mSize)
{
@ -157,7 +146,7 @@ ConstexprInterpreter::Value::Value(const Location& location, const uint8* data,
ConstexprInterpreter::Value::Value(const Location& location, const ValueItem* data, Declaration* type)
: mLocation(location),
mDecType(type), mDecValue(nullptr),
mDecType(type),
mBaseValue(nullptr), mOffset(0),
mDataSize(type->mSize)
{
@ -350,14 +339,6 @@ ConstexprInterpreter::Value ConstexprInterpreter::Value::GetPtrAt(int at, Declar
return Value(mLocation, dp->mBaseValue, type, uint16(dp[0].mByte | ((uint32)(dp[1].mByte) << 8)));
}
void ConstexprInterpreter::Value::PutVarAt(Declaration* var, int64 v, int at, Declaration* type)
{
ValueItem* dp = GetAddr() + at;
dp[0].mByte = uint8(v & 0xff);
dp[1].mByte = uint8((v >> 8) & 0xff);
mDecValue = var;
}
void ConstexprInterpreter::Value::PutIntAt(int64 v, int at, Declaration* type)
{
if (type->mType == DT_TYPE_FLOAT)
@ -518,10 +499,7 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
for (int i=0; i<type->mSize; i += type->mBase->mSize)
{
Declaration* cdec = GetConst(offset + i, type->mBase, dataSection);
if (type->mStride)
cdec->mOffset = i / type->mBase->mSize;
else
cdec->mOffset = i;
cdec->mOffset = i;
if (ldec)
ldec->mNext = cdec;
@ -543,26 +521,7 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
Declaration* target;
if (vp.mBaseValue->mDecValue)
{
target = new Declaration(mLocation, DT_VARIABLE_REF);
if (vp.mBaseValue->mDecValue->mType == DT_VARIABLE_REF)
{
target->mBase = vp.mBaseValue->mDecValue->mBase;
target->mOffset = vp.mBaseValue->mDecValue->mOffset;
}
else
target->mBase = vp.mBaseValue->mDecValue;
target->mOffset += vp.mOffset;
dec->mValue = new Expression(mLocation, EX_CONSTANT);
dec->mValue->mDecType = type;
dec->mValue->mDecValue = target;
return dec;
}
else if (vp.mBaseValue->mDecType->mType == DT_TYPE_ARRAY)
if (vp.mBaseValue->mDecType->mType == DT_TYPE_ARRAY)
{
target = new Declaration(mLocation, DT_CONST_DATA);
target->mSize = vp.mBaseValue->mDataSize;
@ -581,14 +540,6 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
dec->mValue->mDecType = target->mBase;
dec->mValue->mDecValue = target;
}
else if (vp.mDecValue)
{
dec = new Declaration(mLocation, DT_VARIABLE_REF);
dec->mBase = vp.mDecValue;
dec->mFlags = 0;
dec->mSize = type->mSize;
dec->mOffset = vp.mOffset;
}
else
{
dec = new Declaration(mLocation, DT_CONST_ADDRESS);
@ -651,7 +602,6 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
{
mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight;
Declaration* cdec = exp->mLeft->mDecType->mParams;
int pos = 0;
@ -660,28 +610,6 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
mParams[pos].PutPtr(Value(&mResult));
pos = 2;
if (pex->mType == EX_LIST)
pex = pex->mRight;
else
pex = nullptr;
cdec = cdec->mNext;
while (pex && pex->mType == EX_LIST)
{
if (!AddParam(pos, pex->mLeft, cdec))
return exp;
pex = pex->mRight;
if (cdec)
cdec = cdec->mNext;
}
if (pex)
{
if (!AddParam(pos, pex, cdec))
return exp;
}
mHeap = new ExpandingArray<Value*>();
Execute(exp->mLeft->mDecValue->mValue);
@ -762,12 +690,7 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
{
mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase);
if (pex->mDecValue->mSize > 0)
{
if (pex->mDecValue->mValue)
mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
else
return false;
}
mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
}
else
return false;
@ -777,9 +700,6 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
{
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
return exp;
mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight;
@ -1046,9 +966,6 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalUnary(Expression* exp, con
break;
case TK_MUL:
return vl.GetPtr();
case TK_SIZEOF:
v.PutInt(vl.mDecType->mSize);
break;
default:
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
}
@ -1182,41 +1099,6 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(cos(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "tan"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(tan(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "log"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(log(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "exp"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::exp(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "sqrt"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::sqrt(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "atan"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::atan(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "atan2"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::atan2(mParams[0].GetFloat(), mParams[1].GetFloat()));
}
else if (!strcmp(iname->mString, "pow"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::pow(mParams[0].GetFloat(), mParams[1].GetFloat()));
}
else
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
}

View File

@ -19,8 +19,8 @@ protected:
struct ValueItem
{
uint8 mByte;
Value * mBaseValue;
uint8 mByte;
Value* mBaseValue;
ValueItem(void);
};
@ -35,7 +35,6 @@ protected:
Value(const Value& value);
Value(Value&& value);
Value(const Location& location, Value * value, Declaration * type, int offset);
Value(const Location& location, Declaration * value, Declaration* type, int offset);
Value(Value* value);
Value(const Location& location, const uint8 * data, Declaration* type);
Value(const Location& location, const ValueItem* data, Declaration* type);
@ -49,7 +48,7 @@ protected:
void Assign(const Value& v);
Location mLocation;
Declaration * mDecType, * mDecValue;
Declaration * mDecType;
Value * mBaseValue;
int mOffset;
ValueItem * mData;
@ -72,7 +71,6 @@ protected:
void PutIntAt(int64 v, int at, Declaration* type);
void PutFloatAt(double v, int at, Declaration* type);
void PutPtrAt(const Value& v, int at, Declaration* type);
void PutVarAt(Declaration* var, int64 v, int at, Declaration* type);
void PutConst(int offset, Declaration * dec);
Declaration* GetConst(int offset, Declaration* type, LinkerSection* dataSection) const;

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,6 @@ enum DecType
DT_PACK_VARIABLE,
DT_PACK_ARGUMENT,
DT_PACK_TYPE,
DT_PACK_ANON,
DT_VARIABLE,
DT_ARGUMENT,
@ -59,7 +58,6 @@ enum DecType
DT_LABEL_REF,
DT_NAMESPACE,
DT_BASECLASS,
DT_CLABEL,
DT_TEMPLATE,
@ -103,8 +101,6 @@ static const uint64 DTF_CONSTEXPR = (1ULL << 31);
static const uint64 DTF_AUTO_TEMPLATE = (1ULL << 32);
static const uint64 DTF_BANK_INLAY = (1ULL << 33);
static const uint64 DTF_PURE_VIRTUAL = (1ULL << 34);
static const uint64 DTF_FORCE_INLINE = (1ULL << 35);
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 36);
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 37);
@ -124,11 +120,6 @@ static const uint64 DTF_FUNC_THIS = (1ULL << 47);
static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
static const uint64 DTF_FPARAM_UNUSED = (1ULL << 49);
static const uint64 DTF_DEPRECATED = (1ULL << 50);
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
static const uint64 DTF_PLACED = (1ULL << 52);
static const uint64 DTF_NO_PAGE_CROSS = (1ULL << 53);
class Declaration;
@ -167,8 +158,6 @@ public:
ScopeLevel mLevel;
const Ident * mName;
DeclarationScope* Clone(void) const;
DeclarationScope* mParent;
protected:
struct Entry
@ -218,7 +207,6 @@ enum ExpressionType
EX_IF,
EX_ELSE,
EX_FOR,
EX_FORBODY,
EX_DO,
EX_SCOPE,
EX_BREAK,
@ -241,25 +229,14 @@ enum ExpressionType
EX_RESULT,
EX_PACK,
EX_PACK_TYPE,
EX_LABEL,
EX_GOTO,
EX_AGGREGATE
};
static const uint32 ANAFL_LHS = (1U << 0);
static const uint32 ANAFL_RHS = (1U << 1);
static const uint32 ANAFL_ASSIGN = (1U << 2);
static const uint32 ANAFL_ALIAS = (1U << 3);
class Expression
{
public:
Expression(const Location& loc, ExpressionType type);
~Expression(void);
uint32 mUID;
Location mLocation, mEndLocation;
ExpressionType mType;
Expression * mLeft, * mRight;
@ -268,23 +245,15 @@ public:
AsmInsType mAsmInsType;
AsmInsMode mAsmInsMode;
bool mConst;
uint32 mFlags;
Expression* LogicInvertExpression(void);
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
bool HasSideEffects(void) const;
Expression* ListAppend(Expression* lexp);
Expression* ToAlternateThis(Declaration* pthis, Declaration* nthis);
void ReplaceVariable(Declaration* pvar, Declaration* nvar);
bool IsSame(const Expression* exp) const;
bool IsRValue(void) const;
bool IsLValue(void) const;
bool IsConstRef(void) const;
bool IsVolatile(void) const;
void Dump(int ident) const;
};
@ -295,14 +264,12 @@ public:
Declaration(const Location & loc, DecType type);
~Declaration(void);
uint32 mUID;
Location mLocation, mEndLocation;
DecType mType;
Token mToken;
Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile;
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment, * mVectorMoveConstructor, * mVectorMoveAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
Declaration * mVTable, * mClass, * mTemplate;
Declaration * mForwardParam, * mForwardCall;
@ -329,7 +296,6 @@ public:
bool IsSame(const Declaration* dec) const;
bool IsDerivedFrom(const Declaration* dec) const;
bool IsSubType(const Declaration* dec) const;
bool IsConstRefSame(const Declaration* dec) const;
bool IsConstSame(const Declaration* dec) const;
bool IsSameValue(const Declaration* dec) const;
bool IsSameParams(const Declaration* dec) const;
@ -344,17 +310,12 @@ public:
bool IsSimpleType(void) const;
bool IsReference(void) const;
bool IsIndexed(void) const;
bool ContainsArray(void) const;
bool IsShortIntStruct(void) const;
bool IsComplexStruct(void) const;
bool HasConstructor(void) const;
void SetDefined(void);
Declaration* ToConstType(void);
Declaration* ToMutableType(void);
Declaration* ToVolatileType(void);
Declaration* ToAlternateThis(Declaration* pthis, int nthis = 1);
Declaration* ToStriped(int stripe);
Declaration* ToStriped(Errors* errors);
@ -378,9 +339,8 @@ public:
DecType ValueType(void) const;
bool CanResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplate(Declaration* fdec, Declaration * tdec, bool same, bool preliminary);
bool ResolveTemplate(Declaration* fdec, Declaration * tdec);
bool ResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary);
Declaration* ExpandTemplate(DeclarationScope* scope);
@ -397,7 +357,6 @@ extern Declaration* TheVoidTypeDeclaration, * TheConstVoidTypeDeclaration, * The
extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheConstVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
extern Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration;
extern Expression* TheVoidExpression;

View File

@ -429,10 +429,6 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
i += 1;
break;
case BC_FILL:
fprintf(file, "FILL\t#%d", memory[start + i + 0]);
i++;
break;
case BC_COPY:
fprintf(file, "COPY\t#%d", memory[start + i + 0]);
i++;
@ -445,10 +441,6 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
fprintf(file, "COPYL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_FILL_LONG:
fprintf(file, "FILLL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_OP_NEGATE_16:
fprintf(file, "NEG\tACCU");
@ -484,19 +476,6 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
fprintf(file, "CNVFS\tACCU");
break;
case BC_CONV_U32_F32:
fprintf(file, "CNVLUF\tACCU");
break;
case BC_CONV_I32_F32:
fprintf(file, "CNVLSF\tACCU");
break;
case BC_CONV_F32_U32:
fprintf(file, "CNVFLU\tACCU");
break;
case BC_CONV_F32_I32:
fprintf(file, "CNVFLS\tACCU");
break;
case BC_MALLOC:
fprintf(file, "MALLOC\tACCU");
break;
@ -846,7 +825,7 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU);
return buffer;
}
else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 8)
else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 7)
{
sprintf_s(buffer, 10, "WORK + %d", tmp - BC_REG_WORK);
return buffer;

View File

@ -31,8 +31,6 @@ static char A2P(char ch)
DiskImage::DiskImage(const char* fname)
{
mInterleave = 10;
for (int i = 0; i < 41; i++)
for (int j = 0; j < 21; j++)
memset(mSectors[i][j], 0, 256);
@ -106,7 +104,7 @@ int DiskImage::AllocBAMSector(int track, int sector)
if (dp[0] > 0)
{
sector += mInterleave;
sector += 4;
if (sector >= SectorsPerTrack[track])
sector -= SectorsPerTrack[track];
@ -230,10 +228,8 @@ void DiskImage::CloseFile(void)
}
bool DiskImage::WriteFile(const char* fname, bool compressed, int interleave)
bool DiskImage::WriteFile(const char* fname, bool compressed)
{
mInterleave = interleave;
FILE* file;
fopen_s(&file, fname, "rb");
if (file)

View File

@ -14,7 +14,7 @@ public:
void CloseFile(void);
int WriteBytes(const uint8* data, ptrdiff_t size);
bool WriteFile(const char* fname, bool compressed, int interleave);
bool WriteFile(const char* fname, bool compressed);
protected:
uint8 mSectors[41][21][256];
@ -24,6 +24,6 @@ protected:
int AllocBAMTrack(int track);
uint8 * mDirEntry;
int mTrack, mSector, mBytes, mInterleave;
int mTrack, mSector, mBytes;
};

View File

@ -115,7 +115,7 @@ void Emulator::DumpCycles(void)
}
}
bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles, bool cross, bool indexed)
bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles)
{
int t;
@ -134,14 +134,12 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mRegA = (t & 255);
UpdateStatusCarry(mRegA, t >= 256);
if (cross) cycles++;
break;
case ASMIT_AND:
if (mode != ASMIM_IMMEDIATE)
addr = mMemory[addr];
mRegA &= addr;
UpdateStatus(mRegA);
if (cross) cycles++;
break;
case ASMIT_ASL:
if (mode == ASMIM_IMPLIED)
@ -156,29 +154,19 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, t >= 256);
cycles += 2;
if (indexed) cycles++;
}
break;
case ASMIT_BCC:
if (!(mRegP & STATUS_CARRY))
{
mIP = addr;
cycles++;
}
break;
case ASMIT_BCS:
if ((mRegP & STATUS_CARRY))
{
mIP = addr;
cycles++;
}
break;
case ASMIT_BEQ:
if ((mRegP & STATUS_ZERO))
{
mIP = addr;
cycles++;
}
break;
case ASMIT_BIT:
t = mMemory[addr];
@ -247,7 +235,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mRegP |= STATUS_OVERFLOW;
UpdateStatusCarry(t & 255, t >= 256);
if (cross) cycles++;
break;
case ASMIT_CPX:
if (mode != ASMIM_IMMEDIATE)
@ -288,7 +275,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255;
UpdateStatus(t & 255);
cycles += 2;
if (indexed) cycles++;
}
break;
case ASMIT_DEX:
@ -306,7 +292,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
addr = mMemory[addr];
mRegA ^= addr;
UpdateStatus(mRegA);
if (cross) cycles++;
break;
case ASMIT_INC:
if (mode == ASMIM_IMPLIED)
@ -321,7 +306,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255;
UpdateStatus(t & 255);
cycles += 2;
if (indexed) cycles++;
}
break;
case ASMIT_INX:
@ -350,21 +334,18 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
addr = mMemory[addr];
mRegA = addr;
UpdateStatus(mRegA);
if (cross) cycles++;
break;
case ASMIT_LDX:
if (mode != ASMIM_IMMEDIATE)
addr = mMemory[addr];
mRegX = addr;
UpdateStatus(mRegX);
if (cross) cycles++;
break;
case ASMIT_LDY:
if (mode != ASMIM_IMMEDIATE)
addr = mMemory[addr];
mRegY = addr;
UpdateStatus(mRegY);
if (cross) cycles++;
break;
case ASMIT_LSR:
if (mode == ASMIM_IMPLIED)
@ -381,7 +362,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, c != 0);
cycles += 2;
if (indexed) cycles++;
}
break;
case ASMIT_NOP:
@ -391,7 +371,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
addr = mMemory[addr];
mRegA |= addr;
UpdateStatus(mRegA);
if (cross) cycles++;
break;
case ASMIT_PHA:
mMemory[0x100 + mRegS] = mRegA;
@ -426,7 +405,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, t >= 256);
cycles+=2;
if (indexed) cycles++;
}
break;
case ASMIT_ROR:
@ -444,7 +422,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, c != 0);
cycles += 2;
if (indexed) cycles++;
}
break;
case ASMIT_RTI:
@ -467,7 +444,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mRegA = (t & 255);
UpdateStatusCarry(t & 255, t >= 256);
if (cross) cycles++;
break;
case ASMIT_SEC:
mRegP |= STATUS_CARRY;
@ -478,7 +454,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
break;
case ASMIT_STA:
mMemory[addr] = mRegA;
if (indexed) cycles++;
break;
case ASMIT_STX:
mMemory[addr] = mRegX;
@ -537,13 +512,13 @@ int Emulator::Emulate(int startIP, int trace)
mMemory[0x1fe] = 0xff;
mMemory[0x1ff] = 0xff;
int tcycles = 0, cycles = 0;
int iip = 0;
int ticks = 0;
while (mIP != 0)
{
if (mJiffies)
{
if (cycles >= tcycles + 16667)
ticks++;
if (ticks > 4500)
{
mMemory[0xa2]++;
if (!mMemory[0xa2])
@ -554,7 +529,7 @@ int Emulator::Emulate(int startIP, int trace)
mMemory[0xa0]++;
}
}
tcycles += 16667;
ticks = 0;
}
}
@ -581,16 +556,11 @@ int Emulator::Emulate(int startIP, int trace)
mRegS += 2;
}
uint8 opcode = mMemory[mIP];
uint8 opcode = mMemory[mIP];
AsmInsData d = DecInsData[opcode];
int addr = 0, taddr;
int ip = mIP;
if (ip == 0x0862)
iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1] + mRegY;
bool cross = false, indexed = false;
int icycles = 0;
int addr = 0, taddr;
int ip = mIP;
int iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1];
mIP++;
switch (d.mMode)
@ -598,60 +568,56 @@ int Emulator::Emulate(int startIP, int trace)
case ASMIM_IMPLIED:
if (trace & 2)
printf("%04x : %04x %02x __ __ %s (A:%02x X:%02x Y:%02x P:%02x S:%02x)\n", iip, ip, mMemory[ip], AsmInstructionNames[d.mType], mRegA, mRegX, mRegY, mRegP, mRegS);
icycles = 2;
mCycles[ip] += 2;
break;
case ASMIM_IMMEDIATE:
addr = mMemory[mIP++];
if (trace & 2)
printf("%04x : %04x %02x %02x __ %s #$%02x (A:%02x X:%02x Y:%02x P:%02x S:%02x)\n", iip, ip, mMemory[ip], mMemory[ip+1], AsmInstructionNames[d.mType], addr, mRegA, mRegX, mRegY, mRegP, mRegS);
icycles = 2;
mCycles[ip] += 2;
break;
case ASMIM_ZERO_PAGE:
addr = mMemory[mIP++];
if (trace & 2)
printf("%04x : %04x %02x %02x __ %s $%02x (A:%02x X:%02x Y:%02x P:%02x S:%02x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr, mRegA, mRegX, mRegY, mRegP, mRegS, mMemory[addr]);
icycles = 3;
mCycles[ip] += 3;
break;
case ASMIM_ZERO_PAGE_X:
taddr = mMemory[mIP++];
addr = (taddr + mRegX) & 0xff;
if (trace & 2)
printf("%04x : %04x %02x %02x __ %s $%02x,x (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]);
icycles = 4;
mCycles[ip] += 3;
break;
case ASMIM_ZERO_PAGE_Y:
taddr = mMemory[mIP++];
addr = (taddr + mRegY) & 0xff;
if (trace & 2)
printf("%04x : %04x %02x %02x __ %s $%02x,y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]);
icycles = 4;
mCycles[ip] += 3;
break;
case ASMIM_ABSOLUTE:
addr = mMemory[mIP] + 256 * mMemory[mIP + 1];
if (trace & 2)
printf("%04x : %04x %02x %02x %02x %s $%04x (A:%02x X:%02x Y:%02x P:%02x S:%02x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr, mRegA, mRegX, mRegY, mRegP, mRegS, mMemory[addr]);
mIP += 2;
icycles = 4;
mCycles[ip] += 4;
break;
case ASMIM_ABSOLUTE_X:
taddr = mMemory[mIP] + 256 * mMemory[mIP + 1];
addr = (taddr + mRegX) & 0xffff;
cross = mMemory[mIP] + mRegX >= 256;
indexed = true;
if (trace & 2)
printf("%04x : %04x %02x %02x %02x %s $%04x,x (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]);
mIP += 2;
icycles = 4;
mCycles[ip] += 5;
break;
case ASMIM_ABSOLUTE_Y:
taddr = mMemory[mIP] + 256 * mMemory[mIP + 1];
addr = (taddr + mRegY) & 0xffff;
cross = mMemory[mIP] + mRegY >= 256;
indexed = true;
if (trace & 2)
printf("%04x : %04x %02x %02x %02x %s $%04x,y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]);
mIP += 2;
icycles = 4;
mCycles[ip] += 5;
break;
case ASMIM_INDIRECT:
taddr = mMemory[mIP] + 256 * mMemory[mIP + 1];
@ -659,23 +625,21 @@ int Emulator::Emulate(int startIP, int trace)
addr = mMemory[taddr] + 256 * mMemory[taddr + 1];
if (trace & 2)
printf("%04x : %04x %02x %02x %02x %s ($%04x) (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr);
icycles = 6;
mCycles[ip] += 6;
break;
case ASMIM_INDIRECT_X:
taddr = (mMemory[mIP++] + mRegX) & 0xff;
addr = mMemory[taddr] + 256 * mMemory[taddr + 1];
if (trace & 2)
printf("%04x : %04x %02x %02x __ %s ($%02x,x) (A:%02x X:%02x Y:%02x P:%02x S:%02x %02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], mMemory[ip + 1], mRegA, mRegX, mRegY, mRegP, mRegS, taddr, addr, mMemory[addr]);
icycles = 6;
mCycles[ip] += 6;
break;
case ASMIM_INDIRECT_Y:
taddr = mMemory[mIP++];
addr = (mMemory[taddr] + 256 * mMemory[taddr + 1] + mRegY) & 0xffff;
cross = mMemory[taddr] + mRegY >= 256;
indexed = true;
if (trace & 2)
printf("%04x : %04x %02x %02x __ %s ($%02x),y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]);
icycles = 5;
mCycles[ip] += 6;
break;
case ASMIM_RELATIVE:
taddr = mMemory[mIP++];
@ -685,7 +649,7 @@ int Emulator::Emulate(int startIP, int trace)
addr = taddr + mIP;
if (trace & 2)
printf("%04x : %04x %02x %02x __ %s $%02x (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr);
icycles = 2;
mCycles[ip] += 2;
break;
}
@ -721,11 +685,8 @@ int Emulator::Emulate(int startIP, int trace)
);
}
if (!EmulateInstruction(d.mType, d.mMode, addr, icycles, cross, indexed))
if (!EmulateInstruction(d.mType, d.mMode, addr, mCycles[ip]))
return -1;
mCycles[ip] += icycles;
cycles += icycles;
}
if (mRegS == 0xff)

View File

@ -22,7 +22,7 @@ public:
int Emulate(int startIP, int trace);
void DumpProfile(void);
bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles, bool cross, bool indexed);
bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles);
protected:
void UpdateStatus(uint8 result);
void UpdateStatusCarry(uint8 result, bool carry);

View File

@ -4,18 +4,11 @@
#include <stdlib.h>
Errors::Errors(void)
: mErrorCount(0), mMinLevel(EINFO_GENERIC), mDisabled(EERR_GENERIC)
: mErrorCount(0)
{
}
ErrorID Errors::SetMinLevel(ErrorID id)
{
ErrorID pid = mMinLevel;
mMinLevel = id;
return pid;
}
void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2)
{
if (!info1)
@ -29,44 +22,41 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Iden
void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char* info1, const char * info2)
{
if (eid >= mMinLevel && !(eid < EERR_GENERIC && mDisabled[eid]))
const char* level = "info";
if (eid >= EERR_GENERIC)
{
const char* level = "info";
if (eid >= EERR_GENERIC)
{
level = "error";
mErrorCount++;
}
else if (eid >= EWARN_GENERIC)
{
level = "warning";
}
if (loc.mFileName)
{
if (!info1)
fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
else if (!info2)
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1);
else
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2);
if (loc.mFrom)
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here");
}
else
{
if (!info1)
fprintf(stderr, "oscar64: %s %d: %s\n", level, eid, msg);
else if (!info2)
fprintf(stderr, "oscar64: %s %d: %s '%s'\n", level, eid, msg, info1);
else
fprintf(stderr, "oscar64: %s %d: %s '%s' != '%s'\n", level, eid, msg, info1, info2);
}
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
exit(20);
level = "error";
mErrorCount++;
}
else if (eid >= EWARN_GENERIC)
{
level = "warning";
}
if (loc.mFileName)
{
if (!info1)
fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
else if (!info2)
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1);
else
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2);
if (loc.mFrom)
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here");
}
else
{
if (!info1)
fprintf(stderr, "oscar64: %s %d: %s\n", level, eid, msg);
else if (!info2)
fprintf(stderr, "oscar64: %s %d: %s '%s'\n", level, eid, msg, info1);
else
fprintf(stderr, "oscar64: %s %d: %s '%s' != '%s'\n", level, eid, msg, info1, info2);
}
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
exit(20);
}

View File

@ -1,8 +1,5 @@
#pragma once
#include "NumberSet.h"
class Location
{
public:
@ -13,11 +10,7 @@ public:
Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {}
Location(const Location& loc, const Location* from)
: mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from)
{
static volatile int k;
if (from)
k = from->mLine;
}
{}
};
class Ident;
@ -46,13 +39,6 @@ enum ErrorID
EWARN_DESTRUCTOR_MISMATCH,
EWARN_NUMERIC_0_USED_AS_NULLPTR,
EWARN_FLOAT_TO_INT,
EWARN_UNDEFINED_POINTER_ARITHMETIC,
EWARN_INVALID_VALUE_RANGE,
EWARN_DEFAULT_COPY_DEPRECATED,
EWARN_INSUFFICIENT_MEMORY,
EWARN_FUNCTION_NOT_INLINED,
EWARN_INVALID_VOID_POINTER_ARITHMETIC,
EWARN_DIVISION_BY_ZERO,
EERR_GENERIC = 3000,
EERR_FILE_NOT_FOUND,
@ -109,10 +95,6 @@ enum ErrorID
EERR_INVALID_CAPTURE,
EERR_INVALID_PACK_USAGE,
EERR_INVALID_FOLD_EXPRESSION,
ERRR_INSTANTIATE_ABSTRACT_CLASS,
ERRR_INVALID_GOTO,
EERR_INVALID_INITIALIZER,
ERRR_INVALID_VOID_POINTER_ARITHMETIC,
EERR_INVALID_CONSTEXPR,
EERR_DOUBLE_FREE,
@ -121,19 +103,12 @@ enum ErrorID
ERRR_STACK_OVERFLOW,
ERRR_INVALID_NUMBER,
EERR_OVERLAPPING_DATA_SECTIONS,
EERR_ASSEMBLER_LIMIT,
EERR_INVALID_PREPROCESSOR,
EERR_INVALID_CLASS_INITIALIZER,
EERR_CALL_OF_DELETED_FUNCTION,
EERR_STATIC_ASSERT,
EFATAL_GENERIC = 4000,
EFATAL_OUT_OF_MEMORY,
EFATAL_MACRO_EXPANSION_DEPTH,
ERROR_MAX = 5000
};
class Errors
@ -141,12 +116,7 @@ class Errors
public:
Errors(void);
ErrorID SetMinLevel(ErrorID id);
int mErrorCount;
ErrorID mMinLevel;
NumberSet mDisabled;
void Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2 = nullptr);
void Error(const Location& loc, ErrorID eid, const char* msg, const char* info1 = nullptr, const char* info2 = nullptr);

View File

@ -1,7 +1,7 @@
#include "GlobalAnalyzer.h"
GlobalAnalyzer::GlobalAnalyzer(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr), mGlobalVariables(nullptr), mTopoFunctions(nullptr), mCompilerOptions(COPT_DEFAULT)
: mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr), mGlobalVariables(nullptr), mCompilerOptions(COPT_DEFAULT)
{
}
@ -132,65 +132,24 @@ void GlobalAnalyzer::AutoZeroPage(LinkerSection* lszp, int zpsize)
}
}
void GlobalAnalyzer::TopoSort(Declaration* procDec)
{
if (!(procDec->mFlags & DTF_FUNC_ANALYZING))
{
procDec->mFlags |= DTF_FUNC_ANALYZING;
if (!mTopoFunctions.Contains(procDec))
{
for (int i = 0; i < procDec->mCalled.Size(); i++)
TopoSort(procDec->mCalled[i]);
mTopoFunctions.Push(procDec);
}
procDec->mFlags &= ~DTF_FUNC_ANALYZING;
}
}
int GlobalAnalyzer::CallerInvokes(Declaration* called)
{
int n = 0;
for (int i = 0; i < called->mCallers.Size(); i++)
{
Declaration* f = called->mCallers[i];
n += CallerInvokes(f, called);
}
return n;
}
int GlobalAnalyzer::CallerInvokes(Declaration* caller, Declaration* called)
{
int n = 1;
if (caller->mType == DT_CONST_FUNCTION && (caller->mFlags & (DTF_INLINE | DTF_FORCE_INLINE | DTF_REQUEST_INLINE)) && !(caller->mFlags & DTF_PREVENT_INLINE) && !(caller->mFlags & DTF_FUNC_RECURSIVE) && !(caller->mFlags & DTF_FUNC_VARIABLE) && !(caller->mFlags & DTF_EXPORT))
n = CallerInvokes(caller);
return n > 1 ? n : 1;
}
void GlobalAnalyzer::AutoInline(void)
{
for (int i = 0; i < mFunctions.Size(); i++)
TopoSort(mFunctions[i]);
bool changed = false;
do
{
changed = false;
// Reverse order, to check inline from bottom to top of call graph
for (int i = 0; i< mTopoFunctions.Size(); i++)
for (int i = 0; i < mFunctions.Size(); i++)
{
Declaration* f = mTopoFunctions[i];
if (f->mType == DT_CONST_FUNCTION &&
!(f->mFlags & DTF_INLINE) &&
Declaration* f = mFunctions[i];
if (!(f->mFlags & DTF_INLINE) &&
!(f->mFlags & DTF_EXPORT) &&
!(f->mFlags & DTF_PREVENT_INLINE) &&
!(f->mBase->mFlags & DTF_VARIADIC) &&
!(f->mFlags & DTF_FUNC_VARIABLE) &&
!((f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_REQUEST_INLINE)) &&
!(f->mFlags & DTF_INTRINSIC) &&
!(f->mFlags & DTF_FUNC_RECURSIVE) &&
!(f->mFlags & DTF_FUNC_NO_RETURN))
!(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100)
{
int nparams = 0;
Declaration* dec = f->mBase->mParams;
@ -200,39 +159,21 @@ void GlobalAnalyzer::AutoInline(void)
dec = dec->mNext;
}
int invokes = CallerInvokes(f);
int cost = (f->mComplexity - 20 * nparams - 10);
int cost = (f->mComplexity - 20 * nparams - 20);
// printf("CHECK INLINING %s (%d) %d * (%d - 1)\n", f->mIdent->mString, f->mComplexity, cost, invokes);
// printf("CHEK INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size());
bool doinline = false;
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE) || (f->mFlags & DTF_FORCE_INLINE))
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE))
doinline = true;
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && (cost * (f->mCallers.Size() - 1) <= 0))
doinline = true;
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (f->mCallers.Size() - 1) <= 10000))
doinline = true;
if (f->mLocalSize < 100)
{
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && ((cost - 20) * (invokes - 1) <= 20))
{
if (f->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE)
{
if (invokes == 1 && f->mSection == f->mCallers[0]->mSection || cost < 0)
doinline = true;
}
else if (invokes == 1 && f->mComplexity > 100)
{
// printf("CHECK INLINING2 %s <- %s %d\n", f->mIdent->mString, f->mCallers[0]->mIdent->mString, f->mCallers[0]->mCalled.Size());
if (cost < 0 || f->mCallers[0]->mComplexity + cost < 1000 || f->mCallers[0]->mCalled.Size() == 1)
doinline = true;
}
else
doinline = true;
}
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (invokes - 1) <= 10000))
doinline = true;
}
if (doinline)
{
// printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, invokes);
// printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size());
f->mFlags |= DTF_INLINE;
for (int j = 0; j < f->mCallers.Size(); j++)
@ -393,7 +334,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
if (procDec->mValue && procDec->mValue->mType == EX_DISPATCH)
{
Declaration* maxf = nullptr, * reff = nullptr;
Declaration* maxf = nullptr;
bool stackCall = false;
@ -402,10 +343,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
Declaration* cf = procDec->mCalled[i];
if (cf->mBase->mFlags & DTF_STACKCALL)
{
stackCall = true;
reff = cf;
}
if (!maxf)
maxf = cf;
@ -413,9 +351,6 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
maxf = cf;
}
if (!reff)
reff = maxf;
for (int i = 0; i < procDec->mCalled.Size(); i++)
{
Declaration* cf = procDec->mCalled[i];
@ -426,9 +361,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
cf->mBase->mFlags |= DTF_STACKCALL;
}
if (cf != reff)
if (cf != maxf)
{
Declaration* fp = cf->mBase->mParams, * mp = reff->mBase->mParams;
Declaration* fp = cf->mBase->mParams, * mp = maxf->mBase->mParams;
while (fp)
{
fp->mVarIndex = mp->mVarIndex;
@ -437,11 +372,10 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
}
assert(!mp);
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize;
}
if (cf != maxf)
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
}
procDec->mFastCallBase = procDec->mBase->mFastCallBase;
@ -481,7 +415,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
fplimit += 256;
}
if (procDec->mBase->mBase->IsComplexStruct())
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
{
if (nbase < numfpzero && nbase + 2 > numfpzero)
nbase = numfpzero;
@ -633,13 +567,6 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
{
dec->mFlags |= DTF_FUNC_ANALYZING;
if (dec->mFlags & DTF_DEPRECATED)
{
mErrors->Error(dec->mLocation, EWARN_DEFAULT_COPY_DEPRECATED, "Using deprecated function", dec->mQualIdent->mString);
if (cexp)
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here");
}
mFunctions.Push(dec);
Declaration* pdec = dec->mBase->mParams;
@ -652,8 +579,6 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
dec->mFlags |= DTF_ANALYZED;
dec->mFlags |= DTF_FUNC_INTRSAVE;
if (dec->mBase->mBase && dec->mBase->mBase->mType != DT_TYPE_VOID)
dec->mFlags |= DTF_FUNC_NO_RETURN;
if (dec->mFlags & DTF_INTERRUPT)
dec->mFlags |= DTF_FUNC_INTRCALLED;
@ -665,7 +590,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS)
dec->mFlags |= DTF_FUNC_CONSTEXPR;
dec->mFlags |= DTF_FUNC_PURE;
Analyze(exp, dec, 0);
Analyze(exp, dec, false);
Declaration* pdec = dec->mBase->mParams;
int vi = 0;
@ -685,7 +610,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
}
else
{
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent);
if (cexp)
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here");
@ -713,10 +638,7 @@ void GlobalAnalyzer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
else if (adec->mType == DT_VARIABLE_REF)
{
if (adec->mBase->mFlags & DTF_GLOBAL)
{
AnalyzeGlobalVariable(adec->mBase);
adec->mBase->mFlags |= DTF_VAR_ALIASING;
}
}
else if (adec->mType == DT_LABEL)
{
@ -725,10 +647,7 @@ void GlobalAnalyzer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
else if (adec->mType == DT_VARIABLE)
{
if (adec->mFlags & DTF_GLOBAL)
{
AnalyzeGlobalVariable(adec);
adec->mFlags |= DTF_VAR_ALIASING;
}
}
else if (adec->mType == DT_FUNCTION_REF)
{
@ -761,7 +680,7 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
if (dec->mValue)
{
Analyze(dec->mValue, dec, 0);
Analyze(dec->mValue, dec, false);
}
}
}
@ -771,19 +690,17 @@ void GlobalAnalyzer::AnalyzeInit(Declaration* mdec)
while (mdec)
{
if (mdec->mValue)
RegisterProc(Analyze(mdec->mValue, mdec, 0));
RegisterProc(Analyze(mdec->mValue, mdec, false));
else if (mdec->mParams)
AnalyzeInit(mdec->mParams);
mdec = mdec->mNext;
}
}
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs)
{
Declaration* ldec, * rdec;
exp->mFlags = flags;
switch (exp->mType)
{
case EX_ERROR:
@ -801,7 +718,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
}
else if (exp->mDecValue->mType == DT_CONST_POINTER)
{
ldec = Analyze(exp->mDecValue->mValue, procDec, ANAFL_LHS | ANAFL_ALIAS);
ldec = Analyze(exp->mDecValue->mValue, procDec, true);
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
RegisterProc(ldec);
@ -817,22 +734,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
return exp->mDecValue;
case EX_VARIABLE:
if (exp->mDecType->IsSimpleType())
procDec->mComplexity += 5 * exp->mDecType->mSize;
else
procDec->mComplexity += 10;
if (mCompilerOptions & COPT_DEBUGINFO)
exp->mDecValue->mReferences.Push(exp);
if (flags & ANAFL_ALIAS)
{
Declaration* dec = exp->mDecValue;
while (dec->mType == DT_VARIABLE_REF)
dec = dec->mBase;
dec->mFlags |= DTF_VAR_ALIASING;
}
if ((exp->mDecValue->mFlags & DTF_STATIC) || (exp->mDecValue->mFlags & DTF_GLOBAL))
{
Declaration* type = exp->mDecValue->mBase;
@ -842,14 +746,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (!(type->mFlags & DTF_CONST))
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (flags & ANAFL_LHS)
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
AnalyzeGlobalVariable(exp->mDecValue);
}
else
{
if (flags & ANAFL_LHS)
if (lhs)
exp->mDecValue->mFlags |= DTF_VAR_ADDRESS;
if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
@ -861,10 +765,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
return exp->mDecValue;
case EX_INITIALIZATION:
case EX_ASSIGNMENT:
procDec->mComplexity += 5 * exp->mLeft->mDecType->mSize;
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
ldec = Analyze(exp->mLeft, procDec, true);
rdec = Analyze(exp->mRight, procDec, false);
if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
exp->mLeft->mDecValue->mFlags |= DTF_VAR_ALIASING;
RegisterProc(rdec);
@ -873,33 +777,33 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_BINARY:
procDec->mComplexity += 10 * exp->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
rdec = Analyze(exp->mRight, procDec, flags & ~ANAFL_ALIAS);
ldec = Analyze(exp->mLeft, procDec, lhs);
rdec = Analyze(exp->mRight, procDec, lhs);
return ldec;
case EX_RELATIONAL:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
return TheBoolTypeDeclaration;
case EX_PREINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
return Analyze(exp->mLeft, procDec, true);
case EX_PREFIX:
if (exp->mToken == TK_BINARY_AND)
{
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ALIAS);
ldec = Analyze(exp->mLeft, procDec, true);
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
}
else if (exp->mToken == TK_MUL)
{
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (flags & ANAFL_LHS)
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
return exp->mDecType;
@ -908,14 +812,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
{
return TheUnsignedCharTypeDeclaration;
}
else if (exp->mToken == TK_SIZEOF)
{
return TheUnsignedIntTypeDeclaration;
}
else
{
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, 0);
return Analyze(exp->mLeft, procDec, false);
}
break;
case EX_POSTFIX:
@ -924,31 +824,31 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_POSTINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
return Analyze(exp->mLeft, procDec, true);
case EX_INDEX:
procDec->mComplexity += 10 * exp->mRight->mDecType->mSize;
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
ldec = Analyze(exp->mLeft, procDec, lhs);
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
{
ldec = ldec->mBase;
if (ldec->mType == DT_TYPE_POINTER)
{
if (flags & ANAFL_LHS)
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
}
}
rdec = Analyze(exp->mRight, procDec, 0);
rdec = Analyze(exp->mRight, procDec, false);
if (ldec->mBase)
return ldec->mBase;
break;
case EX_QUALIFY:
Analyze(exp->mLeft, procDec, flags);
Analyze(exp->mLeft, procDec, lhs);
return exp->mDecValue->mBase;
case EX_DISPATCH:
procDec->mFlags |= DTF_PREVENT_INLINE;
Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
Analyze(exp->mLeft, procDec, lhs);
// RegisterCall(procDec, exp->mLeft->mDecType);
break;
case EX_VCALL:
@ -959,20 +859,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_INLINE:
procDec->mComplexity += 10;
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
{
}
else
{
if (exp->mType == EX_INLINE)
{
for (int i = 0; i < ldec->mCalled.Size(); i++)
RegisterCall(procDec, ldec->mCalled[i]);
}
else
RegisterCall(procDec, ldec);
RegisterCall(procDec, ldec);
if (!(GetProcFlags(ldec) & (DTF_FUNC_INTRSAVE | DTF_INTERRUPT)))
{
procDec->mFlags &= ~DTF_FUNC_INTRSAVE;
@ -1046,7 +940,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
ldec->mBase->mFlags |= DTF_STACKCALL;
RegisterProc(Analyze(pex, procDec, (pdec && pdec->mBase->IsReference()) ? ANAFL_LHS : 0));
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference()));
if (pdec)
pdec = pdec->mNext;
@ -1060,12 +954,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
break;
case EX_LIST:
case EX_COMMA:
RegisterProc(Analyze(exp->mLeft, procDec, 0));
return Analyze(exp->mRight, procDec, 0);
RegisterProc(Analyze(exp->mLeft, procDec, false));
return Analyze(exp->mRight, procDec, false);
case EX_RETURN:
if (exp->mLeft)
{
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference() ? ANAFL_LHS : 0));
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference()));
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
{
if (procDec->mBase->mBase->mMoveConstructor)
@ -1076,8 +970,6 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
AnalyzeProcedure(exp, procDec->mBase->mBase->mCopyConstructor->mValue, procDec->mBase->mBase->mCopyConstructor);
RegisterCall(procDec, procDec->mBase->mBase->mCopyConstructor);
}
procDec->mFlags &= ~DTF_FUNC_NO_RETURN;
}
break;
case EX_SEQUENCE:
@ -1086,47 +978,47 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (exp->mType == EX_SEQUENCE)
{
if (exp->mLeft)
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
exp = exp->mRight;
}
else
return Analyze(exp, procDec, 0);
return Analyze(exp, procDec, false);
} while (exp);
break;
case EX_SCOPE:
Analyze(exp->mLeft, procDec, 0);
Analyze(exp->mLeft, procDec, false);
break;
case EX_CONSTRUCT:
if (exp->mLeft->mLeft)
Analyze(exp->mLeft->mLeft, procDec, 0);
Analyze(exp->mLeft->mLeft, procDec, false);
if (exp->mLeft->mRight)
Analyze(exp->mLeft->mRight, procDec, 0);
Analyze(exp->mLeft->mRight, procDec, false);
if (exp->mRight)
return Analyze(exp->mRight, procDec, 0);
return Analyze(exp->mRight, procDec, false);
break;
case EX_CLEANUP:
Analyze(exp->mRight, procDec, 0);
return Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
Analyze(exp->mRight, procDec, false);
return Analyze(exp->mLeft, procDec, lhs);
case EX_WHILE:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
break;
case EX_IF:
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight->mLeft, procDec, false);
if (exp->mRight->mRight)
rdec = Analyze(exp->mRight->mRight, procDec, 0);
rdec = Analyze(exp->mRight->mRight, procDec, false);
break;
case EX_ELSE:
break;
@ -1136,23 +1028,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
procDec->mComplexity += 30;
if (exp->mLeft->mRight)
ldec = Analyze(exp->mLeft->mRight, procDec, 0);
ldec = Analyze(exp->mLeft->mRight, procDec, false);
if (exp->mLeft->mLeft->mLeft)
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
break;
case EX_FORBODY:
ldec = Analyze(exp->mLeft, procDec, 0);
if (exp->mRight)
Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false);
break;
case EX_DO:
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
break;
case EX_BREAK:
case EX_CONTINUE:
@ -1161,18 +1048,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_TYPE:
break;
case EX_TYPECAST:
return Analyze(exp->mLeft, procDec, 0);
return Analyze(exp->mLeft, procDec, false);
break;
case EX_LOGICAL_AND:
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
break;
case EX_LOGICAL_OR:
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
break;
case EX_LOGICAL_NOT:
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
break;
case EX_ASSEMBLER:
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
@ -1183,14 +1070,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_UNDEFINED:
break;
case EX_SWITCH:
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false);
exp = exp->mRight;
while (exp)
{
procDec->mComplexity += 10;
if (exp->mLeft->mRight)
rdec = Analyze(exp->mLeft->mRight, procDec, 0);
rdec = Analyze(exp->mLeft->mRight, procDec, false);
exp = exp->mRight;
}
break;
@ -1201,9 +1088,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_CONDITIONAL:
procDec->mComplexity += exp->mDecType->mSize * 10;
ldec = Analyze(exp->mLeft, procDec, 0);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, flags));
RegisterProc(Analyze(exp->mRight->mRight, procDec, flags));
ldec = Analyze(exp->mLeft, procDec, false);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs));
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs));
break;
}

View File

@ -11,7 +11,6 @@ public:
~GlobalAnalyzer(void);
void DumpCallGraph(void);
void TopoSort(Declaration * procDec);
void AutoInline(void);
void CheckFastcall(Declaration* procDec, bool head);
void CheckInterrupt(void);
@ -28,14 +27,12 @@ protected:
Errors* mErrors;
Linker* mLinker;
GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions, mTopoFunctions;
GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions;
GrowingArray<Declaration*> mGlobalVariables;
void AnalyzeInit(Declaration* mdec);
int CallerInvokes(Declaration* called);
int CallerInvokes(Declaration* caller, Declaration* called);
Declaration* Analyze(Expression* exp, Declaration* procDec, uint32 flags);
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs);
bool IsStackParam(const Declaration* pdec) const;
bool MarkCycle(Declaration* rootDec, Declaration* procDec);

View File

@ -60,7 +60,7 @@ void GlobalOptimizer::Reset(void)
mFunctions.SetSize(0);
mGlobalVariables.SetSize(0);
mCalledFunctions.SetSize(0);
mCallingFunctions.SetSize(0);
mCalledFunctions.SetSize(0);
}
void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp)
@ -134,7 +134,7 @@ bool GlobalOptimizer::CheckConstReturns(Expression*& exp)
Expression* lexp = new Expression(exp->mLocation, EX_COMMA);
lexp->mLeft = exp;
lexp->mRight = new Expression(pcall->mReturn->mLocation, EX_CONSTANT);
lexp->mRight->mDecValue = pcall->mReturn->mLeft->mDecValue->ConstCast(exp->mDecType);
lexp->mRight->mDecValue = pcall->mReturn->mLeft->mDecValue;
lexp->mRight->mDecType = exp->mDecType;
lexp->mDecType = exp->mDecType;
exp->mDecType = TheVoidTypeDeclaration;
@ -160,7 +160,6 @@ bool GlobalOptimizer::CheckConstReturns(Expression*& exp)
lexp->mRight->mToken = TK_MUL;
lexp->mRight->mLeft = pex;
lexp->mRight->mDecType = pcall->mBase->mBase;
lexp->mDecType = lexp->mRight->mDecType;
exp->mDecType = TheVoidTypeDeclaration;
exp = lexp;
return true;
@ -189,7 +188,7 @@ bool GlobalOptimizer::CheckUnusedLocals(Expression*& exp)
if (vexp->mType == EX_VARIABLE)
{
Declaration* vdec = vexp->mDecValue;
if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED) && !exp->mRight->IsVolatile())
if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED))
{
exp = exp->mRight;
return true;
@ -243,19 +242,6 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
bool changed = false;
if (exp)
{
if (ReplaceParamConst(exp->mLeft, param))
changed = true;
if (ReplaceParamConst(exp->mRight, param))
changed = true;
if (changed)
{
if (exp->mLeft)
exp->mLeft = exp->mLeft->ConstantFold(mErrors, nullptr);
if (exp->mRight)
exp->mRight = exp->mRight->ConstantFold(mErrors, nullptr);
}
if (exp->mType == EX_VARIABLE && exp->mDecValue == param)
{
exp->mType = EX_CONSTANT;
@ -264,39 +250,9 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
changed = true;
}
}
return changed;
}
bool GlobalOptimizer::ReplaceGlobalConst(Expression* exp)
{
bool changed = false;
if (exp)
{
if (exp->mType == EX_VARIABLE && (exp->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(exp->mDecValue->mOptFlags & (OPTF_VAR_MODIFIED | OPTF_VAR_ADDRESS)) && exp->mDecValue->mValue)
{
Expression* cexp = exp->mDecValue->mValue;
if (cexp->mType == EX_CONSTANT)
{
if (cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT)
{
exp->mType = EX_CONSTANT;
exp->mDecValue = cexp->mDecValue->ConstCast(exp->mDecType);
changed = true;
}
else if (exp->mDecValue->mBase->mType == DT_TYPE_STRUCT)
{
exp->mDecValue->mBase = exp->mDecValue->mBase->ToConstType();
}
}
}
if (ReplaceGlobalConst(exp->mLeft))
if (ReplaceParamConst(exp->mLeft, param))
changed = true;
if (ReplaceGlobalConst(exp->mRight))
if (ReplaceParamConst(exp->mRight, param))
changed = true;
}
return changed;
@ -325,9 +281,6 @@ bool GlobalOptimizer::Optimize(void)
if (CheckConstReturns(func->mValue))
changed = true;
if (ReplaceGlobalConst(func->mValue))
changed = true;
if (func->mOptFlags & OPTF_MULTI_CALL)
{
Declaration* pdata = ftype->mParams;
@ -341,7 +294,7 @@ bool GlobalOptimizer::Optimize(void)
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL))
{
if (!(func->mOptFlags & (OPTF_VAR_USED | OPTF_VAR_ADDRESS)) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
{
#if DUMP_OPTS
printf("Remove return value\n");
@ -359,57 +312,54 @@ bool GlobalOptimizer::Optimize(void)
changed = true;
}
if (!(ftype->mFlags & DTF_VARIADIC))
Declaration* pdec = ftype->mParams;
int vi = 0;
while (pdec)
{
Declaration* pdec = ftype->mParams;
int vi = 0;
while (pdec)
pdec->mVarIndex += vi;
if (!(pdec->mOptFlags & OPTF_VAR_USED) && !(pdec->mFlags & DTF_FPARAM_UNUSED))
{
pdec->mVarIndex += vi;
if (!(pdec->mOptFlags & OPTF_VAR_USED) && !(pdec->mFlags & DTF_FPARAM_UNUSED))
{
if (!pdec->mBase->IsReference() || !(pdec->mOptFlags & OPTF_VAR_ADDRESS))
{
#if DUMP_OPTS
printf("Unused parameter %s\n", pdec->mIdent ? pdec->mIdent->mString : "_");
#endif
vi -= pdec->mSize;
pdec->mFlags |= DTF_FPARAM_UNUSED;
pdec->mVarIndex = func->mNumVars++;
changed = true;
}
}
else if (!(pdec->mOptFlags & OPTF_VAR_ADDRESS) && pdec->mBase->IsReference() && pdec->mBase->mBase->IsSimpleType())
if (!pdec->mBase->IsReference() || !(pdec->mOptFlags & OPTF_VAR_ADDRESS))
{
#if DUMP_OPTS
printf("Reference parameter %s to value\n", pdec->mIdent ? pdec->mIdent->mString : "_");
printf("Unused parameter %s\n", pdec->mIdent ? pdec->mIdent->mString : "_");
#endif
vi += pdec->mSize - 2;
vi -= pdec->mSize;
pdec->mBase = pdec->mBase->mBase;
pdec->mSize = pdec->mBase->mSize;
UndoParamReference(func->mValue, pdec);
pdec->mFlags |= DTF_FPARAM_UNUSED;
pdec->mVarIndex = func->mNumVars++;
changed = true;
}
else if ((pdec->mOptFlags & OPTF_VAR_CONST) && !(pdec->mOptFlags & OPTF_VAR_ADDRESS))
{
if (ReplaceParamConst(func->mValue, pdec))
{
func->mValue = func->mValue->ConstantFold(mErrors, nullptr);
#if DUMP_OPTS
printf("Const parameter %s\n", pdec->mIdent ? pdec->mIdent->mString : "_");
#endif
changed = true;
}
}
pdec->mOptFlags = 0;
pdec = pdec->mNext;
}
else if (!(pdec->mOptFlags & OPTF_VAR_ADDRESS) && pdec->mBase->IsReference() && pdec->mBase->mBase->IsSimpleType())
{
#if DUMP_OPTS
printf("Reference parameter %s to value\n", pdec->mIdent ? pdec->mIdent->mString : "_");
#endif
vi += pdec->mSize - 2;
pdec->mBase = pdec->mBase->mBase;
pdec->mSize = pdec->mBase->mSize;
UndoParamReference(func->mValue, pdec);
changed = true;
}
else if ((pdec->mOptFlags & OPTF_VAR_CONST) && !(pdec->mOptFlags & OPTF_VAR_ADDRESS))
{
if (ReplaceParamConst(func->mValue, pdec))
{
#if DUMP_OPTS
printf("Const parameter %s\n", pdec->mIdent ? pdec->mIdent->mString : "_");
#endif
changed = true;
}
}
pdec->mOptFlags = 0;
pdec = pdec->mNext;
}
}
@ -462,7 +412,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec)
Analyze(exp, procDec, false);
}
else
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->FullIdent());
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->mQualIdent);
procDec->mOptFlags &= ~OPTF_ANALYZING;
}
@ -483,7 +433,8 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
{
if (adec->mBase->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec->mBase);
adec->mBase->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
else
adec->mBase->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
}
else if (adec->mType == DT_LABEL)
{
@ -493,7 +444,8 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
{
if (adec->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec);
adec->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
else
adec->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
}
else if (adec->mType == DT_ARGUMENT)
{
@ -614,6 +566,9 @@ void GlobalOptimizer::RegisterProc(Declaration* to)
}
}
static const uint32 ANAFL_LHS = (1U << 0);
static const uint32 ANAFL_RHS = (1U << 1);
Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
{
Declaration* ldec, * rdec;
@ -655,14 +610,14 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
AnalyzeGlobalVariable(exp->mDecValue);
}
if (flags & ANAFL_RHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
if (flags & ANAFL_LHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
if (exp->mDecValue->mBase->IsReference() && (flags & ANAFL_ASSIGN))
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
if (exp->mDecValue->mType == DT_ARGUMENT && (flags & ANAFL_LHS))
else
{
if (flags & ANAFL_RHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
if (flags & ANAFL_LHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
}
if (exp->mDecValue->mType == DT_ARGUMENT)
{
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
exp->mDecValue->mForwardParam = nullptr;
@ -672,12 +627,7 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_INITIALIZATION:
case EX_ASSIGNMENT:
if (exp->mToken == TK_ASSIGN)
{
if (exp->mType == EX_ASSIGNMENT)
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ASSIGN | flags);
else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
}
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags);
@ -825,22 +775,6 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
pdec->mOptFlags |= OPTF_VAR_CONST;
}
}
else if (pex->mType == EX_VARIABLE && pdec->mBase->mType == DT_TYPE_POINTER && pex->mDecType->mType == DT_TYPE_ARRAY && (pex->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && pdec->mBase->CanAssign(pex->mDecType))
{
if (pdec->mOptFlags & OPTF_VAR_CONST)
{
if (pdec->mValue->mType != EX_VARIABLE || pdec->mValue->mDecValue != pex->mDecValue)
{
pdec->mOptFlags |= OPTF_VAR_NOCONST;
pdec->mOptFlags &= ~OPTF_VAR_CONST;
}
}
else
{
pdec->mValue = pex;
pdec->mOptFlags |= OPTF_VAR_CONST;
}
}
else
{
pdec->mOptFlags |= OPTF_VAR_NOCONST;
@ -986,20 +920,13 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
break;
case EX_FORBODY:
ldec = Analyze(exp->mLeft, procDec, 0);
if (exp->mRight)
rdec = Analyze(exp->mRight, procDec, 0);
break;
case EX_DO:
ldec = Analyze(exp->mRight, procDec, 0);
rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
break;
case EX_BREAK:
case EX_CONTINUE:
break;
case EX_ASSUME:
return Analyze(exp->mLeft, procDec, ANAFL_RHS);
break;
case EX_TYPE:
break;

View File

@ -39,6 +39,5 @@ protected:
bool ReplaceParamConst(Expression* exp, Declaration* param);
void PropagateCommas(Expression*& exp);
void PropagateParamCommas(Expression *& fexp, Expression*& exp);
bool ReplaceGlobalConst(Expression* exp);
};

View File

@ -47,7 +47,7 @@ const Ident* Ident::Unique(const char* str)
const Ident* Ident::PreMangle(const char* str) const
{
char buffer[1000];
char buffer[200];
strcpy_s(buffer, str);
strcat_s(buffer, mString);
return Unique(buffer);
@ -55,14 +55,14 @@ const Ident* Ident::PreMangle(const char* str) const
const Ident* Ident::Unique(const char* str, int id)
{
char buffer[1000];
char buffer[200];
sprintf_s(buffer, "%s#%d", str, id);
return Unique(buffer);
}
const Ident* Ident::Mangle(const char* str) const
{
char buffer[1000];
char buffer[200];
strcpy_s(buffer, mString);
strcat_s(buffer, str);
return Unique(buffer);

Some files were not shown because too many files have changed in this diff Show More