Compare commits

..

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

155 changed files with 14002 additions and 43632 deletions

3
.gitignore vendored
View File

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

View File

@ -334,6 +334,7 @@ void test_add_word_cross(void)
} }
int main(void) int main(void)
{ {
test_char_fit(); test_char_fit();
test_char_cross(); test_char_cross();
test_word_fit(); 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(shl32n)
#pragma native(shr32n) #pragma native(shr32n)
@ -385,30 +373,24 @@ int main(void)
shr16n(0xfedc, 0xfedc); shr16n(0xfedc, 0xfedc);
shl32b(0x00000000UL, 0x00000000L); shl32b(0x00000000UL, 0x00000000L);
shl32b(0x00000001UL, 0x00000001L);
shl32b(0xffffffffUL, 0xffffffffL); shl32b(0xffffffffUL, 0xffffffffL);
shl32b(0x12345678UL, 0x12345678L); shl32b(0x12345678UL, 0x12345678L);
shl32b(0xfedcba98UL, 0xfedcba98L); shl32b(0xfedcba98UL, 0xfedcba98L);
shr32b(0x00000000UL, 0x00000000L); shr32b(0x00000000UL, 0x00000000L);
shr32b(0x00000001UL, 0x00000001L);
shr32b(0xffffffffUL, 0xffffffffL); shr32b(0xffffffffUL, 0xffffffffL);
shr32b(0x12345678UL, 0x12345678L); shr32b(0x12345678UL, 0x12345678L);
shr32b(0xfedcba98UL, 0xfedcba98L); shr32b(0xfedcba98UL, 0xfedcba98L);
shl32n(0x00000000UL, 0x00000000L); shl32n(0x00000000UL, 0x00000000L);
shl32n(0x00000001UL, 0x00000001L);
shl32n(0xffffffffUL, 0xffffffffL); shl32n(0xffffffffUL, 0xffffffffL);
shl32n(0x12345678UL, 0x12345678L); shl32n(0x12345678UL, 0x12345678L);
shl32n(0xfedcba98UL, 0xfedcba98L); shl32n(0xfedcba98UL, 0xfedcba98L);
shr32n(0x00000000UL, 0x00000000L); shr32n(0x00000000UL, 0x00000000L);
shr32n(0x00000001UL, 0x00000001L);
shr32n(0xffffffffUL, 0xffffffffL); shr32n(0xffffffffUL, 0xffffffffL);
shr32n(0x12345678UL, 0x12345678L); shr32n(0x12345678UL, 0x12345678L);
shr32n(0xfedcba98UL, 0xfedcba98L); shr32n(0xfedcba98UL, 0xfedcba98L);
shl1_32n();
return 0; return 0;
} }

View File

@ -1,5 +1,4 @@
#include <assert.h> #include <assert.h>
#include <stdio.h>
int t, n; int t, n;
@ -162,7 +161,7 @@ void test_return_value(void)
C2 c(test_ret_v()); C2 c(test_ret_v());
} }
assert(n == 6 && t == 0); assert(n == 4 && t == 0);
} }
void test_return_reference(void) void test_return_reference(void)
@ -185,7 +184,7 @@ void test_retparam_value(void)
test_param_fv(test_ret_v()); test_param_fv(test_ret_v());
} }
assert(n == 6 && t == 0); assert(n == 4 && t == 0);
} }
void test_retparam_reference(void) void test_retparam_reference(void)
@ -201,6 +200,7 @@ void test_retparam_reference(void)
int main(void) int main(void)
{ {
#if 0
test_dcopy_init(); test_dcopy_init();
test_copy_init(); test_copy_init();
test_minit(); test_minit();
@ -208,8 +208,9 @@ int main(void)
test_param_value(); test_param_value();
test_param_ref(); test_param_ref();
test_return_value(); test_return_value();
#endif
test_retparam_value(); test_retparam_value();
test_retparam_reference(); // test_retparam_reference();
return 0; 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)) SRCS=$(filter-out opp_part1.cpp opp_part2.cpp, $(wildcard *.c *.cpp))
EXES=$(patsubst %.c,%,$(SRCS)) EXES=$(patsubst %.c,%,$(SRCS))
EXES:=$(patsubst %.cpp,%,$(EXES)) EXES:=$(patsubst %.cpp,%,$(EXES))
@ -5,56 +7,44 @@ EXES:=$(patsubst %.cpp,%,$(EXES))
all: $(EXES) all: $(EXES)
%: %.c %: %.c
$(OSCAR64_CC) -e -bc $< $(CC) -e -bc $<
$(OSCAR64_CC) -e -n $< $(CC) -e -n $<
$(OSCAR64_CC) -e -O2 -bc $< $(CC) -e -O2 -bc $<
$(OSCAR64_CC) -e -O2 -n $< $(CC) -e -O2 -n $<
$(OSCAR64_CC) -e -O0 -bc $< $(CC) -e -O0 -bc $<
$(OSCAR64_CC) -e -O0 -n $< $(CC) -e -O0 -n $<
$(OSCAR64_CC) -e -Os -bc $< $(CC) -e -Os -bc $<
$(OSCAR64_CC) -e -Os -n $< $(CC) -e -Os -n $<
$(OSCAR64_CC) -e -O3 -bc $< $(CC) -e -O3 -bc $<
$(OSCAR64_CC) -e -O3 -n $< $(CC) -e -O3 -n $<
%: %.cpp %: %.cpp
$(OSCAR64_CXX) -e -bc $< $(CXX) -e -bc $<
$(OSCAR64_CXX) -e -n $< $(CXX) -e -n $<
$(OSCAR64_CXX) -e -O2 -bc $< $(CXX) -e -O2 -bc $<
$(OSCAR64_CXX) -e -O2 -n $< $(CXX) -e -O2 -n $<
$(OSCAR64_CXX) -e -O0 -bc $< $(CXX) -e -O0 -bc $<
$(OSCAR64_CXX) -e -O0 -n $< $(CXX) -e -O0 -n $<
$(OSCAR64_CXX) -e -Os -bc $< $(CXX) -e -Os -bc $<
$(OSCAR64_CXX) -e -Os -n $< $(CXX) -e -Os -n $<
$(OSCAR64_CXX) -e -O3 -bc $< $(CXX) -e -O3 -bc $<
$(OSCAR64_CXX) -e -O3 -n $< $(CXX) -e -O3 -n $<
# testb # testb
bitshifttest: bitshifttest.c bitshifttest: bitshifttest.c
$(OSCAR64_CC) -e -bc $< $(CC) -e -bc $<
$(OSCAR64_CC) -e -bc -O2 $< $(CC) -e -bc -O2 $<
$(OSCAR64_CC) -e -bc -O0 $< $(CC) -e -bc -O0 $<
$(OSCAR64_CC) -e -bc -Os $< $(CC) -e -bc -Os $<
$(OSCAR64_CC) -e -bc -O3 $< $(CC) -e -bc -O3 $<
$(OSCAR64_CC) -e -n $< $(CC) -e -n $<
# testn # testn
stripedarraytest: stripedarraytest.c stripedarraytest: stripedarraytest.c
$(OSCAR64_CC) -e -O2 -n $< $(CC) -e -O2 -n $<
$(OSCAR64_CC) -e -O0 -n $< $(CC) -e -O0 -n $<
$(OSCAR64_CC) -e -Os -n $< $(CC) -e -Os -n $<
$(OSCAR64_CC) -e -O3 -n $< $(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 $<
clean: 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 << i << ", ";
opp::cout << "\n"; 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; 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); 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) void testdivi(long a, long b, long ab)
{ {
assert (a / b == ab); assert (a / b == ab);
@ -85,26 +80,6 @@ int main(void)
testmuli( -1024, 1237, -1266688l); testmuli( -1024, 1237, -1266688l);
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); 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) bool beqz(long a)
{ {
return a == 0; return a == 0;
@ -215,71 +188,7 @@ bool nge1(long a)
bool beqm(long a) void cmp(long a, long b)
{
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)
{ {
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, 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); 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); 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) void cmpz(long a)
{ {
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(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); 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) int main(void)
{ {
cmp( 0, 1); cmp( 0, 1);
@ -454,10 +327,6 @@ int main(void)
cmp1(256); cmp1(256);
cmp1(10000); cmp1(10000);
cmp1(20000); cmp1(20000);
cmp1(1000000l);
cmp1(2000000l);
cmp1(100000000l);
cmp1(200000000l);
cmp1(-1); cmp1(-1);
cmp1(-2); cmp1(-2);
cmp1(-3); cmp1(-3);
@ -465,34 +334,6 @@ int main(void)
cmp1(-256); cmp1(-256);
cmp1(-10000); cmp1(-10000);
cmp1(-20000); 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; 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 SIDFX_WAIT
}; };
__striped static struct SIDFXChannel static struct SIDFXChannel
{ {
const SIDFX * volatile com; const SIDFX * com;
byte delay, priority; byte delay, cnt, priority;
volatile byte cnt; volatile SIDFXState state;
volatile SIDFXState state; unsigned freq, pwm;
unsigned freq, pwm;
} channels[3]; } channels[3];
@ -27,20 +26,9 @@ void sidfx_init(void)
channels[i].com = nullptr; channels[i].com = nullptr;
channels[i].state = SIDFX_IDLE; channels[i].state = SIDFX_IDLE;
channels[i].priority = 0; 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) void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
{ {
SIDFXState ns = channels[chn].state; SIDFXState ns = channels[chn].state;
@ -53,7 +41,6 @@ void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
return; return;
channels[chn].state = SIDFX_IDLE; channels[chn].state = SIDFX_IDLE;
channels[chn].delay = 1;
channels[chn].com = fx; channels[chn].com = fx;
channels[chn].cnt = cnt - 1; channels[chn].cnt = cnt - 1;
@ -66,126 +53,103 @@ void sidfx_stop(byte chn)
{ {
channels[chn].com = nullptr; channels[chn].com = nullptr;
if (channels[chn].state != SIDFX_IDLE) if (channels[chn].state != SIDFX_IDLE)
{
channels[chn].state = SIDFX_RESET_0; channels[chn].state = SIDFX_RESET_0;
channels[chn].delay = 1;
}
} }
inline void sidfx_loop_ch(byte ch) inline void sidfx_loop_ch(byte ch)
{ {
if (channels[ch].state) switch (channels[ch].state)
{ {
const SIDFX * com = channels[ch].com; case SIDFX_IDLE:
break;
channels[ch].delay--; case SIDFX_RESET_0:
if (channels[ch].delay) sid.voices[ch].ctrl = 0;
{ sid.voices[ch].attdec = 0;
if (com->dfreq) 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; 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; sid.voices[ch].pwm = channels[ch].pwm;
} }
}
while (!channels[ch].delay) if (channels[ch].delay)
{ channels[ch].delay--;
switch (channels[ch].state) else if (channels[ch].com->time0)
{ {
case SIDFX_IDLE: sid.voices[ch].ctrl = channels[ch].com->ctrl & ~SID_CTRL_GATE;
channels[ch].delay = 1; channels[ch].delay = channels[ch].com->time0;
break; channels[ch].state = SIDFX_WAIT;
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;
} }
} 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); void sidfx_init(void);
inline bool sidfx_idle(byte chn);
inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt); inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
void sidfx_stop(byte chn); void sidfx_stop(byte chn);
char sidfx_cnt(byte chn);
void sidfx_loop(void); void sidfx_loop(void);
void sidfx_loop_2(void); void sidfx_loop_2(void);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#ifndef C64_KERNALIO_H #ifndef C64_KERNALIO_H
#define C64_KERNALIO_H #ifndef C64_KERNALIO_H
// Error and status codes returned by krnio_status // 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 // 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 // read a single byte from the given file/channel, returns
// a negative result on failure. If this was the last byte // a negative result on failure. If this was the last byte

View File

@ -5,16 +5,16 @@
#include <c64/asm6502.h> #include <c64/asm6502.h>
#include <stdlib.h> #include <stdlib.h>
volatile char npos = 1, tpos = 0;
volatile byte rirq_count; volatile byte rirq_count;
static byte rirq_pcount;
byte rasterIRQRows[NUM_IRQS + 1]; byte rasterIRQRows[NUM_IRQS + 1];
byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one byte rasterIRQIndex[NUM_IRQS + 1];
#ifdef ZPAGE_IRQS #ifdef ZPAGE_IRQS
__zeropage __zeropage
#endif #endif
byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff byte rasterIRQNext[NUM_IRQS + 1];
byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code byte rasterIRQLow[NUM_IRQS];
byte rasterIRQHigh[NUM_IRQS]; byte rasterIRQHigh[NUM_IRQS];
#ifdef ZPAGE_IRQS #ifdef ZPAGE_IRQS
@ -22,87 +22,28 @@ __zeropage
#endif #endif
byte nextIRQ; byte nextIRQ;
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled __asm irq0
__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
{ {
pha pha
txa txa
pha pha
tya tya
pha pha
kentry:
asl $d019
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y tax
stx ji + 1 lda rasterIRQLow, y
ldx rasterIRQHigh, y sta ji + 1
stx ji + 2 lda rasterIRQHigh, y
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -110,20 +51,20 @@ ji:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
ldy rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
asl $d019
cpy #$ff
beq e2 beq e2
// carry is cleared at this point
tay
dey dey
sbc #2
cmp $d012
bcc l1
sty $d012 sty $d012
dey
cpy $d012
bcc l1
exd: ex:
pla pla
tay tay
pla pla
@ -131,44 +72,56 @@ exd:
pla pla
rti rti
exi:
asl $d019
jmp exd
e2: e2:
ldx npos
stx tpos
inc rirq_count inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext ldy rasterIRQNext
dey dey
sty $d012 sty $d012
ldx #0 jmp ex
stx nextIRQ
beq exd
} }
__asm rirq_isr_noio __asm irq2
{ {
pha pha
txa txa
pha pha
tya tya
pha pha
kentry:
lda $01 lda $01
pha pha
lda #$35 lda #$35
sta $01 sta $01
asl $d019
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y tax
stx ji + 1 lda rasterIRQLow, y
ldx rasterIRQHigh, y sta ji + 1
stx ji + 2 lda rasterIRQHigh, y
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -176,20 +129,21 @@ ji:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
ldy rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
asl $d019
cpy #$ff
beq e2 beq e2
// carry is cleared at this point
tay
dey dey
sbc #2
cmp $d012
bcc l1
sty $d012 sty $d012
dey
cpy $d012
bcc l1
exd: ex:
pla pla
sta $01 sta $01
@ -200,35 +154,45 @@ exd:
pla pla
rti rti
exi:
asl $d019
jmp exd
e2: e2:
ldx npos
stx tpos
inc rirq_count inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext ldy rasterIRQNext
dey dey
sty $d012 sty $d012
ldx #0 jmp ex
stx nextIRQ
beq exd
} }
__asm rirq_isr_kernal_io __asm irq1
{ {
lda $d019 lda $d019
bpl ex2 bpl ex2
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y tax
stx ji + 1 lda rasterIRQLow, y
ldx rasterIRQHigh, y sta ji + 1
stx ji + 2 lda rasterIRQHigh, y
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -237,111 +201,50 @@ jx:
inc nextIRQ inc nextIRQ
ldx 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 lda rasterIRQNext, x
ldy rasterIRQIndex + 1, x cmp #$ff
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
beq e2 beq e2
dey tay
sec
sbc #4
cmp $d012
bcc l1
dey dey
sty $d012 sty $d012
dey w1:
cpy $d012 jmp ex
bcc l1
exd:
pla
sta $01
jmp $ea81
exi:
asl $d019
jmp exd
e2: e2:
ldx npos
stx tpos
inc rirq_count inc rirq_count
ldy rasterIRQNext bit $d011
dey bmi e1
dey
sty $d012 sta $d012
jmp ex
e1:
ldx #0 ldx #0
stx nextIRQ stx nextIRQ
beq exd lda rasterIRQNext, x
sec
sbc #1
sta $d012
ex:
asl $d019
jmp $ea81
ex2: ex2:
LDA $DC0D LDA $DC0D
cli cli
pla
sta $01
jmp $ea31 jmp $ea31
} }
@ -365,8 +268,8 @@ void rirq_build(RIRQCode * ic, byte size)
ic->size = size; ic->size = size;
asm_im(ic->code + 0, ASM_LDY, 0); asm_im(ic->code + 0, ASM_LDY, 0);
asm_im(ic->code + 2, ASM_LDX, 0); asm_im(ic->code + 2, ASM_LDA, 0);
asm_ab(ic->code + 4, ASM_CMP, 0xd012); asm_ab(ic->code + 4, ASM_CPX, 0xd012);
asm_rl(ic->code + 7, ASM_BCS, -5); asm_rl(ic->code + 7, ASM_BCS, -5);
asm_ab(ic->code + 9, ASM_STY, 0x0000); asm_ab(ic->code + 9, ASM_STY, 0x0000);
@ -380,7 +283,7 @@ void rirq_build(RIRQCode * ic, byte size)
} }
else else
{ {
asm_ab(ic->code + 12, ASM_STX, 0x0000); asm_ab(ic->code + 12, ASM_STA, 0x0000);
byte p = 15; byte p = 15;
for(byte i=2; i<size; i++) 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) void rirq_data(RIRQCode * ic, byte n, byte data)
{ {
byte p = irqdi[n]; byte p = irqdi[n];
// ic->code[p] = data; ic->code[p] = data;
(volatile char *)(ic->code)[p] = data;
} }
void rirq_write(RIRQCode * ic, byte n, void * addr, byte data) void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
@ -500,60 +402,7 @@ void rirq_init_kernal(void)
sei sei
} }
*(void **)0x0314 = rirq_isr_kernal_io; *(void **)0x0314 = irq1;
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;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -570,7 +419,7 @@ void rirq_init_io(void)
sei sei
} }
*(void **)0xfffe = rirq_isr_ram_io; *(void **)0xfffe = irq0;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -587,7 +436,7 @@ void rirq_init_memmap(void)
sei sei
} }
*(void **)0xfffe = rirq_isr_noio; *(void **)0xfffe = irq2;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -605,18 +454,12 @@ void rirq_init(bool kernalIRQ)
void rirq_wait(void) void rirq_wait(void)
{ {
char i0 = rirq_pcount; while (tpos != npos) ;
char i1; npos++;
do {
i1 = rirq_count;
} while (i0 == i1);
rirq_pcount = i1;
} }
void rirq_sort(bool inirq) void rirq_sort(void)
{ {
// disable raster interrupts while sorting
nextIRQ = 0xff;
#if 1 #if 1
byte maxr = rasterIRQRows[rasterIRQIndex[1]]; byte maxr = rasterIRQRows[rasterIRQIndex[1]];
for(byte i = 2; i<NUM_IRQS + 1; i++) for(byte i = 2; i<NUM_IRQS + 1; i++)
@ -651,31 +494,13 @@ void rirq_sort(bool inirq)
rasterIRQIndex[j] = ri; rasterIRQIndex[j] = ri;
} }
#endif #endif
#if NUM_IRQS & 3
for(sbyte i=NUM_IRQS-1; i>=0; i--) for(sbyte i=NUM_IRQS-1; i>=0; i--)
rasterIRQNext[i] = rasterIRQRows[rasterIRQIndex[i + 1]]; 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; npos++;
if (inirq) byte yp = rasterIRQNext[nextIRQ];
nextIRQ = NUM_IRQS - 1; if (yp != 0xff)
else vic.raster = yp - 1;
{
byte yp = rasterIRQNext[0];
if (yp != 0xff)
{
vic.raster = yp - 1;
nextIRQ = 0;
}
}
} }
void rirq_start(void) void rirq_start(void)
@ -689,7 +514,6 @@ void rirq_start(void)
lda #100 lda #100
sta $d012 sta $d012
asl $d019
cli 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 // Add a delay of 5 * cycles to a raster IRQ
inline void rirq_delay(RIRQCode * ic, byte cycles); inline void rirq_delay(RIRQCode * ic, byte cycles);
// Place a raster IRQ into one of the 16 slots, the interrupt will fire // Place a raster IRQ into one of the 16 slots
// one line below the given row
inline void rirq_set(byte n, byte row, RIRQCode * write); inline void rirq_set(byte n, byte row, RIRQCode * write);
// Remove a raster IRQ from one of the 16 slots // 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) // the less resource hungry option)
inline void rirq_init(bool kernalIRQ); inline void rirq_init(bool kernalIRQ);
// Raster IRQ through kernal, with IO range always enabled
// calls kernal continuation
void rirq_init_kernal(void); 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); 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); void rirq_init_memmap(void);
// Start raster IRQ // Start raster IRQ
@ -179,9 +160,8 @@ void rirq_start(void);
void rirq_stop(void); void rirq_stop(void);
// Sort the raster IRQ, must be performed at the end of the frame after changing // Sort the raster IRQ, must be performed at the end of the frame after changing
// the vertical position of one of the interrupt operations. // the vertical position of one of the interrupt operatins.
// Set the inirq flag to true when calling this from an interrupt void rirq_sort(void);
void rirq_sort(bool inirq = false);
// Wait for the last raster IRQ op to have completed. Must be called before a // Wait for the last raster IRQ op to have completed. Must be called before a
// sort if the raster IRQ system is active // sort if the raster IRQ system is active

View File

@ -3,9 +3,6 @@
static volatile char * vspriteScreen; static volatile char * vspriteScreen;
#ifdef VSPRITE_BSS
#pragma bss(VSPRITE_BSS)
#endif
void spr_init(char * screen) void spr_init(char * screen)
{ {
@ -146,11 +143,7 @@ void vspr_init(char * screen)
for(int i=0; i<VSPRITES_MAX - 8; i++) for(int i=0; i<VSPRITES_MAX - 8; i++)
{ {
#ifdef VSPRITE_REVERSE
int j = (i & 7) ^ 7;
#else
int j = i & 7; int j = i & 7;
#endif
rirq_build(spirq + i, 5); rirq_build(spirq + i, 5);
rirq_write(spirq + i, 0, &vic.spr_color[j], 0); rirq_write(spirq + i, 0, &vic.spr_color[j], 0);
@ -171,12 +164,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) void vspr_screen(char * screen)
{ {
vspriteScreen = screen + 0x3f8; vspriteScreen = screen + 0x3f8;
@ -214,21 +201,6 @@ void vspr_move(char sp, int xpos, int ypos)
vspriteXHigh[sp] = (char)(xpos >> 8); 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) void vspr_image(char sp, char image)
{ {
vspriteImage[sp] = image; vspriteImage[sp] = image;
@ -279,30 +251,19 @@ void vspr_update(void)
{ {
char xymask = 0; char xymask = 0;
volatile char * vsprs = vspriteScreen; volatile char * vsprs = vspriteScreen;
// char sypos[VSPRITES_MAX]; char sypos[VSPRITES_MAX];
#pragma unroll(full) #pragma unroll(full)
for(char ui=0; ui<8; ui++) for(char ui=0; ui<8; ui++)
{ {
byte ri = spriteOrder[ui]; byte ri = spriteOrder[ui];
#ifdef VSPRITE_REVERSE
char uj = ui ^ 7;
#else
char uj = ui;
#endif
vic.spr_color[uj] = vspriteColor[ri]; vic.spr_color[ui] = vspriteColor[ri];
vsprs[uj] = vspriteImage[ri]; vsprs[ui] = vspriteImage[ri];
#ifdef VSPRITE_REVERSE
xymask = (xymask << 1) | (vspriteXHigh[ri] & 1);
#else
xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1; xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1;
#endif vic.spr_pos[ui].x = vspriteXLow[ri];
vic.spr_pos[uj].x = vspriteXLow[ri]; vic.spr_pos[ui].y = vspriteYLow[ri];
vic.spr_pos[uj].y = spriteYPos[ui + 1]; sypos[ui] = vspriteYLow[ri];
// sypos[ui] = vspriteYLow[ri];
} }
vic.spr_msbx = xymask; vic.spr_msbx = xymask;
@ -312,28 +273,23 @@ void vspr_update(void)
for(char ti=0; ti<VSPRITES_MAX - 8; ti++) 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
char m = 1 << (ti & 7); char m = 1 << (ti & 7);
#endif
xymask |= m; xymask |= m;
if (!(vspriteXHigh[ri] & 1)) if (!(vspriteXHigh[ri] & 1))
xymask ^= m; 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, 0, vspriteColor[ri]);
rirq_data(spirq + ti, 1, vspriteXLow[ri]); rirq_data(spirq + ti, 1, vspriteXLow[ri]);
rirq_data(spirq + ti, 3, vspriteImage[ri]); rirq_data(spirq + ti, 3, vspriteImage[ri]);
rirq_data(spirq + ti, 4, xymask); rirq_data(spirq + ti, 4, xymask);
// spriteYPos[ti + 9] = vspriteYLow[ri]; rirq_move(ti, sypos[ti] + 23);
sypos[ti + 8] = vspriteYLow[ri];
} }
else else
{ {

View File

@ -68,8 +68,6 @@ inline void spr_expand(char sp, bool xexpand, bool yexpand);
void vspr_init(char * screen); void vspr_init(char * screen);
void vspr_shutdown(void);
void vspr_screen(char * screen); void vspr_screen(char * screen);
// set one sprite with the given attribute // 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_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 // change the image of a virtual sprite
inline void vspr_image(char sp, char image); 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) #pragma native(vic_waitLine)

View File

@ -118,9 +118,6 @@ void vic_waitLine(int line);
// wait for beam to be below a line // wait for beam to be below a line
void vic_waitBelow(int 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 // reference to the VIC chip
#define vic (*((struct VIC *)0xd000)) #define vic (*((struct VIC *)0xd000))

View File

@ -18,13 +18,6 @@ __asm bsin
jsr 0xffe4 jsr 0xffe4
sta 0xff01 sta 0xff01
} }
__asm bsget
{
lda #0
sta 0xff00
jsr 0xffcf
sta 0xff01
}
__asm bsplot __asm bsplot
{ {
lda #0 lda #0
@ -50,7 +43,6 @@ __asm dswap
#define dswap 0xff5f #define dswap 0xff5f
#define bsout 0xffd2 #define bsout 0xffd2
#define bsin 0xffe4 #define bsin 0xffe4
#define bsget 0xffcf
#define bsplot 0xfff0 #define bsplot 0xfff0
#define bsinit 0xff81 #define bsinit 0xff81
#elif defined(__PLUS4__) #elif defined(__PLUS4__)
@ -67,12 +59,6 @@ __asm bsin
jsr 0xffe4 jsr 0xffe4
sta 0xff3f sta 0xff3f
} }
__asm bsget
{
sta 0xff3e
jsr 0xffcf
sta 0xff3f
}
__asm bsplot __asm bsplot
{ {
sta 0xff3e sta 0xff3e
@ -105,14 +91,6 @@ __asm bsin
pha pha
} }
__asm bsget
{
lda 0xe405
pha
lda 0xe404
pha
}
__asm bsplot __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 #else
#define bsout 0xffd2 #define bsout 0xffd2
#define bsin 0xffe4 #define bsin 0xffe4
#define bsplot 0xfff0 #define bsplot 0xfff0
#define bsinit 0xff81 #define bsinit 0xff81
#define bsget 0xffcf
#endif #endif
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__) #if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
@ -181,246 +136,204 @@ void iocharmap(IOCharMap chmap)
giocharmap = chmap; giocharmap = chmap;
#if !defined(__ATARI__) #if !defined(__ATARI__)
if (chmap == IOCHM_PETSCII_1) if (chmap == IOCHM_PETSCII_1)
putrch(128 + 14); putch(128 + 14);
else if (chmap == IOCHM_PETSCII_2) else if (chmap == IOCHM_PETSCII_2)
putrch(14); putch(14);
#endif #endif
} }
void putrch(char c) __asm putpch
{ {
__asm { ldx giocharmap
lda c cpx #IOCHM_ASCII
jsr bsout 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 defined(__CBMPET__)
if (c >= 97) cmp #97
c ^= 0xa0; bcs w4
c ^= 0x20; cmp #91
bcs w3
w2:
eor #$a0
w4:
eor #$20
#else #else
c ^= 0x20; cmp #97
#endif bcs w2
cmp #91
if (giocharmap == IOCHM_PETSCII_1) bcs w3
c &= 0xdf; w2:
} eor #$20
}
}
}
#endif #endif
cpx #IOCHM_PETSCII_2
putrch(c); beq w3
and #$df
w3:
jmp bsout
} }
static char convch(char ch) __asm getpch
{ {
#if !defined(__ATARI__) jsr bsin
if (giocharmap >= IOCHM_ASCII) ldx giocharmap
{ cpx #IOCHM_ASCII
if (ch == 13) bcc w3
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;
}
}
}
#endif cmp #13
return ch; bne w1
} lda #10
w1:
cpx #IOCHM_PETSCII_1
bcc w3
char getrch(void) cmp #219
{ bcs w3
return __asm { cmp #65
jsr bsget bcc w3
sta accu
};
}
char getpch(void) cmp #193
{ bcc w4
return convch(getrch()); eor #$a0
w4:
cmp #123
bcs w3
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
w3:
} }
char kbhit(void) int kbhit(void)
{ {
#if defined(__CBMPET__) __asm
return __asm
{
lda $9e
sta accu
};
#else
return __asm
{ {
lda $c6 lda $c6
sta accu sta accu
}; lda #0
#endif sta accu + 1
}
} }
char getche(void) int getche(void)
{ {
char ch; __asm
do { {
ch = __asm { L1:
jsr bsin jsr getpch
sta accu cmp #0
}; beq L1
} while (!ch);
__asm { sta accu
lda ch jsr putpch
jsr bsout lda #0
sta accu + 1
} }
return convch(ch);
} }
char getch(void) int getch(void)
{ {
char ch; __asm
do { {
ch = __asm { L1:
jsr bsin jsr getpch
sta accu cmp #0
}; beq L1
} while (!ch);
return convch(ch); sta accu
lda #0
sta accu + 1
}
} }
char getchx(void) int getchx(void)
{ {
char ch = __asm { __asm
jsr bsin {
sta accu jsr getpch
}; sta accu
lda #0
return convch(ch); sta accu + 1
}
} }
void putch(char c) void putch(int c)
{ {
putpch(c); __asm {
lda c
jsr bsout
}
} }
void clrscr(void) void clrscr(void)
{ {
putrch(147); __asm
{
jsr bsinit
}
} }
void textcursor(bool show) void textcursor(bool show)
{ {
*(volatile char *)0xcc = show ? 0 : 1; *(char *)0xcc = show ? 0 : 1;
} }
void gotoxy(char cx, char cy) void gotoxy(int cx, int 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 __asm
{ {
ldx cy ldx cy
ldy cx ldy cx
clc clc
jsr bsplot jsr bsplot
}
}
void textcolor(int c)
{
__asm
{
lda c
sta $0286
} }
#endif
} }
void textcolor(char c) int wherex(void)
{ {
*(volatile char *)0x0286 = c; __asm
{
lda $d3
sta accu
lda #0
sta accu + 1
}
} }
void bgcolor(char c) int wherey(void)
{ {
*(volatile char *)0xd021 = c; __asm
} {
lda $d6
void bordercolor(char c) sta accu
{ lda #0
*(volatile char *)0xd020 = c; sta accu + 1
} }
void revers(char r)
{
if (r)
putrch(18);
else
putrch(18 + 128);
}
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
}
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
} }

View File

@ -31,7 +31,7 @@ void dispmode80col(void);
#define PETSCII_CLEAR 0x94 #define PETSCII_CLEAR 0x94
#define PETSCII_DEL 0x14 #define PETSCII_DEL 0x14
#define PETSCII_INSERT 0x94 #define PETSCII_INSERT 0x94
#define PETSCII_STOP 0x03 #define PETSCII_STOP 0x0c
#define PETSCII_RETURN 0x0d #define PETSCII_RETURN 0x0d
#define PETSCII_F1 0x85 #define PETSCII_F1 0x85
@ -43,70 +43,31 @@ void dispmode80col(void);
#define PETSCII_F7 0x88 #define PETSCII_F7 0x88
#define PETSCII_F8 0x8c #define PETSCII_F8 0x8c
enum ConioColors int kbhit(void);
{
COLOR_BLACK,
COLOR_WHITE,
COLOR_RED,
COLOR_CYAN,
COLOR_PURPLE,
COLOR_GREEN,
COLOR_BLUE,
COLOR_YELLOW,
COLOR_ORANGE, int getche(void);
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 int getch(void);
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);
char getch(void);
// like getch but does not wait, returns zero if no // like getch but does not wait, returns zero if no
// key is pressed // key is pressed
char getchx(void); int getchx(void);
void putch(char c); void putch(int c);
void clrscr(void); void clrscr(void);
void gotoxy(char x, char y); void gotoxy(int x, int y);
inline void textcolor(char c); void textcolor(int c);
inline void bgcolor(char c); int wherex(void);
inline void bordercolor(char c); int wherey(void);
inline void revers(char r);
inline char wherex(void);
inline char wherey(void);
// show or hide the text cursor // show or hide the text cursor
inline void textcursor(bool show); void textcursor(bool show);
#pragma compile("conio.c") #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_LOOP_U8,
BC_MALLOC, BC_MALLOC,
BC_FREE, BC_FREE,
BC_FILL, BC_UNUSED_4,
BC_FILL_LONG, BC_UNUSED_5,
BC_UNUSED_6, BC_UNUSED_6,
BC_JSR, BC_JSR,
@ -186,11 +186,6 @@ enum ByteCode
BC_BINOP_SHR_I32, BC_BINOP_SHR_I32,
BC_BINOP_CMP_U32, BC_BINOP_CMP_U32,
BC_BINOP_CMP_S32, BC_BINOP_CMP_S32,
BC_CONV_U32_F32,
BC_CONV_I32_F32,
BC_CONV_F32_U32,
BC_CONV_F32_I32,
}; };
#endif #endif

View File

@ -116,38 +116,31 @@ int lmul4f12s(int x, int y)
{ {
__asm __asm
{ {
sec bit y + 1
lda x bpl W0
ror
sta accu
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 lda #0
sta accu + 1 sta accu + 1
bcc W4 L1: lsr x + 1
L2: ror x
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:
bcc W1 bcc W1
tay tay
clc clc
@ -163,31 +156,23 @@ W1:
dex dex
bne L1 bne L1
lsr x
bcc W2 bcc W2
tay tay
// sec ; we know it is set here sec
lda accu + 1 lda accu + 1
sbc y sbc y
sta accu + 1 sta accu + 1
tya tya
sbc y + 1 sbc y + 1
sec
W2: W2:
ror ror
ror accu + 1 ror accu + 1
ror accu ror accu
bit y + 1
bpl W3
tax
sec
lda accu + 1
sbc x
sta accu + 1
txa
sbc x + 1
W3:
lsr lsr
ror accu + 1 ror accu + 1
ror accu ror accu
@ -285,17 +270,15 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
__asm __asm
{ {
lda #0 lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2 sta __tmp + 2
sta __tmp + 3 sta __tmp + 3
lda a ldx #16
sec L1: lsr a + 1
T1: ror a
ldy #8
L1:
ror
bcc W1 bcc W1
tax
clc clc
lda __tmp + 2 lda __tmp + 2
adc b adc b
@ -303,38 +286,20 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3 lda __tmp + 3
adc b + 1 adc b + 1
sta __tmp + 3 sta __tmp + 3
txa
W1: W1:
ror __tmp + 3 ror __tmp + 3
ror __tmp + 2 ror __tmp + 2
dey ror __tmp + 1
ror __tmp
dex
bne L1 bne L1
ror
bcc T2
sta __tmp + 0 lda #0
lda a + 1 sta accu
clc sta accu + 1
bcc T1
T2: ldx #17
sec
L3:
sta __tmp + 1
ldx #8
L2: 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 sec
lda __tmp + 2 lda __tmp + 2
sbc c sbc c
@ -342,23 +307,33 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3 lda __tmp + 3
sbc c + 1 sbc c + 1
bcc W2 bcc W2
W4:
sta __tmp + 3 sta __tmp + 3
sty __tmp + 2 sty __tmp + 2
W2: W2:
dex rol accu
bne L2 rol accu + 1
lda __tmp + 1
rol asl __tmp
bcc T3 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) int lmuldiv16s(int a, int b, int c)
@ -383,17 +358,15 @@ int lmuldiv16s(int a, int b, int c)
__asm __asm
{ {
lda #0 lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2 sta __tmp + 2
sta __tmp + 3 sta __tmp + 3
lda a ldx #16
sec L1: lsr a + 1
T1: ror a
ldy #8
L1:
ror
bcc W1 bcc W1
tax
clc clc
lda __tmp + 2 lda __tmp + 2
adc b adc b
@ -401,38 +374,20 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3 lda __tmp + 3
adc b + 1 adc b + 1
sta __tmp + 3 sta __tmp + 3
txa
W1: W1:
ror __tmp + 3 ror __tmp + 3
ror __tmp + 2 ror __tmp + 2
dey ror __tmp + 1
ror __tmp
dex
bne L1 bne L1
ror
bcc T2
sta __tmp + 0 lda #0
lda a + 1 sta accu
clc sta accu + 1
bcc T1
T2: ldx #17
sec
L3:
sta __tmp + 1
ldx #8
L2: 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 sec
lda __tmp + 2 lda __tmp + 2
sbc c sbc c
@ -440,23 +395,30 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3 lda __tmp + 3
sbc c + 1 sbc c + 1
bcc W2 bcc W2
W4:
sta __tmp + 3 sta __tmp + 3
sty __tmp + 2 sty __tmp + 2
W2: W2:
rol accu
rol accu + 1
asl __tmp
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
dex dex
bne L2 beq E2
lda __tmp + 1 bcc L2
rol
bcc T3
sta accu + 1
lda __tmp + 0
clc
bcc L3
T3:
sta accu
lda __tmp + 2
sbc c
sta __tmp + 2
lda __tmp + 3
sbc c + 1
sta __tmp + 3
sec
bcs W2
E2:
lda sign lda sign
beq E1 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) 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; char ip = 0;
bool delta16 =((dx | dy) & 0xff80) != 0; bool delta16 = ((dx | dy) & 0xff80) != 0;
// ylow // ylow
ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly); 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; 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; ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
if (dx) ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
{
// 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
} }
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_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 12); ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
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);
} }
// l -- // l --
@ -695,7 +649,6 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern)
{ {
__asm __asm
{ {
lda dst lda dst
sta REG_SP sta REG_SP
lda dst + 1 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_MIN SCHAR_MIN
#define CHAR_MAX SCHAR_MAX #define CHAR_MAX SCHAR_MAX
#define INT_MIN (-32767-1) #define INT_MIN -32767
#define INT_MAX 32767 #define INT_MAX 32767
#define UINT_MAX 65535 #define UINT_MAX 65535

View File

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

View File

@ -32,15 +32,6 @@ bool isfinite(float f);
#pragma intrinsic(sin) #pragma intrinsic(sin)
#pragma intrinsic(cos) #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") #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

@ -6,7 +6,7 @@ namespace opp {
ifstream::ifstream(char fnum, char device, char channel, const string & name) ifstream::ifstream(char fnum, char device, char channel, const string & name)
{ {
this->fnum = fnum; this->fnum = fnum;
krnio_setnam(name.tocstr()); krnio_setnam(name);
krnio_open(fnum, device, channel); krnio_open(fnum, device, channel);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -86,53 +86,3 @@ const char * oscar_expand_rle(char * dp, const char * sp)
return sp + 1; 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); __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") #pragma compile("oscar.c")

View File

@ -2,50 +2,237 @@
#include "conio.h" #include "conio.h"
#include "stdlib.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) void putchar(char c)
{ {
putpch(c); __asm {
lda c
jsr putpch
}
} }
char getchar(void) char getchar(void)
{ {
return getpch(); __asm {
jsr getpch
sta accu
lda #0
sta accu + 1
}
} }
void puts(const char * str) void puts(const char * str)
{ {
while (char ch = *str++) __asm {
putpch(ch); 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 * gets(char * str)
{ {
char i = 0; __asm {
while ((char ch = getpch()) != '\n') gloop:
str[i++] = ch; jsr getpch
str[i] = 0; ldy #0
return str; cmp #10
} beq gdone
sta (str), y
char * gets_s(char * str, size_t n) inc str
{ bne gloop
if (str == NULL) inc str + 1
return NULL; bne gloop
gdone:
if (n < 2) lda #0
return NULL; sta (str), y
char i = 0, t = n - 1;
while ((char ch = getpch()) != '\n')
{
if (i < t)
str[i] = ch;
++i;
} }
str[(i < t) ? i : t] = '\0';
if (i > t)
return NULL;
return str; return str;
} }
@ -396,7 +583,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
if (c >= '0' && c <='9') if (c >= '0' && c <='9')
{ {
char i = 0; int i = 0;
while (c >= '0' && c <='9') while (c >= '0' && c <='9')
{ {
i = i * 10 + c - '0'; i = i * 10 + c - '0';
@ -407,7 +594,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
if (c == '.') if (c == '.')
{ {
char i = 0; int i = 0;
c = *p++; c = *p++;
while (c >= '0' && c <='9') while (c >= '0' && c <='9')
{ {
@ -417,7 +604,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
si.precision = i; 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); bi = nformi(&si, bp, *fps++, true);
} }
@ -556,17 +743,6 @@ int sprintf(char * str, const char * fmt, ...)
return d - str; 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) static inline bool isspace(char c)
{ {

View File

@ -2,8 +2,7 @@
#define STDIO_H #define STDIO_H
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
void putchar(char c); void putchar(char c);
@ -13,16 +12,10 @@ void puts(const char * str);
char * gets(char * str); char * gets(char * str);
char * gets_s(char * str, size_t n);
void printf(const char * fmt, ...); void printf(const char * fmt, ...);
int sprintf(char * str, 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 scanf(const char * fmt, ...);
int sscanf(const char * str, 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) void itoa(int n, char * s, unsigned radix)
{ {
bool neg = n < 0; bool neg = n < 0;
unsigned un = neg ? -n : n; if (neg)
{
n = - n;
}
char i = 0; char i = 0;
do { do {
unsigned d = un % radix; int d = n % radix;
if (d < 10) if (d < 10)
d += '0'; d += '0';
else else
d += 'A' - 10; d += 'A' - 10;
s[i++] = d; s[i++] = d;
} while ((un /= radix) > 0); } while ((n /= radix) > 0);
if (neg) if (neg)
{ {
@ -521,12 +524,6 @@ void exit(int status)
} }
} }
void abort(void)
{
exit(-1);
}
extern struct Heap { extern struct Heap {
Heap * next, * end; Heap * next, * end;
} HeapNode; } HeapNode;
@ -544,7 +541,7 @@ unsigned heapfree(void)
} }
#if 0 #if 0
struct Heap {q struct Heap {
unsigned int size; unsigned int size;
Heap * next; Heap * next;
} * freeHeap; } * freeHeap;
@ -667,97 +664,6 @@ void * calloc(int num, int size)
return p; 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; static unsigned seed = 31232;
unsigned int rand(void) unsigned int rand(void)

View File

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

View File

@ -138,20 +138,6 @@ char * cpycat(char * dst, const char * src)
#pragma native(cpycat) #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) void * memset(void * dst, int value, int size)
{ {
__asm __asm
@ -237,8 +223,8 @@ void * memmove(void * dst, const void * src, int size)
int sz = size; int sz = size;
if (sz > 0) if (sz > 0)
{ {
char * d = (char *)dst; char * d = dst;
const char * s = (const char *)src; const char * s = src;
if (d < s) if (d < s)
{ {
do { do {
@ -259,7 +245,7 @@ void * memmove(void * dst, const void * src, int size)
int memcmp(const void * ptr1, const void * ptr2, 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; char c, d;
while (size--) 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); void * memmove(void * dst, const void * src, int size);
char* strchr( const char* str, int ch );
#pragma intrinsic(strcpy) #pragma intrinsic(strcpy)
#pragma intrinsic(memcpy) #pragma intrinsic(memcpy)
#pragma intrinsic(memset)
#pragma intrinsic(memclr)
#pragma compile("string.c") #pragma compile("string.c")
#endif #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) sources = $(wildcard ../oscar64/*.cpp)
objects = $(patsubst $(project_dir)/oscar64/%.cpp,$(srcdir)/%.o,$(sources)) objects = $(patsubst ../oscar64/%.cpp,%.o,$(sources))
CXX = c++ CXX = c++
CPPFLAGS = -g -O2 -std=c++11 -Wno-switch CPPFLAGS = -g -O2 -std=c++11 -Wno-switch
SED = /usr/bin/sed
REMOVE_FORCE_ALL = $(RM) --recursive --dir $(shell mkdir -p ../bin)
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
ifdef WINDIR ifdef WINDIR
linklibs = -lpthread linklibs = -lpthread
@ -29,87 +16,26 @@ else
ifeq ($(UNAME_S), Darwin) ifeq ($(UNAME_S), Darwin)
linklibs = -lpthread linklibs = -lpthread
else else
# MSVC
linklibs = -lrt -lpthread linklibs = -lrt -lpthread
# MinGW
#linklibs = -lversion -lpthread
endif endif
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 ../bin/oscar64 : $(objects)
$(CXX) $(CPPFLAGS) $(linklibs) $(objects) -o ../bin/oscar64
$(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
.PHONY : clean .PHONY : clean
clean : clean :
@echo "Cleaning compiler..." -rm *.o *.d ../bin/oscar64
@$(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/
ifeq ($(UNAME_S), Darwin) ifeq ($(UNAME_S), Darwin)
@ -118,9 +44,3 @@ else
include $(objects:.o=.d) include $(objects:.o=.d)
endif 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 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 16
VisualStudioVersion = 17.13.35931.197 VisualStudioVersion = 16.0.31624.102
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}"
EndProject EndProject
@ -23,14 +23,10 @@ Global
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x64.Build.0 = Release|x64 {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.ActiveCfg = Release|Win32
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.Build.0 = 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.ActiveCfg = Debug
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.Build.0 = Debug|x64 {567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug|x86 {567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.Build.0 = Debug|x86 {567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release
{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
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -153,8 +153,8 @@ template <class T>
class GrowingArray class GrowingArray
{ {
protected: protected:
int size, range; int size, range;
T * array; T* array;
T empty; T empty;
void Grow(int to, bool clear) void Grow(int to, bool clear)
@ -166,15 +166,10 @@ protected:
if (to > range) if (to > range)
{ {
int trange = range * sizeof(T) < 65536 ? range * 2 : range + (range >> 2); if (to > range * 2)
if (trange < 4)
trange = 4;
if (to > trange)
range = to; range = to;
else else
range = trange; range = range * 2;
a2 = new T[range]; a2 = new T[range];
if (to > size) if (to > size)
@ -196,8 +191,8 @@ public:
: empty(empty_) : empty(empty_)
{ {
size = 0; size = 0;
range = 0; range = 4;
array = nullptr; array = new T[range];
} }
GrowingArray(const GrowingArray& a) GrowingArray(const GrowingArray& a)
@ -231,22 +226,14 @@ public:
delete[] array; delete[] array;
} }
void shrink(void) T& operator[](int n)
{
size = 0;
range = 0;
delete[] array;
array = nullptr;
}
__forceinline T& operator[](int n)
{ {
assert(n >= 0); assert(n >= 0);
if (n >= size) Grow(n + 1, false); if (n >= size) Grow(n + 1, false);
return array[n]; return array[n];
} }
__forceinline const T & operator[](int n) const const T & operator[](int n) const
{ {
assert(n >= 0); assert(n >= 0);
if (n >= size) return empty; if (n >= size) return empty;
@ -264,7 +251,7 @@ public:
if (n < size) if (n < size)
array[n] = empty; array[n] = empty;
} }
void Push(T t) void Push(T t)
{ {
(*this)[size] = t; (*this)[size] = t;
@ -335,7 +322,7 @@ public:
bool IsEmpty(void) const { return size == 0; } bool IsEmpty(void) const { return size == 0; }
__forceinline int Size(void) const { return size; } int Size(void) const { return size; }
T Last() const T Last() const
{ {
@ -421,33 +408,9 @@ protected:
array = a2; array = a2;
} }
for (int i = size; i < to; i++) array[i] = T{};
size = to; 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: public:
ExpandingArray(void) ExpandingArray(void)
{ {
@ -620,24 +583,6 @@ public:
return false; 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) __forceinline T& operator[](int n)
{ {
assert(n >= 0 && n < size); assert(n >= 0 && n < size);

View File

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

View File

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

View File

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

View File

@ -144,8 +144,8 @@ static const char* ByteCodeNames[] = {
"LOOP_U8", "LOOP_U8",
"MALLOC", "MALLOC",
"FREE", "FREE",
"FILL", nullptr,
"FILL_LONG", nullptr,
nullptr, nullptr,
"JSR", //114 "JSR", //114
@ -623,10 +623,6 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
case BC_OP_CEIL_F32: case BC_OP_CEIL_F32:
case BC_CONV_F32_U16: case BC_CONV_F32_U16:
case BC_CONV_F32_I16: 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; used = 0xffffffff;
break; break;
@ -684,8 +680,6 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
used = 0xffffffff; used = 0xffffffff;
break; break;
case BC_FILL:
case BC_FILL_LONG:
case BC_COPY: case BC_COPY:
case BC_COPY_LONG: case BC_COPY_LONG:
case BC_STRCPY: case BC_STRCPY:
@ -786,7 +780,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
return true; return true;
if (mCode == BC_LEA_ACCU_INDEX) if (mCode == BC_LEA_ACCU_INDEX)
return true; return true;
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL) if (mCode == BC_COPY || mCode == BC_STRCPY)
return true; return true;
if (mCode == BC_BINOP_ADDA_16) if (mCode == BC_BINOP_ADDA_16)
return true; return true;
@ -799,7 +793,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_STORE_ADDR_32) if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_STORE_ADDR_32)
return true; return true;
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL) if (mCode == BC_COPY || mCode == BC_STRCPY)
return true; return true;
if (mCode == BC_JSR || mCode == BC_CALL_ADDR || mCode == BC_CALL_ABS) 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); block->PutByte(mValue);
break; 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:
case BC_COPY_LONG: case BC_COPY_LONG:
if (mValue < 256) if (mValue < 256)
@ -1282,23 +1262,6 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
block->PutByte(mRegister); block->PutByte(mRegister);
break; 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: default:
assert(false); 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) void ByteCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins)
{ {
LoadOperandAddress(proc, ins->mSrc[0], BC_REG_ACCU); 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].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); ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; cins.mValue = int(ins->mSrc[1].mIntConst);
lins.mRegisterFinal = ins->mSrc[0].mFinal; mIns.Push(cins);
mIns.Push(lins); }
else
if (csigned) {
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); 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); mIns.Push(cins);
} }
else else
{ {
ByteCodeInstruction cins(BC_BINOP_CMPUI_16); ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
cins.mValue = int(ins->mSrc[1].mIntConst); cins.mValue = int(ins->mSrc[0].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;
mIns.Push(cins); mIns.Push(cins);
} }
} }
code = TransposeBranchCondition(code);
} }
else else
{ {
@ -3799,67 +3681,6 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
} break; } 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: case IA_EXT8TO16S:
{ {
if (ins->mSrc[0].mTemp == ins->mDst.mTemp) if (ins->mSrc[0].mTemp == ins->mDst.mTemp)
@ -4499,9 +4320,6 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
else else
LoadDirectValue(iproc, ins); LoadDirectValue(iproc, ins);
break; break;
case IC_FILL:
FillValue(iproc, ins);
break;
case IC_COPY: case IC_COPY:
CopyValue(iproc, ins); CopyValue(iproc, ins);
break; break;
@ -6605,7 +6423,7 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
{ {
mID = proc->mID; mID = proc->mID;
mNumBlocks = proc->mNumBlocks; mNumBlocks = proc->mBlocks.Size();
tblocks = new ByteCodeBasicBlock * [mNumBlocks]; tblocks = new ByteCodeBasicBlock * [mNumBlocks];
for (int i = 0; i < mNumBlocks; i++) for (int i = 0; i < mNumBlocks; i++)

View File

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

View File

@ -49,7 +49,7 @@ bool CompilationUnits::AddUnit(Location& location, const char* name, const char*
else else
{ {
strcpy_s(filename, from); strcpy_s(filename, from);
ptrdiff_t i = strlen(filename); int i = strlen(filename);
while (i > 0 && (filename[i - 1] != '/' && filename[i - 1] != '\\')) while (i > 0 && (filename[i - 1] != '/' && filename[i - 1] != '\\'))
i--; i--;
while (name[0] == '.' && name[1] == '.' && name[2] == '/') while (name[0] == '.' && name[1] == '.' && name[2] == '/')

View File

@ -174,13 +174,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
linkerObject = bcdec->mLinkerObject; linkerObject = bcdec->mLinkerObject;
} }
else if (bcdec->mType == DT_LABEL) else if (bcdec->mType == DT_LABEL)
{ {
if (!bcdec->mBase->mLinkerObject) if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
linkerObject = bcdec->mBase->mLinkerObject; linkerObject = bcdec->mBase->mLinkerObject;
offset = int(bcdec->mInteger); offset = int(bcdec->mInteger);
@ -466,7 +466,7 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
printf("Generate native code <%s>\n", proc->mIdent->mString); printf("Generate native code <%s>\n", proc->mIdent->mString);
ncproc->Compile(proc); ncproc->Compile(proc);
mNativeCodeGenerator->mProcedures.Push(ncproc); mNativeProcedures.Push(ncproc);
} }
else else
{ {
@ -508,8 +508,6 @@ bool Compiler::GenerateCode(void)
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff); regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES)) else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES))
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff); 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 else
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff); regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff);
} }
@ -523,12 +521,6 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) 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_C64:
case TMACH_X16: case TMACH_X16:
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
@ -560,12 +552,12 @@ bool Compiler::GenerateCode(void)
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
{ {
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080); regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1180); regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1100);
} }
else else
{ {
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080); regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1180); regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1000);
} }
regionLowcode->mSections.Push(mCompilationUnits->mSectionLowCode); regionLowcode->mSections.Push(mCompilationUnits->mSectionLowCode);
break; break;
@ -631,9 +623,6 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) switch (mTargetMachine)
{ {
case TMACH_MEGA65:
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
break;
case TMACH_C64: case TMACH_C64:
case TMACH_X16: case TMACH_X16:
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00); regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
@ -644,8 +633,6 @@ bool Compiler::GenerateCode(void)
regionBytecode = mLinker->AddRegion(identBytecode, 0x1d00, 0x1e00); regionBytecode = mLinker->AddRegion(identBytecode, 0x1d00, 0x1e00);
break; break;
case TMACH_PLUS4: case TMACH_PLUS4:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1200, 0x1300);
break;
case TMACH_VIC20: case TMACH_VIC20:
regionBytecode = mLinker->AddRegion(identBytecode, 0x1100, 0x1200); regionBytecode = mLinker->AddRegion(identBytecode, 0x1100, 0x1200);
break; break;
@ -695,9 +682,6 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) switch (mTargetMachine)
{ {
case TMACH_MEGA65:
regionMain = mLinker->AddRegion(identMain, 0x2300, 0xc000);
break;
case TMACH_C64: case TMACH_C64:
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000); regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
break; break;
@ -714,7 +698,7 @@ bool Compiler::GenerateCode(void)
regionMain = mLinker->AddRegion(identMain, 0x1e00, 0xc000); regionMain = mLinker->AddRegion(identMain, 0x1e00, 0xc000);
break; break;
case TMACH_PLUS4: case TMACH_PLUS4:
regionMain = mLinker->AddRegion(identMain, 0x1300, 0xfc00); regionMain = mLinker->AddRegion(identMain, 0x1200, 0xfc00);
break; break;
case TMACH_VIC20: case TMACH_VIC20:
regionMain = mLinker->AddRegion(identMain, 0x1200, 0x1e00); regionMain = mLinker->AddRegion(identMain, 0x1200, 0x1e00);
@ -749,14 +733,6 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) 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: case TMACH_C64:
if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16)) if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
@ -777,7 +753,7 @@ bool Compiler::GenerateCode(void)
regionMain = mLinker->AddRegion(identMain, 0x1c80, 0xc000); regionMain = mLinker->AddRegion(identMain, 0x1c80, 0xc000);
break; break;
case TMACH_PLUS4: case TMACH_PLUS4:
regionMain = mLinker->AddRegion(identMain, 0x1180, 0xfc00); regionMain = mLinker->AddRegion(identMain, 0x1100, 0xfc00);
break; break;
case TMACH_VIC20: case TMACH_VIC20:
regionMain = mLinker->AddRegion(identMain, 0x1080, 0x1e00); regionMain = mLinker->AddRegion(identMain, 0x1080, 0x1e00);
@ -932,7 +908,7 @@ bool Compiler::GenerateCode(void)
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Generate intermediate code\n"); 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++) for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
{ {
Declaration* dec = mCompilationUnits->mReferenced[i]; Declaration* dec = mCompilationUnits->mReferenced[i];
@ -941,19 +917,13 @@ bool Compiler::GenerateCode(void)
if (!dec->mLinkerObject) if (!dec->mLinkerObject)
mInterCodeGenerator->TranslateProcedure(mInterCodeModule, dec->mValue, dec); mInterCodeGenerator->TranslateProcedure(mInterCodeModule, dec->mValue, dec);
} }
} else
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
{
Declaration* dec = mCompilationUnits->mReferenced[i];
if (dec->mType != DT_CONST_FUNCTION)
{ {
if (!dec->mLinkerObject) if (!dec->mLinkerObject)
mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, dec); mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, dec);
} }
} }
mInterCodeGenerator->CompleteMainInit();
if (mErrors->mErrorCount != 0) if (mErrors->mErrorCount != 0)
return false; return false;
@ -965,8 +935,7 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("fsplitt")); RegisterRuntime(loc, Ident::Unique("fsplitt"));
RegisterRuntime(loc, Ident::Unique("fsplitx")); RegisterRuntime(loc, Ident::Unique("fsplitx"));
RegisterRuntime(loc, Ident::Unique("fsplita")); RegisterRuntime(loc, Ident::Unique("fsplita"));
RegisterRuntime(loc, Ident::Unique("fadd")); RegisterRuntime(loc, Ident::Unique("faddsub"));
RegisterRuntime(loc, Ident::Unique("fsub"));
RegisterRuntime(loc, Ident::Unique("fmul")); RegisterRuntime(loc, Ident::Unique("fmul"));
RegisterRuntime(loc, Ident::Unique("fdiv")); RegisterRuntime(loc, Ident::Unique("fdiv"));
RegisterRuntime(loc, Ident::Unique("mul16")); RegisterRuntime(loc, Ident::Unique("mul16"));
@ -979,12 +948,8 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("fceil")); RegisterRuntime(loc, Ident::Unique("fceil"));
RegisterRuntime(loc, Ident::Unique("ftoi")); RegisterRuntime(loc, Ident::Unique("ftoi"));
RegisterRuntime(loc, Ident::Unique("ftou")); RegisterRuntime(loc, Ident::Unique("ftou"));
RegisterRuntime(loc, Ident::Unique("ftoli"));
RegisterRuntime(loc, Ident::Unique("ftolu"));
RegisterRuntime(loc, Ident::Unique("ffromi")); RegisterRuntime(loc, Ident::Unique("ffromi"));
RegisterRuntime(loc, Ident::Unique("ffromu")); RegisterRuntime(loc, Ident::Unique("ffromu"));
RegisterRuntime(loc, Ident::Unique("ffromli"));
RegisterRuntime(loc, Ident::Unique("ffromlu"));
RegisterRuntime(loc, Ident::Unique("fcmp")); RegisterRuntime(loc, Ident::Unique("fcmp"));
RegisterRuntime(loc, Ident::Unique("bcexec")); RegisterRuntime(loc, Ident::Unique("bcexec"));
RegisterRuntime(loc, Ident::Unique("jmpaddr")); RegisterRuntime(loc, Ident::Unique("jmpaddr"));
@ -994,12 +959,8 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("divu32")); RegisterRuntime(loc, Ident::Unique("divu32"));
RegisterRuntime(loc, Ident::Unique("modu32")); RegisterRuntime(loc, Ident::Unique("modu32"));
RegisterRuntime(loc, Ident::Unique("store32"));
RegisterRuntime(loc, Ident::Unique("load32"));
RegisterRuntime(loc, Ident::Unique("malloc")); RegisterRuntime(loc, Ident::Unique("malloc"));
RegisterRuntime(loc, Ident::Unique("free")); RegisterRuntime(loc, Ident::Unique("free"));
RegisterRuntime(loc, Ident::Unique("breakpoint"));
} }
// Register extended byte code functions // Register extended byte code functions
@ -1015,7 +976,7 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject; mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
} }
} }
@ -1058,18 +1019,13 @@ bool Compiler::GenerateCode(void)
mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection); mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection);
} }
mNativeCodeGenerator->OutlineFunctions();
mNativeCodeGenerator->BuildFunctionProxies(); mNativeCodeGenerator->BuildFunctionProxies();
for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++) for (int i = 0; i < mNativeProcedures.Size(); i++)
{ {
if (mCompilerOptions & COPT_VERBOSE2) if (mCompilerOptions & COPT_VERBOSE2)
{ printf("Assemble native code <%s>\n", mNativeProcedures[i]->mInterProc->mIdent->mString);
if (mNativeCodeGenerator->mProcedures[i]->mInterProc) mNativeProcedures[i]->Assemble();
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
}
mNativeCodeGenerator->mProcedures[i]->Assemble();
} }
LinkerObject* byteCodeObject = nullptr; LinkerObject* byteCodeObject = nullptr;
@ -1095,13 +1051,13 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
linkerObject = bcdec->mLinkerObject; linkerObject = bcdec->mLinkerObject;
} }
else if (bcdec->mType == DT_LABEL) else if (bcdec->mType == DT_LABEL)
{ {
if (!bcdec->mBase->mLinkerObject) if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
linkerObject = bcdec->mBase->mLinkerObject; linkerObject = bcdec->mBase->mLinkerObject;
offset = int(bcdec->mInteger); offset = int(bcdec->mInteger);
} }
@ -1141,7 +1097,6 @@ bool Compiler::GenerateCode(void)
if (mCompilerOptions & COPT_OPTIMIZE_BASIC) if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
{ {
mLinker->CombineSameConst(); mLinker->CombineSameConst();
mLinker->InlineSimpleJumps();
mLinker->CheckDirectJumps(); mLinker->CheckDirectJumps();
} }
@ -1187,7 +1142,7 @@ bool Compiler::BuildLZO(const char* targetPath)
char prgPath[200]; char prgPath[200];
strcpy_s(prgPath, targetPath); strcpy_s(prgPath, targetPath);
ptrdiff_t i = strlen(prgPath); int i = strlen(prgPath);
while (i > 0 && prgPath[i - 1] != '.') while (i > 0 && prgPath[i - 1] != '.')
i--; i--;
if (i > 0) if (i > 0)
@ -1201,7 +1156,7 @@ bool Compiler::BuildLZO(const char* targetPath)
fopen_s(&file, prgPath, "wb"); fopen_s(&file, prgPath, "wb");
if (file) if (file)
{ {
ptrdiff_t done = fwrite(data, 1, n, file); int done = fwrite(data, 1, n, file);
fclose(file); fclose(file);
delete[] data; delete[] data;
return done == n; return done == n;
@ -1219,96 +1174,12 @@ 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) 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);
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); strcpy_s(prgPath, targetPath);
i = strlen(prgPath); int i = strlen(prgPath);
while (i > 0 && prgPath[i - 1] != '.') while (i > 0 && prgPath[i - 1] != '.')
i--; i--;
if (i > 0) if (i > 0)
@ -1320,7 +1191,6 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcpy_s(intPath, prgPath); strcpy_s(intPath, prgPath);
strcpy_s(bcsPath, prgPath); strcpy_s(bcsPath, prgPath);
strcpy_s(dbjPath, prgPath); strcpy_s(dbjPath, prgPath);
strcpy_s(cszPath, prgPath);
strcat_s(mapPath, "map"); strcat_s(mapPath, "map");
strcat_s(asmPath, "asm"); strcat_s(asmPath, "asm");
@ -1328,7 +1198,6 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcat_s(intPath, "int"); strcat_s(intPath, "int");
strcat_s(bcsPath, "bcs"); strcat_s(bcsPath, "bcs");
strcat_s(dbjPath, "dbj"); strcat_s(dbjPath, "dbj");
strcat_s(cszPath, "csz");
if (mCompilerOptions & COPT_TARGET_PRG) if (mCompilerOptions & COPT_TARGET_PRG)
{ {
@ -1344,7 +1213,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcat_s(prgPath, "prg"); strcat_s(prgPath, "prg");
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", prgPath); printf("Writing <%s>\n", prgPath);
mLinker->WritePrgFile(prgPath, basePath); mLinker->WritePrgFile(prgPath);
} }
} }
else if (mCompilerOptions & COPT_TARGET_CRT) else if (mCompilerOptions & COPT_TARGET_CRT)
@ -1376,7 +1245,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
if (d64) if (d64)
{ {
ptrdiff_t i = strlen(prgPath); int i = strlen(prgPath);
while (i > 0 && prgPath[i - 1] != '.') while (i > 0 && prgPath[i - 1] != '.')
i--; i--;
if (i > 0) if (i > 0)
@ -1394,7 +1263,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", asmPath); printf("Writing <%s>\n", asmPath);
mLinker->WriteAsmFile(asmPath, mVersion); mLinker->WriteAsmFile(asmPath);
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", lblPath); printf("Writing <%s>\n", lblPath);
@ -1411,9 +1280,6 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
if (mCompilerOptions & COPT_DEBUGINFO) if (mCompilerOptions & COPT_DEBUGINFO)
WriteDbjFile(dbjPath); WriteDbjFile(dbjPath);
if (mCompilerOptions & COPT_PROFILEINFO)
WriteCszFile(cszPath);
if (!(mCompilerOptions & COPT_NATIVE)) if (!(mCompilerOptions & COPT_NATIVE))
{ {
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
@ -1480,111 +1346,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) bool Compiler::WriteDbjFile(const char* filename)
{ {
FILE* file; FILE* file;

View File

@ -29,11 +29,11 @@ public:
GlobalOptimizer* mGlobalOptimizer; GlobalOptimizer* mGlobalOptimizer;
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions; GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
ExpandingArray<NativeCodeProcedure*> mNativeProcedures;
TargetMachine mTargetMachine; TargetMachine mTargetMachine;
uint64 mCompilerOptions; uint64 mCompilerOptions;
uint16 mCartridgeID; uint16 mCartridgeID;
char mVersion[32];
struct Define struct Define
{ {
@ -47,8 +47,6 @@ public:
bool ParseSource(void); bool ParseSource(void);
bool GenerateCode(void); bool GenerateCode(void);
bool WriteOutputFile(const char* targetPath, DiskImage * d64); bool WriteOutputFile(const char* targetPath, DiskImage * d64);
bool WriteErrorFile(const char* targetPath);
bool RemoveErrorFile(const char* targetPath);
int ExecuteCode(bool profile, int trace); int ExecuteCode(bool profile, int trace);
void AddDefine(const Ident* ident, const char* value); void AddDefine(const Ident* ident, const char* value);
@ -60,5 +58,4 @@ public:
void CompleteTemplateExpansion(void); void CompleteTemplateExpansion(void);
bool WriteDbjFile(const char* filename); 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_CONST_PARAMS = 1ULL << 9;
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10; static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11; 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_OPTIMIZE_CODE_SIZE = 1ULL << 16;
static const uint64 COPT_NATIVE = 1ULL << 17; 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_DEBUGINFO = 1ULL << 51;
static const uint64 COPT_CPLUSPLUS = 1ULL << 52; 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_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; 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_MMC1,
TMACH_NES_MMC3, TMACH_NES_MMC3,
TMACH_ATARI, TMACH_ATARI,
TMACH_X16, TMACH_X16
TMACH_MEGA65
}; };

View File

@ -11,7 +11,7 @@ int CompressLZO(uint8* dst, const uint8* source, int size)
while (pi < 127 && pos < size) while (pi < 127 && pos < size)
{ {
int bi = pi, bj = 0; 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; int j = 0;
while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j]) while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j])

View File

@ -2,7 +2,7 @@
#include <math.h> #include <math.h>
ConstexprInterpreter::Value::Value(void) ConstexprInterpreter::Value::Value(void)
: mDecType(TheVoidTypeDeclaration), mDecValue(nullptr), : mDecType(TheVoidTypeDeclaration),
mBaseValue(nullptr), mOffset(0), mBaseValue(nullptr), mOffset(0),
mData(mShortData), mDataSize(0) mData(mShortData), mDataSize(0)
{ {
@ -10,7 +10,7 @@ ConstexprInterpreter::Value::Value(void)
ConstexprInterpreter::Value::Value(const Location & location) ConstexprInterpreter::Value::Value(const Location & location)
: mLocation(location), : mLocation(location),
mDecType(TheVoidTypeDeclaration), mDecValue(nullptr), mDecType(TheVoidTypeDeclaration),
mBaseValue(nullptr), mOffset(0), mBaseValue(nullptr), mOffset(0),
mData(mShortData), mDataSize(0) mData(mShortData), mDataSize(0)
{ {
@ -18,7 +18,7 @@ ConstexprInterpreter::Value::Value(const Location & location)
ConstexprInterpreter::Value::Value(Expression* exp) ConstexprInterpreter::Value::Value(Expression* exp)
: mLocation(exp->mLocation), : mLocation(exp->mLocation),
mDecType(exp->mDecType), mDecValue(nullptr), mDecType(exp->mDecType),
mBaseValue(nullptr), mOffset(0), mBaseValue(nullptr), mOffset(0),
mDataSize(exp->mDecType->mSize) 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++) for (int i = 0; i < dec->mBase->mSize; i++)
PutIntAt(dec->mData[i], offset + i, TheConstCharTypeDeclaration); PutIntAt(dec->mData[i], offset + i, TheConstCharTypeDeclaration);
break; 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) ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec)
: mLocation(location), : mLocation(location),
mDecType(dec), mDecValue(nullptr), mDecType(dec),
mBaseValue(nullptr), mOffset(0), mBaseValue(nullptr), mOffset(0),
mDataSize(dec->mSize) 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) ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec, int size)
: mLocation(location), : mLocation(location),
mDecType(dec), mDecValue(nullptr), mDecType(dec),
mBaseValue(nullptr), mOffset(0), mBaseValue(nullptr), mOffset(0),
mDataSize(size) mDataSize(size)
{ {
@ -83,7 +80,7 @@ ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec, i
ConstexprInterpreter::Value::Value(const Value& value) ConstexprInterpreter::Value::Value(const Value& value)
: mLocation(value.mLocation), : mLocation(value.mLocation),
mDecType(value.mDecType), mDecValue(nullptr), mDecType(value.mDecType),
mBaseValue(value.mBaseValue), mOffset(value.mOffset), mBaseValue(value.mBaseValue), mOffset(value.mOffset),
mDataSize(value.mDataSize) mDataSize(value.mDataSize)
@ -99,7 +96,7 @@ ConstexprInterpreter::Value::Value(const Value& value)
ConstexprInterpreter::Value::Value(Value&& value) ConstexprInterpreter::Value::Value(Value&& value)
: mLocation(value.mLocation), : mLocation(value.mLocation),
mDecType(value.mDecType), mDecValue(nullptr), mDecType(value.mDecType),
mBaseValue(value.mBaseValue), mOffset(value.mOffset), mBaseValue(value.mBaseValue), mOffset(value.mOffset),
mDataSize(value.mDataSize) mDataSize(value.mDataSize)
{ {
@ -118,7 +115,7 @@ ConstexprInterpreter::Value::Value(Value&& value)
ConstexprInterpreter::Value::Value(Value* value) ConstexprInterpreter::Value::Value(Value* value)
: mLocation(value->mLocation), : mLocation(value->mLocation),
mDecType(value->mDecType), mDecValue(value->mDecValue), mDecType(value->mDecType),
mBaseValue(value), mOffset(0), mBaseValue(value), mOffset(0),
mDataSize(0), mData(mShortData) 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) ConstexprInterpreter::Value::Value(const Location& location, Value* value, Declaration* type, int offset)
: mLocation(location), : mLocation(location),
mDecType(type), mDecValue(nullptr), mDecType(type),
mBaseValue(value), mOffset(offset), mBaseValue(value), mOffset(offset),
mDataSize(0), mData(mShortData) 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) ConstexprInterpreter::Value::Value(const Location& location, const uint8* data, Declaration* type)
: mLocation(location), : mLocation(location),
mDecType(type), mDecValue(nullptr), mDecType(type),
mBaseValue(nullptr), mOffset(0), mBaseValue(nullptr), mOffset(0),
mDataSize(type->mSize) 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) ConstexprInterpreter::Value::Value(const Location& location, const ValueItem* data, Declaration* type)
: mLocation(location), : mLocation(location),
mDecType(type), mDecValue(nullptr), mDecType(type),
mBaseValue(nullptr), mOffset(0), mBaseValue(nullptr), mOffset(0),
mDataSize(type->mSize) 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))); 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) void ConstexprInterpreter::Value::PutIntAt(int64 v, int at, Declaration* type)
{ {
if (type->mType == DT_TYPE_FLOAT) 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) for (int i=0; i<type->mSize; i += type->mBase->mSize)
{ {
Declaration* cdec = GetConst(offset + i, type->mBase, dataSection); Declaration* cdec = GetConst(offset + i, type->mBase, dataSection);
if (type->mStride) cdec->mOffset = i;
cdec->mOffset = i / type->mBase->mSize;
else
cdec->mOffset = i;
if (ldec) if (ldec)
ldec->mNext = cdec; ldec->mNext = cdec;
@ -543,26 +521,7 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
Declaration* target; Declaration* target;
if (vp.mBaseValue->mDecValue) if (vp.mBaseValue->mDecType->mType == DT_TYPE_ARRAY)
{
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)
{ {
target = new Declaration(mLocation, DT_CONST_DATA); target = new Declaration(mLocation, DT_CONST_DATA);
target->mSize = vp.mBaseValue->mDataSize; target->mSize = vp.mBaseValue->mDataSize;
@ -581,14 +540,6 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
dec->mValue->mDecType = target->mBase; dec->mValue->mDecType = target->mBase;
dec->mValue->mDecValue = target; 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 else
{ {
dec = new Declaration(mLocation, DT_CONST_ADDRESS); dec = new Declaration(mLocation, DT_CONST_ADDRESS);
@ -651,7 +602,6 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
{ {
mProcType = exp->mLeft->mDecType; mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight;
Declaration* cdec = exp->mLeft->mDecType->mParams; Declaration* cdec = exp->mLeft->mDecType->mParams;
int pos = 0; int pos = 0;
@ -660,28 +610,6 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
mParams[pos].PutPtr(Value(&mResult)); mParams[pos].PutPtr(Value(&mResult));
pos = 2; 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*>(); mHeap = new ExpandingArray<Value*>();
Execute(exp->mLeft->mDecValue->mValue); 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); mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase);
if (pex->mDecValue->mSize > 0) if (pex->mDecValue->mSize > 0)
{ mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
if (pex->mDecValue->mValue)
mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
else
return false;
}
} }
else else
return false; return false;
@ -777,9 +700,6 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
Expression* ConstexprInterpreter::EvalCall(Expression* exp) Expression* ConstexprInterpreter::EvalCall(Expression* exp)
{ {
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
return exp;
mProcType = exp->mLeft->mDecType; mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight; Expression* pex = exp->mRight;
@ -1046,9 +966,6 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalUnary(Expression* exp, con
break; break;
case TK_MUL: case TK_MUL:
return vl.GetPtr(); return vl.GetPtr();
case TK_SIZEOF:
v.PutInt(vl.mDecType->mSize);
break;
default: default:
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]); 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 = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(cos(mParams[0].GetFloat())); 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 else
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname); mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
} }

View File

@ -19,8 +19,8 @@ protected:
struct ValueItem struct ValueItem
{ {
uint8 mByte; uint8 mByte;
Value * mBaseValue; Value* mBaseValue;
ValueItem(void); ValueItem(void);
}; };
@ -35,7 +35,6 @@ protected:
Value(const Value& value); Value(const Value& value);
Value(Value&& value); Value(Value&& value);
Value(const Location& location, Value * value, Declaration * type, int offset); Value(const Location& location, Value * value, Declaration * type, int offset);
Value(const Location& location, Declaration * value, Declaration* type, int offset);
Value(Value* value); Value(Value* value);
Value(const Location& location, const uint8 * data, Declaration* type); Value(const Location& location, const uint8 * data, Declaration* type);
Value(const Location& location, const ValueItem* data, Declaration* type); Value(const Location& location, const ValueItem* data, Declaration* type);
@ -49,7 +48,7 @@ protected:
void Assign(const Value& v); void Assign(const Value& v);
Location mLocation; Location mLocation;
Declaration * mDecType, * mDecValue; Declaration * mDecType;
Value * mBaseValue; Value * mBaseValue;
int mOffset; int mOffset;
ValueItem * mData; ValueItem * mData;
@ -72,7 +71,6 @@ protected:
void PutIntAt(int64 v, int at, Declaration* type); void PutIntAt(int64 v, int at, Declaration* type);
void PutFloatAt(double v, int at, Declaration* type); void PutFloatAt(double v, int at, Declaration* type);
void PutPtrAt(const Value& 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); void PutConst(int offset, Declaration * dec);
Declaration* GetConst(int offset, Declaration* type, LinkerSection* dataSection) const; 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_VARIABLE,
DT_PACK_ARGUMENT, DT_PACK_ARGUMENT,
DT_PACK_TYPE, DT_PACK_TYPE,
DT_PACK_ANON,
DT_VARIABLE, DT_VARIABLE,
DT_ARGUMENT, DT_ARGUMENT,
@ -59,7 +58,6 @@ enum DecType
DT_LABEL_REF, DT_LABEL_REF,
DT_NAMESPACE, DT_NAMESPACE,
DT_BASECLASS, DT_BASECLASS,
DT_CLABEL,
DT_TEMPLATE, 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_AUTO_TEMPLATE = (1ULL << 32);
static const uint64 DTF_BANK_INLAY = (1ULL << 33); 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_VARIABLE = (1ULL << 36);
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 37); 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_VAR_ALIASING = (1ULL << 48);
static const uint64 DTF_FPARAM_UNUSED = (1ULL << 49); 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; class Declaration;
@ -167,8 +158,6 @@ public:
ScopeLevel mLevel; ScopeLevel mLevel;
const Ident * mName; const Ident * mName;
DeclarationScope* Clone(void) const;
DeclarationScope* mParent; DeclarationScope* mParent;
protected: protected:
struct Entry struct Entry
@ -218,7 +207,6 @@ enum ExpressionType
EX_IF, EX_IF,
EX_ELSE, EX_ELSE,
EX_FOR, EX_FOR,
EX_FORBODY,
EX_DO, EX_DO,
EX_SCOPE, EX_SCOPE,
EX_BREAK, EX_BREAK,
@ -241,25 +229,14 @@ enum ExpressionType
EX_RESULT, EX_RESULT,
EX_PACK, EX_PACK,
EX_PACK_TYPE, 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 class Expression
{ {
public: public:
Expression(const Location& loc, ExpressionType type); Expression(const Location& loc, ExpressionType type);
~Expression(void); ~Expression(void);
uint32 mUID;
Location mLocation, mEndLocation; Location mLocation, mEndLocation;
ExpressionType mType; ExpressionType mType;
Expression * mLeft, * mRight; Expression * mLeft, * mRight;
@ -268,23 +245,15 @@ public:
AsmInsType mAsmInsType; AsmInsType mAsmInsType;
AsmInsMode mAsmInsMode; AsmInsMode mAsmInsMode;
bool mConst; bool mConst;
uint32 mFlags;
Expression* LogicInvertExpression(void); Expression* LogicInvertExpression(void);
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr); Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
bool HasSideEffects(void) const; 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 IsSame(const Expression* exp) const;
bool IsRValue(void) const; bool IsRValue(void) const;
bool IsLValue(void) const; bool IsLValue(void) const;
bool IsConstRef(void) const; bool IsConstRef(void) const;
bool IsVolatile(void) const;
void Dump(int ident) const; void Dump(int ident) const;
}; };
@ -295,14 +264,12 @@ public:
Declaration(const Location & loc, DecType type); Declaration(const Location & loc, DecType type);
~Declaration(void); ~Declaration(void);
uint32 mUID;
Location mLocation, mEndLocation; Location mLocation, mEndLocation;
DecType mType; DecType mType;
Token mToken; Token mToken;
Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile; Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile;
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment; Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment, * mVectorMoveConstructor, * mVectorMoveAssignment; Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
Declaration * mVTable, * mClass, * mTemplate; Declaration * mVTable, * mClass, * mTemplate;
Declaration * mForwardParam, * mForwardCall; Declaration * mForwardParam, * mForwardCall;
@ -329,7 +296,6 @@ public:
bool IsSame(const Declaration* dec) const; bool IsSame(const Declaration* dec) const;
bool IsDerivedFrom(const Declaration* dec) const; bool IsDerivedFrom(const Declaration* dec) const;
bool IsSubType(const Declaration* dec) const; bool IsSubType(const Declaration* dec) const;
bool IsConstRefSame(const Declaration* dec) const;
bool IsConstSame(const Declaration* dec) const; bool IsConstSame(const Declaration* dec) const;
bool IsSameValue(const Declaration* dec) const; bool IsSameValue(const Declaration* dec) const;
bool IsSameParams(const Declaration* dec) const; bool IsSameParams(const Declaration* dec) const;
@ -344,17 +310,12 @@ public:
bool IsSimpleType(void) const; bool IsSimpleType(void) const;
bool IsReference(void) const; bool IsReference(void) const;
bool IsIndexed(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); void SetDefined(void);
Declaration* ToConstType(void); Declaration* ToConstType(void);
Declaration* ToMutableType(void); Declaration* ToMutableType(void);
Declaration* ToVolatileType(void); Declaration* ToVolatileType(void);
Declaration* ToAlternateThis(Declaration* pthis, int nthis = 1);
Declaration* ToStriped(int stripe); Declaration* ToStriped(int stripe);
Declaration* ToStriped(Errors* errors); Declaration* ToStriped(Errors* errors);
@ -378,9 +339,8 @@ public:
DecType ValueType(void) const; DecType ValueType(void) const;
bool CanResolveTemplate(Expression* pexp, Declaration* tdec); 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 ResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary);
Declaration* ExpandTemplate(DeclarationScope* scope); Declaration* ExpandTemplate(DeclarationScope* scope);
@ -397,7 +357,6 @@ extern Declaration* TheVoidTypeDeclaration, * TheConstVoidTypeDeclaration, * The
extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheConstVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration; extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheConstVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration; extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration; extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration; extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration;
extern Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
extern Expression* TheVoidExpression; extern Expression* TheVoidExpression;

View File

@ -429,10 +429,6 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
i += 1; i += 1;
break; break;
case BC_FILL:
fprintf(file, "FILL\t#%d", memory[start + i + 0]);
i++;
break;
case BC_COPY: case BC_COPY:
fprintf(file, "COPY\t#%d", memory[start + i + 0]); fprintf(file, "COPY\t#%d", memory[start + i + 0]);
i++; 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])); fprintf(file, "COPYL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2; i += 2;
break; 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: case BC_OP_NEGATE_16:
fprintf(file, "NEG\tACCU"); fprintf(file, "NEG\tACCU");
@ -484,19 +476,6 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
fprintf(file, "CNVFS\tACCU"); fprintf(file, "CNVFS\tACCU");
break; 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: case BC_MALLOC:
fprintf(file, "MALLOC\tACCU"); fprintf(file, "MALLOC\tACCU");
break; break;
@ -846,7 +825,7 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU); sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU);
return buffer; 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); sprintf_s(buffer, 10, "WORK + %d", tmp - BC_REG_WORK);
return buffer; return buffer;

View File

@ -31,8 +31,6 @@ static char A2P(char ch)
DiskImage::DiskImage(const char* fname) DiskImage::DiskImage(const char* fname)
{ {
mInterleave = 10;
for (int i = 0; i < 41; i++) for (int i = 0; i < 41; i++)
for (int j = 0; j < 21; j++) for (int j = 0; j < 21; j++)
memset(mSectors[i][j], 0, 256); memset(mSectors[i][j], 0, 256);
@ -55,7 +53,7 @@ DiskImage::DiskImage(const char* fname)
for (int i = 0x90; i < 0xab; i++) for (int i = 0x90; i < 0xab; i++)
bam[i] = 0xa0; bam[i] = 0xa0;
ptrdiff_t i = strlen(fname); int i = strlen(fname);
while (i > 0 && fname[i - 1] != '/' && fname[i - 1] != '\\') while (i > 0 && fname[i - 1] != '/' && fname[i - 1] != '\\')
i--; i--;
@ -106,7 +104,7 @@ int DiskImage::AllocBAMSector(int track, int sector)
if (dp[0] > 0) if (dp[0] > 0)
{ {
sector += mInterleave; sector += 4;
if (sector >= SectorsPerTrack[track]) if (sector >= SectorsPerTrack[track])
sector -= SectorsPerTrack[track]; sector -= SectorsPerTrack[track];
@ -230,16 +228,14 @@ 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; FILE* file;
fopen_s(&file, fname, "rb"); fopen_s(&file, fname, "rb");
if (file) if (file)
{ {
char dname[200]; char dname[200];
ptrdiff_t i = strlen(fname); int i = strlen(fname);
while (i > 0 && fname[i - 1] != '/' && fname[i - 1] != '\\') while (i > 0 && fname[i - 1] != '/' && fname[i - 1] != '\\')
i--; i--;
@ -255,7 +251,7 @@ bool DiskImage::WriteFile(const char* fname, bool compressed, int interleave)
if (OpenFile(dname)) if (OpenFile(dname))
{ {
uint8 * buffer = new uint8[65536], * cbuffer = new uint8[65536]; uint8 * buffer = new uint8[65536], * cbuffer = new uint8[65536];
ptrdiff_t size = fread(buffer, 1, 65536, file); int size = fread(buffer, 1, 65536, file);
int csize = 0; int csize = 0;
if (compressed) if (compressed)
@ -327,10 +323,10 @@ bool DiskImage::WriteFile(const char* fname, bool compressed, int interleave)
return false; return false;
} }
int DiskImage::WriteBytes(const uint8* data, ptrdiff_t size) int DiskImage::WriteBytes(const uint8* data, int size)
{ {
uint8* dp = mSectors[mTrack][mSector]; uint8* dp = mSectors[mTrack][mSector];
for (ptrdiff_t i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
if (mBytes >= 256) if (mBytes >= 256)
{ {

View File

@ -13,8 +13,8 @@ public:
bool OpenFile(const char* fname); bool OpenFile(const char* fname);
void CloseFile(void); void CloseFile(void);
int WriteBytes(const uint8* data, ptrdiff_t size); int WriteBytes(const uint8* data, int size);
bool WriteFile(const char* fname, bool compressed, int interleave); bool WriteFile(const char* fname, bool compressed);
protected: protected:
uint8 mSectors[41][21][256]; uint8 mSectors[41][21][256];
@ -24,6 +24,6 @@ protected:
int AllocBAMTrack(int track); int AllocBAMTrack(int track);
uint8 * mDirEntry; 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; int t;
@ -134,14 +134,12 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mRegA = (t & 255); mRegA = (t & 255);
UpdateStatusCarry(mRegA, t >= 256); UpdateStatusCarry(mRegA, t >= 256);
if (cross) cycles++;
break; break;
case ASMIT_AND: case ASMIT_AND:
if (mode != ASMIM_IMMEDIATE) if (mode != ASMIM_IMMEDIATE)
addr = mMemory[addr]; addr = mMemory[addr];
mRegA &= addr; mRegA &= addr;
UpdateStatus(mRegA); UpdateStatus(mRegA);
if (cross) cycles++;
break; break;
case ASMIT_ASL: case ASMIT_ASL:
if (mode == ASMIM_IMPLIED) if (mode == ASMIM_IMPLIED)
@ -156,29 +154,19 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255; mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, t >= 256); UpdateStatusCarry(t & 255, t >= 256);
cycles += 2; cycles += 2;
if (indexed) cycles++;
} }
break; break;
case ASMIT_BCC: case ASMIT_BCC:
if (!(mRegP & STATUS_CARRY)) if (!(mRegP & STATUS_CARRY))
{
mIP = addr; mIP = addr;
cycles++;
}
break; break;
case ASMIT_BCS: case ASMIT_BCS:
if ((mRegP & STATUS_CARRY)) if ((mRegP & STATUS_CARRY))
{
mIP = addr; mIP = addr;
cycles++;
}
break; break;
case ASMIT_BEQ: case ASMIT_BEQ:
if ((mRegP & STATUS_ZERO)) if ((mRegP & STATUS_ZERO))
{
mIP = addr; mIP = addr;
cycles++;
}
break; break;
case ASMIT_BIT: case ASMIT_BIT:
t = mMemory[addr]; t = mMemory[addr];
@ -247,7 +235,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mRegP |= STATUS_OVERFLOW; mRegP |= STATUS_OVERFLOW;
UpdateStatusCarry(t & 255, t >= 256); UpdateStatusCarry(t & 255, t >= 256);
if (cross) cycles++;
break; break;
case ASMIT_CPX: case ASMIT_CPX:
if (mode != ASMIM_IMMEDIATE) if (mode != ASMIM_IMMEDIATE)
@ -288,7 +275,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255; mMemory[addr] = t & 255;
UpdateStatus(t & 255); UpdateStatus(t & 255);
cycles += 2; cycles += 2;
if (indexed) cycles++;
} }
break; break;
case ASMIT_DEX: case ASMIT_DEX:
@ -306,7 +292,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
addr = mMemory[addr]; addr = mMemory[addr];
mRegA ^= addr; mRegA ^= addr;
UpdateStatus(mRegA); UpdateStatus(mRegA);
if (cross) cycles++;
break; break;
case ASMIT_INC: case ASMIT_INC:
if (mode == ASMIM_IMPLIED) if (mode == ASMIM_IMPLIED)
@ -321,7 +306,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255; mMemory[addr] = t & 255;
UpdateStatus(t & 255); UpdateStatus(t & 255);
cycles += 2; cycles += 2;
if (indexed) cycles++;
} }
break; break;
case ASMIT_INX: case ASMIT_INX:
@ -350,21 +334,18 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
addr = mMemory[addr]; addr = mMemory[addr];
mRegA = addr; mRegA = addr;
UpdateStatus(mRegA); UpdateStatus(mRegA);
if (cross) cycles++;
break; break;
case ASMIT_LDX: case ASMIT_LDX:
if (mode != ASMIM_IMMEDIATE) if (mode != ASMIM_IMMEDIATE)
addr = mMemory[addr]; addr = mMemory[addr];
mRegX = addr; mRegX = addr;
UpdateStatus(mRegX); UpdateStatus(mRegX);
if (cross) cycles++;
break; break;
case ASMIT_LDY: case ASMIT_LDY:
if (mode != ASMIM_IMMEDIATE) if (mode != ASMIM_IMMEDIATE)
addr = mMemory[addr]; addr = mMemory[addr];
mRegY = addr; mRegY = addr;
UpdateStatus(mRegY); UpdateStatus(mRegY);
if (cross) cycles++;
break; break;
case ASMIT_LSR: case ASMIT_LSR:
if (mode == ASMIM_IMPLIED) if (mode == ASMIM_IMPLIED)
@ -381,7 +362,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255; mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, c != 0); UpdateStatusCarry(t & 255, c != 0);
cycles += 2; cycles += 2;
if (indexed) cycles++;
} }
break; break;
case ASMIT_NOP: case ASMIT_NOP:
@ -391,7 +371,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
addr = mMemory[addr]; addr = mMemory[addr];
mRegA |= addr; mRegA |= addr;
UpdateStatus(mRegA); UpdateStatus(mRegA);
if (cross) cycles++;
break; break;
case ASMIT_PHA: case ASMIT_PHA:
mMemory[0x100 + mRegS] = mRegA; mMemory[0x100 + mRegS] = mRegA;
@ -426,7 +405,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255; mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, t >= 256); UpdateStatusCarry(t & 255, t >= 256);
cycles+=2; cycles+=2;
if (indexed) cycles++;
} }
break; break;
case ASMIT_ROR: case ASMIT_ROR:
@ -444,7 +422,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mMemory[addr] = t & 255; mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, c != 0); UpdateStatusCarry(t & 255, c != 0);
cycles += 2; cycles += 2;
if (indexed) cycles++;
} }
break; break;
case ASMIT_RTI: case ASMIT_RTI:
@ -467,7 +444,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
mRegA = (t & 255); mRegA = (t & 255);
UpdateStatusCarry(t & 255, t >= 256); UpdateStatusCarry(t & 255, t >= 256);
if (cross) cycles++;
break; break;
case ASMIT_SEC: case ASMIT_SEC:
mRegP |= STATUS_CARRY; mRegP |= STATUS_CARRY;
@ -478,7 +454,6 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
break; break;
case ASMIT_STA: case ASMIT_STA:
mMemory[addr] = mRegA; mMemory[addr] = mRegA;
if (indexed) cycles++;
break; break;
case ASMIT_STX: case ASMIT_STX:
mMemory[addr] = mRegX; mMemory[addr] = mRegX;
@ -537,13 +512,13 @@ int Emulator::Emulate(int startIP, int trace)
mMemory[0x1fe] = 0xff; mMemory[0x1fe] = 0xff;
mMemory[0x1ff] = 0xff; mMemory[0x1ff] = 0xff;
int tcycles = 0, cycles = 0; int ticks = 0;
int iip = 0;
while (mIP != 0) while (mIP != 0)
{ {
if (mJiffies) if (mJiffies)
{ {
if (cycles >= tcycles + 16667) ticks++;
if (ticks > 4500)
{ {
mMemory[0xa2]++; mMemory[0xa2]++;
if (!mMemory[0xa2]) if (!mMemory[0xa2])
@ -554,7 +529,7 @@ int Emulator::Emulate(int startIP, int trace)
mMemory[0xa0]++; mMemory[0xa0]++;
} }
} }
tcycles += 16667; ticks = 0;
} }
} }
@ -581,16 +556,11 @@ int Emulator::Emulate(int startIP, int trace)
mRegS += 2; mRegS += 2;
} }
uint8 opcode = mMemory[mIP]; uint8 opcode = mMemory[mIP];
AsmInsData d = DecInsData[opcode]; AsmInsData d = DecInsData[opcode];
int addr = 0, taddr; int addr = 0, taddr;
int ip = mIP; int ip = mIP;
int iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1];
if (ip == 0x0862)
iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1] + mRegY;
bool cross = false, indexed = false;
int icycles = 0;
mIP++; mIP++;
switch (d.mMode) switch (d.mMode)
@ -598,60 +568,56 @@ int Emulator::Emulate(int startIP, int trace)
case ASMIM_IMPLIED: case ASMIM_IMPLIED:
if (trace & 2) 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); 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; break;
case ASMIM_IMMEDIATE: case ASMIM_IMMEDIATE:
addr = mMemory[mIP++]; addr = mMemory[mIP++];
if (trace & 2) 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); 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; break;
case ASMIM_ZERO_PAGE: case ASMIM_ZERO_PAGE:
addr = mMemory[mIP++]; addr = mMemory[mIP++];
if (trace & 2) 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]); 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; break;
case ASMIM_ZERO_PAGE_X: case ASMIM_ZERO_PAGE_X:
taddr = mMemory[mIP++]; taddr = mMemory[mIP++];
addr = (taddr + mRegX) & 0xff; addr = (taddr + mRegX) & 0xff;
if (trace & 2) 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]); 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; break;
case ASMIM_ZERO_PAGE_Y: case ASMIM_ZERO_PAGE_Y:
taddr = mMemory[mIP++]; taddr = mMemory[mIP++];
addr = (taddr + mRegY) & 0xff; addr = (taddr + mRegY) & 0xff;
if (trace & 2) 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]); 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; break;
case ASMIM_ABSOLUTE: case ASMIM_ABSOLUTE:
addr = mMemory[mIP] + 256 * mMemory[mIP + 1]; addr = mMemory[mIP] + 256 * mMemory[mIP + 1];
if (trace & 2) 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]); 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; mIP += 2;
icycles = 4; mCycles[ip] += 4;
break; break;
case ASMIM_ABSOLUTE_X: case ASMIM_ABSOLUTE_X:
taddr = mMemory[mIP] + 256 * mMemory[mIP + 1]; taddr = mMemory[mIP] + 256 * mMemory[mIP + 1];
addr = (taddr + mRegX) & 0xffff; addr = (taddr + mRegX) & 0xffff;
cross = mMemory[mIP] + mRegX >= 256;
indexed = true;
if (trace & 2) 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]); 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; mIP += 2;
icycles = 4; mCycles[ip] += 5;
break; break;
case ASMIM_ABSOLUTE_Y: case ASMIM_ABSOLUTE_Y:
taddr = mMemory[mIP] + 256 * mMemory[mIP + 1]; taddr = mMemory[mIP] + 256 * mMemory[mIP + 1];
addr = (taddr + mRegY) & 0xffff; addr = (taddr + mRegY) & 0xffff;
cross = mMemory[mIP] + mRegY >= 256;
indexed = true;
if (trace & 2) 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]); 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; mIP += 2;
icycles = 4; mCycles[ip] += 5;
break; break;
case ASMIM_INDIRECT: case ASMIM_INDIRECT:
taddr = mMemory[mIP] + 256 * mMemory[mIP + 1]; 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]; addr = mMemory[taddr] + 256 * mMemory[taddr + 1];
if (trace & 2) 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); 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; break;
case ASMIM_INDIRECT_X: case ASMIM_INDIRECT_X:
taddr = (mMemory[mIP++] + mRegX) & 0xff; taddr = (mMemory[mIP++] + mRegX) & 0xff;
addr = mMemory[taddr] + 256 * mMemory[taddr + 1]; addr = mMemory[taddr] + 256 * mMemory[taddr + 1];
if (trace & 2) 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]); 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; break;
case ASMIM_INDIRECT_Y: case ASMIM_INDIRECT_Y:
taddr = mMemory[mIP++]; taddr = mMemory[mIP++];
addr = (mMemory[taddr] + 256 * mMemory[taddr + 1] + mRegY) & 0xffff; addr = (mMemory[taddr] + 256 * mMemory[taddr + 1] + mRegY) & 0xffff;
cross = mMemory[taddr] + mRegY >= 256;
indexed = true;
if (trace & 2) 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]); 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; break;
case ASMIM_RELATIVE: case ASMIM_RELATIVE:
taddr = mMemory[mIP++]; taddr = mMemory[mIP++];
@ -685,7 +649,7 @@ int Emulator::Emulate(int startIP, int trace)
addr = taddr + mIP; addr = taddr + mIP;
if (trace & 2) 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); 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; 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; return -1;
mCycles[ip] += icycles;
cycles += icycles;
} }
if (mRegS == 0xff) if (mRegS == 0xff)

View File

@ -22,7 +22,7 @@ public:
int Emulate(int startIP, int trace); int Emulate(int startIP, int trace);
void DumpProfile(void); 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: protected:
void UpdateStatus(uint8 result); void UpdateStatus(uint8 result);
void UpdateStatusCarry(uint8 result, bool carry); void UpdateStatusCarry(uint8 result, bool carry);

View File

@ -4,18 +4,11 @@
#include <stdlib.h> #include <stdlib.h>
Errors::Errors(void) 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) void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2)
{ {
if (!info1) if (!info1)
@ -29,44 +22,29 @@ 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) 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"; level = "error";
if (eid >= EERR_GENERIC) mErrorCount++;
{
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);
} }
else if (eid >= EWARN_GENERIC)
{
level = "warning";
}
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");
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
exit(20);
} }

View File

@ -1,8 +1,5 @@
#pragma once #pragma once
#include "NumberSet.h"
class Location class Location
{ {
public: public:
@ -13,11 +10,7 @@ public:
Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {} Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {}
Location(const Location& loc, const Location* from) Location(const Location& loc, const Location* from)
: mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from) : mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from)
{ {}
static volatile int k;
if (from)
k = from->mLine;
}
}; };
class Ident; class Ident;
@ -28,7 +21,6 @@ enum ErrorID
EINFO_EXPANDED = 1001, EINFO_EXPANDED = 1001,
EINFO_ORIGINAL_DEFINITION = 1002, EINFO_ORIGINAL_DEFINITION = 1002,
EINFO_CALLED_FROM = 1003, EINFO_CALLED_FROM = 1003,
EINFO_SIZE = 1004,
EWARN_GENERIC = 2000, EWARN_GENERIC = 2000,
EWARN_CONSTANT_TRUNCATED, EWARN_CONSTANT_TRUNCATED,
@ -46,13 +38,6 @@ enum ErrorID
EWARN_DESTRUCTOR_MISMATCH, EWARN_DESTRUCTOR_MISMATCH,
EWARN_NUMERIC_0_USED_AS_NULLPTR, EWARN_NUMERIC_0_USED_AS_NULLPTR,
EWARN_FLOAT_TO_INT, 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_GENERIC = 3000,
EERR_FILE_NOT_FOUND, EERR_FILE_NOT_FOUND,
@ -109,10 +94,6 @@ enum ErrorID
EERR_INVALID_CAPTURE, EERR_INVALID_CAPTURE,
EERR_INVALID_PACK_USAGE, EERR_INVALID_PACK_USAGE,
EERR_INVALID_FOLD_EXPRESSION, EERR_INVALID_FOLD_EXPRESSION,
ERRR_INSTANTIATE_ABSTRACT_CLASS,
ERRR_INVALID_GOTO,
EERR_INVALID_INITIALIZER,
ERRR_INVALID_VOID_POINTER_ARITHMETIC,
EERR_INVALID_CONSTEXPR, EERR_INVALID_CONSTEXPR,
EERR_DOUBLE_FREE, EERR_DOUBLE_FREE,
@ -121,19 +102,12 @@ enum ErrorID
ERRR_STACK_OVERFLOW, ERRR_STACK_OVERFLOW,
ERRR_INVALID_NUMBER, ERRR_INVALID_NUMBER,
EERR_OVERLAPPING_DATA_SECTIONS, EERR_OVERLAPPING_DATA_SECTIONS,
EERR_ASSEMBLER_LIMIT,
EERR_INVALID_PREPROCESSOR, EERR_INVALID_PREPROCESSOR,
EERR_INVALID_CLASS_INITIALIZER,
EERR_CALL_OF_DELETED_FUNCTION,
EERR_STATIC_ASSERT,
EFATAL_GENERIC = 4000, EFATAL_GENERIC = 4000,
EFATAL_OUT_OF_MEMORY, EFATAL_OUT_OF_MEMORY,
EFATAL_MACRO_EXPANSION_DEPTH, EFATAL_MACRO_EXPANSION_DEPTH,
ERROR_MAX = 5000
}; };
class Errors class Errors
@ -141,12 +115,7 @@ class Errors
public: public:
Errors(void); Errors(void);
ErrorID SetMinLevel(ErrorID id);
int mErrorCount; 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 Ident* info1, const Ident* info2 = nullptr);
void Error(const Location& loc, ErrorID eid, const char* msg, const char* info1 = nullptr, const char* 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" #include "GlobalAnalyzer.h"
GlobalAnalyzer::GlobalAnalyzer(Errors* errors, Linker* linker) 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) void GlobalAnalyzer::AutoInline(void)
{ {
for (int i = 0; i < mFunctions.Size(); i++)
TopoSort(mFunctions[i]);
bool changed = false; bool changed = false;
do do
{ {
changed = false; changed = false;
// Reverse order, to check inline from bottom to top of call graph for (int i = 0; i < mFunctions.Size(); i++)
for (int i = 0; i< mTopoFunctions.Size(); i++)
{ {
Declaration* f = mTopoFunctions[i]; Declaration* f = mFunctions[i];
if (!(f->mFlags & DTF_INLINE) &&
if (f->mType == DT_CONST_FUNCTION &&
!(f->mFlags & DTF_INLINE) &&
!(f->mFlags & DTF_EXPORT) && !(f->mFlags & DTF_EXPORT) &&
!(f->mFlags & DTF_PREVENT_INLINE) && !(f->mFlags & DTF_PREVENT_INLINE) &&
!(f->mBase->mFlags & DTF_VARIADIC) && !(f->mBase->mFlags & DTF_VARIADIC) &&
!(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_FUNC_VARIABLE) &&
!((f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_REQUEST_INLINE)) && !((f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_REQUEST_INLINE)) &&
!(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_INTRINSIC) &&
!(f->mFlags & DTF_FUNC_RECURSIVE) && !(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100)
!(f->mFlags & DTF_FUNC_NO_RETURN))
{ {
int nparams = 0; int nparams = 0;
Declaration* dec = f->mBase->mParams; Declaration* dec = f->mBase->mParams;
@ -200,39 +159,21 @@ void GlobalAnalyzer::AutoInline(void)
dec = dec->mNext; dec = dec->mNext;
} }
int invokes = CallerInvokes(f); int cost = (f->mComplexity - 20 * nparams - 20);
int cost = (f->mComplexity - 20 * nparams - 10);
// 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; 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; 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) 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; f->mFlags |= DTF_INLINE;
for (int j = 0; j < f->mCallers.Size(); j++) 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) if (procDec->mValue && procDec->mValue->mType == EX_DISPATCH)
{ {
Declaration* maxf = nullptr, * reff = nullptr; Declaration* maxf = nullptr;
bool stackCall = false; bool stackCall = false;
@ -402,10 +343,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
Declaration* cf = procDec->mCalled[i]; Declaration* cf = procDec->mCalled[i];
if (cf->mBase->mFlags & DTF_STACKCALL) if (cf->mBase->mFlags & DTF_STACKCALL)
{
stackCall = true; stackCall = true;
reff = cf;
}
if (!maxf) if (!maxf)
maxf = cf; maxf = cf;
@ -413,9 +351,6 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
maxf = cf; maxf = cf;
} }
if (!reff)
reff = maxf;
for (int i = 0; i < procDec->mCalled.Size(); i++) for (int i = 0; i < procDec->mCalled.Size(); i++)
{ {
Declaration* cf = procDec->mCalled[i]; Declaration* cf = procDec->mCalled[i];
@ -426,9 +361,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
cf->mBase->mFlags |= DTF_STACKCALL; 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) while (fp)
{ {
fp->mVarIndex = mp->mVarIndex; fp->mVarIndex = mp->mVarIndex;
@ -437,11 +372,10 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
} }
assert(!mp); assert(!mp);
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize; cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize;
} }
if (cf != maxf)
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
} }
procDec->mFastCallBase = procDec->mBase->mFastCallBase; procDec->mFastCallBase = procDec->mBase->mFastCallBase;
@ -481,7 +415,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
fplimit += 256; fplimit += 256;
} }
if (procDec->mBase->mBase->IsComplexStruct()) if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
{ {
if (nbase < numfpzero && nbase + 2 > numfpzero) if (nbase < numfpzero && nbase + 2 > numfpzero)
nbase = numfpzero; nbase = numfpzero;
@ -633,13 +567,6 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
{ {
dec->mFlags |= DTF_FUNC_ANALYZING; 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); mFunctions.Push(dec);
Declaration* pdec = dec->mBase->mParams; Declaration* pdec = dec->mBase->mParams;
@ -652,8 +579,6 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
dec->mFlags |= DTF_ANALYZED; dec->mFlags |= DTF_ANALYZED;
dec->mFlags |= DTF_FUNC_INTRSAVE; 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) if (dec->mFlags & DTF_INTERRUPT)
dec->mFlags |= DTF_FUNC_INTRCALLED; dec->mFlags |= DTF_FUNC_INTRCALLED;
@ -665,7 +590,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS) if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS)
dec->mFlags |= DTF_FUNC_CONSTEXPR; dec->mFlags |= DTF_FUNC_CONSTEXPR;
dec->mFlags |= DTF_FUNC_PURE; dec->mFlags |= DTF_FUNC_PURE;
Analyze(exp, dec, 0); Analyze(exp, dec, false);
Declaration* pdec = dec->mBase->mParams; Declaration* pdec = dec->mBase->mParams;
int vi = 0; int vi = 0;
@ -685,7 +610,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
} }
else 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) if (cexp)
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here"); 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) else if (adec->mType == DT_VARIABLE_REF)
{ {
if (adec->mBase->mFlags & DTF_GLOBAL) if (adec->mBase->mFlags & DTF_GLOBAL)
{
AnalyzeGlobalVariable(adec->mBase); AnalyzeGlobalVariable(adec->mBase);
adec->mBase->mFlags |= DTF_VAR_ALIASING;
}
} }
else if (adec->mType == DT_LABEL) else if (adec->mType == DT_LABEL)
{ {
@ -725,10 +647,7 @@ void GlobalAnalyzer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
else if (adec->mType == DT_VARIABLE) else if (adec->mType == DT_VARIABLE)
{ {
if (adec->mFlags & DTF_GLOBAL) if (adec->mFlags & DTF_GLOBAL)
{
AnalyzeGlobalVariable(adec); AnalyzeGlobalVariable(adec);
adec->mFlags |= DTF_VAR_ALIASING;
}
} }
else if (adec->mType == DT_FUNCTION_REF) else if (adec->mType == DT_FUNCTION_REF)
{ {
@ -761,7 +680,7 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
if (dec->mValue) if (dec->mValue)
{ {
Analyze(dec->mValue, dec, 0); Analyze(dec->mValue, dec, false);
} }
} }
} }
@ -771,19 +690,17 @@ void GlobalAnalyzer::AnalyzeInit(Declaration* mdec)
while (mdec) while (mdec)
{ {
if (mdec->mValue) if (mdec->mValue)
RegisterProc(Analyze(mdec->mValue, mdec, 0)); RegisterProc(Analyze(mdec->mValue, mdec, false));
else if (mdec->mParams) else if (mdec->mParams)
AnalyzeInit(mdec->mParams); AnalyzeInit(mdec->mParams);
mdec = mdec->mNext; mdec = mdec->mNext;
} }
} }
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uint32 flags) Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs)
{ {
Declaration* ldec, * rdec; Declaration* ldec, * rdec;
exp->mFlags = flags;
switch (exp->mType) switch (exp->mType)
{ {
case EX_ERROR: case EX_ERROR:
@ -801,7 +718,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
} }
else if (exp->mDecValue->mType == DT_CONST_POINTER) 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) if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING; ldec->mFlags |= DTF_VAR_ALIASING;
RegisterProc(ldec); RegisterProc(ldec);
@ -817,22 +734,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
return exp->mDecValue; return exp->mDecValue;
case EX_VARIABLE: case EX_VARIABLE:
if (exp->mDecType->IsSimpleType())
procDec->mComplexity += 5 * exp->mDecType->mSize;
else
procDec->mComplexity += 10;
if (mCompilerOptions & COPT_DEBUGINFO) if (mCompilerOptions & COPT_DEBUGINFO)
exp->mDecValue->mReferences.Push(exp); 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)) if ((exp->mDecValue->mFlags & DTF_STATIC) || (exp->mDecValue->mFlags & DTF_GLOBAL))
{ {
Declaration* type = exp->mDecValue->mBase; Declaration* type = exp->mDecValue->mBase;
@ -842,14 +746,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (!(type->mFlags & DTF_CONST)) if (!(type->mFlags & DTF_CONST))
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (flags & ANAFL_LHS) if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE; procDec->mFlags &= ~DTF_FUNC_PURE;
AnalyzeGlobalVariable(exp->mDecValue); AnalyzeGlobalVariable(exp->mDecValue);
} }
else else
{ {
if (flags & ANAFL_LHS) if (lhs)
exp->mDecValue->mFlags |= DTF_VAR_ADDRESS; exp->mDecValue->mFlags |= DTF_VAR_ADDRESS;
if (!(exp->mDecValue->mFlags & DTF_ANALYZED)) if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
@ -861,10 +765,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
return exp->mDecValue; return exp->mDecValue;
case EX_INITIALIZATION: case EX_INITIALIZATION:
case EX_ASSIGNMENT: 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); ldec = Analyze(exp->mLeft, procDec, true);
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS); rdec = Analyze(exp->mRight, procDec, false);
if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT) 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; exp->mLeft->mDecValue->mFlags |= DTF_VAR_ALIASING;
RegisterProc(rdec); RegisterProc(rdec);
@ -873,33 +777,33 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_BINARY: case EX_BINARY:
procDec->mComplexity += 10 * exp->mDecType->mSize; procDec->mComplexity += 10 * exp->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS); ldec = Analyze(exp->mLeft, procDec, lhs);
rdec = Analyze(exp->mRight, procDec, flags & ~ANAFL_ALIAS); rdec = Analyze(exp->mRight, procDec, lhs);
return ldec; return ldec;
case EX_RELATIONAL: case EX_RELATIONAL:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, ANAFL_RHS); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS); rdec = Analyze(exp->mRight, procDec, false);
return TheBoolTypeDeclaration; return TheBoolTypeDeclaration;
case EX_PREINCDEC: case EX_PREINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; 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: case EX_PREFIX:
if (exp->mToken == TK_BINARY_AND) 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) if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING; ldec->mFlags |= DTF_VAR_ALIASING;
} }
else if (exp->mToken == TK_MUL) else if (exp->mToken == TK_MUL)
{ {
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (flags & ANAFL_LHS) if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE; procDec->mFlags &= ~DTF_FUNC_PURE;
return exp->mDecType; return exp->mDecType;
@ -908,14 +812,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
{ {
return TheUnsignedCharTypeDeclaration; return TheUnsignedCharTypeDeclaration;
} }
else if (exp->mToken == TK_SIZEOF)
{
return TheUnsignedIntTypeDeclaration;
}
else else
{ {
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, 0); return Analyze(exp->mLeft, procDec, false);
} }
break; break;
case EX_POSTFIX: case EX_POSTFIX:
@ -924,31 +824,31 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_POSTINCDEC: case EX_POSTINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; 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: 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) if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
{ {
ldec = ldec->mBase; ldec = ldec->mBase;
if (ldec->mType == DT_TYPE_POINTER) if (ldec->mType == DT_TYPE_POINTER)
{ {
if (flags & ANAFL_LHS) if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE; procDec->mFlags &= ~DTF_FUNC_PURE;
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
} }
} }
rdec = Analyze(exp->mRight, procDec, 0); rdec = Analyze(exp->mRight, procDec, false);
if (ldec->mBase) if (ldec->mBase)
return ldec->mBase; return ldec->mBase;
break; break;
case EX_QUALIFY: case EX_QUALIFY:
Analyze(exp->mLeft, procDec, flags); Analyze(exp->mLeft, procDec, lhs);
return exp->mDecValue->mBase; return exp->mDecValue->mBase;
case EX_DISPATCH: case EX_DISPATCH:
procDec->mFlags |= DTF_PREVENT_INLINE; procDec->mFlags |= DTF_PREVENT_INLINE;
Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS); Analyze(exp->mLeft, procDec, lhs);
// RegisterCall(procDec, exp->mLeft->mDecType); // RegisterCall(procDec, exp->mLeft->mDecType);
break; break;
case EX_VCALL: case EX_VCALL:
@ -959,20 +859,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_INLINE: case EX_INLINE:
procDec->mComplexity += 10; procDec->mComplexity += 10;
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue) if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
{ {
} }
else else
{ {
if (exp->mType == EX_INLINE) RegisterCall(procDec, ldec);
{
for (int i = 0; i < ldec->mCalled.Size(); i++)
RegisterCall(procDec, ldec->mCalled[i]);
}
else
RegisterCall(procDec, ldec);
if (!(GetProcFlags(ldec) & (DTF_FUNC_INTRSAVE | DTF_INTERRUPT))) if (!(GetProcFlags(ldec) & (DTF_FUNC_INTRSAVE | DTF_INTERRUPT)))
{ {
procDec->mFlags &= ~DTF_FUNC_INTRSAVE; 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))) 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; 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) if (pdec)
pdec = pdec->mNext; pdec = pdec->mNext;
@ -1060,12 +954,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
break; break;
case EX_LIST: case EX_LIST:
case EX_COMMA: case EX_COMMA:
RegisterProc(Analyze(exp->mLeft, procDec, 0)); RegisterProc(Analyze(exp->mLeft, procDec, false));
return Analyze(exp->mRight, procDec, 0); return Analyze(exp->mRight, procDec, false);
case EX_RETURN: case EX_RETURN:
if (exp->mLeft) 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 && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
{ {
if (procDec->mBase->mBase->mMoveConstructor) 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); AnalyzeProcedure(exp, procDec->mBase->mBase->mCopyConstructor->mValue, procDec->mBase->mBase->mCopyConstructor);
RegisterCall(procDec, procDec->mBase->mBase->mCopyConstructor); RegisterCall(procDec, procDec->mBase->mBase->mCopyConstructor);
} }
procDec->mFlags &= ~DTF_FUNC_NO_RETURN;
} }
break; break;
case EX_SEQUENCE: case EX_SEQUENCE:
@ -1086,47 +978,47 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (exp->mType == EX_SEQUENCE) if (exp->mType == EX_SEQUENCE)
{ {
if (exp->mLeft) if (exp->mLeft)
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
exp = exp->mRight; exp = exp->mRight;
} }
else else
return Analyze(exp, procDec, 0); return Analyze(exp, procDec, false);
} while (exp); } while (exp);
break; break;
case EX_SCOPE: case EX_SCOPE:
Analyze(exp->mLeft, procDec, 0); Analyze(exp->mLeft, procDec, false);
break; break;
case EX_CONSTRUCT: case EX_CONSTRUCT:
if (exp->mLeft->mLeft) if (exp->mLeft->mLeft)
Analyze(exp->mLeft->mLeft, procDec, 0); Analyze(exp->mLeft->mLeft, procDec, false);
if (exp->mLeft->mRight) if (exp->mLeft->mRight)
Analyze(exp->mLeft->mRight, procDec, 0); Analyze(exp->mLeft->mRight, procDec, false);
if (exp->mRight) if (exp->mRight)
return Analyze(exp->mRight, procDec, 0); return Analyze(exp->mRight, procDec, false);
break; break;
case EX_CLEANUP: case EX_CLEANUP:
Analyze(exp->mRight, procDec, 0); Analyze(exp->mRight, procDec, false);
return Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS); return Analyze(exp->mLeft, procDec, lhs);
case EX_WHILE: case EX_WHILE:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
procDec->mComplexity += 20; procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, 0); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_IF: case EX_IF:
procDec->mComplexity += 20; procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight->mLeft, procDec, 0); rdec = Analyze(exp->mRight->mLeft, procDec, false);
if (exp->mRight->mRight) if (exp->mRight->mRight)
rdec = Analyze(exp->mRight->mRight, procDec, 0); rdec = Analyze(exp->mRight->mRight, procDec, false);
break; break;
case EX_ELSE: case EX_ELSE:
break; break;
@ -1136,23 +1028,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
procDec->mComplexity += 30; procDec->mComplexity += 30;
if (exp->mLeft->mRight) if (exp->mLeft->mRight)
ldec = Analyze(exp->mLeft->mRight, procDec, 0); ldec = Analyze(exp->mLeft->mRight, procDec, false);
if (exp->mLeft->mLeft->mLeft) if (exp->mLeft->mLeft->mLeft)
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, 0); ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, 0); rdec = Analyze(exp->mRight, procDec, false);
if (exp->mLeft->mLeft->mRight) if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0); ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false);
break;
case EX_FORBODY:
ldec = Analyze(exp->mLeft, procDec, 0);
if (exp->mRight)
Analyze(exp->mRight, procDec, 0);
break; break;
case EX_DO: case EX_DO:
procDec->mComplexity += 20; procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, 0); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_BREAK: case EX_BREAK:
case EX_CONTINUE: case EX_CONTINUE:
@ -1161,18 +1048,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_TYPE: case EX_TYPE:
break; break;
case EX_TYPECAST: case EX_TYPECAST:
return Analyze(exp->mLeft, procDec, 0); return Analyze(exp->mLeft, procDec, false);
break; break;
case EX_LOGICAL_AND: case EX_LOGICAL_AND:
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, 0); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_LOGICAL_OR: case EX_LOGICAL_OR:
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, 0); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_LOGICAL_NOT: case EX_LOGICAL_NOT:
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
break; break;
case EX_ASSEMBLER: case EX_ASSEMBLER:
procDec->mFlags |= DTF_FUNC_ASSEMBLER; procDec->mFlags |= DTF_FUNC_ASSEMBLER;
@ -1183,14 +1070,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_UNDEFINED: case EX_UNDEFINED:
break; break;
case EX_SWITCH: case EX_SWITCH:
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
exp = exp->mRight; exp = exp->mRight;
while (exp) while (exp)
{ {
procDec->mComplexity += 10; procDec->mComplexity += 10;
if (exp->mLeft->mRight) if (exp->mLeft->mRight)
rdec = Analyze(exp->mLeft->mRight, procDec, 0); rdec = Analyze(exp->mLeft->mRight, procDec, false);
exp = exp->mRight; exp = exp->mRight;
} }
break; break;
@ -1201,9 +1088,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_CONDITIONAL: case EX_CONDITIONAL:
procDec->mComplexity += exp->mDecType->mSize * 10; procDec->mComplexity += exp->mDecType->mSize * 10;
ldec = Analyze(exp->mLeft, procDec, 0); ldec = Analyze(exp->mLeft, procDec, false);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, flags)); RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs));
RegisterProc(Analyze(exp->mRight->mRight, procDec, flags)); RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs));
break; break;
} }

View File

@ -11,7 +11,6 @@ public:
~GlobalAnalyzer(void); ~GlobalAnalyzer(void);
void DumpCallGraph(void); void DumpCallGraph(void);
void TopoSort(Declaration * procDec);
void AutoInline(void); void AutoInline(void);
void CheckFastcall(Declaration* procDec, bool head); void CheckFastcall(Declaration* procDec, bool head);
void CheckInterrupt(void); void CheckInterrupt(void);
@ -28,14 +27,12 @@ protected:
Errors* mErrors; Errors* mErrors;
Linker* mLinker; Linker* mLinker;
GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions, mTopoFunctions; GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions;
GrowingArray<Declaration*> mGlobalVariables; GrowingArray<Declaration*> mGlobalVariables;
void AnalyzeInit(Declaration* mdec); 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 IsStackParam(const Declaration* pdec) const;
bool MarkCycle(Declaration* rootDec, Declaration* procDec); bool MarkCycle(Declaration* rootDec, Declaration* procDec);

View File

@ -60,7 +60,7 @@ void GlobalOptimizer::Reset(void)
mFunctions.SetSize(0); mFunctions.SetSize(0);
mGlobalVariables.SetSize(0); mGlobalVariables.SetSize(0);
mCalledFunctions.SetSize(0); mCalledFunctions.SetSize(0);
mCallingFunctions.SetSize(0); mCalledFunctions.SetSize(0);
} }
void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp) void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp)
@ -134,7 +134,7 @@ bool GlobalOptimizer::CheckConstReturns(Expression*& exp)
Expression* lexp = new Expression(exp->mLocation, EX_COMMA); Expression* lexp = new Expression(exp->mLocation, EX_COMMA);
lexp->mLeft = exp; lexp->mLeft = exp;
lexp->mRight = new Expression(pcall->mReturn->mLocation, EX_CONSTANT); 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->mRight->mDecType = exp->mDecType;
lexp->mDecType = exp->mDecType; lexp->mDecType = exp->mDecType;
exp->mDecType = TheVoidTypeDeclaration; exp->mDecType = TheVoidTypeDeclaration;
@ -160,7 +160,6 @@ bool GlobalOptimizer::CheckConstReturns(Expression*& exp)
lexp->mRight->mToken = TK_MUL; lexp->mRight->mToken = TK_MUL;
lexp->mRight->mLeft = pex; lexp->mRight->mLeft = pex;
lexp->mRight->mDecType = pcall->mBase->mBase; lexp->mRight->mDecType = pcall->mBase->mBase;
lexp->mDecType = lexp->mRight->mDecType;
exp->mDecType = TheVoidTypeDeclaration; exp->mDecType = TheVoidTypeDeclaration;
exp = lexp; exp = lexp;
return true; return true;
@ -189,7 +188,7 @@ bool GlobalOptimizer::CheckUnusedLocals(Expression*& exp)
if (vexp->mType == EX_VARIABLE) if (vexp->mType == EX_VARIABLE)
{ {
Declaration* vdec = vexp->mDecValue; 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; exp = exp->mRight;
return true; return true;
@ -243,19 +242,6 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
bool changed = false; bool changed = false;
if (exp) 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) if (exp->mType == EX_VARIABLE && exp->mDecValue == param)
{ {
exp->mType = EX_CONSTANT; exp->mType = EX_CONSTANT;
@ -264,39 +250,9 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
changed = true; changed = true;
} }
} if (ReplaceParamConst(exp->mLeft, param))
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))
changed = true; changed = true;
if (ReplaceGlobalConst(exp->mRight)) if (ReplaceParamConst(exp->mRight, param))
changed = true; changed = true;
} }
return changed; return changed;
@ -325,9 +281,6 @@ bool GlobalOptimizer::Optimize(void)
if (CheckConstReturns(func->mValue)) if (CheckConstReturns(func->mValue))
changed = true; changed = true;
if (ReplaceGlobalConst(func->mValue))
changed = true;
if (func->mOptFlags & OPTF_MULTI_CALL) if (func->mOptFlags & OPTF_MULTI_CALL)
{ {
Declaration* pdata = ftype->mParams; 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_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 #if DUMP_OPTS
printf("Remove return value\n"); printf("Remove return value\n");
@ -359,57 +312,54 @@ bool GlobalOptimizer::Optimize(void)
changed = true; changed = true;
} }
if (!(ftype->mFlags & DTF_VARIADIC))
Declaration* pdec = ftype->mParams;
int vi = 0;
while (pdec)
{ {
Declaration* pdec = ftype->mParams; pdec->mVarIndex += vi;
int vi = 0; if (!(pdec->mOptFlags & OPTF_VAR_USED) && !(pdec->mFlags & DTF_FPARAM_UNUSED))
while (pdec)
{ {
pdec->mVarIndex += vi; if (!pdec->mBase->IsReference() || !(pdec->mOptFlags & OPTF_VAR_ADDRESS))
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 DUMP_OPTS #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 #endif
vi += pdec->mSize - 2; vi -= pdec->mSize;
pdec->mBase = pdec->mBase->mBase; pdec->mFlags |= DTF_FPARAM_UNUSED;
pdec->mSize = pdec->mBase->mSize; pdec->mVarIndex = func->mNumVars++;
UndoParamReference(func->mValue, pdec);
changed = true; 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); Analyze(exp, procDec, false);
} }
else 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; procDec->mOptFlags &= ~OPTF_ANALYZING;
} }
@ -483,7 +433,8 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
{ {
if (adec->mBase->mFlags & DTF_GLOBAL) if (adec->mBase->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec->mBase); 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) else if (adec->mType == DT_LABEL)
{ {
@ -493,7 +444,8 @@ void GlobalOptimizer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
{ {
if (adec->mFlags & DTF_GLOBAL) if (adec->mFlags & DTF_GLOBAL)
AnalyzeGlobalVariable(adec); 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) 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* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
{ {
Declaration* ldec, * rdec; Declaration* ldec, * rdec;
@ -655,14 +610,14 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
AnalyzeGlobalVariable(exp->mDecValue); AnalyzeGlobalVariable(exp->mDecValue);
} }
if (flags & ANAFL_RHS) else
exp->mDecValue->mOptFlags |= OPTF_VAR_USED; {
if (flags & ANAFL_LHS) if (flags & ANAFL_RHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS; exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
if (exp->mDecValue->mBase->IsReference() && (flags & ANAFL_ASSIGN)) if (flags & ANAFL_LHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_USED; exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
}
if (exp->mDecValue->mType == DT_ARGUMENT && (flags & ANAFL_LHS)) if (exp->mDecValue->mType == DT_ARGUMENT)
{ {
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD; exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
exp->mDecValue->mForwardParam = nullptr; exp->mDecValue->mForwardParam = nullptr;
@ -672,12 +627,7 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_INITIALIZATION: case EX_INITIALIZATION:
case EX_ASSIGNMENT: case EX_ASSIGNMENT:
if (exp->mToken == TK_ASSIGN) if (exp->mToken == TK_ASSIGN)
{ ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
if (exp->mType == EX_ASSIGNMENT)
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ASSIGN | flags);
else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
}
else else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags); 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; 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 else
{ {
pdec->mOptFlags |= OPTF_VAR_NOCONST; pdec->mOptFlags |= OPTF_VAR_NOCONST;
@ -986,20 +920,13 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
if (exp->mLeft->mLeft->mRight) if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0); ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
break; break;
case EX_FORBODY:
ldec = Analyze(exp->mLeft, procDec, 0);
if (exp->mRight)
rdec = Analyze(exp->mRight, procDec, 0);
break;
case EX_DO: case EX_DO:
ldec = Analyze(exp->mRight, procDec, 0); ldec = Analyze(exp->mRight, procDec, 0);
rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS); rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
break; break;
case EX_BREAK: case EX_BREAK:
case EX_CONTINUE: case EX_CONTINUE:
break;
case EX_ASSUME: case EX_ASSUME:
return Analyze(exp->mLeft, procDec, ANAFL_RHS);
break; break;
case EX_TYPE: case EX_TYPE:
break; break;

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