Compare commits
313 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6ed4adb0ed | ||
|
f16c24363c | ||
|
fd7e68573c | ||
|
f1873f0794 | ||
|
a01d98e584 | ||
|
c7a53a5be6 | ||
|
4633631d7e | ||
|
100608e0ac | ||
|
35a0b36a0d | ||
|
5470db3a5f | ||
|
d6802f3cb9 | ||
|
5b4e0c2b55 | ||
|
8175fae67a | ||
|
13c90eb542 | ||
|
f98665c577 | ||
|
8843f3feba | ||
|
514cf59398 | ||
|
03c133cd48 | ||
|
880abea32e | ||
|
fc9a8f2a89 | ||
|
40c467d958 | ||
|
4bde6385b8 | ||
|
688ef958e3 | ||
|
6da7223472 | ||
|
a1d4bc8375 | ||
|
197e2a91be | ||
|
4d9d628b67 | ||
|
f720feebbf | ||
|
6076808f5e | ||
|
0af17f0f40 | ||
|
81e5321bfc | ||
|
27d3666285 | ||
|
c6b794db3a | ||
|
1fa4c39a20 | ||
|
0ba148b6bb | ||
|
65540da3f7 | ||
|
e660757824 | ||
|
05a6d16dde | ||
|
79ec9af3f2 | ||
|
8f37df448f | ||
|
d710a71ba0 | ||
|
8dd211b662 | ||
|
398ed22b09 | ||
|
6f1da4335b | ||
|
c86dc364b1 | ||
|
70eb7a5eab | ||
|
c1cd2ba57e | ||
|
00da0ef87d | ||
|
be9abbf510 | ||
|
0b72e6b2f2 | ||
|
6ea39d7bfa | ||
|
c0abe031ee | ||
|
fe667863b2 | ||
|
e514e05dc8 | ||
|
d978d0a483 | ||
|
37cacdafa7 | ||
|
78e3696663 | ||
|
a0215a4f21 | ||
|
2310416c46 | ||
|
52db653ec1 | ||
|
6fe76e478f | ||
|
ba05ec743d | ||
|
05ef25a61e | ||
|
b26cc4ede7 | ||
|
8dc5f703e8 | ||
|
c05d7e47f4 | ||
|
9dc8489693 | ||
|
f443c97f70 | ||
|
4837ceb73f | ||
|
42299c9406 | ||
|
850bbfc31a | ||
|
1e95f51469 | ||
|
e525e5d62e | ||
|
18deb8846d | ||
|
34ce9afeae | ||
|
d0411b7d52 | ||
|
34fda8c9b5 | ||
|
b4a357e44f | ||
|
2b224f262b | ||
|
3c306e0899 | ||
|
e82ab0c7ca | ||
|
983064c694 | ||
|
9230d95bad | ||
|
8b0790588b | ||
|
0a9c43757a | ||
|
fccfe35c4f | ||
|
064fed63f5 | ||
|
f43f471124 | ||
|
f99abb32e2 | ||
|
18f044e90c | ||
|
5b961c031c | ||
|
500cce511f | ||
|
885d6ff706 | ||
|
efc182ce27 | ||
|
06ef87fe63 | ||
|
f3d8251072 | ||
|
0d5efc90ed | ||
|
30b8e4e970 | ||
|
3da1ddf5da | ||
|
bfdd1b85fb | ||
|
686d468d32 | ||
|
23b15678cd | ||
|
d1054abd90 | ||
|
d358c8359b | ||
|
9e9494ebf9 | ||
|
015ada7a33 | ||
|
12e832ebd3 | ||
|
e327d2a148 | ||
|
366f9686dd | ||
|
a2927401bc | ||
|
bbb339d641 | ||
|
8e76334c20 | ||
|
739f1e2161 | ||
|
4ee6ca5b94 | ||
|
347898ea53 | ||
|
6caed58be4 | ||
|
c4185832ba | ||
|
2b0994b086 | ||
|
f9acbc152d | ||
|
3eed21567e | ||
|
f3370cb149 | ||
|
494fb97e49 | ||
|
bd8786af0b | ||
|
f0a7499814 | ||
|
da4a90b724 | ||
|
96a9109915 | ||
|
f5a33edcf4 | ||
|
1bd98bdeb2 | ||
|
e4696a6539 | ||
|
74350d6133 | ||
|
cbf86b2e8f | ||
|
cb757dfaf9 | ||
|
5ad94d01d4 | ||
|
cdba71b353 | ||
|
01d187cf83 | ||
|
ab06ce74c5 | ||
|
1e2b227113 | ||
|
9d5dbe67fe | ||
|
9a409ca347 | ||
|
449acece05 | ||
|
ee3f6fc4a5 | ||
|
e95b51609c | ||
|
323589a484 | ||
|
33f4b25f28 | ||
|
538d965636 | ||
|
4b99110533 | ||
|
94f2489083 | ||
|
6de1b1fd96 | ||
|
80abcdfe95 | ||
|
0dc6588a66 | ||
|
65ad05c608 | ||
|
2db8890453 | ||
|
3f4268328e | ||
|
33cabb487b | ||
|
ab2ca897ce | ||
|
2c37e150a9 | ||
|
ee68f2575a | ||
|
4f100266c3 | ||
|
c22a67f95f | ||
|
e6bc6371c9 | ||
|
2acca6d7b1 | ||
|
fc2095301d | ||
|
32f0b8c6f3 | ||
|
10c9b735e9 | ||
|
fefb511404 | ||
|
bedafe7b6f | ||
|
242d7f1700 | ||
|
90e892dfa5 | ||
|
c98e0751b0 | ||
|
f3b4a4e5fc | ||
|
1c7d71cadb | ||
|
840050738f | ||
|
2ee5cc7bf4 | ||
|
490180f9dc | ||
|
2582f3076d | ||
|
0032d42b2c | ||
|
5c70c20c6e | ||
|
71236aa405 | ||
|
31a38e2a62 | ||
|
ee0e4d5428 | ||
|
f6296e83e5 | ||
|
39840b5fb1 | ||
|
fe0bfccfaa | ||
|
25ee4e9b2b | ||
|
9f7d4c0ab0 | ||
|
038928232c | ||
|
100affa083 | ||
|
e27075955d | ||
|
0959a15b10 | ||
|
4a87e4d97b | ||
|
9de7caa68d | ||
|
e23d78eb86 | ||
|
d0b45fce78 | ||
|
0126dd53a3 | ||
|
901c8459ec | ||
|
746fed6704 | ||
|
54c0f2a670 | ||
|
28ea8ef24f | ||
|
115129e1dd | ||
|
f41d594015 | ||
|
c8abb42c3c | ||
|
95732265f6 | ||
|
9f834c4232 | ||
|
d10d8bf7ae | ||
|
f6a2db7866 | ||
|
d2fdbd29f5 | ||
|
f5dff9620b | ||
|
28e75a8fa2 | ||
|
6170c81af3 | ||
|
3d578170db | ||
|
d99499b6e3 | ||
|
950c434157 | ||
|
d6362a305f | ||
|
38bb033328 | ||
|
87f1ddd27f | ||
|
9e994560a7 | ||
|
e37de95079 | ||
|
8e46ae95ec | ||
|
e7cece0f0f | ||
|
890a4b996e | ||
|
5b2ae228cc | ||
|
9fc8315f92 | ||
|
32935cd7a1 | ||
|
fd02382d38 | ||
|
4fce263228 | ||
|
50c7e10814 | ||
|
7c8ab991be | ||
|
067e169803 | ||
|
ccdbbe799a | ||
|
fac53cfd54 | ||
|
cfe2c7bed5 | ||
|
f0b9b5cce4 | ||
|
803b868356 | ||
|
907452d918 | ||
|
c12bca7b4e | ||
|
e1736c8214 | ||
|
d3e7a991a4 | ||
|
e7b0d17a83 | ||
|
df18dc273e | ||
|
b6341e402d | ||
|
3f2f703936 | ||
|
4acee4531c | ||
|
2a476d3372 | ||
|
0a41cb044c | ||
|
5a0f736d41 | ||
|
020534dbc8 | ||
|
cee2801847 | ||
|
51c38a4723 | ||
|
bb01d1024a | ||
|
903a5d9b8b | ||
|
e360dea558 | ||
|
582443ef5c | ||
|
80a42216c7 | ||
|
6576f4d090 | ||
|
55e983e5a1 | ||
|
a6f9c733a1 | ||
|
3c129ff4e5 | ||
|
db386a5958 | ||
|
179cc694e3 | ||
|
887a51b176 | ||
|
5b81379dac | ||
|
4fff9f7060 | ||
|
40c407782d | ||
|
5946f17632 | ||
|
7e0ff7449c | ||
|
d597219aea | ||
|
a311396cf8 | ||
|
94607cab7f | ||
|
4d193a30b0 | ||
|
c1ad265f47 | ||
|
4e2a2c99ba | ||
|
ea33f253d4 | ||
|
ebc41560d9 | ||
|
2d2c696aa4 | ||
|
b622c25a56 | ||
|
439cf499ed | ||
|
cd5f1daaba | ||
|
ec95f6dc98 | ||
|
66dfe5df46 | ||
|
9117827cfc | ||
|
ad115701d5 | ||
|
a15125d6af | ||
|
dadd8eb41c | ||
|
056b49e1d1 | ||
|
1f492e7820 | ||
|
4c687dfa54 | ||
|
e1f5bdf48b | ||
|
3ba7e0a8a4 | ||
|
a71fae5bb1 | ||
|
f6c78d57ef | ||
|
6af50f5eae | ||
|
62ab925e01 | ||
|
5126ba482e | ||
|
fb477b33f7 | ||
|
756fe9354a | ||
|
73c2206a1a | ||
|
c1071ecd3c | ||
|
534ddc3a4c | ||
|
ebce50320f | ||
|
cfd2e5142a | ||
|
581137ade7 | ||
|
c3b46d6a78 | ||
|
84a8bf22e8 | ||
|
daeb3ddfdd | ||
|
bf5f5a807c | ||
|
3dfba389ff | ||
|
a4f1341587 | ||
|
57d8747cb7 | ||
|
1fb68c1bf3 | ||
|
5613a719c5 | ||
|
bf6343616b | ||
|
861eeaefe2 | ||
|
db3c6a3135 |
|
@ -0,0 +1,67 @@
|
|||
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
|
||||
)
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
rem @echo off
|
||||
|
||||
@call :test rolrortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test bitfields.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -15,6 +18,9 @@ rem @echo off
|
|||
@call :testh opp_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_static_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_vector_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -33,7 +39,7 @@ rem @echo off
|
|||
@call :testh opp_list.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_functional.cpp
|
||||
@call :testn opp_functional.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh operatoroverload.cpp
|
||||
|
@ -51,7 +57,7 @@ rem @echo off
|
|||
@call :testh constructortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh copyconstructor.cpp
|
||||
@call :testn copyconstructor.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh copyassign.cpp
|
||||
|
@ -274,6 +280,15 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O0 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -331,6 +346,12 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
||||
:testb
|
||||
|
@ -370,4 +391,10 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int t, n;
|
||||
|
||||
|
@ -161,7 +162,7 @@ void test_return_value(void)
|
|||
C2 c(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_return_reference(void)
|
||||
|
@ -184,7 +185,7 @@ void test_retparam_value(void)
|
|||
test_param_fv(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_retparam_reference(void)
|
||||
|
@ -200,7 +201,6 @@ void test_retparam_reference(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
#if 0
|
||||
test_dcopy_init();
|
||||
test_copy_init();
|
||||
test_minit();
|
||||
|
@ -208,9 +208,8 @@ int main(void)
|
|||
test_param_value();
|
||||
test_param_ref();
|
||||
test_return_value();
|
||||
#endif
|
||||
test_retparam_value();
|
||||
// test_retparam_reference();
|
||||
test_retparam_reference();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -50,5 +50,11 @@ autorefreturn: autorefreturn.cpp
|
|||
$(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:
|
||||
@$(RM) *.asm *.bcs *.int *.lbl *.map *.prg
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#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;
|
||||
}
|
|
@ -64,5 +64,15 @@ int main(void)
|
|||
opp::cout << i << ", ";
|
||||
opp::cout << "\n";
|
||||
|
||||
assert(v.size() == 36);
|
||||
assert(v[18] == 60);
|
||||
|
||||
v.assign(42, 11);
|
||||
|
||||
assert(v.size() == 42);
|
||||
assert(v[0] == 11);
|
||||
assert(v[15] == 11);
|
||||
assert(v[41] == 11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#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;
|
||||
}
|
|
@ -63,6 +63,33 @@ bool nge(long a, long b)
|
|||
|
||||
|
||||
|
||||
|
||||
inline bool ieq(long a, long b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
inline bool ilt(long a, long b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
inline bool igt(long a, long b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
inline bool ile(long a, long b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
inline bool ige(long a, long b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
|
||||
bool beqz(long a)
|
||||
{
|
||||
return a == 0;
|
||||
|
@ -188,7 +215,71 @@ bool nge1(long a)
|
|||
|
||||
|
||||
|
||||
void cmp(long a, long b)
|
||||
bool beqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
bool bltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
bool bgtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
bool blem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
bool bgem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool neqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
#pragma native(neqm)
|
||||
|
||||
bool nltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
#pragma native(nltm)
|
||||
|
||||
bool ngtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
#pragma native(ngtm)
|
||||
|
||||
bool nlem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
#pragma native(nlem)
|
||||
|
||||
bool ngem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
#pragma native(ngem)
|
||||
|
||||
|
||||
|
||||
void cmpc(long a, long b)
|
||||
{
|
||||
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);
|
||||
|
@ -203,6 +294,27 @@ void cmp(long a, long b)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpi(long a, long b)
|
||||
{
|
||||
bool ieqf = ieq(a, b), iltf = ilt(a, b), igtf = igt(a, b), ilef = ile(a, b), igef = ige(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
||||
printf("INLINE %ld, %ld : EQ %d LT %d GT %d\r", a, b, ieqf, iltf, igtf);
|
||||
printf("NATIVE %ld, %ld : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
|
||||
|
||||
assert(ieqf == neqf);
|
||||
assert(iltf == nltf);
|
||||
assert(igtf == ngtf);
|
||||
assert(ilef == nlef);
|
||||
assert(igef == ngef);
|
||||
}
|
||||
|
||||
void cmp(long a, long b)
|
||||
{
|
||||
cmpc(a, b);
|
||||
cmpi(a, b);
|
||||
}
|
||||
|
||||
void cmpz(long a)
|
||||
{
|
||||
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
|
||||
|
@ -233,6 +345,21 @@ void cmp1(long a)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpm(long a)
|
||||
{
|
||||
bool beqf = beqm(a), bltf = bltm(a), bgtf = bgtm(a), blef = blem(a), bgef = bgem(a);
|
||||
bool neqf = neqm(a), nltf = nltm(a), ngtf = ngtm(a), nlef = nlem(a), ngef = ngem(a);
|
||||
|
||||
printf("BYTE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
|
||||
printf("NATIVE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, neqf, nltf, ngtf, nlef, ngef);
|
||||
|
||||
assert(beqf == neqf);
|
||||
assert(bltf == nltf);
|
||||
assert(bgtf == ngtf);
|
||||
assert(blef == nlef);
|
||||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cmp( 0, 1);
|
||||
|
@ -327,6 +454,10 @@ int main(void)
|
|||
cmp1(256);
|
||||
cmp1(10000);
|
||||
cmp1(20000);
|
||||
cmp1(1000000l);
|
||||
cmp1(2000000l);
|
||||
cmp1(100000000l);
|
||||
cmp1(200000000l);
|
||||
cmp1(-1);
|
||||
cmp1(-2);
|
||||
cmp1(-3);
|
||||
|
@ -334,6 +465,34 @@ int main(void)
|
|||
cmp1(-256);
|
||||
cmp1(-10000);
|
||||
cmp1(-20000);
|
||||
cmp1(-1000000l);
|
||||
cmp1(-2000000l);
|
||||
cmp1(-100000000l);
|
||||
cmp1(-200000000l);
|
||||
|
||||
cmpm(0);
|
||||
cmpm(1);
|
||||
cmpm(2);
|
||||
cmpm(3);
|
||||
cmpm(255);
|
||||
cmpm(256);
|
||||
cmpm(10000);
|
||||
cmpm(20000);
|
||||
cmpm(1000000l);
|
||||
cmpm(2000000l);
|
||||
cmpm(100000000l);
|
||||
cmpm(200000000l);
|
||||
cmpm(-1);
|
||||
cmpm(-2);
|
||||
cmpm(-3);
|
||||
cmpm(-255);
|
||||
cmpm(-256);
|
||||
cmpm(-10000);
|
||||
cmpm(-20000);
|
||||
cmpm(-1000000l);
|
||||
cmpm(-2000000l);
|
||||
cmpm(-100000000l);
|
||||
cmpm(-200000000l);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ enum SIDFXState
|
|||
SIDFX_WAIT
|
||||
};
|
||||
|
||||
static struct SIDFXChannel
|
||||
__striped static struct SIDFXChannel
|
||||
{
|
||||
const SIDFX * volatile com;
|
||||
byte delay, priority;
|
||||
|
@ -27,6 +27,7 @@ void sidfx_init(void)
|
|||
channels[i].com = nullptr;
|
||||
channels[i].state = SIDFX_IDLE;
|
||||
channels[i].priority = 0;
|
||||
channels[i].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,11 @@ bool sidfx_idle(byte chn)
|
|||
return channels[chn].state == SIDFX_IDLE;
|
||||
}
|
||||
|
||||
char sidfx_cnt(byte chn)
|
||||
{
|
||||
return channels[chn].cnt;
|
||||
}
|
||||
|
||||
void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
||||
{
|
||||
SIDFXState ns = channels[chn].state;
|
||||
|
@ -47,6 +53,7 @@ void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
|||
return;
|
||||
|
||||
channels[chn].state = SIDFX_IDLE;
|
||||
channels[chn].delay = 1;
|
||||
|
||||
channels[chn].com = fx;
|
||||
channels[chn].cnt = cnt - 1;
|
||||
|
@ -59,71 +66,95 @@ void sidfx_stop(byte chn)
|
|||
{
|
||||
channels[chn].com = nullptr;
|
||||
if (channels[chn].state != SIDFX_IDLE)
|
||||
{
|
||||
channels[chn].state = SIDFX_RESET_0;
|
||||
channels[chn].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void sidfx_loop_ch(byte ch)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
if (channels[ch].state)
|
||||
{
|
||||
case SIDFX_IDLE:
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
// sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
const SIDFX * com = channels[ch].com;
|
||||
|
||||
channels[ch].delay--;
|
||||
if (channels[ch].delay)
|
||||
{
|
||||
if (com->dfreq)
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
}
|
||||
|
||||
while (!channels[ch].delay)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
{
|
||||
case SIDFX_IDLE:
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
if (com)
|
||||
channels[ch].state = SIDFX_READY;
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
channels[ch].freq = com->freq;
|
||||
channels[ch].pwm = com->pwm;
|
||||
|
||||
sid.voices[ch].freq = com->freq;
|
||||
sid.voices[ch].pwm = com->pwm;
|
||||
sid.voices[ch].attdec = com->attdec;
|
||||
sid.voices[ch].susrel = com->susrel;
|
||||
sid.voices[ch].ctrl = com->ctrl;
|
||||
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
{
|
||||
channels[ch].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;
|
||||
|
||||
channels[ch].delay = com->time1;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
}
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
channels[ch].delay = com->time0;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (com->time0)
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
if (com->time0)
|
||||
{
|
||||
sid.voices[ch].ctrl = com->ctrl & ~SID_CTRL_GATE;
|
||||
channels[ch].delay = com->time0;
|
||||
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;
|
||||
|
@ -131,42 +162,30 @@ inline void sidfx_loop_ch(byte ch)
|
|||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (channels[ch].cnt)
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
if (channels[ch].cnt)
|
||||
{
|
||||
com++;
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com = com;
|
||||
channels[ch].priority = com->priority;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
else
|
||||
channels[ch].state = SIDFX_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
|
|||
|
||||
void sidfx_stop(byte chn);
|
||||
|
||||
char sidfx_cnt(byte chn);
|
||||
|
||||
void sidfx_loop(void);
|
||||
|
||||
void sidfx_loop_2(void);
|
||||
|
|
|
@ -16,7 +16,7 @@ void cia_init(void)
|
|||
cia2.ddrb = 0x00;
|
||||
cia1.ddra = 0xff;
|
||||
|
||||
cia2.prb = 0x07;
|
||||
cia2.pra = 0x07;
|
||||
cia2.ddra = 0x3f;
|
||||
|
||||
char i0 = cia1.icr;
|
||||
|
|
|
@ -18,6 +18,46 @@ struct EasyFlash
|
|||
|
||||
#define eflash (*(EasyFlash *)0xde00)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#ifdef EFPROX_SECTION
|
||||
#pragma code(EFPROX_SECTION)
|
||||
#endif
|
||||
|
||||
template<int back, class fn, class ... P>
|
||||
__noinline auto ef_call_p(P... p)
|
||||
{
|
||||
if (back != __bankof(fn))
|
||||
eflash.bank = __bankof(fn);
|
||||
auto r = fn(p...);
|
||||
if (back != 0xff && back != __bankof(fn))
|
||||
eflash.bank = back;
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef EFPROX_SECTION
|
||||
#pragma code(code)
|
||||
#endif
|
||||
|
||||
template<class fn>
|
||||
class EFlashCall
|
||||
{
|
||||
public:
|
||||
template<class ... P>
|
||||
__forceinline auto operator()(P ... p) const
|
||||
{
|
||||
switch(__bankof(0))
|
||||
{
|
||||
#for(i,64) case i: return ef_call_p<i, fn, P...>(p...);
|
||||
default:
|
||||
return ef_call_p<0xff, fn, P...>(p...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define EF_CALL(fn) EFlashCall<fn##_p> fn
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
|
|||
{
|
||||
krnio_pstatus[fnum] = KRNIO_OK;
|
||||
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
lda #0
|
||||
sta accu
|
||||
|
@ -94,8 +94,7 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
|
|||
|
||||
BANKOUT
|
||||
E2:
|
||||
};
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_open)
|
||||
|
@ -131,7 +130,7 @@ BANKINLINE krnioerr krnio_status(void)
|
|||
|
||||
BANKINLINE bool krnio_load(char fnum, char device, char channel)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda fnum
|
||||
|
@ -149,14 +148,14 @@ BANKINLINE bool krnio_load(char fnum, char device, char channel)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_load)
|
||||
|
||||
BANKINLINE bool krnio_save(char device, const char* start, const char* end)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda #0
|
||||
|
@ -175,14 +174,14 @@ BANKINLINE bool krnio_save(char device, const char* start, const char* end)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_save)
|
||||
|
||||
BANKINLINE bool krnio_chkout(char fnum)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
|
@ -193,14 +192,14 @@ BANKINLINE bool krnio_chkout(char fnum)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkout)
|
||||
|
||||
BANKINLINE bool krnio_chkin(char fnum)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
|
@ -211,7 +210,7 @@ BANKINLINE bool krnio_chkin(char fnum)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkin)
|
||||
|
@ -230,14 +229,14 @@ BANKINLINE void krnio_clrchn(void)
|
|||
|
||||
BANKINLINE bool krnio_chrout(char ch)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda ch
|
||||
jsr $ffd2 // chrout
|
||||
sta accu
|
||||
BANKOUT
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chrout)
|
||||
|
@ -422,7 +421,7 @@ int krnio_gets(char fnum, char * data, int num)
|
|||
|
||||
if (krnio_chkin(fnum))
|
||||
{
|
||||
krnioerr err;
|
||||
krnioerr err = KRNIO_OK;
|
||||
int i = 0;
|
||||
int ch;
|
||||
while (i + 1 < num)
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
#include <c64/asm6502.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
volatile char npos = 1, tpos = 0;
|
||||
volatile byte rirq_count;
|
||||
static byte rirq_pcount;
|
||||
|
||||
byte rasterIRQRows[NUM_IRQS + 1];
|
||||
byte rasterIRQIndex[NUM_IRQS + 1];
|
||||
byte rasterIRQRows[NUM_IRQS + 1];
|
||||
byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one
|
||||
#ifdef ZPAGE_IRQS
|
||||
__zeropage
|
||||
#endif
|
||||
byte rasterIRQNext[NUM_IRQS + 1];
|
||||
byte rasterIRQLow[NUM_IRQS];
|
||||
byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff
|
||||
byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code
|
||||
byte rasterIRQHigh[NUM_IRQS];
|
||||
|
||||
#ifdef ZPAGE_IRQS
|
||||
|
@ -22,28 +22,25 @@ __zeropage
|
|||
#endif
|
||||
byte nextIRQ;
|
||||
|
||||
__asm irq0
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
|
||||
|
||||
asl $d019
|
||||
__asm rirq_isr_ram_io
|
||||
{
|
||||
stx plrx + 1
|
||||
|
||||
ldx nextIRQ
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
bmi exi
|
||||
|
||||
sta plra + 1
|
||||
sty plry + 1
|
||||
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -51,20 +48,82 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
|
||||
tay
|
||||
dey
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
ex:
|
||||
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
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
kentry:
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
||||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
|
@ -72,56 +131,44 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
e2:
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
jmp ex
|
||||
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm irq2
|
||||
__asm rirq_isr_noio
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
kentry:
|
||||
lda $01
|
||||
pha
|
||||
|
||||
lda #$35
|
||||
sta $01
|
||||
|
||||
asl $d019
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -129,21 +176,20 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
|
||||
tay
|
||||
dey
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
ex:
|
||||
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
|
@ -154,45 +200,35 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
e2:
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
jmp ex
|
||||
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm irq1
|
||||
__asm rirq_isr_kernal_io
|
||||
{
|
||||
lda $d019
|
||||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -201,45 +237,36 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e2
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
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:
|
||||
|
@ -248,7 +275,7 @@ ex2:
|
|||
jmp $ea31
|
||||
}
|
||||
|
||||
__asm irq3
|
||||
__asm rirq_isr_kernal_noio
|
||||
{
|
||||
lda $01
|
||||
pha
|
||||
|
@ -259,17 +286,14 @@ __asm irq3
|
|||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -278,49 +302,40 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
|
||||
ex2:
|
||||
LDA $DC0D
|
||||
cli
|
||||
|
@ -350,8 +365,8 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
ic->size = size;
|
||||
|
||||
asm_im(ic->code + 0, ASM_LDY, 0);
|
||||
asm_im(ic->code + 2, ASM_LDA, 0);
|
||||
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
|
||||
asm_im(ic->code + 2, ASM_LDX, 0);
|
||||
asm_ab(ic->code + 4, ASM_CMP, 0xd012);
|
||||
asm_rl(ic->code + 7, ASM_BCS, -5);
|
||||
asm_ab(ic->code + 9, ASM_STY, 0x0000);
|
||||
|
||||
|
@ -365,7 +380,7 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
}
|
||||
else
|
||||
{
|
||||
asm_ab(ic->code + 12, ASM_STA, 0x0000);
|
||||
asm_ab(ic->code + 12, ASM_STX, 0x0000);
|
||||
|
||||
byte p = 15;
|
||||
for(byte i=2; i<size; i++)
|
||||
|
@ -424,7 +439,8 @@ void rirq_addrhi(RIRQCode * ic, byte n, byte hi)
|
|||
void rirq_data(RIRQCode * ic, byte n, byte data)
|
||||
{
|
||||
byte p = irqdi[n];
|
||||
ic->code[p] = data;
|
||||
// ic->code[p] = data;
|
||||
(volatile char *)(ic->code)[p] = data;
|
||||
}
|
||||
|
||||
void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
|
||||
|
@ -484,7 +500,7 @@ void rirq_init_kernal(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq1;
|
||||
*(void **)0x0314 = rirq_isr_kernal_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -492,7 +508,7 @@ void rirq_init_kernal(void)
|
|||
|
||||
}
|
||||
|
||||
void rirq_init_kernal_io(void)
|
||||
void rirq_init_kernal_noio(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
|
@ -501,7 +517,43 @@ void rirq_init_kernal_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq3;
|
||||
*(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.ctrl1 &= 0x7f;
|
||||
|
@ -518,7 +570,7 @@ void rirq_init_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq0;
|
||||
*(void **)0xfffe = rirq_isr_ram_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -535,7 +587,7 @@ void rirq_init_memmap(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq2;
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -553,12 +605,18 @@ void rirq_init(bool kernalIRQ)
|
|||
|
||||
void rirq_wait(void)
|
||||
{
|
||||
while (tpos != npos) ;
|
||||
npos++;
|
||||
char i0 = rirq_pcount;
|
||||
char i1;
|
||||
do {
|
||||
i1 = rirq_count;
|
||||
} while (i0 == i1);
|
||||
rirq_pcount = i1;
|
||||
}
|
||||
|
||||
void rirq_sort(void)
|
||||
void rirq_sort(bool inirq)
|
||||
{
|
||||
// disable raster interrupts while sorting
|
||||
nextIRQ = 0xff;
|
||||
#if 1
|
||||
byte maxr = rasterIRQRows[rasterIRQIndex[1]];
|
||||
for(byte i = 2; i<NUM_IRQS + 1; i++)
|
||||
|
@ -606,10 +664,18 @@ void rirq_sort(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
npos++;
|
||||
byte yp = rasterIRQNext[nextIRQ];
|
||||
if (yp != 0xff)
|
||||
vic.raster = yp - 1;
|
||||
rirq_pcount = rirq_count;
|
||||
if (inirq)
|
||||
nextIRQ = NUM_IRQS - 1;
|
||||
else
|
||||
{
|
||||
byte yp = rasterIRQNext[0];
|
||||
if (yp != 0xff)
|
||||
{
|
||||
vic.raster = yp - 1;
|
||||
nextIRQ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rirq_start(void)
|
||||
|
@ -623,6 +689,7 @@ void rirq_start(void)
|
|||
lda #100
|
||||
sta $d012
|
||||
|
||||
asl $d019
|
||||
cli
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,8 @@ inline void rirq_data(RIRQCode * ic, byte n, byte data);
|
|||
// Add a delay of 5 * cycles to a raster IRQ
|
||||
inline void rirq_delay(RIRQCode * ic, byte cycles);
|
||||
|
||||
// Place a raster IRQ into one of the 16 slots
|
||||
// Place a raster IRQ into one of the 16 slots, the interrupt will fire
|
||||
// one line below the given row
|
||||
inline void rirq_set(byte n, byte row, RIRQCode * write);
|
||||
|
||||
// Remove a raster IRQ from one of the 16 slots
|
||||
|
@ -147,12 +148,28 @@ inline void rirq_move(byte n, byte row);
|
|||
// the less resource hungry option)
|
||||
inline void rirq_init(bool kernalIRQ);
|
||||
|
||||
// Raster IRQ through kernal, with IO range always enabled
|
||||
// calls kernal continuation
|
||||
void rirq_init_kernal(void);
|
||||
|
||||
void rirq_init_kernal_io(void);
|
||||
// Raster IRQ through kernal, with IO range not always enabled
|
||||
// calls kernal continuation
|
||||
void rirq_init_kernal_noio(void);
|
||||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_crt(void);
|
||||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range not always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_crt_noio(void);
|
||||
|
||||
// Raster IRQ through RAM vector, with ROM disabled and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_io(void);
|
||||
|
||||
// Raster IRQ through RAM vector, with ROM disabled and IO range not always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_memmap(void);
|
||||
|
||||
// Start raster IRQ
|
||||
|
@ -162,8 +179,9 @@ void rirq_start(void);
|
|||
void rirq_stop(void);
|
||||
|
||||
// Sort the raster IRQ, must be performed at the end of the frame after changing
|
||||
// the vertical position of one of the interrupt operatins.
|
||||
void rirq_sort(void);
|
||||
// the vertical position of one of the interrupt operations.
|
||||
// Set the inirq flag to true when calling this from an interrupt
|
||||
void rirq_sort(bool inirq = false);
|
||||
|
||||
// Wait for the last raster IRQ op to have completed. Must be called before a
|
||||
// sort if the raster IRQ system is active
|
||||
|
|
|
@ -171,6 +171,12 @@ void vspr_init(char * screen)
|
|||
}
|
||||
}
|
||||
|
||||
void vspr_shutdown(void)
|
||||
{
|
||||
for(int i=0; i<VSPRITES_MAX - 7; i++)
|
||||
rirq_clear(i);
|
||||
}
|
||||
|
||||
void vspr_screen(char * screen)
|
||||
{
|
||||
vspriteScreen = screen + 0x3f8;
|
||||
|
@ -309,6 +315,8 @@ void vspr_update(void)
|
|||
if (!done && spriteYPos[ti + 9] < 250)
|
||||
{
|
||||
byte ri = spriteOrder[ti + 8];
|
||||
rirq_move(ti, spriteYPos[ti + 1] + 23);
|
||||
|
||||
#ifdef VSPRITE_REVERSE
|
||||
char m = 0x80 >> (ti & 7);
|
||||
#else
|
||||
|
@ -325,7 +333,6 @@ void vspr_update(void)
|
|||
rirq_data(spirq + ti, 3, vspriteImage[ri]);
|
||||
|
||||
rirq_data(spirq + ti, 4, xymask);
|
||||
rirq_move(ti, spriteYPos[ti + 1] + 23);
|
||||
// spriteYPos[ti + 9] = vspriteYLow[ri];
|
||||
}
|
||||
else
|
||||
|
|
|
@ -68,6 +68,8 @@ inline void spr_expand(char sp, bool xexpand, bool yexpand);
|
|||
|
||||
void vspr_init(char * screen);
|
||||
|
||||
void vspr_shutdown(void);
|
||||
|
||||
void vspr_screen(char * screen);
|
||||
|
||||
// set one sprite with the given attribute
|
||||
|
|
|
@ -114,4 +114,21 @@ 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)
|
||||
|
|
|
@ -118,6 +118,9 @@ void vic_waitLine(int line);
|
|||
// wait for beam to be below a line
|
||||
void vic_waitBelow(int line);
|
||||
|
||||
// wait for beam to be in a given range on screen
|
||||
void vic_waitRange(char below, char above);
|
||||
|
||||
// reference to the VIC chip
|
||||
#define vic (*((struct VIC *)0xd000))
|
||||
|
||||
|
|
320
include/conio.c
320
include/conio.c
|
@ -18,6 +18,13 @@ __asm bsin
|
|||
jsr 0xffe4
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsget
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xffcf
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
lda #0
|
||||
|
@ -43,6 +50,7 @@ __asm dswap
|
|||
#define dswap 0xff5f
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
#define bsget 0xffcf
|
||||
#define bsplot 0xfff0
|
||||
#define bsinit 0xff81
|
||||
#elif defined(__PLUS4__)
|
||||
|
@ -59,6 +67,12 @@ __asm bsin
|
|||
jsr 0xffe4
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsget
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffcf
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
sta 0xff3e
|
||||
|
@ -91,6 +105,14 @@ __asm bsin
|
|||
pha
|
||||
}
|
||||
|
||||
__asm bsget
|
||||
{
|
||||
lda 0xe405
|
||||
pha
|
||||
lda 0xe404
|
||||
pha
|
||||
}
|
||||
|
||||
__asm bsplot
|
||||
{
|
||||
|
||||
|
@ -103,16 +125,30 @@ __asm bsinit
|
|||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
#define bsplot 0xfff0
|
||||
#define bsget 0xffcf
|
||||
__asm bsinit
|
||||
{
|
||||
lda #147
|
||||
jmp $ffd2
|
||||
}
|
||||
#elif defined(__CBMPET__)
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
__asm bsplot
|
||||
{
|
||||
/* no equivalent on PET */
|
||||
}
|
||||
__asm bsinit
|
||||
{
|
||||
/* no equivalent on PET */
|
||||
}
|
||||
#define bsget 0xffcf
|
||||
#else
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
#define bsplot 0xfff0
|
||||
#define bsinit 0xff81
|
||||
#define bsget 0xffcf
|
||||
#endif
|
||||
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
|
@ -145,192 +181,246 @@ void iocharmap(IOCharMap chmap)
|
|||
giocharmap = chmap;
|
||||
#if !defined(__ATARI__)
|
||||
if (chmap == IOCHM_PETSCII_1)
|
||||
putch(128 + 14);
|
||||
putrch(128 + 14);
|
||||
else if (chmap == IOCHM_PETSCII_2)
|
||||
putch(14);
|
||||
putrch(14);
|
||||
#endif
|
||||
}
|
||||
|
||||
__asm putpch
|
||||
void putrch(char c)
|
||||
{
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
|
||||
cmp #10
|
||||
bne w1
|
||||
lda #13
|
||||
w1:
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
|
||||
cmp #65
|
||||
bcc w3
|
||||
cmp #123
|
||||
bcs w3
|
||||
|
||||
#if defined(__CBMPET__)
|
||||
cmp #97
|
||||
bcs w4
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$a0
|
||||
w4:
|
||||
eor #$20
|
||||
__asm {
|
||||
lda c
|
||||
jsr bsout
|
||||
}
|
||||
}
|
||||
|
||||
void putpch(char c)
|
||||
{
|
||||
#if defined(__ATARI__)
|
||||
if (c == 10)
|
||||
c = 0x9b;
|
||||
#else
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
if (giocharmap >= IOCHM_ASCII)
|
||||
{
|
||||
if (c == '\n')
|
||||
c = 13;
|
||||
else if (c == '\t')
|
||||
{
|
||||
char n = wherex() & 3;
|
||||
do {
|
||||
putrch(' ');
|
||||
} while (++n < 4);
|
||||
return;
|
||||
}
|
||||
else if (giocharmap >= IOCHM_PETSCII_1)
|
||||
{
|
||||
if (c >= 65 && c < 123)
|
||||
{
|
||||
if (c >= 97 || c < 91)
|
||||
{
|
||||
#if defined(__CBMPET__)
|
||||
if (c >= 97)
|
||||
c ^= 0xa0;
|
||||
c ^= 0x20;
|
||||
#else
|
||||
c ^= 0x20;
|
||||
#endif
|
||||
|
||||
if (giocharmap == IOCHM_PETSCII_1)
|
||||
c &= 0xdf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
cpx #IOCHM_PETSCII_2
|
||||
beq w3
|
||||
and #$df
|
||||
w3:
|
||||
jmp bsout
|
||||
|
||||
putrch(c);
|
||||
}
|
||||
|
||||
__asm getpch
|
||||
static char convch(char ch)
|
||||
{
|
||||
jsr bsin
|
||||
#if !defined(__ATARI__)
|
||||
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
if (giocharmap >= IOCHM_ASCII)
|
||||
{
|
||||
if (ch == 13)
|
||||
ch = 10;
|
||||
else if (giocharmap >= IOCHM_PETSCII_1)
|
||||
{
|
||||
if (ch >= 65 && ch < 219)
|
||||
{
|
||||
if (ch >= 193)
|
||||
ch ^= 0xa0;
|
||||
if (ch < 123 && (ch >= 97 || ch < 91))
|
||||
ch ^= 0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmp #13
|
||||
bne w1
|
||||
lda #10
|
||||
w1:
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
|
||||
cmp #219
|
||||
bcs w3
|
||||
cmp #65
|
||||
bcc w3
|
||||
char getrch(void)
|
||||
{
|
||||
return __asm {
|
||||
jsr bsget
|
||||
sta accu
|
||||
};
|
||||
}
|
||||
|
||||
cmp #193
|
||||
bcc w4
|
||||
eor #$a0
|
||||
w4:
|
||||
cmp #123
|
||||
bcs w3
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
w3:
|
||||
char getpch(void)
|
||||
{
|
||||
return convch(getrch());
|
||||
}
|
||||
|
||||
|
||||
char kbhit(void)
|
||||
{
|
||||
__asm
|
||||
#if defined(__CBMPET__)
|
||||
return __asm
|
||||
{
|
||||
lda $9e
|
||||
sta accu
|
||||
};
|
||||
#else
|
||||
return __asm
|
||||
{
|
||||
lda $c6
|
||||
sta accu
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
char getche(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
L1:
|
||||
jsr getpch
|
||||
cmp #0
|
||||
beq L1
|
||||
char ch;
|
||||
do {
|
||||
ch = __asm {
|
||||
jsr bsin
|
||||
sta accu
|
||||
};
|
||||
} while (!ch);
|
||||
|
||||
sta accu
|
||||
jsr putpch
|
||||
__asm {
|
||||
lda ch
|
||||
jsr bsout
|
||||
}
|
||||
|
||||
return convch(ch);
|
||||
}
|
||||
|
||||
char getch(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
L1:
|
||||
jsr getpch
|
||||
cmp #0
|
||||
beq L1
|
||||
char ch;
|
||||
do {
|
||||
ch = __asm {
|
||||
jsr bsin
|
||||
sta accu
|
||||
};
|
||||
} while (!ch);
|
||||
|
||||
sta accu
|
||||
}
|
||||
return convch(ch);
|
||||
}
|
||||
|
||||
char getchx(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jsr getpch
|
||||
sta accu
|
||||
}
|
||||
char ch = __asm {
|
||||
jsr bsin
|
||||
sta accu
|
||||
};
|
||||
|
||||
return convch(ch);
|
||||
}
|
||||
|
||||
void putch(char c)
|
||||
{
|
||||
__asm {
|
||||
lda c
|
||||
jsr bsout
|
||||
}
|
||||
putpch(c);
|
||||
}
|
||||
|
||||
void clrscr(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jsr bsinit
|
||||
}
|
||||
putrch(147);
|
||||
}
|
||||
|
||||
void textcursor(bool show)
|
||||
{
|
||||
*(char *)0xcc = show ? 0 : 1;
|
||||
*(volatile char *)0xcc = show ? 0 : 1;
|
||||
}
|
||||
|
||||
void gotoxy(char cx, char cy)
|
||||
{
|
||||
#if defined(__CBMPET__)
|
||||
#define CURS_X 0xc6
|
||||
#define CURS_Y 0xd8
|
||||
#define SCREEN_PTR 0xc4
|
||||
#define SCR_LINELEN 0xd5
|
||||
|
||||
__assume(cy < 25);
|
||||
|
||||
*(volatile char *)CURS_X = cx;
|
||||
*(volatile char *)CURS_Y = cy;
|
||||
|
||||
if (*(volatile char *)SCR_LINELEN > 40)
|
||||
cy <<= 1;
|
||||
|
||||
const unsigned off = cy * 40;
|
||||
|
||||
* (volatile unsigned *)SCREEN_PTR = off + 0x8000;
|
||||
#else
|
||||
__asm
|
||||
{
|
||||
ldx cy
|
||||
ldy cx
|
||||
clc
|
||||
jsr bsplot
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void textcolor(char c)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda c
|
||||
sta $0286
|
||||
}
|
||||
*(volatile char *)0x0286 = c;
|
||||
}
|
||||
|
||||
void bgcolor(char c)
|
||||
{
|
||||
*(volatile char *)0xd021 = c;
|
||||
}
|
||||
|
||||
void bordercolor(char c)
|
||||
{
|
||||
*(volatile char *)0xd020 = c;
|
||||
}
|
||||
|
||||
void revers(char r)
|
||||
{
|
||||
if (r)
|
||||
putrch(18);
|
||||
else
|
||||
putrch(18 + 128);
|
||||
}
|
||||
|
||||
char wherex(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda $d3
|
||||
sta accu
|
||||
}
|
||||
#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)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda $d6
|
||||
sta accu
|
||||
}
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
return *(volatile char *)0xeb;
|
||||
#elif defined(__PLUS4__)
|
||||
return *(volatile char *)0xcd;
|
||||
#else
|
||||
return *(volatile char *)0xd6;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -43,6 +43,39 @@ void dispmode80col(void);
|
|||
#define PETSCII_F7 0x88
|
||||
#define PETSCII_F8 0x8c
|
||||
|
||||
enum ConioColors
|
||||
{
|
||||
COLOR_BLACK,
|
||||
COLOR_WHITE,
|
||||
COLOR_RED,
|
||||
COLOR_CYAN,
|
||||
COLOR_PURPLE,
|
||||
COLOR_GREEN,
|
||||
COLOR_BLUE,
|
||||
COLOR_YELLOW,
|
||||
|
||||
COLOR_ORANGE,
|
||||
COLOR_BROWN,
|
||||
COLOR_LT_RED,
|
||||
COLOR_DARK_GREY,
|
||||
COLOR_MED_GREY,
|
||||
COLOR_LT_GREEN,
|
||||
COLOR_LT_BLUE,
|
||||
COLOR_LT_GREY
|
||||
};
|
||||
// Lowlevel console in/out
|
||||
|
||||
// using petscii translation
|
||||
void putpch(char c);
|
||||
char getpch(void);
|
||||
|
||||
// using no translation
|
||||
inline void putrch(char c);
|
||||
inline char getrch(void);
|
||||
|
||||
|
||||
// Standard console in/out
|
||||
|
||||
char kbhit(void);
|
||||
|
||||
char getche(void);
|
||||
|
@ -59,15 +92,21 @@ void clrscr(void);
|
|||
|
||||
void gotoxy(char x, char y);
|
||||
|
||||
void textcolor(char c);
|
||||
inline void textcolor(char c);
|
||||
|
||||
char wherex(void);
|
||||
inline void bgcolor(char c);
|
||||
|
||||
char wherey(void);
|
||||
inline void bordercolor(char c);
|
||||
|
||||
inline void revers(char r);
|
||||
|
||||
inline char wherex(void);
|
||||
|
||||
inline char wherey(void);
|
||||
|
||||
// show or hide the text cursor
|
||||
|
||||
void textcursor(bool show);
|
||||
inline void textcursor(bool show);
|
||||
|
||||
#pragma compile("conio.c")
|
||||
|
||||
|
|
230
include/crt.c
230
include/crt.c
|
@ -236,46 +236,40 @@ w0:
|
|||
// Clear BSS Segment
|
||||
|
||||
#ifndef NOBSSCLEAR
|
||||
lda #<BSSStart
|
||||
sta ip
|
||||
lda #>BSSStart
|
||||
sta ip + 1
|
||||
ldx #>BSSStart
|
||||
ldy #<BSSStart
|
||||
|
||||
sec
|
||||
lda #>BSSEnd
|
||||
sbc #>BSSStart
|
||||
beq w1
|
||||
tax
|
||||
lda #0
|
||||
ldy #0
|
||||
l1: sta (ip), y
|
||||
sta ip
|
||||
l3:
|
||||
stx ip + 1
|
||||
cpx #>BSSEnd
|
||||
beq w2
|
||||
l1:
|
||||
sta (ip), y
|
||||
iny
|
||||
bne l1
|
||||
inc ip + 1
|
||||
dex
|
||||
bne l1
|
||||
w1:
|
||||
sec
|
||||
lda #<BSSEnd
|
||||
sbc #<BSSStart
|
||||
beq w2
|
||||
tay
|
||||
lda #0
|
||||
l2: dey
|
||||
sta (ip), y
|
||||
bne l2
|
||||
w2:
|
||||
#endif
|
||||
#ifndef NOZPCLEAR
|
||||
ldx #<ZeroStart
|
||||
cpx #<ZeroEnd
|
||||
beq w3
|
||||
l3: sta $00, x
|
||||
inx
|
||||
cpx #<ZeroEnd
|
||||
bne l3
|
||||
w3:
|
||||
bne l3
|
||||
l2:
|
||||
sta (ip), y
|
||||
iny
|
||||
w2:
|
||||
cpy #<BSSEnd
|
||||
bne l2
|
||||
#endif
|
||||
|
||||
#ifndef NOZPCLEAR
|
||||
lda #0
|
||||
ldx #<ZeroStart
|
||||
bne w3
|
||||
l4: sta $00, x
|
||||
inx
|
||||
w3:
|
||||
cpx #<ZeroEnd
|
||||
bne l4
|
||||
#endif
|
||||
|
||||
lda #<StackEnd - 2
|
||||
sta sp
|
||||
lda #>StackEnd - 2
|
||||
|
@ -673,21 +667,19 @@ L1: rol accu
|
|||
sbc tmp + 1
|
||||
lda tmp + 6
|
||||
sbc tmp + 2
|
||||
tax
|
||||
lda tmp + 7
|
||||
sbc tmp + 3
|
||||
bcc W1
|
||||
stx tmp + 6
|
||||
sta tmp + 7
|
||||
lda tmp + 4
|
||||
sbc tmp + 0
|
||||
sta tmp + 4
|
||||
lda tmp + 5
|
||||
sbc tmp + 1
|
||||
sta tmp + 5
|
||||
lda tmp + 6
|
||||
sbc tmp + 2
|
||||
sta tmp + 6
|
||||
lda tmp + 7
|
||||
sbc tmp + 3
|
||||
sta tmp + 7
|
||||
sec
|
||||
W1: dey
|
||||
bne L1
|
||||
rol accu
|
||||
|
@ -764,6 +756,11 @@ __asm mul32
|
|||
sta tmp + 6
|
||||
sta tmp + 7
|
||||
|
||||
lda tmp + 3
|
||||
ora tmp + 2
|
||||
ora tmp + 1
|
||||
beq WB
|
||||
|
||||
lda tmp + 0
|
||||
jsr WM
|
||||
lda tmp + 1
|
||||
|
@ -781,6 +778,7 @@ WM:
|
|||
stx accu + 1
|
||||
sta accu
|
||||
rts
|
||||
WB: lda tmp + 0
|
||||
W0:
|
||||
sec
|
||||
ror
|
||||
|
@ -839,6 +837,55 @@ W1: asl accu
|
|||
#endif
|
||||
}
|
||||
|
||||
#if 1
|
||||
__asm mul16by8
|
||||
{
|
||||
lsr
|
||||
beq zero
|
||||
more:
|
||||
ldx #0
|
||||
ldy #0
|
||||
bcc skip
|
||||
odd:
|
||||
ldy accu
|
||||
ldx accu + 1
|
||||
bcs skip
|
||||
|
||||
loop:
|
||||
sta tmpy
|
||||
|
||||
clc
|
||||
tya
|
||||
adc accu
|
||||
tay
|
||||
txa
|
||||
adc accu + 1
|
||||
tax
|
||||
|
||||
lda tmpy
|
||||
skip:
|
||||
asl accu
|
||||
rol accu + 1
|
||||
lsr
|
||||
bcc skip
|
||||
bne loop
|
||||
done:
|
||||
clc
|
||||
tya
|
||||
adc accu
|
||||
sta accu
|
||||
txa
|
||||
adc accu + 1
|
||||
sta accu + 1
|
||||
rts
|
||||
zero:
|
||||
bcs one
|
||||
sta accu
|
||||
sta accu + 1
|
||||
one:
|
||||
rts
|
||||
}
|
||||
#else
|
||||
__asm mul16by8
|
||||
{
|
||||
ldy #0
|
||||
|
@ -866,6 +913,7 @@ L2:
|
|||
sty tmp + 2
|
||||
rts
|
||||
}
|
||||
#endif
|
||||
|
||||
__asm divs16
|
||||
{
|
||||
|
@ -2858,6 +2906,11 @@ W1:
|
|||
|
||||
__asm faddsub
|
||||
{
|
||||
fsub:
|
||||
lda tmp + 3
|
||||
eor #$80
|
||||
sta tmp + 3
|
||||
fadd:
|
||||
lda #$ff
|
||||
cmp tmp + 4
|
||||
beq INF
|
||||
|
@ -3008,7 +3061,7 @@ fas_zero:
|
|||
__asm inp_binop_add_f32
|
||||
{
|
||||
jsr freg.split_exp
|
||||
jsr faddsub
|
||||
jsr faddsub.fadd
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
|
@ -3017,16 +3070,13 @@ __asm inp_binop_add_f32
|
|||
__asm inp_binop_sub_f32
|
||||
{
|
||||
jsr freg.split_exp
|
||||
lda tmp + 3
|
||||
eor #$80
|
||||
sta tmp + 3
|
||||
jsr faddsub
|
||||
jsr faddsub.fsub
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_BINOP_SUB_F32, inp_binop_sub_f32)
|
||||
|
||||
__asm fmul8
|
||||
__asm crt_fmul8
|
||||
{
|
||||
sec
|
||||
ror
|
||||
|
@ -3060,14 +3110,12 @@ W1:
|
|||
rts
|
||||
}
|
||||
|
||||
__asm fmul
|
||||
__asm crt_fmul
|
||||
{
|
||||
lda accu
|
||||
ora accu + 1
|
||||
ora accu + 2
|
||||
bne W1
|
||||
sta accu + 3
|
||||
rts
|
||||
beq E3
|
||||
W1:
|
||||
lda tmp
|
||||
ora tmp + 1
|
||||
|
@ -3076,6 +3124,7 @@ W1:
|
|||
sta accu
|
||||
sta accu + 1
|
||||
sta accu + 2
|
||||
E3:
|
||||
sta accu + 3
|
||||
rts
|
||||
W2:
|
||||
|
@ -3102,13 +3151,13 @@ W2:
|
|||
beq W5
|
||||
bne W6
|
||||
W4:
|
||||
jsr fmul8
|
||||
jsr crt_fmul8
|
||||
lda tmp + 1
|
||||
W6:
|
||||
jsr fmul8
|
||||
jsr crt_fmul8
|
||||
W5:
|
||||
lda tmp + 2
|
||||
jsr fmul8
|
||||
jsr crt_fmul8
|
||||
|
||||
sec
|
||||
lda tmp + 8
|
||||
|
@ -3133,6 +3182,7 @@ INF:
|
|||
ora #$7f
|
||||
sta accu + 3
|
||||
lda #$80
|
||||
E2:
|
||||
sta accu + 2
|
||||
lda #$00
|
||||
sta accu + 0
|
||||
|
@ -3156,23 +3206,20 @@ W8:
|
|||
rts
|
||||
ZERO:
|
||||
lda #0
|
||||
sta accu
|
||||
sta accu + 1
|
||||
sta accu + 2
|
||||
sta accu + 3
|
||||
rts
|
||||
beq E2
|
||||
}
|
||||
|
||||
__asm inp_binop_mul_f32
|
||||
{
|
||||
jsr freg.split_exp
|
||||
sty tmpy
|
||||
jsr fmul
|
||||
jsr crt_fmul
|
||||
ldy tmpy
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
__asm fdiv
|
||||
__asm crt_fdiv
|
||||
{
|
||||
lda accu
|
||||
ora accu + 1
|
||||
|
@ -3294,13 +3341,13 @@ ZERO:
|
|||
__asm inp_binop_div_f32
|
||||
{
|
||||
jsr freg.split_exp
|
||||
jsr fdiv
|
||||
jsr crt_fdiv
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_BINOP_DIV_F32, inp_binop_div_f32)
|
||||
|
||||
__asm fcmp
|
||||
__asm crt_fcmp
|
||||
{
|
||||
lda accu + 3
|
||||
eor tmp + 3
|
||||
|
@ -3983,14 +4030,41 @@ fru3:
|
|||
jmp freg.merge_aexp
|
||||
}
|
||||
|
||||
__asm store32
|
||||
{
|
||||
lda accu + 0
|
||||
sta $00, x
|
||||
lda accu + 1
|
||||
sta $01, x
|
||||
lda accu + 2
|
||||
sta $02, x
|
||||
lda accu + 3
|
||||
sta $03, x
|
||||
rts
|
||||
}
|
||||
|
||||
__asm load32
|
||||
{
|
||||
lda $00, x
|
||||
sta accu + 0
|
||||
lda $01, x
|
||||
sta accu + 1
|
||||
lda $02, x
|
||||
sta accu + 2
|
||||
lda $03, x
|
||||
sta accu + 3
|
||||
rts
|
||||
}
|
||||
|
||||
#pragma runtime(fsplita, freg.split_aexp)
|
||||
#pragma runtime(fsplitt, freg.split_texp)
|
||||
#pragma runtime(fsplitx, freg.split_xexp)
|
||||
#pragma runtime(fmergea, freg.merge_aexp)
|
||||
#pragma runtime(faddsub, faddsub)
|
||||
#pragma runtime(fmul, fmul)
|
||||
#pragma runtime(fdiv, fdiv)
|
||||
#pragma runtime(fcmp, fcmp)
|
||||
#pragma runtime(fadd, faddsub.fadd)
|
||||
#pragma runtime(fsub, faddsub.fsub)
|
||||
#pragma runtime(fmul, crt_fmul)
|
||||
#pragma runtime(fdiv, crt_fdiv)
|
||||
#pragma runtime(fcmp, crt_fcmp)
|
||||
#pragma runtime(ffromi, sint16_to_float)
|
||||
#pragma runtime(ffromu, uint16_to_float)
|
||||
#pragma runtime(ftoi, f32_to_i16)
|
||||
|
@ -4001,6 +4075,8 @@ fru3:
|
|||
#pragma runtime(ffromlu, uint32_to_float)
|
||||
#pragma runtime(ftoli, f32_to_i32)
|
||||
#pragma runtime(ftolu, f32_to_u32)
|
||||
#pragma runtime(store32, store32)
|
||||
#pragma runtime(load32, load32)
|
||||
|
||||
__asm inp_op_floor_f32
|
||||
{
|
||||
|
@ -4486,7 +4562,7 @@ struct Heap {
|
|||
|
||||
#pragma section(heap, 0x0000, HeapStart, HeapEnd)
|
||||
|
||||
__asm malloc
|
||||
__asm crt_malloc
|
||||
{
|
||||
// make room for two additional bytes
|
||||
// to store pointer to end of used memory
|
||||
|
@ -4571,6 +4647,9 @@ loop:
|
|||
adc tmp + 1
|
||||
sta tmp + 3
|
||||
|
||||
// exit if overflowing memory
|
||||
bcs hzempty
|
||||
|
||||
|
||||
// Check if in range of current free block
|
||||
|
||||
|
@ -4587,7 +4666,10 @@ loop:
|
|||
lda accu
|
||||
ldx accu + 1
|
||||
jmp loop
|
||||
|
||||
hzempty:
|
||||
lda #0
|
||||
sta accu
|
||||
sta accu + 1
|
||||
hempty:
|
||||
// no more heap blocks
|
||||
#ifdef HEAPCHECK
|
||||
|
@ -4707,14 +4789,14 @@ hc2:
|
|||
__asm inp_malloc
|
||||
{
|
||||
sty tmpy
|
||||
jsr malloc
|
||||
jsr crt_malloc
|
||||
ldy tmpy
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_MALLOC, inp_malloc)
|
||||
|
||||
__asm free
|
||||
__asm crt_free
|
||||
{
|
||||
|
||||
// check nullptr free
|
||||
|
@ -4931,21 +5013,21 @@ nostart:
|
|||
__asm inp_free
|
||||
{
|
||||
sty tmpy
|
||||
jsr free
|
||||
jsr crt_free
|
||||
ldy tmpy
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_FREE, inp_free)
|
||||
|
||||
__asm breakpoint
|
||||
__asm crt_breakpoint
|
||||
{
|
||||
rts
|
||||
}
|
||||
|
||||
#pragma runtime(malloc, malloc)
|
||||
#pragma runtime(free, free)
|
||||
#pragma runtime(breakpoint, breakpoint)
|
||||
#pragma runtime(malloc, crt_malloc)
|
||||
#pragma runtime(free, crt_free)
|
||||
#pragma runtime(breakpoint, crt_breakpoint)
|
||||
|
||||
#if 0
|
||||
|
||||
|
|
|
@ -123,8 +123,9 @@ int lmul4f12s(int x, int y)
|
|||
|
||||
lda #0
|
||||
sta accu + 1
|
||||
L2:
|
||||
|
||||
bcc W4
|
||||
L2:
|
||||
tay
|
||||
clc
|
||||
lda accu + 1
|
||||
|
@ -165,7 +166,7 @@ W1:
|
|||
bcc W2
|
||||
|
||||
tay
|
||||
sec
|
||||
// sec ; we know it is set here
|
||||
lda accu + 1
|
||||
sbc y
|
||||
sta accu + 1
|
||||
|
|
|
@ -525,7 +525,7 @@ void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int
|
|||
static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
|
||||
{
|
||||
char ip = 0;
|
||||
bool delta16 = ((dx | dy) & 0xff80) != 0;
|
||||
bool delta16 =((dx | dy) & 0xff80) != 0;
|
||||
|
||||
// ylow
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly);
|
||||
|
@ -579,82 +579,105 @@ static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool
|
|||
break;
|
||||
}
|
||||
|
||||
if (dx && 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);
|
||||
}
|
||||
|
||||
if (dy)
|
||||
{
|
||||
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);
|
||||
bool delta8 = false;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (dx && dy)
|
||||
{
|
||||
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)
|
||||
if (dx)
|
||||
{
|
||||
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);
|
||||
// m >= 0
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
|
||||
char n = delta16 ? 18 + 13 + 2 : 18 + 7 + 2;
|
||||
if (!up) n++;
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, n);
|
||||
delta8 = !delta16;
|
||||
}
|
||||
|
||||
if (up)
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_DEY);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta8 ? 17 : 15);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x07);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_INY);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_CPY, 0x08);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, delta8 ? 16 : 14);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x00);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
}
|
||||
|
||||
if (dx)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
|
||||
if (delta16)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 13 + 4 + 12);
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We know regdp to be in the accu at this point
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 5 + 4 + 12);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
}
|
||||
}
|
||||
|
||||
// m < 0
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta16 ? 4 + 13 + 13 : 4 + 13 + 7);
|
||||
}
|
||||
|
||||
if (dx)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 13);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 12);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (dx && dy)
|
||||
{
|
||||
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, 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);
|
||||
}
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
}
|
||||
|
||||
// l --
|
||||
|
|
|
@ -110,12 +110,12 @@ float atan2(float p, float q)
|
|||
return s;
|
||||
}
|
||||
|
||||
#define F_EXP_0 1.0000003
|
||||
#define F_EXP_1 0.693147059
|
||||
#define F_EXP_2 0.240173099
|
||||
#define F_EXP_3 0.055816392
|
||||
#define F_EXP_4 0.008965036
|
||||
#define F_EXP_5 0.001898429
|
||||
#define F_EXP_0 1.0
|
||||
#define F_EXP_1 0.69315668
|
||||
#define F_EXP_2 0.240132068
|
||||
#define F_EXP_3 0.055876024
|
||||
#define F_EXP_4 0.008940801
|
||||
#define F_EXP_5 0.001894414
|
||||
|
||||
float exp(float f)
|
||||
{
|
||||
|
@ -143,12 +143,12 @@ float exp(float f)
|
|||
return s * x.f;
|
||||
}
|
||||
|
||||
#define F_LOG_0 -3.78712618
|
||||
#define F_LOG_1 10.0957081
|
||||
#define F_LOG_2 -13.9747486
|
||||
#define F_LOG_3 12.7568806
|
||||
#define F_LOG_4 -6.48114552
|
||||
#define F_LOG_5 1.39045416
|
||||
#define F_LOG_0 -3.78717706
|
||||
#define F_LOG_1 10.0960498
|
||||
#define F_LOG_2 -13.975654
|
||||
#define F_LOG_3 12.7580616
|
||||
#define F_LOG_4 -6.48190725
|
||||
#define F_LOG_5 1.39064767
|
||||
|
||||
float log(float f)
|
||||
{
|
||||
|
|
|
@ -33,10 +33,15 @@ bool isfinite(float f);
|
|||
#pragma intrinsic(sin)
|
||||
#pragma intrinsic(cos)
|
||||
#pragma intrinsic(tan)
|
||||
#pragma intrinsic(atan)
|
||||
#pragma intrinsic(atan2)
|
||||
|
||||
#pragma intrinsic(log)
|
||||
#pragma intrinsic(exp)
|
||||
|
||||
#pragma intrinsic(pow)
|
||||
#pragma intrinsic(sqrt)
|
||||
|
||||
#pragma compile("math.c")
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#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
|
|
@ -37,7 +37,7 @@ public:
|
|||
showpos = 0x0800,
|
||||
skipws = 0x1000,
|
||||
unitbuf = 0x2000,
|
||||
uppercase = 0x3000,
|
||||
uppercase = 0x4000,
|
||||
|
||||
adjustfield = 0x00b0,
|
||||
basefield = 0x004a,
|
||||
|
|
|
@ -124,8 +124,8 @@ public:
|
|||
{
|
||||
head.succ = l.head.succ;
|
||||
head.pred = l.head.pred;
|
||||
head.succ->pred = head;
|
||||
head.pred->succ = head;
|
||||
head.succ->pred = (listnode<T> *)&head;
|
||||
head.pred->succ = (listnode<T> *)&head;
|
||||
l.head.succ = (listnode<T> *)&(l.head);
|
||||
l.head.pred = (listnode<T> *)&(l.head);
|
||||
}
|
||||
|
@ -136,8 +136,8 @@ public:
|
|||
{
|
||||
head.succ = l.head.succ;
|
||||
head.pred = l.head.pred;
|
||||
head.succ->pred = head;
|
||||
head.pred->succ = head;
|
||||
head.succ->pred = (listnode<T> *)&head;
|
||||
head.pred->succ = (listnode<T> *)&head;
|
||||
l.head.succ = (listnode<T> *)&(l.head);
|
||||
l.head.pred = (listnode<T> *)&(l.head);
|
||||
return *this;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <opp/utility.h>
|
||||
#include <oscar.h>
|
||||
|
||||
namespace opp {
|
||||
|
||||
|
@ -11,8 +12,8 @@ template <class T, int N>
|
|||
class static_vector
|
||||
{
|
||||
protected:
|
||||
char _space[N * sizeof(T)];
|
||||
enum { m = N } _size;
|
||||
char _space[N * sizeof(T)];
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
|
@ -20,23 +21,28 @@ public:
|
|||
|
||||
static_vector(size_t n) : _size(n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i) T;
|
||||
new (data + i) T();
|
||||
}
|
||||
|
||||
static_vector(const static_vector & v)
|
||||
: _size(v._size)
|
||||
{
|
||||
size_t n = _size;
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
for(size_t i=0; i<_size; i++)
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
|
||||
~static_vector(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
}
|
||||
|
||||
|
@ -45,10 +51,12 @@ public:
|
|||
if (this != &v)
|
||||
{
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
_size = v._size;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
return *this;
|
||||
|
@ -69,6 +77,11 @@ public:
|
|||
return _size == 0;
|
||||
}
|
||||
|
||||
bool full(void) const
|
||||
{
|
||||
return _size == N;
|
||||
}
|
||||
|
||||
size_t capacity(void) const
|
||||
{
|
||||
return N;
|
||||
|
@ -76,6 +89,8 @@ public:
|
|||
|
||||
void resize(size_t n);
|
||||
|
||||
void clear(void);
|
||||
|
||||
T & at(size_t at)
|
||||
{
|
||||
return ((T*)_space)[at];
|
||||
|
@ -166,6 +181,8 @@ public:
|
|||
((T*)_space)[_size].~T();
|
||||
}
|
||||
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
@ -177,34 +194,50 @@ public:
|
|||
};
|
||||
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::clear(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::resize(size_t n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
if (n < _size)
|
||||
{
|
||||
for(size_t i=n; i<_size; i++)
|
||||
data[i].~T();
|
||||
_size = n;
|
||||
}
|
||||
else
|
||||
else if (n > 0)
|
||||
{
|
||||
for(size_t i=_size; i<n; i++)
|
||||
new(data + i)T;
|
||||
_size = n;
|
||||
new(data + i)T();
|
||||
}
|
||||
_size = n;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(T && t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
|
@ -212,14 +245,28 @@ template <class T, int N>
|
|||
template <typename ...P>
|
||||
void static_vector<T, N>::emplace_back(const P&... p)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(p...);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::assign(size_t count, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
for(size_t i=0; i<count; i++)
|
||||
new (data + i)T(t);
|
||||
_size = count;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::insert(size_t at, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
new (data + _size)T;
|
||||
new (data + _size)T();
|
||||
for(size_t i=_size; i>at; i--)
|
||||
data[i] = move(data[i - 1]);
|
||||
data[at] = t;
|
||||
|
@ -240,9 +287,12 @@ void static_vector<T, N>::erase(size_t at, size_t n)
|
|||
template <class T, int N>
|
||||
T * static_vector<T, N>::insert(T * at, const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
T * dp = data + _size;
|
||||
new (dp)T;
|
||||
new (dp)T();
|
||||
while (dp != at)
|
||||
{
|
||||
dp--;
|
||||
|
|
|
@ -21,13 +21,14 @@ public:
|
|||
vector(size_t n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
|
||||
{
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i) T;
|
||||
new (_data + i) T();
|
||||
}
|
||||
|
||||
vector(const vector & v)
|
||||
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
|
||||
|
@ -50,14 +51,16 @@ public:
|
|||
{
|
||||
if (this != &v)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
_data[i].~T();
|
||||
free(_data);
|
||||
|
||||
_data = (T*)malloc(v._size * sizeof(T));
|
||||
_size = v._size;
|
||||
_capacity = v._size;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
return *this;
|
||||
|
@ -94,6 +97,8 @@ public:
|
|||
return _capacity;
|
||||
}
|
||||
|
||||
void clear(void);
|
||||
|
||||
void resize(size_t n);
|
||||
|
||||
void reserve(size_t n);
|
||||
|
@ -190,6 +195,8 @@ public:
|
|||
_data[_size].~T();
|
||||
}
|
||||
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
@ -204,7 +211,7 @@ protected:
|
|||
|
||||
|
||||
template <class T>
|
||||
void vector<T>::reserve(size_t n)
|
||||
__noinline void vector<T>::reserve(size_t n)
|
||||
{
|
||||
if (n > _capacity)
|
||||
{
|
||||
|
@ -221,7 +228,15 @@ void vector<T>::reserve(size_t n)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::resize(size_t n)
|
||||
void vector<T>::clear(void)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
__noinline void vector<T>::resize(size_t n)
|
||||
{
|
||||
if (n < _size)
|
||||
{
|
||||
|
@ -232,7 +247,7 @@ void vector<T>::resize(size_t n)
|
|||
else if (n < _capacity)
|
||||
{
|
||||
for(size_t i=_size; i<n; i++)
|
||||
new(_data + i)T;
|
||||
new(_data + i)T();
|
||||
_size = n;
|
||||
}
|
||||
else
|
||||
|
@ -286,12 +301,27 @@ void vector<T>::emplace_back(const P&... p)
|
|||
new (add_back())T(p...);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::assign(size_t count, const T & t)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
if (count > _capacity)
|
||||
{
|
||||
_size = 0;
|
||||
reserve(count);
|
||||
}
|
||||
for(size_t i=0; i<count; i++)
|
||||
new (_data + i)T(t);
|
||||
_size = count;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::insert(size_t at, const T & t)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
reserve(_size + 1 + (_size >> 1));
|
||||
new (_data + _size)T;
|
||||
new (_data + _size)T();
|
||||
for(size_t i=_size; i>at; i--)
|
||||
_data[i] = move(_data[i - 1]);
|
||||
_data[at] = t;
|
||||
|
@ -318,7 +348,7 @@ T * vector<T>::insert(T * at, const T & t)
|
|||
at = (T *)(f + unsigned(_data));
|
||||
}
|
||||
T * dp = _data + _size;
|
||||
new (dp)T;
|
||||
new (dp)T();
|
||||
while (dp != at)
|
||||
{
|
||||
dp--;
|
||||
|
|
|
@ -129,3 +129,10 @@ __native const char * oscar_expand_lzo_buf(char * dp, const char * sp)
|
|||
|
||||
return sp + 1;
|
||||
}
|
||||
|
||||
void debugcrash(void)
|
||||
{
|
||||
__asm volatile {
|
||||
byt $02
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ void breakpoint(void);
|
|||
|
||||
#pragma intrinsic(breakpoint)
|
||||
|
||||
void debugcrash(void);
|
||||
|
||||
#pragma compile("oscar.c")
|
||||
|
||||
#endif
|
||||
|
|
258
include/stdio.c
258
include/stdio.c
|
@ -2,237 +2,50 @@
|
|||
#include "conio.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#if defined(__C128__)
|
||||
#pragma code(lowcode)
|
||||
__asm bsout
|
||||
{
|
||||
ldx #0
|
||||
stx 0xff00
|
||||
jsr 0xffd2
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xfff0
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsin
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xffcf
|
||||
sta 0xff01
|
||||
}
|
||||
|
||||
#pragma code(code)
|
||||
#elif defined(__PLUS4__)
|
||||
#pragma code(lowcode)
|
||||
__asm bsout
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffd2
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsin
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffe4
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xfff0
|
||||
sta 0xff3f
|
||||
}
|
||||
#pragma code(code)
|
||||
#elif defined(__ATARI__)
|
||||
__asm bsout
|
||||
{
|
||||
tax
|
||||
lda 0xe407
|
||||
pha
|
||||
lda 0xe406
|
||||
pha
|
||||
txa
|
||||
}
|
||||
|
||||
__asm bsin
|
||||
{
|
||||
lda 0xe405
|
||||
pha
|
||||
lda 0xe404
|
||||
pha
|
||||
}
|
||||
|
||||
__asm bsplot
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#define bsout 0xffd2
|
||||
#define bsplot 0xfff0
|
||||
#define bsin 0xffcf
|
||||
#endif
|
||||
|
||||
__asm putpch
|
||||
{
|
||||
#if defined(__ATARI__)
|
||||
cmp #10
|
||||
bne w1
|
||||
lda #0x9b
|
||||
w1:
|
||||
jmp bsout
|
||||
#else
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
|
||||
cmp #10
|
||||
bne w1
|
||||
lda #13
|
||||
w1:
|
||||
cmp #9
|
||||
beq t1
|
||||
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
|
||||
cmp #65
|
||||
bcc w3
|
||||
cmp #123
|
||||
bcs w3
|
||||
#if defined(__CBMPET__)
|
||||
cmp #97
|
||||
bcs w4
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$a0
|
||||
w4:
|
||||
eor #$20
|
||||
|
||||
#else
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
#endif
|
||||
cpx #IOCHM_PETSCII_2
|
||||
beq w3
|
||||
and #$df
|
||||
w3:
|
||||
jmp bsout
|
||||
t1:
|
||||
sec
|
||||
jsr bsplot
|
||||
tya
|
||||
and #3
|
||||
eor #3
|
||||
tax
|
||||
lda #$20
|
||||
l1:
|
||||
jsr bsout
|
||||
dex
|
||||
bpl l1
|
||||
#endif
|
||||
}
|
||||
|
||||
__asm getpch
|
||||
{
|
||||
jsr bsin
|
||||
#if !defined(__ATARI__)
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
|
||||
cmp #13
|
||||
bne w1
|
||||
lda #10
|
||||
w1:
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
|
||||
cmp #219
|
||||
bcs w3
|
||||
cmp #65
|
||||
bcc w3
|
||||
|
||||
cmp #193
|
||||
bcc w4
|
||||
eor #$a0
|
||||
w4:
|
||||
cmp #123
|
||||
bcs w3
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
w3:
|
||||
#endif
|
||||
}
|
||||
|
||||
void putchar(char c)
|
||||
{
|
||||
__asm {
|
||||
lda c
|
||||
jsr putpch
|
||||
}
|
||||
putpch(c);
|
||||
}
|
||||
|
||||
char getchar(void)
|
||||
{
|
||||
__asm {
|
||||
jsr getpch
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
return getpch();
|
||||
}
|
||||
|
||||
void puts(const char * str)
|
||||
{
|
||||
__asm {
|
||||
ploop:
|
||||
ldy #0
|
||||
lda (str), y
|
||||
beq pdone
|
||||
|
||||
jsr putpch
|
||||
|
||||
inc str
|
||||
bne ploop
|
||||
inc str + 1
|
||||
bne ploop
|
||||
pdone:
|
||||
}
|
||||
while (char ch = *str++)
|
||||
putpch(ch);
|
||||
}
|
||||
|
||||
char * gets(char * str)
|
||||
{
|
||||
__asm {
|
||||
gloop:
|
||||
jsr getpch
|
||||
ldy #0
|
||||
cmp #10
|
||||
beq gdone
|
||||
sta (str), y
|
||||
inc str
|
||||
bne gloop
|
||||
inc str + 1
|
||||
bne gloop
|
||||
gdone:
|
||||
lda #0
|
||||
sta (str), y
|
||||
char i = 0;
|
||||
while ((char ch = getpch()) != '\n')
|
||||
str[i++] = ch;
|
||||
str[i] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
char * gets_s(char * str, size_t n)
|
||||
{
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
if (n < 2)
|
||||
return NULL;
|
||||
char i = 0, t = n - 1;
|
||||
|
||||
while ((char ch = getpch()) != '\n')
|
||||
{
|
||||
if (i < t)
|
||||
str[i] = ch;
|
||||
++i;
|
||||
}
|
||||
|
||||
str[(i < t) ? i : t] = '\0';
|
||||
|
||||
if (i > t)
|
||||
return NULL;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -604,7 +417,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
|
|||
si.precision = i;
|
||||
}
|
||||
|
||||
if (c == 'd' || c == p'd')
|
||||
if (c == 'd' || c == p'd' || c == 'i' || c == p'i')
|
||||
{
|
||||
bi = nformi(&si, bp, *fps++, true);
|
||||
}
|
||||
|
@ -743,6 +556,17 @@ int sprintf(char * str, const char * fmt, ...)
|
|||
return d - str;
|
||||
}
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist)
|
||||
{
|
||||
char buff[50];
|
||||
sformat(buff, fmt, (int *)vlist, true);
|
||||
}
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist)
|
||||
{
|
||||
char * d = sformat(str, fmt, (int *)vlist, false);
|
||||
return d - str;
|
||||
}
|
||||
|
||||
static inline bool isspace(char c)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#define STDIO_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void putchar(char c);
|
||||
|
||||
|
@ -12,10 +13,16 @@ void puts(const char * str);
|
|||
|
||||
char * gets(char * str);
|
||||
|
||||
char * gets_s(char * str, size_t n);
|
||||
|
||||
void printf(const char * fmt, ...);
|
||||
|
||||
int sprintf(char * str, const char * fmt, ...);
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist);
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist);
|
||||
|
||||
int scanf(const char * fmt, ...);
|
||||
|
||||
int sscanf(const char * str, const char * fmt, ...);
|
||||
|
|
|
@ -544,7 +544,7 @@ unsigned heapfree(void)
|
|||
}
|
||||
|
||||
#if 0
|
||||
struct Heap {
|
||||
struct Heap {q
|
||||
unsigned int size;
|
||||
Heap * next;
|
||||
} * freeHeap;
|
||||
|
@ -667,6 +667,97 @@ void * calloc(int num, int size)
|
|||
return p;
|
||||
}
|
||||
|
||||
void * realloc(void * ptr, unsigned size)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
#ifdef HEAPCHECK
|
||||
Heap * pheap = (Heap *)((char *)ptr - 6);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 6);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#else
|
||||
unsigned nsize = (size + 5) & ~3;
|
||||
|
||||
// Get heap info
|
||||
Heap * pheap = (Heap *)((char *)ptr - 2);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
Heap * h = HeapNode.next;
|
||||
Heap * hp = &HeapNode;
|
||||
while (h && h < pheap)
|
||||
{
|
||||
hp = h;
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (nsize <= psize)
|
||||
{
|
||||
// check if we should free some memory
|
||||
if (nsize + sizeof(HeapNode) < psize)
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
|
||||
if (h == eheap)
|
||||
{
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
nheap->end = eheap;
|
||||
nheap->next = h;
|
||||
}
|
||||
|
||||
hp->next = nheap;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
else if (h == eheap)
|
||||
{
|
||||
// Free space after this
|
||||
|
||||
// Check if enough space if extending
|
||||
unsigned xsize = (char *)h->end - (char *)pheap;
|
||||
if (xsize >= nsize)
|
||||
{
|
||||
if (xsize > nsize + sizeof(HeapNode))
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
hp->next = nheap;
|
||||
}
|
||||
else
|
||||
{
|
||||
pheap->next = h->end;
|
||||
hp->next = h->next;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 2);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static unsigned seed = 31232;
|
||||
|
||||
unsigned int rand(void)
|
||||
|
|
|
@ -45,6 +45,8 @@ void free(void * ptr);
|
|||
|
||||
void * calloc(int num, int size);
|
||||
|
||||
void * realloc(void * ptr, unsigned size);
|
||||
|
||||
unsigned heapfree(void);
|
||||
|
||||
unsigned int rand(void);
|
||||
|
|
|
@ -138,6 +138,20 @@ char * cpycat(char * dst, const char * src)
|
|||
|
||||
#pragma native(cpycat)
|
||||
|
||||
char* strchr( const char* str, int ch )
|
||||
{
|
||||
char * p = (char *)str;
|
||||
|
||||
while (*p != (char)ch)
|
||||
{
|
||||
if (!*p)
|
||||
return nullptr;
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void * memset(void * dst, int value, int size)
|
||||
{
|
||||
__asm
|
||||
|
@ -223,8 +237,8 @@ void * memmove(void * dst, const void * src, int size)
|
|||
int sz = size;
|
||||
if (sz > 0)
|
||||
{
|
||||
char * d = dst;
|
||||
const char * s = src;
|
||||
char * d = (char *)dst;
|
||||
const char * s = (const char *)src;
|
||||
if (d < s)
|
||||
{
|
||||
do {
|
||||
|
@ -245,7 +259,7 @@ void * memmove(void * dst, const void * src, int size)
|
|||
|
||||
int memcmp(const void * ptr1, const void * ptr2, int size)
|
||||
{
|
||||
const char * p = ptr1, * q = ptr2;
|
||||
const char * p = (const char *)ptr1, * q = (const char *)ptr2;
|
||||
char c, d;
|
||||
|
||||
while (size--)
|
||||
|
|
|
@ -21,6 +21,8 @@ int memcmp(const void * ptr1, const void * ptr2, int size);
|
|||
|
||||
void * memmove(void * dst, const void * src, int size);
|
||||
|
||||
char* strchr( const char* str, int ch );
|
||||
|
||||
#pragma intrinsic(strcpy)
|
||||
|
||||
#pragma intrinsic(memcpy)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
project_dir := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))/../)
|
||||
sources = $(wildcard $(project_dir)/oscar64/*.cpp)
|
||||
objects = $(patsubst $(project_dir)/oscar64/%.cpp,%.o,$(sources))
|
||||
srcdir := $(if $(srcdir),$(srcdir),$(project_dir)/build)
|
||||
objects = $(patsubst $(project_dir)/oscar64/%.cpp,$(srcdir)/%.o,$(sources))
|
||||
|
||||
CXX = c++
|
||||
CPPFLAGS = -g -O2 -std=c++11 -Wno-switch
|
||||
|
@ -12,8 +12,8 @@ export OSCAR64_CFLAGS =
|
|||
export OSCAR64_CXX = $(project_dir)/bin/oscar64
|
||||
MKDIR_PARENT = /bin/mkdir -p -m 755
|
||||
INSTALL = /usr/bin/install
|
||||
INSTALL_PROGRAM = $(INSTALL) --mode=755
|
||||
INSTALL_DATA = $(INSTALL) --mode=644
|
||||
INSTALL_PROGRAM = $(INSTALL) -m 755
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
DESTDIR =
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
|
@ -38,26 +38,27 @@ else
|
|||
endif
|
||||
|
||||
|
||||
all: --prep-build-dir compiler samples tests
|
||||
all: compiler samples check
|
||||
|
||||
|
||||
%.o: $(project_dir)/oscar64/%.cpp
|
||||
@echo "Compiling compiler file" $@ "..."
|
||||
@$(CXX) -c $(CPPFLAGS) $< -o $(srcdir)/$@
|
||||
$(srcdir)/%.o: $(project_dir)/oscar64/%.cpp
|
||||
@echo "Compiling compiler file" $@ "..." $<
|
||||
@$(CXX) -c $(CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
%.d: $(project_dir)/oscar64/%.cpp
|
||||
@echo "Transforming file" $@ "..."
|
||||
$(srcdir)/%.d: $(project_dir)/oscar64/%.cpp
|
||||
@$(MKDIR_PARENT) $(srcdir)
|
||||
@echo "Transforming file" $@ "..." $<
|
||||
@set -e; \
|
||||
$(RM) $(srcdir)/$@; \
|
||||
@$(CC) -MM $(CPPFLAGS) $< > $(srcdir)/$@.$$$$; \
|
||||
$(SED) 's,\($*\)\.o[ :]*,\1.o $(srcdir)/$@ : ,g' < $(srcdir)/$@.$$$$ > $(srcdir)/$@; \
|
||||
$(RM) $(srcdir)/$@.$$$$
|
||||
$(RM) $@; \
|
||||
$(CC) -MM -MT $(patsubst %.d,%.o,$@) $(CPPFLAGS) $< > $@.$$$$; \
|
||||
$(SED) 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
|
||||
$(RM) $@.$$$$
|
||||
|
||||
|
||||
compiler: $(objects)
|
||||
compiler: --prep-build-dir $(objects)
|
||||
@$(MKDIR_PARENT) $(srcdir)
|
||||
@echo "Linking compiler..."
|
||||
@cd $(srcdir); \
|
||||
$(CXX) $(CPPFLAGS) $(objects) $(linklibs) -o $(project_dir)/bin/oscar64
|
||||
|
||||
|
||||
|
@ -84,7 +85,7 @@ samples: compiler
|
|||
@$(MAKE) -C $(project_dir)/samples all
|
||||
|
||||
|
||||
tests: compiler
|
||||
check: compiler
|
||||
@$(MAKE) -C $(project_dir)/autotest all
|
||||
|
||||
install: compiler
|
||||
|
@ -92,16 +93,16 @@ install: compiler
|
|||
@$(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) $(project_dir)/include/*.{h,c} $(DESTDIR)$(includedir)/oscar64
|
||||
$(INSTALL_DATA) $(project_dir)/include/audio/*.{h,c} $(DESTDIR)$(includedir)/oscar64/audio
|
||||
$(INSTALL_DATA) $(project_dir)/include/c64/*.{h,c} $(DESTDIR)$(includedir)/oscar64/c64
|
||||
$(INSTALL_DATA) $(project_dir)/include/c128/*.{h,c} $(DESTDIR)$(includedir)/oscar64/c128
|
||||
$(INSTALL_DATA) $(project_dir)/include/cx16/*.{h,c} $(DESTDIR)$(includedir)/oscar64/cx16
|
||||
$(INSTALL_DATA) $(project_dir)/include/gfx/*.{h,c} $(DESTDIR)$(includedir)/oscar64/gfx
|
||||
$(INSTALL_DATA) $(project_dir)/include/nes/*.{h,c} $(DESTDIR)$(includedir)/oscar64/nes
|
||||
$(INSTALL_DATA) $(project_dir)/include/opp/*.{h,cpp} $(DESTDIR)$(includedir)/oscar64/opp
|
||||
$(INSTALL_DATA) $(project_dir)/include/plus4/*.{h,c} $(DESTDIR)$(includedir)/oscar64/plus4
|
||||
$(INSTALL_DATA) $(project_dir)/include/vic20/*.{h,c} $(DESTDIR)$(includedir)/oscar64/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:
|
||||
|
@ -114,11 +115,12 @@ ifeq ($(UNAME_S), Darwin)
|
|||
|
||||
else
|
||||
|
||||
include $($(srcdir)/objects:.o=.d)
|
||||
include $(objects:.o=.d)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
--prep-build-dir:
|
||||
echo "makedir"
|
||||
@if [ ! -d $(srcdir) ]; then $(MKDIR_PARENT) $(srcdir); fi
|
||||
@if [ ! -d $(project_dir)/bin ]; then $(MKDIR_PARENT) $(project_dir)/bin; fi
|
||||
|
|
File diff suppressed because it is too large
Load Diff
16
oscar64.sln
16
oscar64.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31624.102
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35931.197
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}"
|
||||
EndProject
|
||||
|
@ -23,10 +23,14 @@ Global
|
|||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x64.Build.0 = Release|x64
|
||||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.Build.0 = Release|Win32
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.Build.0 = Debug|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.Build.0 = Debug|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.Build.0 = Release|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -421,9 +421,33 @@ protected:
|
|||
array = a2;
|
||||
}
|
||||
|
||||
for (int i = size; i < to; i++) array[i] = T{};
|
||||
|
||||
size = to;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Partition(const F & f, int l, int r)
|
||||
{
|
||||
if (r > l + 1)
|
||||
{
|
||||
int pi = l;
|
||||
T p(array[pi]);
|
||||
|
||||
for (int i = l + 1; i < r; i++)
|
||||
{
|
||||
if (f(array[i], p))
|
||||
{
|
||||
array[pi++] = array[i];
|
||||
array[i] = array[pi];
|
||||
}
|
||||
}
|
||||
array[pi] = p;
|
||||
|
||||
Partition(f, l, pi);
|
||||
Partition(f, pi + 1, r);
|
||||
}
|
||||
}
|
||||
public:
|
||||
ExpandingArray(void)
|
||||
{
|
||||
|
@ -596,6 +620,24 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
void Fill(const T& t)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
array[i] = t;
|
||||
}
|
||||
|
||||
void Clear(void)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
array[i] = T{};
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Sort(const F & f)
|
||||
{
|
||||
Partition(f, 0, size);
|
||||
}
|
||||
|
||||
__forceinline T& operator[](int n)
|
||||
{
|
||||
assert(n >= 0 && n < size);
|
||||
|
|
|
@ -293,7 +293,7 @@ const char* AsmInstructionNames[NUM_ASM_INS_TYPES] = {
|
|||
"INV", "BYT"
|
||||
};
|
||||
|
||||
int AsmInsModeSize[NUM_ASM_INS_MODES] = {
|
||||
int AsmInsModeSize[NUM_ASM_INS_MODES_X] = {
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
|
@ -306,6 +306,8 @@ int AsmInsModeSize[NUM_ASM_INS_MODES] = {
|
|||
2,
|
||||
2,
|
||||
2,
|
||||
0,
|
||||
2
|
||||
};
|
||||
|
||||
void InitAssembler(void)
|
||||
|
|
|
@ -31,7 +31,9 @@ enum AsmInsMode
|
|||
|
||||
NUM_ASM_INS_MODES,
|
||||
|
||||
ASMIM_IMMEDIATE_ADDRESS
|
||||
ASMIM_IMMEDIATE_ADDRESS,
|
||||
|
||||
NUM_ASM_INS_MODES_X,
|
||||
};
|
||||
|
||||
struct AsmInsData
|
||||
|
@ -45,6 +47,8 @@ extern AsmInsData DecInsData[256];
|
|||
|
||||
extern short AsmInsOpcodes[NUM_ASM_INS_TYPES][NUM_ASM_INS_MODES];
|
||||
|
||||
extern int AsmInsModeSize[NUM_ASM_INS_MODES_X];
|
||||
|
||||
extern const char* AsmInstructionNames[NUM_ASM_INS_TYPES];
|
||||
|
||||
AsmInsType FindAsmInstruction(const char * ins);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
class BitVector
|
||||
{
|
||||
|
|
|
@ -3462,94 +3462,151 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
|
|||
{
|
||||
if (ins->mSrc[1].mTemp < 0)
|
||||
{
|
||||
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)
|
||||
if (ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[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);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[1].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
if (ins->mSrc[0].mType == IT_INT16 || ins->mSrc[0].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
case IA_CMPLEU:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPGEU:
|
||||
return BC_JUMPS;
|
||||
case IA_CMPLU:
|
||||
return BC_NOP;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[0].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6548,7 +6605,7 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
|
|||
{
|
||||
mID = proc->mID;
|
||||
|
||||
mNumBlocks = proc->mBlocks.Size();
|
||||
mNumBlocks = proc->mNumBlocks;
|
||||
|
||||
tblocks = new ByteCodeBasicBlock * [mNumBlocks];
|
||||
for (int i = 0; i < mNumBlocks; i++)
|
||||
|
|
|
@ -174,13 +174,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
|
||||
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = int(bcdec->mInteger);
|
||||
|
@ -466,7 +466,7 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
|
|||
printf("Generate native code <%s>\n", proc->mIdent->mString);
|
||||
|
||||
ncproc->Compile(proc);
|
||||
mNativeProcedures.Push(ncproc);
|
||||
mNativeCodeGenerator->mProcedures.Push(ncproc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -508,6 +508,8 @@ bool Compiler::GenerateCode(void)
|
|||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
|
||||
else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES))
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
|
||||
else if (mTargetMachine == TMACH_PET_8K || mTargetMachine == TMACH_PET_16K || mTargetMachine == TMACH_PET_32K)
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00ed, 0x00f7);
|
||||
else
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff);
|
||||
}
|
||||
|
@ -521,6 +523,12 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2080);
|
||||
else
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2100);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
case TMACH_X16:
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
|
@ -623,6 +631,9 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
case TMACH_X16:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
|
||||
|
@ -684,6 +695,9 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x2300, 0xc000);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
|
||||
break;
|
||||
|
@ -735,6 +749,14 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
// TODO: Disable M65 cartridges for now.
|
||||
//
|
||||
// if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
|
||||
// regionMain = mLinker->AddRegion(identMain, 0x2666, 0xff00);
|
||||
// else
|
||||
regionMain = mLinker->AddRegion(identMain, 0x2080, 0xc000);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
|
||||
if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
|
||||
|
@ -910,7 +932,7 @@ bool Compiler::GenerateCode(void)
|
|||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Generate intermediate code\n");
|
||||
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart, nullptr);
|
||||
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
|
||||
{
|
||||
Declaration* dec = mCompilationUnits->mReferenced[i];
|
||||
|
@ -943,7 +965,8 @@ bool Compiler::GenerateCode(void)
|
|||
RegisterRuntime(loc, Ident::Unique("fsplitt"));
|
||||
RegisterRuntime(loc, Ident::Unique("fsplitx"));
|
||||
RegisterRuntime(loc, Ident::Unique("fsplita"));
|
||||
RegisterRuntime(loc, Ident::Unique("faddsub"));
|
||||
RegisterRuntime(loc, Ident::Unique("fadd"));
|
||||
RegisterRuntime(loc, Ident::Unique("fsub"));
|
||||
RegisterRuntime(loc, Ident::Unique("fmul"));
|
||||
RegisterRuntime(loc, Ident::Unique("fdiv"));
|
||||
RegisterRuntime(loc, Ident::Unique("mul16"));
|
||||
|
@ -971,6 +994,9 @@ bool Compiler::GenerateCode(void)
|
|||
RegisterRuntime(loc, Ident::Unique("divu32"));
|
||||
RegisterRuntime(loc, Ident::Unique("modu32"));
|
||||
|
||||
RegisterRuntime(loc, Ident::Unique("store32"));
|
||||
RegisterRuntime(loc, Ident::Unique("load32"));
|
||||
|
||||
RegisterRuntime(loc, Ident::Unique("malloc"));
|
||||
RegisterRuntime(loc, Ident::Unique("free"));
|
||||
RegisterRuntime(loc, Ident::Unique("breakpoint"));
|
||||
|
@ -989,7 +1015,7 @@ bool Compiler::GenerateCode(void)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
|
||||
}
|
||||
}
|
||||
|
@ -1032,13 +1058,18 @@ bool Compiler::GenerateCode(void)
|
|||
mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection);
|
||||
}
|
||||
|
||||
mNativeCodeGenerator->OutlineFunctions();
|
||||
|
||||
mNativeCodeGenerator->BuildFunctionProxies();
|
||||
|
||||
for (int i = 0; i < mNativeProcedures.Size(); i++)
|
||||
for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++)
|
||||
{
|
||||
if (mCompilerOptions & COPT_VERBOSE2)
|
||||
printf("Assemble native code <%s>\n", mNativeProcedures[i]->mInterProc->mIdent->mString);
|
||||
mNativeProcedures[i]->Assemble();
|
||||
{
|
||||
if (mNativeCodeGenerator->mProcedures[i]->mInterProc)
|
||||
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
|
||||
}
|
||||
mNativeCodeGenerator->mProcedures[i]->Assemble();
|
||||
}
|
||||
|
||||
LinkerObject* byteCodeObject = nullptr;
|
||||
|
@ -1064,13 +1095,13 @@ bool Compiler::GenerateCode(void)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = int(bcdec->mInteger);
|
||||
}
|
||||
|
@ -1188,9 +1219,85 @@ bool Compiler::BuildLZO(const char* targetPath)
|
|||
}
|
||||
}
|
||||
|
||||
bool Compiler::RemoveErrorFile(const char* targetPath)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], intPath[200];
|
||||
char basePath[200];
|
||||
|
||||
strcpy_s(basePath, targetPath);
|
||||
ptrdiff_t i = strlen(basePath);
|
||||
while (i > 0 && basePath[i - 1] != '/' && basePath[i - 1] != '\\' && basePath[i - 1] != ':')
|
||||
i--;
|
||||
if (i > 0)
|
||||
basePath[i] = 0;
|
||||
|
||||
strcpy_s(prgPath, targetPath);
|
||||
i = strlen(prgPath);
|
||||
while (i > 0 && prgPath[i - 1] != '.')
|
||||
i--;
|
||||
if (i > 0)
|
||||
prgPath[i] = 0;
|
||||
|
||||
strcpy_s(mapPath, prgPath);
|
||||
strcpy_s(asmPath, prgPath);
|
||||
strcpy_s(intPath, prgPath);
|
||||
|
||||
strcat_s(mapPath, "error.map");
|
||||
strcat_s(asmPath, "error.asm");
|
||||
strcat_s(intPath, "error.int");
|
||||
|
||||
remove(mapPath);
|
||||
remove(asmPath);
|
||||
remove(intPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::WriteErrorFile(const char* targetPath)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], intPath[200];
|
||||
char basePath[200];
|
||||
|
||||
strcpy_s(basePath, targetPath);
|
||||
ptrdiff_t i = strlen(basePath);
|
||||
while (i > 0 && basePath[i - 1] != '/' && basePath[i - 1] != '\\' && basePath[i - 1] != ':')
|
||||
i--;
|
||||
if (i > 0)
|
||||
basePath[i] = 0;
|
||||
|
||||
strcpy_s(prgPath, targetPath);
|
||||
i = strlen(prgPath);
|
||||
while (i > 0 && prgPath[i - 1] != '.')
|
||||
i--;
|
||||
if (i > 0)
|
||||
prgPath[i] = 0;
|
||||
|
||||
strcpy_s(mapPath, prgPath);
|
||||
strcpy_s(asmPath, prgPath);
|
||||
strcpy_s(intPath, prgPath);
|
||||
|
||||
strcat_s(mapPath, "error.map");
|
||||
strcat_s(asmPath, "error.asm");
|
||||
strcat_s(intPath, "error.int");
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", mapPath);
|
||||
mLinker->WriteMapFile(mapPath);
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", asmPath);
|
||||
mLinker->WriteAsmFile(asmPath, mVersion);
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", intPath);
|
||||
mInterCodeModule->Disassemble(intPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200];
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200], cszPath[200];
|
||||
char basePath[200];
|
||||
|
||||
strcpy_s(basePath, targetPath);
|
||||
|
@ -1213,6 +1320,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
strcpy_s(intPath, prgPath);
|
||||
strcpy_s(bcsPath, prgPath);
|
||||
strcpy_s(dbjPath, prgPath);
|
||||
strcpy_s(cszPath, prgPath);
|
||||
|
||||
strcat_s(mapPath, "map");
|
||||
strcat_s(asmPath, "asm");
|
||||
|
@ -1220,6 +1328,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
strcat_s(intPath, "int");
|
||||
strcat_s(bcsPath, "bcs");
|
||||
strcat_s(dbjPath, "dbj");
|
||||
strcat_s(cszPath, "csz");
|
||||
|
||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||
{
|
||||
|
@ -1302,6 +1411,9 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
if (mCompilerOptions & COPT_DEBUGINFO)
|
||||
WriteDbjFile(dbjPath);
|
||||
|
||||
if (mCompilerOptions & COPT_PROFILEINFO)
|
||||
WriteCszFile(cszPath);
|
||||
|
||||
if (!(mCompilerOptions & COPT_NATIVE))
|
||||
{
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
|
@ -1368,6 +1480,111 @@ static void DumpReferences(FILE* file, Declaration* dec)
|
|||
|
||||
}
|
||||
|
||||
bool Compiler::WriteCszFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
if (file)
|
||||
{
|
||||
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
|
||||
{
|
||||
InterCodeProcedure* p(mInterCodeModule->mProcedures[i]);
|
||||
if (p->mLinkerObject && p->mIdent && p->mDeclaration)
|
||||
{
|
||||
LinkerObject* lo = p->mLinkerObject;
|
||||
|
||||
struct SourceCount
|
||||
{
|
||||
const char* mFileName;
|
||||
int mLine, mAddress;
|
||||
int mBytes;
|
||||
};
|
||||
|
||||
ExpandingArray<SourceCount> ea;
|
||||
|
||||
for (int j = 0; j < lo->mCodeLocations.Size(); j++)
|
||||
{
|
||||
const CodeLocation& co(lo->mCodeLocations[j]);
|
||||
const Location* ls = &(co.mLocation);
|
||||
while (ls->mFrom)
|
||||
ls = ls->mFrom;
|
||||
|
||||
int k = 0;
|
||||
while (k < ea.Size() && (ea[k].mFileName != ls->mFileName || ea[k].mLine != ls->mLine))
|
||||
k++;
|
||||
if (k == ea.Size())
|
||||
{
|
||||
SourceCount sc;
|
||||
sc.mFileName = ls->mFileName;
|
||||
sc.mLine = ls->mLine;
|
||||
sc.mBytes = 0;
|
||||
sc.mAddress = co.mStart + lo->mAddress;
|
||||
ea.Push(sc);
|
||||
}
|
||||
|
||||
ea[k].mBytes += co.mEnd - co.mStart;
|
||||
}
|
||||
|
||||
if (ea.Size())
|
||||
{
|
||||
ea.Sort([](const SourceCount& l, const SourceCount& r)->bool {
|
||||
return l.mFileName == r.mFileName ? l.mLine < r.mLine : l.mAddress < r.mAddress;
|
||||
});
|
||||
|
||||
FILE* fsrc;
|
||||
fopen_s(&fsrc, ea[0].mFileName, "r");
|
||||
if (fsrc)
|
||||
{
|
||||
fprintf(file, "<%s, %s>\n", p->mDeclaration->mQualIdent->mString, ea[0].mFileName);
|
||||
#if 0
|
||||
for (int i = 0; i < ea.Size(); i++)
|
||||
{
|
||||
fprintf(file, "%s:%d : %d\n", ea[i].mFileName, ea[i].mLine, ea[i].mBytes);
|
||||
}
|
||||
#endif
|
||||
int k = 0, l = 1;
|
||||
char line[1024];
|
||||
while (k < ea.Size() && fgets(line, 1024, fsrc))
|
||||
{
|
||||
size_t ll = strlen(line);
|
||||
while (ll > 0 && (line[ll - 1] == '\r' || line[ll - 1] == '\n'))
|
||||
ll--;
|
||||
line[ll] = 0;
|
||||
|
||||
if (l < ea[k].mLine)
|
||||
{
|
||||
if (k > 0)
|
||||
fprintf(file, "%5d,---- ( ) : %s\n", l, line);
|
||||
}
|
||||
else
|
||||
{
|
||||
int ks = k, sum = 0;
|
||||
do {
|
||||
sum += ea[ks].mBytes;
|
||||
ks++;
|
||||
} while (ks < ea.Size() && ea[ks].mFileName != ea[0].mFileName);
|
||||
|
||||
fprintf(file, "%5d,%04x (%3d) : %s\n", l, ea[k].mAddress, ea[k].mBytes, line);
|
||||
|
||||
k = ks;
|
||||
}
|
||||
l++;
|
||||
}
|
||||
|
||||
fclose(fsrc);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::WriteDbjFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
|
|
@ -29,7 +29,6 @@ public:
|
|||
GlobalOptimizer* mGlobalOptimizer;
|
||||
|
||||
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
|
||||
ExpandingArray<NativeCodeProcedure*> mNativeProcedures;
|
||||
|
||||
TargetMachine mTargetMachine;
|
||||
uint64 mCompilerOptions;
|
||||
|
@ -48,6 +47,8 @@ public:
|
|||
bool ParseSource(void);
|
||||
bool GenerateCode(void);
|
||||
bool WriteOutputFile(const char* targetPath, DiskImage * d64);
|
||||
bool WriteErrorFile(const char* targetPath);
|
||||
bool RemoveErrorFile(const char* targetPath);
|
||||
int ExecuteCode(bool profile, int trace);
|
||||
|
||||
void AddDefine(const Ident* ident, const char* value);
|
||||
|
@ -59,4 +60,5 @@ public:
|
|||
void CompleteTemplateExpansion(void);
|
||||
|
||||
bool WriteDbjFile(const char* filename);
|
||||
bool WriteCszFile(const char* filename);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,8 @@ static const uint64 COPT_OPTIMIZE_AUTO_ZEROPAGE = 1ULL << 8;
|
|||
static const uint64 COPT_OPTIMIZE_CONST_PARAMS = 1ULL << 9;
|
||||
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
|
||||
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11;
|
||||
static const uint64 COPT_OPTIMIZE_OUTLINE = 1ULL << 12;
|
||||
static const uint64 COPT_OPTIMIZE_PAGE_CROSSING = 1ULL << 13;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 1ULL << 16;
|
||||
static const uint64 COPT_NATIVE = 1ULL << 17;
|
||||
|
@ -39,6 +41,10 @@ static const uint64 COPT_DEBUGINFO = 1ULL << 51;
|
|||
|
||||
static const uint64 COPT_CPLUSPLUS = 1ULL << 52;
|
||||
static const uint64 COPT_PETSCII = 1ULL << 53;
|
||||
static const uint64 COPT_ERROR_FILES = 1ULL << 54;
|
||||
|
||||
static const uint64 COPT_PROFILEINFO = 1ULL << 55;
|
||||
static const uint64 COPT_STRICT = 1ULL << 56;
|
||||
|
||||
|
||||
|
||||
|
@ -46,7 +52,7 @@ static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE |
|
|||
|
||||
static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
|
||||
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_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;
|
||||
|
||||
|
@ -73,7 +79,8 @@ enum TargetMachine
|
|||
TMACH_NES_MMC1,
|
||||
TMACH_NES_MMC3,
|
||||
TMACH_ATARI,
|
||||
TMACH_X16
|
||||
TMACH_X16,
|
||||
TMACH_MEGA65
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ int CompressLZO(uint8* dst, const uint8* source, int size)
|
|||
while (pi < 127 && pos < size)
|
||||
{
|
||||
int bi = pi, bj = 0;
|
||||
for (int i = 1; i < (pos < 255 ? pos : 255); i++)
|
||||
for (int i = 1; i <= (pos < 255 ? pos : 255); i++)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j])
|
||||
|
|
|
@ -651,6 +651,7 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
{
|
||||
mProcType = exp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = exp->mRight;
|
||||
Declaration* cdec = exp->mLeft->mDecType->mParams;
|
||||
|
||||
int pos = 0;
|
||||
|
@ -659,6 +660,28 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
mParams[pos].PutPtr(Value(&mResult));
|
||||
pos = 2;
|
||||
|
||||
if (pex->mType == EX_LIST)
|
||||
pex = pex->mRight;
|
||||
else
|
||||
pex = nullptr;
|
||||
cdec = cdec->mNext;
|
||||
|
||||
while (pex && pex->mType == EX_LIST)
|
||||
{
|
||||
if (!AddParam(pos, pex->mLeft, cdec))
|
||||
return exp;
|
||||
|
||||
pex = pex->mRight;
|
||||
if (cdec)
|
||||
cdec = cdec->mNext;
|
||||
}
|
||||
|
||||
if (pex)
|
||||
{
|
||||
if (!AddParam(pos, pex, cdec))
|
||||
return exp;
|
||||
}
|
||||
|
||||
mHeap = new ExpandingArray<Value*>();
|
||||
|
||||
Execute(exp->mLeft->mDecValue->mValue);
|
||||
|
@ -754,6 +777,9 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
|
|||
|
||||
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||
{
|
||||
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
|
||||
return exp;
|
||||
|
||||
mProcType = exp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = exp->mRight;
|
||||
|
@ -1020,6 +1046,9 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalUnary(Expression* exp, con
|
|||
break;
|
||||
case TK_MUL:
|
||||
return vl.GetPtr();
|
||||
case TK_SIZEOF:
|
||||
v.PutInt(vl.mDecType->mSize);
|
||||
break;
|
||||
default:
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
|
||||
}
|
||||
|
@ -1168,6 +1197,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
|
|||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::exp(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "sqrt"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::sqrt(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan2"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan2(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "pow"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::pow(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else
|
||||
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -104,6 +104,7 @@ static const uint64 DTF_CONSTEXPR = (1ULL << 31);
|
|||
static const uint64 DTF_AUTO_TEMPLATE = (1ULL << 32);
|
||||
static const uint64 DTF_BANK_INLAY = (1ULL << 33);
|
||||
static const uint64 DTF_PURE_VIRTUAL = (1ULL << 34);
|
||||
static const uint64 DTF_FORCE_INLINE = (1ULL << 35);
|
||||
|
||||
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 36);
|
||||
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 37);
|
||||
|
@ -125,6 +126,9 @@ static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
|
|||
static const uint64 DTF_FPARAM_UNUSED = (1ULL << 49);
|
||||
static const uint64 DTF_DEPRECATED = (1ULL << 50);
|
||||
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
|
||||
static const uint64 DTF_PLACED = (1ULL << 52);
|
||||
static const uint64 DTF_NO_PAGE_CROSS = (1ULL << 53);
|
||||
|
||||
|
||||
|
||||
class Declaration;
|
||||
|
@ -163,6 +167,8 @@ public:
|
|||
ScopeLevel mLevel;
|
||||
const Ident * mName;
|
||||
|
||||
DeclarationScope* Clone(void) const;
|
||||
|
||||
DeclarationScope* mParent;
|
||||
protected:
|
||||
struct Entry
|
||||
|
@ -212,6 +218,7 @@ enum ExpressionType
|
|||
EX_IF,
|
||||
EX_ELSE,
|
||||
EX_FOR,
|
||||
EX_FORBODY,
|
||||
EX_DO,
|
||||
EX_SCOPE,
|
||||
EX_BREAK,
|
||||
|
@ -235,9 +242,16 @@ enum ExpressionType
|
|||
EX_PACK,
|
||||
EX_PACK_TYPE,
|
||||
EX_LABEL,
|
||||
EX_GOTO
|
||||
EX_GOTO,
|
||||
EX_AGGREGATE
|
||||
};
|
||||
|
||||
static const uint32 ANAFL_LHS = (1U << 0);
|
||||
static const uint32 ANAFL_RHS = (1U << 1);
|
||||
static const uint32 ANAFL_ASSIGN = (1U << 2);
|
||||
static const uint32 ANAFL_ALIAS = (1U << 3);
|
||||
|
||||
|
||||
class Expression
|
||||
{
|
||||
public:
|
||||
|
@ -254,16 +268,23 @@ public:
|
|||
AsmInsType mAsmInsType;
|
||||
AsmInsMode mAsmInsMode;
|
||||
bool mConst;
|
||||
uint32 mFlags;
|
||||
|
||||
Expression* LogicInvertExpression(void);
|
||||
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
|
||||
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
|
||||
bool HasSideEffects(void) const;
|
||||
Expression* ListAppend(Expression* lexp);
|
||||
Expression* ToAlternateThis(Declaration* pthis, Declaration* nthis);
|
||||
|
||||
void ReplaceVariable(Declaration* pvar, Declaration* nvar);
|
||||
|
||||
bool IsSame(const Expression* exp) const;
|
||||
bool IsRValue(void) const;
|
||||
bool IsLValue(void) const;
|
||||
bool IsConstRef(void) const;
|
||||
bool IsVolatile(void) const;
|
||||
|
||||
|
||||
void Dump(int ident) const;
|
||||
};
|
||||
|
@ -281,7 +302,7 @@ public:
|
|||
Token mToken;
|
||||
Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile;
|
||||
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
|
||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
|
||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment, * mVectorMoveConstructor, * mVectorMoveAssignment;
|
||||
Declaration * mVTable, * mClass, * mTemplate;
|
||||
Declaration * mForwardParam, * mForwardCall;
|
||||
|
||||
|
@ -323,12 +344,17 @@ public:
|
|||
bool IsSimpleType(void) const;
|
||||
bool IsReference(void) const;
|
||||
bool IsIndexed(void) const;
|
||||
bool ContainsArray(void) const;
|
||||
bool IsShortIntStruct(void) const;
|
||||
bool IsComplexStruct(void) const;
|
||||
bool HasConstructor(void) const;
|
||||
|
||||
void SetDefined(void);
|
||||
|
||||
Declaration* ToConstType(void);
|
||||
Declaration* ToMutableType(void);
|
||||
Declaration* ToVolatileType(void);
|
||||
Declaration* ToAlternateThis(Declaration* pthis, int nthis = 1);
|
||||
|
||||
Declaration* ToStriped(int stripe);
|
||||
Declaration* ToStriped(Errors* errors);
|
||||
|
@ -352,8 +378,9 @@ public:
|
|||
DecType ValueType(void) const;
|
||||
|
||||
bool CanResolveTemplate(Expression* pexp, Declaration* tdec);
|
||||
bool ResolveTemplate(Declaration* fdec, Declaration * tdec);
|
||||
bool ResolveTemplate(Declaration* fdec, Declaration * tdec, bool same, bool preliminary);
|
||||
bool ResolveTemplate(Expression* pexp, Declaration* tdec);
|
||||
bool ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary);
|
||||
|
||||
Declaration* ExpandTemplate(DeclarationScope* scope);
|
||||
|
||||
|
@ -371,5 +398,6 @@ extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoid
|
|||
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
|
||||
extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
|
||||
extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
|
||||
extern Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
|
||||
extern Expression* TheVoidExpression;
|
||||
|
||||
|
|
|
@ -846,7 +846,7 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
|
|||
sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU);
|
||||
return buffer;
|
||||
}
|
||||
else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 7)
|
||||
else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 8)
|
||||
{
|
||||
sprintf_s(buffer, 10, "WORK + %d", tmp - BC_REG_WORK);
|
||||
return buffer;
|
||||
|
|
|
@ -4,11 +4,18 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
Errors::Errors(void)
|
||||
: mErrorCount(0)
|
||||
: mErrorCount(0), mMinLevel(EINFO_GENERIC), mDisabled(EERR_GENERIC)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ErrorID Errors::SetMinLevel(ErrorID id)
|
||||
{
|
||||
ErrorID pid = mMinLevel;
|
||||
mMinLevel = id;
|
||||
return pid;
|
||||
}
|
||||
|
||||
void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2)
|
||||
{
|
||||
if (!info1)
|
||||
|
@ -22,41 +29,44 @@ 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)
|
||||
{
|
||||
const char* level = "info";
|
||||
if (eid >= EERR_GENERIC)
|
||||
if (eid >= mMinLevel && !(eid < EERR_GENERIC && mDisabled[eid]))
|
||||
{
|
||||
level = "error";
|
||||
mErrorCount++;
|
||||
}
|
||||
else if (eid >= EWARN_GENERIC)
|
||||
{
|
||||
level = "warning";
|
||||
}
|
||||
const char* level = "info";
|
||||
if (eid >= EERR_GENERIC)
|
||||
{
|
||||
level = "error";
|
||||
mErrorCount++;
|
||||
}
|
||||
else if (eid >= EWARN_GENERIC)
|
||||
{
|
||||
level = "warning";
|
||||
}
|
||||
|
||||
if (loc.mFileName)
|
||||
{
|
||||
if (!info1)
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
|
||||
else if (!info2)
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1);
|
||||
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
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2);
|
||||
{
|
||||
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 (loc.mFrom)
|
||||
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here");
|
||||
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
|
||||
exit(20);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "NumberSet.h"
|
||||
|
||||
|
||||
class Location
|
||||
{
|
||||
public:
|
||||
|
@ -10,7 +13,11 @@ public:
|
|||
Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {}
|
||||
Location(const Location& loc, const Location* from)
|
||||
: mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from)
|
||||
{}
|
||||
{
|
||||
static volatile int k;
|
||||
if (from)
|
||||
k = from->mLine;
|
||||
}
|
||||
};
|
||||
|
||||
class Ident;
|
||||
|
@ -42,6 +49,10 @@ enum ErrorID
|
|||
EWARN_UNDEFINED_POINTER_ARITHMETIC,
|
||||
EWARN_INVALID_VALUE_RANGE,
|
||||
EWARN_DEFAULT_COPY_DEPRECATED,
|
||||
EWARN_INSUFFICIENT_MEMORY,
|
||||
EWARN_FUNCTION_NOT_INLINED,
|
||||
EWARN_INVALID_VOID_POINTER_ARITHMETIC,
|
||||
EWARN_DIVISION_BY_ZERO,
|
||||
|
||||
EERR_GENERIC = 3000,
|
||||
EERR_FILE_NOT_FOUND,
|
||||
|
@ -100,6 +111,8 @@ enum ErrorID
|
|||
EERR_INVALID_FOLD_EXPRESSION,
|
||||
ERRR_INSTANTIATE_ABSTRACT_CLASS,
|
||||
ERRR_INVALID_GOTO,
|
||||
EERR_INVALID_INITIALIZER,
|
||||
ERRR_INVALID_VOID_POINTER_ARITHMETIC,
|
||||
|
||||
EERR_INVALID_CONSTEXPR,
|
||||
EERR_DOUBLE_FREE,
|
||||
|
@ -114,9 +127,13 @@ enum ErrorID
|
|||
EERR_INVALID_CLASS_INITIALIZER,
|
||||
EERR_CALL_OF_DELETED_FUNCTION,
|
||||
|
||||
EERR_STATIC_ASSERT,
|
||||
|
||||
EFATAL_GENERIC = 4000,
|
||||
EFATAL_OUT_OF_MEMORY,
|
||||
EFATAL_MACRO_EXPANSION_DEPTH,
|
||||
|
||||
ERROR_MAX = 5000
|
||||
};
|
||||
|
||||
class Errors
|
||||
|
@ -124,7 +141,12 @@ class Errors
|
|||
public:
|
||||
Errors(void);
|
||||
|
||||
ErrorID SetMinLevel(ErrorID id);
|
||||
|
||||
int mErrorCount;
|
||||
ErrorID mMinLevel;
|
||||
|
||||
NumberSet mDisabled;
|
||||
|
||||
void Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2 = nullptr);
|
||||
void Error(const Location& loc, ErrorID eid, const char* msg, const char* info1 = nullptr, const char* info2 = nullptr);
|
||||
|
|
|
@ -147,6 +147,25 @@ void GlobalAnalyzer::TopoSort(Declaration* procDec)
|
|||
}
|
||||
}
|
||||
|
||||
int GlobalAnalyzer::CallerInvokes(Declaration* called)
|
||||
{
|
||||
int n = 0;
|
||||
for (int i = 0; i < called->mCallers.Size(); i++)
|
||||
{
|
||||
Declaration* f = called->mCallers[i];
|
||||
n += CallerInvokes(f, called);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int GlobalAnalyzer::CallerInvokes(Declaration* caller, Declaration* called)
|
||||
{
|
||||
int n = 1;
|
||||
if (caller->mType == DT_CONST_FUNCTION && (caller->mFlags & (DTF_INLINE | DTF_FORCE_INLINE | DTF_REQUEST_INLINE)) && !(caller->mFlags & DTF_PREVENT_INLINE) && !(caller->mFlags & DTF_FUNC_RECURSIVE) && !(caller->mFlags & DTF_FUNC_VARIABLE) && !(caller->mFlags & DTF_EXPORT))
|
||||
n = CallerInvokes(caller);
|
||||
return n > 1 ? n : 1;
|
||||
}
|
||||
|
||||
void GlobalAnalyzer::AutoInline(void)
|
||||
{
|
||||
for (int i = 0; i < mFunctions.Size(); i++)
|
||||
|
@ -181,33 +200,39 @@ void GlobalAnalyzer::AutoInline(void)
|
|||
dec = dec->mNext;
|
||||
}
|
||||
|
||||
int invokes = CallerInvokes(f);
|
||||
int cost = (f->mComplexity - 20 * nparams - 10);
|
||||
|
||||
// printf("CHECK INLINING %s (%d) %d * (%d - 1)\n", f->mIdent->mString, f->mComplexity, cost, f->mCallers.Size());
|
||||
// printf("CHECK INLINING %s (%d) %d * (%d - 1)\n", f->mIdent->mString, f->mComplexity, cost, invokes);
|
||||
|
||||
bool doinline = false;
|
||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE))
|
||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE) || (f->mFlags & DTF_FORCE_INLINE))
|
||||
doinline = true;
|
||||
if (f->mLocalSize < 100)
|
||||
{
|
||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && ((cost - 20) * (f->mCallers.Size() - 1) <= 20))
|
||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && ((cost - 20) * (invokes - 1) <= 20))
|
||||
{
|
||||
if (f->mCallers.Size() == 1 && f->mComplexity > 100)
|
||||
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
|
||||
else
|
||||
doinline = true;
|
||||
}
|
||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (f->mCallers.Size() - 1) <= 10000))
|
||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (invokes - 1) <= 10000))
|
||||
doinline = true;
|
||||
}
|
||||
|
||||
if (doinline)
|
||||
{
|
||||
// printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size());
|
||||
// printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, invokes);
|
||||
|
||||
f->mFlags |= DTF_INLINE;
|
||||
for (int j = 0; j < f->mCallers.Size(); j++)
|
||||
|
@ -368,7 +393,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
|
||||
if (procDec->mValue && procDec->mValue->mType == EX_DISPATCH)
|
||||
{
|
||||
Declaration* maxf = nullptr;
|
||||
Declaration* maxf = nullptr, * reff = nullptr;
|
||||
|
||||
bool stackCall = false;
|
||||
|
||||
|
@ -377,7 +402,10 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
Declaration* cf = procDec->mCalled[i];
|
||||
|
||||
if (cf->mBase->mFlags & DTF_STACKCALL)
|
||||
{
|
||||
stackCall = true;
|
||||
reff = cf;
|
||||
}
|
||||
|
||||
if (!maxf)
|
||||
maxf = cf;
|
||||
|
@ -385,6 +413,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
maxf = cf;
|
||||
}
|
||||
|
||||
if (!reff)
|
||||
reff = maxf;
|
||||
|
||||
for (int i = 0; i < procDec->mCalled.Size(); i++)
|
||||
{
|
||||
Declaration* cf = procDec->mCalled[i];
|
||||
|
@ -395,9 +426,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
cf->mBase->mFlags |= DTF_STACKCALL;
|
||||
}
|
||||
|
||||
if (cf != maxf)
|
||||
if (cf != reff)
|
||||
{
|
||||
Declaration* fp = cf->mBase->mParams, * mp = maxf->mBase->mParams;
|
||||
Declaration* fp = cf->mBase->mParams, * mp = reff->mBase->mParams;
|
||||
while (fp)
|
||||
{
|
||||
fp->mVarIndex = mp->mVarIndex;
|
||||
|
@ -406,10 +437,11 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
}
|
||||
|
||||
assert(!mp);
|
||||
|
||||
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
|
||||
cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize;
|
||||
}
|
||||
|
||||
if (cf != maxf)
|
||||
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
|
||||
}
|
||||
|
||||
procDec->mFastCallBase = procDec->mBase->mFastCallBase;
|
||||
|
@ -449,7 +481,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
fplimit += 256;
|
||||
}
|
||||
|
||||
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
|
||||
if (procDec->mBase->mBase->IsComplexStruct())
|
||||
{
|
||||
if (nbase < numfpzero && nbase + 2 > numfpzero)
|
||||
nbase = numfpzero;
|
||||
|
@ -633,7 +665,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
|
|||
if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS)
|
||||
dec->mFlags |= DTF_FUNC_CONSTEXPR;
|
||||
dec->mFlags |= DTF_FUNC_PURE;
|
||||
Analyze(exp, dec, false, false);
|
||||
Analyze(exp, dec, 0);
|
||||
|
||||
Declaration* pdec = dec->mBase->mParams;
|
||||
int vi = 0;
|
||||
|
@ -653,7 +685,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
|
|||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent);
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
|
||||
if (cexp)
|
||||
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here");
|
||||
|
||||
|
@ -729,7 +761,7 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
|
|||
|
||||
if (dec->mValue)
|
||||
{
|
||||
Analyze(dec->mValue, dec, false, false);
|
||||
Analyze(dec->mValue, dec, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -739,17 +771,19 @@ void GlobalAnalyzer::AnalyzeInit(Declaration* mdec)
|
|||
while (mdec)
|
||||
{
|
||||
if (mdec->mValue)
|
||||
RegisterProc(Analyze(mdec->mValue, mdec, false, false));
|
||||
RegisterProc(Analyze(mdec->mValue, mdec, 0));
|
||||
else if (mdec->mParams)
|
||||
AnalyzeInit(mdec->mParams);
|
||||
mdec = mdec->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing)
|
||||
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
|
||||
{
|
||||
Declaration* ldec, * rdec;
|
||||
|
||||
exp->mFlags = flags;
|
||||
|
||||
switch (exp->mType)
|
||||
{
|
||||
case EX_ERROR:
|
||||
|
@ -767,7 +801,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
}
|
||||
else if (exp->mDecValue->mType == DT_CONST_POINTER)
|
||||
{
|
||||
ldec = Analyze(exp->mDecValue->mValue, procDec, true, true);
|
||||
ldec = Analyze(exp->mDecValue->mValue, procDec, ANAFL_LHS | ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE)
|
||||
ldec->mFlags |= DTF_VAR_ALIASING;
|
||||
RegisterProc(ldec);
|
||||
|
@ -791,7 +825,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (mCompilerOptions & COPT_DEBUGINFO)
|
||||
exp->mDecValue->mReferences.Push(exp);
|
||||
|
||||
if (aliasing)
|
||||
if (flags & ANAFL_ALIAS)
|
||||
{
|
||||
Declaration* dec = exp->mDecValue;
|
||||
while (dec->mType == DT_VARIABLE_REF)
|
||||
|
@ -808,14 +842,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (!(type->mFlags & DTF_CONST))
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
|
||||
AnalyzeGlobalVariable(exp->mDecValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
exp->mDecValue->mFlags |= DTF_VAR_ADDRESS;
|
||||
|
||||
if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
|
||||
|
@ -829,8 +863,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_ASSIGNMENT:
|
||||
procDec->mComplexity += 5 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, true, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
|
||||
if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
|
||||
exp->mLeft->mDecValue->mFlags |= DTF_VAR_ALIASING;
|
||||
RegisterProc(rdec);
|
||||
|
@ -839,33 +873,33 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_BINARY:
|
||||
procDec->mComplexity += 10 * exp->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, lhs, false);
|
||||
rdec = Analyze(exp->mRight, procDec, lhs, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
rdec = Analyze(exp->mRight, procDec, flags & ~ANAFL_ALIAS);
|
||||
return ldec;
|
||||
|
||||
case EX_RELATIONAL:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
|
||||
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
|
||||
return TheBoolTypeDeclaration;
|
||||
|
||||
case EX_PREINCDEC:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
return Analyze(exp->mLeft, procDec, true, false);
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
case EX_PREFIX:
|
||||
if (exp->mToken == TK_BINARY_AND)
|
||||
{
|
||||
ldec = Analyze(exp->mLeft, procDec, true, true);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE)
|
||||
ldec->mFlags |= DTF_VAR_ALIASING;
|
||||
}
|
||||
else if (exp->mToken == TK_MUL)
|
||||
{
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
|
||||
return exp->mDecType;
|
||||
|
@ -874,10 +908,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
{
|
||||
return TheUnsignedCharTypeDeclaration;
|
||||
}
|
||||
else if (exp->mToken == TK_SIZEOF)
|
||||
{
|
||||
return TheUnsignedIntTypeDeclaration;
|
||||
}
|
||||
else
|
||||
{
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
return Analyze(exp->mLeft, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, 0);
|
||||
}
|
||||
break;
|
||||
case EX_POSTFIX:
|
||||
|
@ -886,31 +924,31 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_POSTINCDEC:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
return Analyze(exp->mLeft, procDec, true, false);
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
case EX_INDEX:
|
||||
procDec->mComplexity += 10 * exp->mRight->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, lhs, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
|
||||
{
|
||||
ldec = ldec->mBase;
|
||||
if (ldec->mType == DT_TYPE_POINTER)
|
||||
{
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
}
|
||||
}
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
if (ldec->mBase)
|
||||
return ldec->mBase;
|
||||
break;
|
||||
case EX_QUALIFY:
|
||||
Analyze(exp->mLeft, procDec, lhs, aliasing);
|
||||
Analyze(exp->mLeft, procDec, flags);
|
||||
return exp->mDecValue->mBase;
|
||||
case EX_DISPATCH:
|
||||
procDec->mFlags |= DTF_PREVENT_INLINE;
|
||||
Analyze(exp->mLeft, procDec, lhs, false);
|
||||
Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
// RegisterCall(procDec, exp->mLeft->mDecType);
|
||||
break;
|
||||
case EX_VCALL:
|
||||
|
@ -921,7 +959,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_INLINE:
|
||||
procDec->mComplexity += 10;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
|
||||
{
|
||||
|
||||
|
@ -1008,7 +1046,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
|
||||
ldec->mBase->mFlags |= DTF_STACKCALL;
|
||||
|
||||
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference(), false));
|
||||
RegisterProc(Analyze(pex, procDec, (pdec && pdec->mBase->IsReference()) ? ANAFL_LHS : 0));
|
||||
|
||||
if (pdec)
|
||||
pdec = pdec->mNext;
|
||||
|
@ -1022,12 +1060,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
break;
|
||||
case EX_LIST:
|
||||
case EX_COMMA:
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, false, false));
|
||||
return Analyze(exp->mRight, procDec, false, false);
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, 0));
|
||||
return Analyze(exp->mRight, procDec, 0);
|
||||
case EX_RETURN:
|
||||
if (exp->mLeft)
|
||||
{
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference(), false));
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference() ? ANAFL_LHS : 0));
|
||||
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
|
||||
{
|
||||
if (procDec->mBase->mBase->mMoveConstructor)
|
||||
|
@ -1048,47 +1086,47 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (exp->mType == EX_SEQUENCE)
|
||||
{
|
||||
if (exp->mLeft)
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
}
|
||||
else
|
||||
return Analyze(exp, procDec, false, false);
|
||||
return Analyze(exp, procDec, 0);
|
||||
|
||||
} while (exp);
|
||||
break;
|
||||
|
||||
case EX_SCOPE:
|
||||
Analyze(exp->mLeft, procDec, false, false);
|
||||
Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
|
||||
case EX_CONSTRUCT:
|
||||
if (exp->mLeft->mLeft)
|
||||
Analyze(exp->mLeft->mLeft, procDec, false, false);
|
||||
Analyze(exp->mLeft->mLeft, procDec, 0);
|
||||
if (exp->mLeft->mRight)
|
||||
Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
if (exp->mRight)
|
||||
return Analyze(exp->mRight, procDec, false, false);
|
||||
return Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
|
||||
case EX_CLEANUP:
|
||||
Analyze(exp->mRight, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, lhs, false);
|
||||
Analyze(exp->mRight, procDec, 0);
|
||||
return Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
|
||||
case EX_WHILE:
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_IF:
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight->mLeft, procDec, 0);
|
||||
if (exp->mRight->mRight)
|
||||
rdec = Analyze(exp->mRight->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_ELSE:
|
||||
break;
|
||||
|
@ -1098,18 +1136,23 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
procDec->mComplexity += 30;
|
||||
|
||||
if (exp->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
if (exp->mLeft->mLeft->mLeft)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
if (exp->mLeft->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_FORBODY:
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if (exp->mRight)
|
||||
Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_DO:
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_BREAK:
|
||||
case EX_CONTINUE:
|
||||
|
@ -1118,18 +1161,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_TYPE:
|
||||
break;
|
||||
case EX_TYPECAST:
|
||||
return Analyze(exp->mLeft, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_AND:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_OR:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_NOT:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
case EX_ASSEMBLER:
|
||||
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
|
||||
|
@ -1140,14 +1183,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_UNDEFINED:
|
||||
break;
|
||||
case EX_SWITCH:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
while (exp)
|
||||
{
|
||||
procDec->mComplexity += 10;
|
||||
|
||||
if (exp->mLeft->mRight)
|
||||
rdec = Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
}
|
||||
break;
|
||||
|
@ -1158,9 +1201,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_CONDITIONAL:
|
||||
procDec->mComplexity += exp->mDecType->mSize * 10;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs, aliasing));
|
||||
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs, aliasing));
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
RegisterProc(Analyze(exp->mRight->mLeft, procDec, flags));
|
||||
RegisterProc(Analyze(exp->mRight->mRight, procDec, flags));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,10 @@ protected:
|
|||
GrowingArray<Declaration*> mGlobalVariables;
|
||||
|
||||
void AnalyzeInit(Declaration* mdec);
|
||||
int CallerInvokes(Declaration* called);
|
||||
int CallerInvokes(Declaration* caller, Declaration* called);
|
||||
|
||||
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing);
|
||||
Declaration* Analyze(Expression* exp, Declaration* procDec, uint32 flags);
|
||||
|
||||
bool IsStackParam(const Declaration* pdec) const;
|
||||
bool MarkCycle(Declaration* rootDec, Declaration* procDec);
|
||||
|
|
|
@ -60,7 +60,7 @@ void GlobalOptimizer::Reset(void)
|
|||
mFunctions.SetSize(0);
|
||||
mGlobalVariables.SetSize(0);
|
||||
mCalledFunctions.SetSize(0);
|
||||
mCalledFunctions.SetSize(0);
|
||||
mCallingFunctions.SetSize(0);
|
||||
}
|
||||
|
||||
void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp)
|
||||
|
@ -189,7 +189,7 @@ bool GlobalOptimizer::CheckUnusedLocals(Expression*& exp)
|
|||
if (vexp->mType == EX_VARIABLE)
|
||||
{
|
||||
Declaration* vdec = vexp->mDecValue;
|
||||
if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED))
|
||||
if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED) && !exp->mRight->IsVolatile())
|
||||
{
|
||||
exp = exp->mRight;
|
||||
return true;
|
||||
|
@ -243,6 +243,19 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
|
|||
bool changed = false;
|
||||
if (exp)
|
||||
{
|
||||
if (ReplaceParamConst(exp->mLeft, param))
|
||||
changed = true;
|
||||
if (ReplaceParamConst(exp->mRight, param))
|
||||
changed = true;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (exp->mLeft)
|
||||
exp->mLeft = exp->mLeft->ConstantFold(mErrors, nullptr);
|
||||
if (exp->mRight)
|
||||
exp->mRight = exp->mRight->ConstantFold(mErrors, nullptr);
|
||||
}
|
||||
|
||||
if (exp->mType == EX_VARIABLE && exp->mDecValue == param)
|
||||
{
|
||||
exp->mType = EX_CONSTANT;
|
||||
|
@ -251,10 +264,6 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
|
|||
changed = true;
|
||||
}
|
||||
|
||||
if (ReplaceParamConst(exp->mLeft, param))
|
||||
changed = true;
|
||||
if (ReplaceParamConst(exp->mRight, param))
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
@ -266,14 +275,22 @@ bool GlobalOptimizer::ReplaceGlobalConst(Expression* 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 &&
|
||||
(cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
|
||||
cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT))
|
||||
if (cexp->mType == EX_CONSTANT)
|
||||
{
|
||||
exp->mType = EX_CONSTANT;
|
||||
exp->mDecValue = cexp->mDecValue;
|
||||
changed = true;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +341,7 @@ bool GlobalOptimizer::Optimize(void)
|
|||
|
||||
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL))
|
||||
{
|
||||
if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
|
||||
if (!(func->mOptFlags & (OPTF_VAR_USED | OPTF_VAR_ADDRESS)) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
|
||||
{
|
||||
#if DUMP_OPTS
|
||||
printf("Remove return value\n");
|
||||
|
@ -382,6 +399,7 @@ bool GlobalOptimizer::Optimize(void)
|
|||
{
|
||||
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
|
||||
|
@ -444,7 +462,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec)
|
|||
Analyze(exp, procDec, false);
|
||||
}
|
||||
else
|
||||
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->mQualIdent);
|
||||
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->FullIdent());
|
||||
|
||||
procDec->mOptFlags &= ~OPTF_ANALYZING;
|
||||
}
|
||||
|
@ -596,9 +614,6 @@ void GlobalOptimizer::RegisterProc(Declaration* to)
|
|||
}
|
||||
}
|
||||
|
||||
static const uint32 ANAFL_LHS = (1U << 0);
|
||||
static const uint32 ANAFL_RHS = (1U << 1);
|
||||
|
||||
Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
|
||||
{
|
||||
Declaration* ldec, * rdec;
|
||||
|
@ -644,8 +659,10 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
|
||||
if (flags & ANAFL_LHS)
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
|
||||
if (exp->mDecValue->mBase->IsReference() && (flags & ANAFL_ASSIGN))
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
|
||||
|
||||
if (exp->mDecValue->mType == DT_ARGUMENT)
|
||||
if (exp->mDecValue->mType == DT_ARGUMENT && (flags & ANAFL_LHS))
|
||||
{
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
|
||||
exp->mDecValue->mForwardParam = nullptr;
|
||||
|
@ -655,7 +672,12 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
case EX_INITIALIZATION:
|
||||
case EX_ASSIGNMENT:
|
||||
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
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags);
|
||||
|
||||
|
@ -803,6 +825,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
pdec->mOptFlags |= OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else if (pex->mType == EX_VARIABLE && pdec->mBase->mType == DT_TYPE_POINTER && pex->mDecType->mType == DT_TYPE_ARRAY && (pex->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && pdec->mBase->CanAssign(pex->mDecType))
|
||||
{
|
||||
if (pdec->mOptFlags & OPTF_VAR_CONST)
|
||||
{
|
||||
if (pdec->mValue->mType != EX_VARIABLE || pdec->mValue->mDecValue != pex->mDecValue)
|
||||
{
|
||||
pdec->mOptFlags |= OPTF_VAR_NOCONST;
|
||||
pdec->mOptFlags &= ~OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec->mValue = pex;
|
||||
pdec->mOptFlags |= OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec->mOptFlags |= OPTF_VAR_NOCONST;
|
||||
|
@ -948,13 +986,20 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
if (exp->mLeft->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_FORBODY:
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if (exp->mRight)
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_DO:
|
||||
ldec = Analyze(exp->mRight, procDec, 0);
|
||||
rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
|
||||
break;
|
||||
case EX_BREAK:
|
||||
case EX_CONTINUE:
|
||||
break;
|
||||
case EX_ASSUME:
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_RHS);
|
||||
break;
|
||||
case EX_TYPE:
|
||||
break;
|
||||
|
|
|
@ -47,7 +47,7 @@ const Ident* Ident::Unique(const char* str)
|
|||
|
||||
const Ident* Ident::PreMangle(const char* str) const
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, str);
|
||||
strcat_s(buffer, mString);
|
||||
return Unique(buffer);
|
||||
|
@ -55,14 +55,14 @@ const Ident* Ident::PreMangle(const char* str) const
|
|||
|
||||
const Ident* Ident::Unique(const char* str, int id)
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
sprintf_s(buffer, "%s#%d", str, id);
|
||||
return Unique(buffer);
|
||||
}
|
||||
|
||||
const Ident* Ident::Mangle(const char* str) const
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, mString);
|
||||
strcat_s(buffer, str);
|
||||
return Unique(buffer);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -169,6 +169,7 @@ public:
|
|||
} mMinState, mMaxState;
|
||||
|
||||
bool Same(const IntegerValueRange& range) const;
|
||||
bool Weaker(const IntegerValueRange& range) const;
|
||||
bool Merge(const IntegerValueRange& range, bool head, bool initial);
|
||||
void Expand(const IntegerValueRange& range);
|
||||
void Union(const IntegerValueRange& range);
|
||||
|
@ -177,6 +178,7 @@ public:
|
|||
void LimitWeak(const IntegerValueRange& range);
|
||||
void MergeUnknown(const IntegerValueRange& range);
|
||||
void SetLimit(int64 minValue, int64 maxValue);
|
||||
void SetBounds(State minState, int64 minValue, State maxState, int64 maxValue);
|
||||
void SetConstant(int64 value);
|
||||
|
||||
bool IsBound(void) const;
|
||||
|
@ -197,7 +199,7 @@ public:
|
|||
|
||||
|
||||
|
||||
typedef GrowingArray<IntegerValueRange> GrowingIntegerValueRangeArray;
|
||||
typedef ExpandingArray<IntegerValueRange> GrowingIntegerValueRangeArray;
|
||||
|
||||
class ValueSet
|
||||
{
|
||||
|
@ -219,7 +221,7 @@ public:
|
|||
void RemoveValue(int index);
|
||||
void InsertValue(InterInstruction * ins);
|
||||
|
||||
void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs);
|
||||
void UpdateValue(InterCodeBasicBlock* block, InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs);
|
||||
void Intersect(ValueSet& set);
|
||||
};
|
||||
|
||||
|
@ -311,15 +313,18 @@ class InterInstruction
|
|||
public:
|
||||
Location mLocation;
|
||||
InterCode mCode;
|
||||
InterOperand mSrc[12];
|
||||
InterOperand * mSrc;
|
||||
InterOperand mDst;
|
||||
InterOperand mConst;
|
||||
InterOperator mOperator;
|
||||
InterOperand mOps[4];
|
||||
int mNumOperands;
|
||||
|
||||
bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment, mNoSideEffects, mConstExpr, mRemove, mAliasing;
|
||||
|
||||
InterInstruction(const Location& loc, InterCode code);
|
||||
InterInstruction(const InterInstruction&) = delete;
|
||||
InterInstruction& operator=(const InterInstruction&) = delete;
|
||||
|
||||
bool IsEqual(const InterInstruction* ins) const;
|
||||
bool IsEqualSource(const InterInstruction* ins) const;
|
||||
|
@ -376,7 +381,7 @@ public:
|
|||
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
|
||||
GrowingInstructionArray mInstructions;
|
||||
|
||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid;
|
||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid, mPatched, mLoopDebug;
|
||||
mutable int mMark;
|
||||
|
||||
NumberSet mLocalUsedTemps, mLocalModifiedTemps;
|
||||
|
@ -419,18 +424,20 @@ public:
|
|||
InterCodeBasicBlock* Clone(void);
|
||||
|
||||
void Append(InterInstruction * code);
|
||||
void AppendBeforeBranch(InterInstruction* code);
|
||||
void AppendBeforeBranch(InterInstruction* code, bool loopindex = false);
|
||||
const InterInstruction* FindByDst(int dst) const;
|
||||
void Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump);
|
||||
|
||||
void CollectEntries(void);
|
||||
void CollectEntryBlocks(InterCodeBasicBlock* from);
|
||||
void GenerateTraces(bool expand, bool compact);
|
||||
void GenerateTraces(int expand, bool compact);
|
||||
void BuildDominatorTree(InterCodeBasicBlock * from);
|
||||
bool StripLoopHead(void);
|
||||
|
||||
bool MergeSameConditionTraces(void);
|
||||
|
||||
void LocalToTemp(int vindex, int temp);
|
||||
void LoadConstantFold(InterInstruction* ins, InterInstruction* ains, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs);
|
||||
|
||||
void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used);
|
||||
|
||||
|
@ -443,6 +450,9 @@ public:
|
|||
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
|
||||
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
bool PropagateConstCompareResults(void);
|
||||
|
||||
bool EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps);
|
||||
|
||||
bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars, const NumberSet & aliasedLocals, const NumberSet & aliasedParams);
|
||||
|
||||
|
@ -473,6 +483,8 @@ public:
|
|||
|
||||
bool CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64 & nloop);
|
||||
|
||||
bool TempIsUnsigned(int temp);
|
||||
|
||||
void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||
void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||
void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||
|
@ -508,6 +520,8 @@ public:
|
|||
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs, FastNumberSet& fsingle);
|
||||
bool EliminateDeadBranches(void);
|
||||
|
||||
bool EliminateIntegerSumAliasTemps(const GrowingInstructionPtrArray& tvalue);
|
||||
|
||||
bool MergeIndexedLoadStore(const GrowingInstructionPtrArray& tvalue);
|
||||
bool SimplifyIntegerNumeric(const GrowingInstructionPtrArray& tvalue, int& spareTemps);
|
||||
bool SimplifyPointerOffsets(void);
|
||||
|
@ -549,6 +563,7 @@ public:
|
|||
bool IsDominator(InterCodeBasicBlock* block);
|
||||
bool IsDirectDominatorBlock(InterCodeBasicBlock* block);
|
||||
bool IsDirectLoopPathBlock(InterCodeBasicBlock* block);
|
||||
bool CollectBlocksToDominator(InterCodeBasicBlock* dblock, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||
|
||||
void MarkRelevantStatics(void);
|
||||
void RemoveNonRelevantStatics(void);
|
||||
|
@ -597,7 +612,7 @@ public:
|
|||
|
||||
bool CheapInlining(int & numTemps);
|
||||
bool CollapseDispatch();
|
||||
|
||||
bool StructReturnPropagation(void);
|
||||
|
||||
void CheckFinalLocal(void);
|
||||
void CheckFinal(void);
|
||||
|
@ -615,29 +630,42 @@ public:
|
|||
void SingleBlockLoopUnrolling(void);
|
||||
bool SingleBlockLoopPointerSplit(int& spareTemps);
|
||||
bool SingleBlockLoopPointerToByte(int& spareTemps);
|
||||
bool SingleBlockLoopSinking(int& spareTemps);
|
||||
bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body);
|
||||
bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||
void CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path);
|
||||
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
||||
void ConstLoopOptimization(void);
|
||||
bool EmptyLoopOptimization(void);
|
||||
void EliminateDoubleLoopCounter(void);
|
||||
void PushMoveOutOfLoop(void);
|
||||
bool MoveConditionOutOfLoop(void);
|
||||
void SingleLoopCountZeroCheck(void);
|
||||
void InnerLoopCountZeroCheck(void);
|
||||
bool PostDecLoopOptimization(void);
|
||||
bool Flatten2DLoop(void);
|
||||
|
||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
|
||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue, bool loops);
|
||||
void RemoveUnusedMallocs(void);
|
||||
|
||||
bool PullStoreUpToConstAddress(void);
|
||||
|
||||
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body);
|
||||
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||
|
||||
bool CollectGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||
void CollectReachable(ExpandingArray<InterCodeBasicBlock*>& lblock);
|
||||
|
||||
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
|
||||
bool MergeLoopTails(void);
|
||||
|
||||
bool ChangeTrueJump(InterCodeBasicBlock* block);
|
||||
bool ChangeFalseJump(InterCodeBasicBlock* block);
|
||||
|
||||
InterCodeBasicBlock* CheckIsSimpleIntRangeBranch(const GrowingIntegerValueRangeArray & irange);
|
||||
InterCodeBasicBlock* CheckIsConstBranch(const GrowingInstructionPtrArray& cins);
|
||||
bool ShortcutConstBranches(const GrowingInstructionPtrArray& cins);
|
||||
bool ShortcutDuplicateBranches(void);
|
||||
|
||||
InterCodeBasicBlock* BuildLoopPrefix(void);
|
||||
void BuildLoopSuffix(void);
|
||||
|
@ -648,6 +676,7 @@ public:
|
|||
void FollowJumps(void);
|
||||
|
||||
bool ShortLeaMerge(int& spareTemps);
|
||||
bool ShortLeaCleanup(void);
|
||||
|
||||
bool IsEqual(const InterCodeBasicBlock* block) const;
|
||||
|
||||
|
@ -684,9 +713,11 @@ protected:
|
|||
GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange;
|
||||
|
||||
void ResetVisited(void);
|
||||
void ResetPatched(void);
|
||||
void ResetEntryBlocks(void);
|
||||
public:
|
||||
InterCodeBasicBlock * mEntryBlock;
|
||||
int mNumBlocks;
|
||||
GrowingInterCodeBasicBlockPtrArray mBlocks;
|
||||
GrowingTypeArray mTemporaries;
|
||||
GrowingIntArray mTempOffset, mTempSizes;
|
||||
|
@ -739,12 +770,14 @@ public:
|
|||
bool ModifiesGlobal(int varindex);
|
||||
|
||||
void MapVariables(void);
|
||||
void ReduceTemporaries(void);
|
||||
void ReduceTemporaries(bool final = false);
|
||||
void Disassemble(FILE* file);
|
||||
void Disassemble(const char* name, bool dumpSets = false);
|
||||
protected:
|
||||
void BuildLocalAliasTable(void);
|
||||
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
|
||||
void BuildTraces(int expand, bool dominators = true, bool compact = false);
|
||||
void TrimBlocks(void);
|
||||
void EarlyBranchElimination(void);
|
||||
void BuildDataFlowSets(void);
|
||||
void RenameTemporaries(void);
|
||||
void TempForwarding(bool reverse = false, bool checkloops = false);
|
||||
|
@ -763,7 +796,9 @@ protected:
|
|||
void SimplifyIntegerNumeric(FastNumberSet& activeSet);
|
||||
void SingleBlockLoopPointerSplit(FastNumberSet& activeSet);
|
||||
void SingleBlockLoopPointerToByte(FastNumberSet& activeSet);
|
||||
void SingleBlockLoopSinking(FastNumberSet& activeSet);
|
||||
void MergeIndexedLoadStore(void);
|
||||
void EliminateIntegerSumAliasTemps(void);
|
||||
void EliminateAliasValues();
|
||||
void LoadStoreForwarding(InterMemory paramMemory);
|
||||
void ReduceRecursionTempSpilling(InterMemory paramMemory);
|
||||
|
@ -783,10 +818,12 @@ protected:
|
|||
void CheckUsedDefinedTemps(void);
|
||||
void WarnUsedUndefinedVariables(void);
|
||||
void WarnInvalidValueRanges(void);
|
||||
void PropagateMemoryAliasingInfo(void);
|
||||
void PropagateMemoryAliasingInfo(bool loops);
|
||||
void MoveConditionsOutOfLoop(void);
|
||||
void ShortcutConstBranches(void);
|
||||
void ShortcutDuplicateBranches(void);
|
||||
void EliminateDoubleLoopCounter(void);
|
||||
void StructReturnPropagation(void);
|
||||
|
||||
void CollapseDispatch(void);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,7 +45,7 @@ public:
|
|||
uint64 mCompilerOptions;
|
||||
|
||||
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
||||
void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray<Declaration *> * refvars);
|
||||
void TranslateAssembler(InterCodeModule* mod, Declaration* adec,GrowingArray<Declaration *> * refvars);
|
||||
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
|
||||
void InitLocalVariable(InterCodeProcedure* proc, Declaration* dec, int index);
|
||||
void InitParameter(InterCodeProcedure* proc, Declaration* dec, int index);
|
||||
|
@ -94,12 +94,12 @@ protected:
|
|||
void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, InlineMapper * inlineMapper, ExValue v, const SwitchNodeArray& nodes, int left, int right, int vleft, int vright, InterCodeBasicBlock* dblock);
|
||||
|
||||
ExValue ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v);
|
||||
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level = 0);
|
||||
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level = 0, int limit = 0);
|
||||
ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, Declaration * type, bool checkTrunc = true);
|
||||
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, GotoNode*& gotos, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr);
|
||||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, GotoNode*& gotos, InlineMapper* inlineMapper);
|
||||
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr, ExValue* lrexp);
|
||||
void CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving);
|
||||
void CopyStruct (InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving);
|
||||
void CopyStructSimple(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock * block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
|
||||
void StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ bool LinkerReference::operator!=(const LinkerReference& ref)
|
|||
}
|
||||
|
||||
LinkerObject::LinkerObject(void)
|
||||
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
|
||||
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mStripe(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
|
||||
, mPrefix(nullptr), mSuffix(nullptr), mProc(nullptr), mNativeProc(nullptr)
|
||||
{}
|
||||
|
||||
|
@ -54,6 +54,23 @@ LinkerObject::~LinkerObject(void)
|
|||
|
||||
}
|
||||
|
||||
LinkerObject* LinkerObject::CloneAssembler(Linker* linker) const
|
||||
{
|
||||
LinkerObject* lo = linker->AddObject(mLocation, mIdent, mSection, mType, mAlignment);
|
||||
lo->AddData(mData, mSize);
|
||||
lo->mFlags = mFlags;
|
||||
|
||||
for (int i = 0; i < mReferences.Size(); i++)
|
||||
{
|
||||
LinkerReference ref = *(mReferences[i]);
|
||||
if (ref.mObject == this) ref.mObject = lo;
|
||||
if (ref.mRefObject == this) ref.mRefObject = lo;
|
||||
lo->AddReference(ref);
|
||||
}
|
||||
|
||||
return lo;
|
||||
}
|
||||
|
||||
void LinkerObject::AddReference(const LinkerReference& ref)
|
||||
{
|
||||
LinkerReference* nref = new LinkerReference(ref);
|
||||
|
@ -633,7 +650,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
|||
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||
int end = start + lobj->mSize;
|
||||
|
||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
||||
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||
;
|
||||
else if (end <= mFreeChunks[i].mEnd)
|
||||
{
|
||||
|
@ -685,7 +702,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
|||
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||
int end = start + lobj->mSize;
|
||||
|
||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
||||
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||
{
|
||||
start = (start + 0x00ff) & 0xff00;
|
||||
end = start + lobj->mSize;
|
||||
|
@ -772,6 +789,8 @@ void LinkerRegion::PlaceStackSection(LinkerSection* stackSection, LinkerSection*
|
|||
|
||||
void Linker::CopyObjects(bool inlays)
|
||||
{
|
||||
bool errors = false;
|
||||
|
||||
for (int i = 0; i < mObjects.Size(); i++)
|
||||
{
|
||||
LinkerObject* obj = mObjects[i];
|
||||
|
@ -809,7 +828,9 @@ void Linker::CopyObjects(bool inlays)
|
|||
{
|
||||
if (!obj->mRegion)
|
||||
{
|
||||
mErrors->Error(obj->mLocation, ERRR_INSUFFICIENT_MEMORY, "Could not place object", obj->mIdent);
|
||||
mErrors->Error(obj->mLocation, errors ? EWARN_INSUFFICIENT_MEMORY : ERRR_INSUFFICIENT_MEMORY, "Could not place object", obj->mIdent);
|
||||
if (mCompilerOptions & COPT_ERROR_FILES)
|
||||
errors = true;
|
||||
|
||||
int avail = 0;
|
||||
for (int i = 0; i < mRegions.Size(); i++)
|
||||
|
@ -1645,7 +1666,7 @@ bool Linker::WriteCrtFile(const char* filename, uint16 id)
|
|||
|
||||
bool Linker::WriteMapFile(const char* filename)
|
||||
{
|
||||
bool banked = mCartridgeBankUsed[0];
|
||||
bool banked = mCartridgeBankUsed[0] || mCartridgeBankUsed[1];
|
||||
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
|
@ -1676,15 +1697,18 @@ bool Linker::WriteMapFile(const char* filename)
|
|||
|
||||
if (obj->mFlags & LOBJF_REFERENCED)
|
||||
{
|
||||
if (banked)
|
||||
if (obj->mRegion)
|
||||
{
|
||||
int k = 0;
|
||||
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
|
||||
k++;
|
||||
if (k < 64)
|
||||
fprintf(file, "%02x:", k);
|
||||
else
|
||||
fprintf(file, "--:");
|
||||
if (banked)
|
||||
{
|
||||
int k = 0;
|
||||
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
|
||||
k++;
|
||||
if (k < 64)
|
||||
fprintf(file, "%02x:", k);
|
||||
else
|
||||
fprintf(file, "--:");
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->mIdent)
|
||||
|
@ -1728,15 +1752,18 @@ bool Linker::WriteMapFile(const char* filename)
|
|||
{
|
||||
const LinkerObject* obj = so[i];
|
||||
|
||||
if (banked)
|
||||
if (obj->mRegion)
|
||||
{
|
||||
int k = 0;
|
||||
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
|
||||
k++;
|
||||
if (k < 64)
|
||||
fprintf(file, "%02x:", k);
|
||||
else
|
||||
fprintf(file, "--:");
|
||||
if (banked)
|
||||
{
|
||||
int k = 0;
|
||||
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
|
||||
k++;
|
||||
if (k < 64)
|
||||
fprintf(file, "%02x:", k);
|
||||
else
|
||||
fprintf(file, "--:");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "%04x (%04x) : %s, %s:%s\n", obj->mAddress, obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString);
|
||||
|
@ -1876,6 +1903,8 @@ bool Linker::WriteDbjFile(FILE* file)
|
|||
return true;
|
||||
}
|
||||
|
||||
static const char hexchars[] = "0123456789abcdef";
|
||||
|
||||
bool Linker::WriteLblFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
@ -1889,7 +1918,28 @@ bool Linker::WriteLblFile(const char* filename)
|
|||
if (obj->mFlags & LOBJF_REFERENCED)
|
||||
{
|
||||
if (obj->mIdent)
|
||||
fprintf(file, "al %04x .%s\n", obj->mAddress, obj->mIdent->mString);
|
||||
{
|
||||
char buffer[400];
|
||||
char nbuffer[500];
|
||||
|
||||
strcpy_s(buffer, obj->mIdent->mString);
|
||||
int i = 0, j = 0;
|
||||
while (buffer[i])
|
||||
{
|
||||
if (buffer[i] >= '0' && buffer[i] <= '9' || buffer[i] >= 'a' && buffer[i] <= 'z' || buffer[i] >= 'A' && buffer[i] <= 'Z' || buffer[i] == '_' || buffer[i] == ':')
|
||||
nbuffer[j++] = buffer[i];
|
||||
else
|
||||
{
|
||||
nbuffer[j++] = '?';
|
||||
nbuffer[j++] = hexchars[(buffer[i] >> 4) & 0x0f];
|
||||
nbuffer[j++] = hexchars[buffer[i] & 0x0f];
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
nbuffer[j] = 0;
|
||||
fprintf(file, "al %04x .%s\n", obj->mAddress, nbuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1926,7 +1976,9 @@ bool Linker::WriteAsmFile(const char* filename, const char* version)
|
|||
mByteCodeDisassembler.Disassemble(file, mMemory, -1, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
|
||||
break;
|
||||
case LOT_NATIVE_CODE:
|
||||
if (obj->mRegion->mCartridgeBanks)
|
||||
if (!obj->mRegion)
|
||||
mNativeDisassembler.Disassemble(file, obj->mData, -1, 0, obj->mSize, obj->mProc, obj->mIdent, this, obj->mFullIdent);
|
||||
else if (obj->mRegion->mCartridgeBanks)
|
||||
{
|
||||
int i = 0;
|
||||
while (!(obj->mRegion->mCartridgeBanks & (1ULL << i)))
|
||||
|
@ -1939,7 +1991,9 @@ bool Linker::WriteAsmFile(const char* filename, const char* version)
|
|||
mNativeDisassembler.Disassemble(file, mMemory, -1, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this, obj->mFullIdent);
|
||||
break;
|
||||
case LOT_DATA:
|
||||
if (obj->mRegion->mCartridgeBanks)
|
||||
if (!obj->mRegion)
|
||||
mNativeDisassembler.DumpMemory(file, obj->mData, -1, 0, obj->mSize, obj->mProc, obj->mIdent, this, obj);
|
||||
else if (obj->mRegion->mCartridgeBanks)
|
||||
{
|
||||
int i = 0;
|
||||
while (!(obj->mRegion->mCartridgeBanks & (1ULL << i)))
|
||||
|
|
|
@ -156,6 +156,7 @@ static const uint32 LOBJF_NO_CROSS = 0x00000080;
|
|||
static const uint32 LOBJF_ZEROPAGE = 0x00000100;
|
||||
static const uint32 LOBJF_FORCE_ALIGN = 0x00000200;
|
||||
static const uint32 LOBJF_ZEROPAGESET = 0x00000400;
|
||||
static const uint32 LOBJF_NEVER_CROSS = 0x00000800;
|
||||
|
||||
static const uint32 LOBJF_ARG_REG_A = 0x00001000;
|
||||
static const uint32 LOBJF_ARG_REG_X = 0x00002000;
|
||||
|
@ -163,6 +164,7 @@ static const uint32 LOBJF_ARG_REG_Y = 0x00004000;
|
|||
|
||||
static const uint32 LOBJF_RET_REG_A = 0x00010000;
|
||||
static const uint32 LOBJF_RET_REG_X = 0x00020000;
|
||||
static const uint32 LOBJF_RET_REG_Y = 0x00020000;
|
||||
|
||||
static const uint32 LOBJF_LOCAL_VAR = 0x00100000;
|
||||
static const uint32 LOBJF_LOCAL_USED = 0x00200000;
|
||||
|
@ -190,7 +192,7 @@ public:
|
|||
LinkerObjectType mType;
|
||||
int mID, mMapID;
|
||||
int mAddress, mRefAddress;
|
||||
int mSize, mAlignment, mStartUsed, mEndUsed;
|
||||
int mSize, mAlignment, mStripe, mStartUsed, mEndUsed;
|
||||
LinkerSection * mSection;
|
||||
LinkerRegion * mRegion;
|
||||
uint8 * mData, * mMemory;
|
||||
|
@ -212,6 +214,8 @@ public:
|
|||
LinkerObject(void);
|
||||
~LinkerObject(void);
|
||||
|
||||
LinkerObject* CloneAssembler(Linker * linker) const;
|
||||
|
||||
void AddData(const uint8* data, int size);
|
||||
void AddLocations(const ExpandingArray<CodeLocation>& locations);
|
||||
uint8* AddSpace(int size);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,9 @@ class NativeCodeBasicBlock;
|
|||
class NativeCodeGenerator;
|
||||
class NativeCodeInstruction;
|
||||
|
||||
class NativeCodeMapper;
|
||||
class SuffixTree;
|
||||
|
||||
enum NativeRegisterDataMode
|
||||
{
|
||||
NRDM_UNKNOWN,
|
||||
|
@ -130,31 +133,42 @@ static const uint32 NCIF_ALIASING = 0x00000800;
|
|||
static const uint32 NCIF_USE_CPU_REG_A = 0x00001000;
|
||||
static const uint32 NCIF_USE_CPU_REG_X = 0x00002000;
|
||||
static const uint32 NCIF_USE_CPU_REG_Y = 0x00004000;
|
||||
static const uint32 NCIF_USE_CPU_REG_C = 0x00008000;
|
||||
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_A = 0x00010000;
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_X = 0x00020000;
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_Y = 0x00040000;
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_C = 0x00080000;
|
||||
|
||||
// use a 32bit zero page register indexed by X for JSR
|
||||
static const uint32 NCIF_USE_ZP_32_X = 0x00008000;
|
||||
static const uint32 NICF_USE_ZP_ADDR = 0x00010000;
|
||||
static const uint32 NICF_USE_WORKREGS = 0x00020000;
|
||||
static const uint32 NCIF_USE_ZP_32_X = 0x00100000;
|
||||
static const uint32 NICF_USE_ZP_ADDR = 0x00200000;
|
||||
static const uint32 NICF_USE_WORKREGS = 0x00400000;
|
||||
|
||||
static const uint32 NCIF_BREAKPOINT = 0x00040000;
|
||||
static const uint32 NCIF_BREAKPOINT = 0x00800000;
|
||||
|
||||
class NativeCodeInstruction
|
||||
{
|
||||
public:
|
||||
NativeCodeInstruction(void);
|
||||
NativeCodeInstruction(const InterInstruction * ins, AsmInsType type, AsmInsMode mode = ASMIM_IMPLIED, int64 address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0);
|
||||
NativeCodeInstruction(const InterInstruction * ins, AsmInsType type, AsmInsMode mode = ASMIM_IMPLIED, int64 address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0, int minv = 0, int maxv = 255);
|
||||
NativeCodeInstruction(const InterInstruction* ins, AsmInsType type, const NativeCodeInstruction & addr);
|
||||
|
||||
AsmInsType mType;
|
||||
AsmInsMode mMode;
|
||||
AsmInsType mType;
|
||||
AsmInsMode mMode;
|
||||
|
||||
int mAddress, mParam;
|
||||
uint32 mFlags;
|
||||
uint32 mLive;
|
||||
LinkerObject * mLinkerObject;
|
||||
int mAddress, mParam;
|
||||
uint32 mFlags;
|
||||
uint32 mLive;
|
||||
LinkerObject * mLinkerObject;
|
||||
const InterInstruction * mIns;
|
||||
uint8 mMinVal, mMaxVal;
|
||||
|
||||
void Disassemble(FILE* file) const;
|
||||
void DisassembleAddress(FILE* file) const;
|
||||
|
||||
void CopyMode(const NativeCodeInstruction& ins);
|
||||
void CopyModeAndRange(const NativeCodeInstruction& ins);
|
||||
|
||||
void Assemble(NativeCodeBasicBlock* block);
|
||||
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||
|
@ -191,6 +205,7 @@ public:
|
|||
bool UsesZeroPage(int address) const;
|
||||
bool ReferencesZeroPage(int address) const;
|
||||
|
||||
bool SameLinkerObjectVariableRange(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
||||
|
||||
bool ChangesGlobalMemory(void) const;
|
||||
bool UsesMemoryOf(const NativeCodeInstruction& ins) const;
|
||||
|
@ -205,7 +220,7 @@ public:
|
|||
bool IsShift(void) const;
|
||||
bool IsShiftOrInc(void) const;
|
||||
bool IsSimpleJSR(void) const;
|
||||
bool MayBeMovedBefore(const NativeCodeInstruction& ins);
|
||||
bool MayBeMovedBefore(const NativeCodeInstruction& ins) const;
|
||||
|
||||
bool ReplaceYRegWithXReg(void);
|
||||
bool ReplaceXRegWithYReg(void);
|
||||
|
@ -216,6 +231,12 @@ public:
|
|||
void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets);
|
||||
|
||||
uint32 NeedsLive(void) const;
|
||||
|
||||
uint32 CodeHash(void) const;
|
||||
bool CodeSame(const NativeCodeInstruction& ins);
|
||||
|
||||
protected:
|
||||
const char* AddrName(char* buffer) const;
|
||||
};
|
||||
|
||||
struct NativeCodeLoadStorePair
|
||||
|
@ -246,10 +267,12 @@ public:
|
|||
ExpandingArray<NativeCodeBasicBlock*> mEntryBlocks;
|
||||
|
||||
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchUsed, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
|
||||
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked;
|
||||
NativeCodeBasicBlock * mDominator, * mSameBlock;
|
||||
|
||||
int mAsmFromJump;
|
||||
|
||||
NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock;
|
||||
|
||||
NativeRegisterDataSet mDataSet, mNDataSet, mFDataSet;
|
||||
|
@ -262,21 +285,27 @@ public:
|
|||
|
||||
NativeCodeInstruction mALSIns, mXLSIns, mYLSIns;
|
||||
|
||||
void Disassemble(FILE* file);
|
||||
void DisassembleBody(FILE* file);
|
||||
|
||||
NativeCodeInstruction DecodeNative(const InterInstruction* ins, LinkerObject * lobj, int& offset) const;
|
||||
|
||||
int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset);
|
||||
int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int offset);
|
||||
int JumpByteSize(NativeCodeBasicBlock * target, int offset);
|
||||
int BranchByteSize(NativeCodeBasicBlock* target, int from, int to);
|
||||
int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int from, int to);
|
||||
int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int from, int to, AsmInsType code = ASMIT_INV);
|
||||
int JumpByteSize(NativeCodeBasicBlock * target, int from, int to, bool second, bool final);
|
||||
int CheckFinalBranchByteSize(NativeCodeBasicBlock* target, int from, int to) const;
|
||||
int BranchByteSize(NativeCodeBasicBlock* target, int from, int to, bool final) const;
|
||||
|
||||
NativeCodeBasicBlock* SplitAt(int at);
|
||||
|
||||
NativeCodeBasicBlock* BypassEmptyBlocks(void);
|
||||
|
||||
int LeadsInto(NativeCodeBasicBlock* block, int dist);
|
||||
NativeCodeBasicBlock* PlaceSequence(ExpandingArray<NativeCodeBasicBlock*>& placement, NativeCodeBasicBlock* block);
|
||||
void BuildPlacement(ExpandingArray<NativeCodeBasicBlock*>& placement);
|
||||
void OptimizePlacement(void);
|
||||
void InitialOffset(int& total);
|
||||
bool CalculateOffset(int& total);
|
||||
bool CalculateOffset(int& total, bool final);
|
||||
|
||||
void CopyCode(NativeCodeProcedure* proc, uint8* target);
|
||||
void Assemble(void);
|
||||
|
@ -299,6 +328,8 @@ public:
|
|||
bool UsesZeroPage(int address, int from = 0, int to = 65536) const;
|
||||
bool ReferencesZeroPage(int address, int from = 0, int to = 65536) const;
|
||||
|
||||
bool ChangesMemory(const NativeCodeInstruction& ins, int from = 0, int to = 65536) const;
|
||||
bool ReferencesMemory(const NativeCodeInstruction& ins, int from = 0, int to = 65536) const;
|
||||
|
||||
bool RemoveNops(void);
|
||||
bool PeepHoleOptimizer(int pass);
|
||||
|
@ -317,18 +348,20 @@ public:
|
|||
bool PeepHoleOptimizerIterate(int pass);
|
||||
bool PeepHoleOptimizerExits(int pass);
|
||||
|
||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
|
||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter, int center);
|
||||
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
|
||||
|
||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full);
|
||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock, bool full);
|
||||
bool RemoveSimpleLoopUnusedIndex(void);
|
||||
bool OptimizeLoopCarryOver(void);
|
||||
bool OptimizeLoopRegisterWrapAround(void);
|
||||
|
||||
bool OptimizeSingleEntryLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prev, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks);
|
||||
bool OptimizeSingleEntryLoop(NativeCodeProcedure* proc);
|
||||
|
||||
bool OptimizeSimpleLoop(NativeCodeProcedure* proc, bool full);
|
||||
bool OptimizeSimpleForLoop(void);
|
||||
bool SimpleLoopReversal(NativeCodeProcedure* proc);
|
||||
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks);
|
||||
bool OptimizeXYSimpleLoop(void);
|
||||
|
@ -340,9 +373,11 @@ public:
|
|||
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
||||
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
|
||||
bool OptimizeGenericLoop(NativeCodeProcedure* proc);
|
||||
bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
int CorrectXOffset(const InterInstruction * ins, int yoffset, int at);
|
||||
int CorrectYOffset(const InterInstruction * ins, int yoffset, int at);
|
||||
bool OptimizeGenericLoop(void);
|
||||
bool CollectGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock);
|
||||
|
||||
bool OptimizeFindLoop(NativeCodeProcedure* proc);
|
||||
|
@ -358,7 +393,7 @@ public:
|
|||
void CheckFrameIndex(const InterInstruction * ins, int & reg, int & index, int size, int treg = 0);
|
||||
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction * ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
|
||||
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, InterType type, int reg);
|
||||
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, const InterOperand & op, InterType type, int reg);
|
||||
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, const InterOperand & op, InterType type, int reg, bool checkRange = true);
|
||||
|
||||
void LoadConstant(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
|
@ -376,7 +411,7 @@ public:
|
|||
NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
|
||||
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
|
||||
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0, bool addrvalid);
|
||||
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0, bool addrvalid, bool addrused = false);
|
||||
void LoadStoreOpAbsolute2D(InterCodeProcedure* proc, const InterInstruction* lins1, const InterInstruction* lins2, const InterInstruction* mins);
|
||||
void SignExtendAddImmediate(InterCodeProcedure* proc, const InterInstruction* xins, const InterInstruction* ains);
|
||||
void BinaryDivModPair(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins1, const InterInstruction* ins2);
|
||||
|
@ -393,6 +428,7 @@ public:
|
|||
|
||||
void LoadByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins);
|
||||
void StoreByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins);
|
||||
void CopyByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* riins, const InterInstruction* wiins, const InterInstruction* rins, const InterInstruction* wins);
|
||||
|
||||
void CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
|
@ -405,6 +441,7 @@ public:
|
|||
int ShortSignedDivide(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins, const InterInstruction* sins, int mul);
|
||||
|
||||
bool CheckPredAccuStore(int reg);
|
||||
bool CheckIsInAccu(int reg);
|
||||
|
||||
NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
|
||||
NumberSet mEntryRequiredRegs, mEntryProvidedRegs;
|
||||
|
@ -426,9 +463,7 @@ public:
|
|||
void CountEntries(NativeCodeBasicBlock* fromJump);
|
||||
NativeCodeBasicBlock * ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit);
|
||||
bool MergeBasicBlocks(void);
|
||||
void RemoveJumpToBranch(void);
|
||||
|
||||
void MarkLoopHead(void);
|
||||
bool RemoveJumpToBranch(void);
|
||||
|
||||
struct DominatorStacks
|
||||
{
|
||||
|
@ -502,7 +537,12 @@ public:
|
|||
bool CombineImmediateADCUp(int at);
|
||||
bool CombineImmediateADCUpX(int at);
|
||||
bool MoveTXADCDown(int at);
|
||||
bool MoveTXALogicTAXDown(int at);
|
||||
bool FoldShiftORAIntoLoadImmUp(int at);
|
||||
bool ReverseShiftByteOrder(int at);
|
||||
|
||||
bool FindAccuExitValue(int& at);
|
||||
bool MoveLoadXAbsUpCrossBlock(int at);
|
||||
|
||||
bool MoveSimpleADCToINCDECDown(int at);
|
||||
bool MoveTAXADCSTADown(int at);
|
||||
|
@ -533,6 +573,7 @@ public:
|
|||
bool CombineSameYtoX(int xpos, int ypos, int end);
|
||||
|
||||
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);
|
||||
int FindImmediateGlobalStore(int at, const NativeCodeInstruction& ins);
|
||||
|
||||
bool JoinXYCrossBlock(void);
|
||||
bool CanCombineSameXtoYCrossBlock(int from);
|
||||
|
@ -552,6 +593,13 @@ public:
|
|||
int FindFreeAccu(int at) const;
|
||||
|
||||
bool ReverseReplaceTAX(int at);
|
||||
|
||||
bool CanReplaceExitAccuWithX(NativeCodeBasicBlock * target);
|
||||
bool CanReplaceExitAccuWithY(NativeCodeBasicBlock* target);
|
||||
void ReplaceExitAccuWithX(NativeCodeBasicBlock* target);
|
||||
void ReplaceExitAccuWithY(NativeCodeBasicBlock* target);
|
||||
|
||||
bool ReverseLoadAccuToRegXY(void);
|
||||
|
||||
void ResetModifiedDataSet(NativeRegisterDataSet& data);
|
||||
|
||||
|
@ -562,6 +610,9 @@ public:
|
|||
bool OffsetValueForwarding(const ValueNumberingDataSet & data);
|
||||
bool AbsoluteValueForwarding(const ExpandingArray<NativeCodeLoadStorePair>& npairs);
|
||||
bool IndexXYValueForwarding(int xreg, int xoffset, int xvalue, int yreg, int yoffset, int yvalue);
|
||||
bool ReduceIndexXYZeroShuffle(NativeCodeBasicBlock* from, int xreg, int yreg);
|
||||
bool CheckLoopIndexXRegisters(NativeCodeBasicBlock* head, int xreg);
|
||||
bool CheckLoopIndexYRegisters(NativeCodeBasicBlock* head, int yreg);
|
||||
|
||||
void MarkLocalUsedLinkerObjects(void);
|
||||
bool RemoveLocalUnusedLinkerObjects(void);
|
||||
|
@ -581,7 +632,14 @@ public:
|
|||
bool HasTailSTY(int& addr, int& index) const;
|
||||
bool HasTailSTAX16(int& addr, int& index0) const;
|
||||
|
||||
bool HasTailSTAInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
|
||||
bool HasTailSTXInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
|
||||
bool HasTailSTYInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
|
||||
|
||||
bool HasTailSTAGlobal(NativeCodeInstruction & ins, int& index) const;
|
||||
|
||||
bool MayBeMovedBeforeBlock(int at);
|
||||
bool MayBeMovedBeforeBlock(int at, const NativeCodeInstruction & ins);
|
||||
bool MayBeMovedBeforeBlock(int start, int end);
|
||||
bool SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end);
|
||||
bool JoinCommonBranchCodeSequences(void);
|
||||
|
@ -685,6 +743,8 @@ public:
|
|||
bool EliminateDeadLoops(void);
|
||||
bool LoopRegisterWrapAround(void);
|
||||
bool CrossBlockFlagsForwarding(void);
|
||||
bool MoveStoresBeforeDiamond(void);
|
||||
bool MoveStoresBehindCondition(void);
|
||||
|
||||
bool SinglePathRegisterForwardY(NativeCodeBasicBlock* path, int yreg);
|
||||
bool SinglePathRegisterForward(void);
|
||||
|
@ -717,8 +777,9 @@ public:
|
|||
bool CanGlobalSwapXY(void);
|
||||
bool GlobalSwapXY(void);
|
||||
bool LocalSwapXY(void);
|
||||
bool UntangleXYUsage(void);
|
||||
bool UntangleXYUsage(bool final);
|
||||
bool AlternateXXUsage(void);
|
||||
bool ShortSwapXY(void);
|
||||
|
||||
bool IsSimpleSubExpression(int at, NativeSimpleSubExpression & ex);
|
||||
bool PropagateCommonSubExpression(void);
|
||||
|
@ -742,6 +803,19 @@ public:
|
|||
bool CheckPatchFailUse(void);
|
||||
|
||||
bool CheckPatchFailLoop(const NativeCodeBasicBlock* block, const NativeCodeBasicBlock* head, int reg, bool changed);
|
||||
bool CheckPatchFailLoopPair(const NativeCodeBasicBlock* block, const NativeCodeBasicBlock* head, int reg, bool changed);
|
||||
|
||||
bool JoinSameBranch(NativeCodeBasicBlock* block);
|
||||
bool MergeSameBranch(void);
|
||||
|
||||
bool CheckBoolBitPropagation(const NativeCodeBasicBlock* block, int at, int reg);
|
||||
bool PatchBoolBitPropagation(const NativeCodeBasicBlock* block, int at, int reg);
|
||||
|
||||
bool CollectRegBoolInstructionsForward(int reg, ExpandingArray<NativeCodeBasicBlock*>& cblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
bool CollectRegBoolInstructionsBackward(int reg, ExpandingArray<NativeCodeBasicBlock*>& cblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
|
||||
bool CollectCheckRegOriginBlocks(int at, int reg, ExpandingArray<NativeCodeBasicBlock*>& lblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
bool PatchBitBoolConstOrigin(void);
|
||||
|
||||
// reg : base register pair to replace
|
||||
// index: index register
|
||||
|
@ -752,9 +826,20 @@ public:
|
|||
bool CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int index, int at, int yval);
|
||||
bool PatchGlobalAddressSumYPointer(const NativeCodeBasicBlock* block, int reg, int index, int at, int yval, LinkerObject * lobj, int address, uint32 flags = NCIF_LOWER | NCIF_UPPER);
|
||||
|
||||
// reg : register to replace
|
||||
// at : start position in block
|
||||
// ains : instruction loading original data
|
||||
// cycles : max number of cycles saving
|
||||
bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles);
|
||||
bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains);
|
||||
|
||||
// rins : instruction storing the data
|
||||
// at : start position in block
|
||||
// ains : instruction loading original data
|
||||
// cycles : max number of cycles saving
|
||||
bool CheckSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains, bool cleared, bool poisoned);
|
||||
bool PatchSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains);
|
||||
|
||||
// reg : base register pair to replace
|
||||
// base: new base register
|
||||
// iins : indexing instruction
|
||||
|
@ -798,6 +883,10 @@ public:
|
|||
|
||||
void PropagateAddGlobalCarry(void);
|
||||
|
||||
bool EliminateNonAliasedLocalStores(void);
|
||||
bool CheckNonAliasedLocalStore(int at, const NativeCodeInstruction& sins);
|
||||
|
||||
|
||||
void RegisterFunctionCalls(void);
|
||||
bool MergeFunctionCalls(void);
|
||||
|
||||
|
@ -807,6 +896,9 @@ public:
|
|||
void CheckBlocks(bool sequence = false);
|
||||
void CheckAsmCode(void);
|
||||
void CheckVisited(void);
|
||||
|
||||
int* mSuffixString;
|
||||
void AddToSuffixTree(NativeCodeMapper& mapper, SuffixTree * tree);
|
||||
};
|
||||
|
||||
class NativeCodeProcedure
|
||||
|
@ -821,6 +913,10 @@ class NativeCodeProcedure
|
|||
NativeCodeGenerator* mGenerator;
|
||||
|
||||
InterCodeProcedure* mInterProc;
|
||||
LinkerObject* mLinkerObject;
|
||||
const Ident* mIdent;
|
||||
Location mLocation;
|
||||
uint64 mCompilerOptions;
|
||||
|
||||
int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand;
|
||||
int mFastCallBase;
|
||||
|
@ -832,10 +928,15 @@ class NativeCodeProcedure
|
|||
ExpandingArray<CodeLocation> mCodeLocations;
|
||||
|
||||
|
||||
void DisassembleDebug(const char* name);
|
||||
void Disassemble(FILE* file);
|
||||
|
||||
void Compile(InterCodeProcedure* proc);
|
||||
void Optimize(void);
|
||||
void Assemble(void);
|
||||
|
||||
void AddToSuffixTree(NativeCodeMapper& mapper, SuffixTree* tree);
|
||||
|
||||
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||
NativeCodeBasicBlock* AllocateBlock(void);
|
||||
|
||||
|
@ -901,6 +1002,8 @@ public:
|
|||
Linker* mLinker;
|
||||
LinkerSection* mRuntimeSection;
|
||||
|
||||
ExpandingArray<NativeCodeProcedure*> mProcedures;
|
||||
|
||||
ExpandingArray<Runtime> mRuntime;
|
||||
ExpandingArray<MulTable> mMulTables;
|
||||
ExpandingArray<FloatTable> mFloatTables;
|
||||
|
@ -919,6 +1022,8 @@ public:
|
|||
|
||||
FunctionCall* mFunctionCalls;
|
||||
|
||||
void OutlineFunctions(void);
|
||||
|
||||
void RegisterFunctionCall(NativeCodeBasicBlock* block, int at);
|
||||
void BuildFunctionProxies(void);
|
||||
bool MergeFunctionCall(NativeCodeBasicBlock* block, int at);
|
||||
|
|
|
@ -0,0 +1,379 @@
|
|||
#include "NativeCodeOutliner.h"
|
||||
|
||||
|
||||
NativeCodeMapper::NativeCodeMapper(void)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
mHash[i] = nullptr;
|
||||
}
|
||||
|
||||
NativeCodeMapper::~NativeCodeMapper(void)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
InsNode* n = mHash[i];
|
||||
while (n)
|
||||
{
|
||||
InsNode* m = n;
|
||||
n = n->mNext;
|
||||
delete m;
|
||||
}
|
||||
mHash[i] = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NativeCodeMapper::Reset(void)
|
||||
{
|
||||
mBlocks.SetSize(0);
|
||||
}
|
||||
|
||||
int NativeCodeMapper::MapBasicBlock(NativeCodeBasicBlock* block)
|
||||
{
|
||||
mBlocks.Push(block);
|
||||
return -mBlocks.Size();
|
||||
}
|
||||
|
||||
int NativeCodeMapper::MapInstruction(const NativeCodeInstruction& ins, LinkerSection* ls)
|
||||
{
|
||||
int hash = ins.CodeHash() % HashSize;
|
||||
InsNode* n = mHash[hash];
|
||||
while (n)
|
||||
{
|
||||
if (mIns[n->mIndex].CodeSame(ins) && n->mSection == ls)
|
||||
return n->mIndex;
|
||||
n = n->mNext;
|
||||
}
|
||||
n = new InsNode();
|
||||
n->mIndex = mIns.Size();
|
||||
n->mSection = ls;
|
||||
mIns.Push(ins);
|
||||
n->mNext = mHash[hash];
|
||||
mHash[hash] = n;
|
||||
return n->mIndex;
|
||||
}
|
||||
|
||||
SuffixTree::SuffixTree(const int* str, int s, SuffixTree* n)
|
||||
{
|
||||
mSeg = str;
|
||||
mSize = s;
|
||||
mNext = n;
|
||||
mParent = nullptr;
|
||||
mFirst = nullptr;
|
||||
}
|
||||
|
||||
SuffixTree::~SuffixTree(void)
|
||||
{
|
||||
delete[] mFirst;
|
||||
}
|
||||
|
||||
void SuffixTree::AddParents(SuffixTree* parent)
|
||||
{
|
||||
mParent = parent;
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->AddParents(this);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::AddSuffix(const int* str, int s)
|
||||
{
|
||||
int hi = str[0] & (HashSize - 1);
|
||||
SuffixTree* c = mFirst ? mFirst[hi] : nullptr;
|
||||
while (c && c->mSeg[0] != str[0])
|
||||
c = c->mNext;
|
||||
|
||||
if (c)
|
||||
{
|
||||
int k = 1;
|
||||
while (k < c->mSize && str[k] == c->mSeg[k])
|
||||
k++;
|
||||
if (k == c->mSize)
|
||||
c->AddSuffix(str + k, s - k);
|
||||
else
|
||||
{
|
||||
SuffixTree * n = new SuffixTree(c->mSeg + k, c->mSize - k, nullptr);
|
||||
if (c->mFirst)
|
||||
{
|
||||
n->mFirst = new SuffixTree * [HashSize];
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
n->mFirst[i] = c->mFirst[i];
|
||||
c->mFirst[i] = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c->mFirst = new SuffixTree * [HashSize];
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
c->mFirst[i] = nullptr;
|
||||
}
|
||||
c->mFirst[c->mSeg[k] & (HashSize - 1)] = n;
|
||||
int hk = str[k] & (HashSize - 1);
|
||||
c->mFirst[hk] = new SuffixTree(str + k, s - k, c->mFirst[hk]);
|
||||
c->mSize = k;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mFirst)
|
||||
{
|
||||
mFirst = new SuffixTree * [HashSize];
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
mFirst[i] = nullptr;
|
||||
}
|
||||
|
||||
mFirst[hi] = new SuffixTree(str, s, mFirst[hi]);
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::AddString(const int* str)
|
||||
{
|
||||
int s = 0;
|
||||
while(str[s] >= 0)
|
||||
s++;
|
||||
s++;
|
||||
|
||||
int i = 0;
|
||||
while (str[i] >= 0)
|
||||
{
|
||||
AddSuffix(str + i, s - i);
|
||||
i++;
|
||||
}
|
||||
AddSuffix(str + i, 1);
|
||||
}
|
||||
|
||||
void SuffixTree::CollectSuffix(NativeCodeMapper& map, int offset, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
offset += mSize;
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* t = mFirst[i];
|
||||
|
||||
while (t)
|
||||
{
|
||||
t->CollectSuffix(map, offset, segs);
|
||||
t = t->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[mSize - 1] + 1)];
|
||||
|
||||
SuffixSegment seg;
|
||||
seg.mBlock = block;
|
||||
seg.mStart = offset;
|
||||
seg.mEnd = block->mIns.Size() + 1;
|
||||
segs.Push(seg);
|
||||
}
|
||||
}
|
||||
|
||||
int SuffixTree::LongestMatch(NativeCodeMapper& map, int size, int isize, int& msize, SuffixTree*& mtree)
|
||||
{
|
||||
if (mFirst)
|
||||
{
|
||||
isize += mSize;
|
||||
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
size += AsmInsModeSize[map.mIns[mSeg[i]].mMode];
|
||||
}
|
||||
|
||||
assert(size < 10000);
|
||||
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* t = mFirst[i];
|
||||
while (t)
|
||||
{
|
||||
cnt += t->LongestMatch(map, size, isize, msize, mtree);
|
||||
t = t->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
if (size >= 6 && (size - 3) * (cnt - 1) > msize)
|
||||
{
|
||||
// Second run to cross check for overlaps
|
||||
ExpandingArray<SuffixSegment> segs;
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* t = mFirst[i];
|
||||
while (t)
|
||||
{
|
||||
t->CollectSuffix(map, 0, segs);
|
||||
t = t->mNext;
|
||||
}
|
||||
}
|
||||
segs.Sort([](const SuffixSegment& l, const SuffixSegment& r)->bool {
|
||||
return l.mBlock == r.mBlock ? l.mStart < r.mStart : ptrdiff_t(l.mBlock) < ptrdiff_t(r.mBlock);
|
||||
});
|
||||
|
||||
for (int i = 0; i + 1 < segs.Size(); i++)
|
||||
{
|
||||
if (segs[i].mBlock == segs[i + 1].mBlock && segs[i].mStart + isize > segs[i + 1].mStart)
|
||||
cnt--;
|
||||
}
|
||||
|
||||
if (cnt > 1 && (size - 3) * (cnt - 1) > msize)
|
||||
{
|
||||
msize = (size - 3) * (cnt - 1);
|
||||
mtree = this;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SuffixTree::Print(FILE * file, NativeCodeMapper& map, int depth)
|
||||
{
|
||||
for (int i = 0; i < depth; i++)
|
||||
fprintf(file, ".");
|
||||
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
fprintf(file, "[");
|
||||
|
||||
if (mSeg[i] >= 0)
|
||||
map.mIns[mSeg[i]].Disassemble(file);
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[- (mSeg[i] + 1)];
|
||||
fprintf(file, "%s,%d", block->mProc->mInterProc->mIdent->mString, block->mIndex);
|
||||
}
|
||||
fprintf(file, "]");
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->Print(file, map, depth + 1);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::ParentPrint(FILE* file, NativeCodeMapper& map)
|
||||
{
|
||||
if (mParent)
|
||||
mParent->ParentPrint(file, map);
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
map.mIns[mSeg[i]].Disassemble(file);
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[i] + 1)];
|
||||
fprintf(file, "%s,%d", block->mProc->mInterProc->mIdent->mString, block->mIndex);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
int SuffixTree::ParentCodeSize(NativeCodeMapper& map) const
|
||||
{
|
||||
int size = 0;
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
size += AsmInsModeSize[map.mIns[mSeg[i]].mMode];
|
||||
}
|
||||
|
||||
if (mParent)
|
||||
size += mParent->ParentCodeSize(map);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void SuffixTree::ParentCollect(NativeCodeMapper& map, NativeCodeBasicBlock* block)
|
||||
{
|
||||
if (mParent)
|
||||
mParent->ParentCollect(map, block);
|
||||
for (int i = 0; i < mSize; i++)
|
||||
block->mIns.Push(map.mIns[mSeg[i]]);
|
||||
}
|
||||
|
||||
void SuffixTree::ReplaceCalls(NativeCodeMapper& map, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->ChildReplaceCalls(map, this, 0, segs);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::ChildReplaceCalls(NativeCodeMapper& map, SuffixTree* tree, int offset, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
offset ++;
|
||||
}
|
||||
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->ChildReplaceCalls(map, tree, offset, segs);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[mSize - 1] + 1)];
|
||||
tree->ParentReplaceCalls(map, block, offset, 0, segs);
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::ParentReplaceCalls(NativeCodeMapper& map, NativeCodeBasicBlock* block, int offset, int size, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
size ++;
|
||||
}
|
||||
if (mParent)
|
||||
mParent->ParentReplaceCalls(map, block, offset, size, segs);
|
||||
else
|
||||
{
|
||||
int at = block->mIns.Size() - offset - size;
|
||||
|
||||
SuffixSegment seg;
|
||||
seg.mBlock = block;
|
||||
seg.mStart = at;
|
||||
seg.mEnd = at + size;
|
||||
segs.Push(seg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "NativeCodeGenerator.h"
|
||||
#include "Array.h"
|
||||
|
||||
class NativeCodeMapper
|
||||
{
|
||||
public:
|
||||
NativeCodeMapper(void);
|
||||
~NativeCodeMapper(void);
|
||||
|
||||
void Reset(void);
|
||||
|
||||
int MapInstruction(const NativeCodeInstruction& ins, LinkerSection * ls);
|
||||
int MapBasicBlock(NativeCodeBasicBlock* block);
|
||||
|
||||
ExpandingArray<NativeCodeInstruction> mIns;
|
||||
ExpandingArray<NativeCodeBasicBlock*> mBlocks;
|
||||
protected:
|
||||
static const int HashSize = 256;
|
||||
|
||||
struct InsNode
|
||||
{
|
||||
int mIndex;
|
||||
LinkerSection * mSection;
|
||||
InsNode* mNext;
|
||||
};
|
||||
|
||||
InsNode * mHash[HashSize];
|
||||
};
|
||||
|
||||
struct SuffixSegment
|
||||
{
|
||||
NativeCodeBasicBlock * mBlock;
|
||||
int mStart, mEnd;
|
||||
};
|
||||
|
||||
class SuffixTree
|
||||
{
|
||||
public:
|
||||
const int * mSeg;
|
||||
int mSize;
|
||||
|
||||
static const int HashSize = 32;
|
||||
|
||||
SuffixTree* mNext, * mParent, ** mFirst;
|
||||
|
||||
SuffixTree(const int* str, int s, SuffixTree* n);
|
||||
~SuffixTree(void);
|
||||
|
||||
void AddParents(SuffixTree* parent);
|
||||
|
||||
void AddSuffix(const int* str, int s);
|
||||
void AddString(const int* str);
|
||||
|
||||
void Print(FILE* file, NativeCodeMapper & map, int depth);
|
||||
void ParentPrint(FILE* file, NativeCodeMapper& map);
|
||||
int LongestMatch(NativeCodeMapper& map, int size, int isize, int & msize, SuffixTree *& mtree);
|
||||
void CollectSuffix(NativeCodeMapper& map, int offset, ExpandingArray<SuffixSegment>& segs);
|
||||
int ParentCodeSize(NativeCodeMapper& map) const;
|
||||
void ParentCollect(NativeCodeMapper& map, NativeCodeBasicBlock * block);
|
||||
void ReplaceCalls(NativeCodeMapper& map, ExpandingArray<SuffixSegment> & segs);
|
||||
void ChildReplaceCalls(NativeCodeMapper& map, SuffixTree * tree, int offset, ExpandingArray<SuffixSegment>& segs);
|
||||
void ParentReplaceCalls(NativeCodeMapper& map, NativeCodeBasicBlock* block, int offset, int size, ExpandingArray<SuffixSegment>& segs);
|
||||
|
||||
};
|
3309
oscar64/Parser.cpp
3309
oscar64/Parser.cpp
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@ public:
|
|||
~Parser(void);
|
||||
|
||||
Parser* Clone(void);
|
||||
Parser * mParent;
|
||||
|
||||
DeclarationScope * mGlobals, * mScope, * mTemplateScope, * mCaptureScope;
|
||||
int mLocalIndex;
|
||||
|
@ -24,6 +25,8 @@ public:
|
|||
uint64 mCompilerOptionStack[32];
|
||||
int mCompilerOptionSP;
|
||||
|
||||
Location FullLocation(const Location& loc);
|
||||
|
||||
void Parse(void);
|
||||
protected:
|
||||
bool ExpectToken(Token token);
|
||||
|
@ -72,14 +75,18 @@ protected:
|
|||
Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr);
|
||||
|
||||
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
||||
Expression* ParseInitExpression(Declaration* dtype, bool inner = false);
|
||||
Expression* ParseConstInitExpression(Declaration* dtype, bool inner = false);
|
||||
Expression* ParseDeclarationExpression(Declaration* pdec);
|
||||
Expression* DefaultInitExpression(Expression* vexp);
|
||||
Expression* ParseVarInitExpression(Expression* lexp, bool inner = false);
|
||||
Expression* CloneVarInitExpression(Expression* vexp, Expression* iexp, Expression * qexp);
|
||||
Expression* CopyElision(Expression* vexp, Expression* rexp);
|
||||
|
||||
Declaration* ParsePostfixDeclaration(void);
|
||||
Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec);
|
||||
|
||||
Expression* ParseFunction(Declaration* dec);
|
||||
Expression* ParseAssembler(void);
|
||||
Expression* ParseAssembler(Declaration * vdassm = nullptr);
|
||||
|
||||
Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset);
|
||||
Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset);
|
||||
|
@ -130,7 +137,10 @@ protected:
|
|||
|
||||
Declaration* ParseTypeID(bool tid, Declaration * bdec = nullptr);
|
||||
|
||||
Expression* ParseConstruction(Declaration* type);
|
||||
|
||||
Expression* ParseCastExpression(Expression* exp);
|
||||
Expression* ParseIdentExpression(const Location & eloc, Declaration* dec, bool lhs, bool tid = false);
|
||||
Expression* ParseSimpleExpression(bool lhs, bool tid = false);
|
||||
Expression* ParsePrefixExpression(bool lhs);
|
||||
Expression* ParsePostfixExpression(bool lhs);
|
||||
|
@ -149,9 +159,10 @@ protected:
|
|||
Expression* ParseRExpression(void);
|
||||
|
||||
Expression* ExpandArgumentPack(Expression * exp, Declaration* dec);
|
||||
Expression* ParseListExpression(bool lhs);
|
||||
Expression* ParseListExpression(bool lhs, Declaration * params = nullptr);
|
||||
|
||||
Expression* ParseParenthesisExpression(void);
|
||||
void ParseStaticAssert(void);
|
||||
|
||||
Errors* mErrors;
|
||||
Scanner* mScanner;
|
||||
|
|
|
@ -44,7 +44,7 @@ bool SourceFile::ReadLineLZO(char* line, ptrdiff_t limit)
|
|||
while (pi < 127 && mPos < mFill)
|
||||
{
|
||||
int bi = pi, bj = 0;
|
||||
for (int i = 1; i < mPos; i++)
|
||||
for (int i = 1; i <= (mPos < 255 ? mPos : 255); i++)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < 127 && mPos + j < mFill && mBuffer[mPos - i + j] == mBuffer[mPos + j])
|
||||
|
@ -327,6 +327,16 @@ struct CTMHeader9
|
|||
uint8 mColors[7];
|
||||
};
|
||||
|
||||
struct CTTHeader9
|
||||
{
|
||||
uint8 mDispMode;
|
||||
uint8 mColorMethod;
|
||||
uint8 mFlags;
|
||||
uint8 mFgridWidth[2], mFGridHeight[2];
|
||||
char mFGridConfig;
|
||||
uint8 mColors[6];
|
||||
};
|
||||
|
||||
#if 0
|
||||
#pragma pack(push, 1)
|
||||
struct SPDHeader5
|
||||
|
@ -391,6 +401,15 @@ struct SPDHeader1
|
|||
uint8 mColors[3];
|
||||
};
|
||||
|
||||
struct SPDHeader3
|
||||
{
|
||||
uint8 mFlags;
|
||||
uint16 mNumSprites, mNumTiles;
|
||||
uint8 mNumSpriteAnmis, mNumTileAnims;
|
||||
uint8 mTileWidth, mTileHeight;
|
||||
uint8 mColors[3];
|
||||
};
|
||||
|
||||
struct SPDHeader5
|
||||
{
|
||||
uint8 mFlags;
|
||||
|
@ -411,6 +430,7 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
|
|||
if (spdHeader.mID[0] == 'S' && spdHeader.mID[1] == 'P' && spdHeader.mID[2] == 'D')
|
||||
{
|
||||
int numSprites = 0;
|
||||
int numTiles = 0, tileSize = 0;
|
||||
|
||||
switch (spdHeader.mVersion[0])
|
||||
{
|
||||
|
@ -419,6 +439,17 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
|
|||
SPDHeader5 spdHeader5;
|
||||
fread(&spdHeader5, sizeof(SPDHeader5), 1, mFile);
|
||||
numSprites = spdHeader5.mNumSprites;
|
||||
numTiles = spdHeader5.mNumTiles;
|
||||
tileSize = spdHeader5.mTileHeight * spdHeader5.mTileWidth;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
SPDHeader3 spdHeader3;
|
||||
fread(&spdHeader3, sizeof(SPDHeader3), 1, mFile);
|
||||
numSprites = spdHeader3.mNumSprites;
|
||||
numTiles = spdHeader3.mNumTiles;
|
||||
tileSize = spdHeader3.mTileHeight * spdHeader3.mTileWidth;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
|
@ -438,6 +469,21 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
|
|||
mLimit = 64 * numSprites;
|
||||
return;
|
||||
}
|
||||
else if (decoder == SFD_SPD_TILES)
|
||||
{
|
||||
fseek(mFile, 64 * numSprites, SEEK_CUR);
|
||||
mMemSize = numTiles * tileSize;
|
||||
mLimit = mMemSize;
|
||||
mMemPos = 0;
|
||||
mMemData = new uint8[mMemSize];
|
||||
for (int i = 0; i < mMemSize; i++)
|
||||
{
|
||||
int16 d;
|
||||
fread(&d, 2, 1, mFile);
|
||||
mMemData[i] = uint8(d);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
errors->Error(location, EERR_UNIMPLEMENTED, "SPD file format not recognized");
|
||||
|
@ -450,6 +496,7 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
|
|||
CTMHeader ctmHeader;
|
||||
CTMHeader8 ctmHeader8;
|
||||
CTMHeader9 ctmHeader9;
|
||||
CTTHeader9 cttHeader9;
|
||||
uint16 ctmMarker, numChars, numTiles;
|
||||
char tileWidth, tileHeight;
|
||||
|
||||
|
@ -460,10 +507,20 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
|
|||
fread(&ctmHeader8, sizeof(CTMHeader8), 1, mFile);
|
||||
break;
|
||||
case 9:
|
||||
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = ctmHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = ctmHeader9.mFlags;
|
||||
if (ctmHeader.mID[2] == 'T')
|
||||
{
|
||||
fread(&cttHeader9, sizeof(CTTHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = cttHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = cttHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = cttHeader9.mFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = ctmHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = ctmHeader9.mFlags;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -709,6 +766,7 @@ void SourceFile::Limit(Errors* errors, const Location& location, SourceFileDecod
|
|||
break;
|
||||
|
||||
case SFD_SPD_SPRITES:
|
||||
case SFD_SPD_TILES:
|
||||
ReadSpritePad(errors, location, decoder);
|
||||
break;
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ enum SourceFileDecoder
|
|||
SFD_CTM_TILES_16,
|
||||
SFD_CTM_MAP_8,
|
||||
SFD_CTM_MAP_16,
|
||||
SFD_SPD_SPRITES
|
||||
SFD_SPD_SPRITES,
|
||||
SFD_SPD_TILES,
|
||||
};
|
||||
|
||||
class SourceFile
|
||||
|
|
|
@ -51,6 +51,7 @@ const char* TokenNames[] =
|
|||
"'extern'",
|
||||
"'inline'",
|
||||
"'__assume'",
|
||||
"'static_assert'",
|
||||
|
||||
"__asm",
|
||||
"__interrupt",
|
||||
|
@ -60,6 +61,7 @@ const char* TokenNames[] =
|
|||
"__export",
|
||||
"__zeropage",
|
||||
"__noinline",
|
||||
"__forceinline",
|
||||
"__striped",
|
||||
"__dynstack",
|
||||
|
||||
|
@ -172,11 +174,12 @@ const char* TokenNames[] =
|
|||
"'friend'",
|
||||
"'constexpr'",
|
||||
"'typename'",
|
||||
"'decltype'",
|
||||
};
|
||||
|
||||
|
||||
Macro::Macro(const Ident* ident, MacroDict * scope)
|
||||
: mIdent(ident), mString(nullptr), mNumArguments(-1), mScope(scope)
|
||||
: mIdent(ident), mString(nullptr), mNumArguments(-1), mScope(scope), mVariadic(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -354,7 +357,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
|||
mToken = TK_NONE;
|
||||
mUngetToken = TK_NONE;
|
||||
mReplay = nullptr;
|
||||
mRecord = mRecordLast = nullptr;
|
||||
mRecord = mRecordLast = mRecordPrev = nullptr;
|
||||
|
||||
mOnceDict = new MacroDict();
|
||||
|
||||
|
@ -371,13 +374,13 @@ Scanner::~Scanner(void)
|
|||
|
||||
void Scanner::BeginRecord(void)
|
||||
{
|
||||
mRecord = mRecordLast = new TokenSequence(this);
|
||||
mRecord = mRecordLast = mRecordPrev = new TokenSequence(this);
|
||||
}
|
||||
|
||||
TokenSequence* Scanner::CompleteRecord(void)
|
||||
{
|
||||
TokenSequence* seq = mRecord;
|
||||
mRecord = mRecordLast = nullptr;
|
||||
mRecord = mRecordLast = mRecordPrev = nullptr;
|
||||
return seq;
|
||||
}
|
||||
|
||||
|
@ -482,6 +485,8 @@ void Scanner::UngetToken(Token token)
|
|||
{
|
||||
mUngetToken = mToken;
|
||||
mToken = token;
|
||||
if (mRecord)
|
||||
mRecordLast = mRecordPrev;
|
||||
}
|
||||
|
||||
void Scanner::NextToken(void)
|
||||
|
@ -490,10 +495,8 @@ void Scanner::NextToken(void)
|
|||
{
|
||||
mToken = mUngetToken;
|
||||
mUngetToken = TK_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mReplay)
|
||||
else if (mReplay)
|
||||
{
|
||||
mLocation = mReplay->mLocation;
|
||||
mToken = mReplay->mToken;
|
||||
|
@ -514,6 +517,7 @@ void Scanner::NextToken(void)
|
|||
|
||||
if (mRecord)
|
||||
{
|
||||
mRecordPrev = mRecordLast;
|
||||
mRecordLast->mNext = new TokenSequence(this);
|
||||
mRecordLast = mRecordLast->mNext;
|
||||
}
|
||||
|
@ -753,6 +757,12 @@ void Scanner::NextPreToken(void)
|
|||
{
|
||||
macro->AddArgument(mTokenIdent);
|
||||
NextRawToken();
|
||||
if (mToken == TK_ELLIPSIS)
|
||||
{
|
||||
macro->mVariadic = true;
|
||||
NextRawToken();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid define argument");
|
||||
|
@ -813,27 +823,36 @@ void Scanner::NextPreToken(void)
|
|||
}
|
||||
else if (mToken == TK_PREP_IDENT)
|
||||
{
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(mTokenIdent);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(mTokenIdent);
|
||||
|
||||
if (def)
|
||||
if (mTokenIdent->mString[0])
|
||||
{
|
||||
if (def->mNumArguments == -1)
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(mTokenIdent);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(mTokenIdent);
|
||||
|
||||
if (def)
|
||||
{
|
||||
mToken = TK_STRING;
|
||||
int i = 0;
|
||||
while ((mTokenString[i] = def->mString[i]))
|
||||
i++;
|
||||
return;
|
||||
if (def->mNumArguments == -1)
|
||||
{
|
||||
mToken = TK_STRING;
|
||||
int i = 0;
|
||||
while ((mTokenString[i] = def->mString[i]))
|
||||
i++;
|
||||
mTokenStringSize = i;
|
||||
return;
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
{
|
||||
mToken = TK_HASH;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (mToken == TK_PREP_UNDEF)
|
||||
{
|
||||
|
@ -978,6 +997,8 @@ void Scanner::NextPreToken(void)
|
|||
decoder = SFD_CTM_MAP_16;
|
||||
else if (!strcmp(mTokenIdent->mString, "spd_sprites"))
|
||||
decoder = SFD_SPD_SPRITES;
|
||||
else if (!strcmp(mTokenIdent->mString, "spd_tiles"))
|
||||
decoder = SFD_SPD_TILES;
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Invalid embed compression mode", mTokenIdent);
|
||||
|
||||
|
@ -1039,7 +1060,8 @@ void Scanner::NextPreToken(void)
|
|||
int offset = mOffset;
|
||||
int level = 0;
|
||||
bool quote = false;
|
||||
while (mLine[offset] && (quote || level > 0 || (mLine[offset] != ',' && mLine[offset] != ')')))
|
||||
|
||||
while (mLine[offset] && (quote || level > 0 || (!(!(def->mVariadic && i + 1 == def->mNumArguments) && mLine[offset] == ',') && mLine[offset] != ')')))
|
||||
{
|
||||
if (mLine[offset] == '"')
|
||||
{
|
||||
|
@ -1059,10 +1081,13 @@ void Scanner::NextPreToken(void)
|
|||
arg->SetString(mLine + mOffset, offset - mOffset);
|
||||
mDefineArguments->Insert(arg);
|
||||
mOffset = offset;
|
||||
|
||||
if (i + 1 != def->mNumArguments)
|
||||
{
|
||||
if (mLine[mOffset] == ',')
|
||||
mOffset++;
|
||||
else if (def->mVariadic && i + 2 == def->mNumArguments && mLine[mOffset] == ')')
|
||||
;
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid define expansion argument");
|
||||
}
|
||||
|
@ -1100,46 +1125,70 @@ void Scanner::NextPreToken(void)
|
|||
while (mTokenChar == ' ')
|
||||
NextChar();
|
||||
|
||||
while (mTokenChar == '#' && mLine[mOffset] == '#')
|
||||
if (mTokenChar == '#' && mLine[mOffset] == '#')
|
||||
{
|
||||
mOffset++;
|
||||
NextChar();
|
||||
|
||||
char tkbase[256];
|
||||
strcpy_s(tkbase, mTokenIdent->mString);
|
||||
|
||||
ptrdiff_t n = 0;
|
||||
char tkident[256];
|
||||
while (IsIdentChar(mTokenChar))
|
||||
{
|
||||
if (n < 255)
|
||||
tkident[n++] = mTokenChar;
|
||||
do {
|
||||
mOffset++;
|
||||
NextChar();
|
||||
}
|
||||
tkident[n] = 0;
|
||||
|
||||
const Ident* ntkident = Ident::Unique(tkident);
|
||||
ptrdiff_t n = 0;
|
||||
char tkident[256];
|
||||
while (IsIdentChar(mTokenChar))
|
||||
{
|
||||
if (n < 255)
|
||||
tkident[n++] = mTokenChar;
|
||||
NextChar();
|
||||
}
|
||||
tkident[n] = 0;
|
||||
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(ntkident);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(ntkident);
|
||||
const Ident* ntkident = Ident::Unique(tkident);
|
||||
|
||||
if (def)
|
||||
strcat_s(tkbase, def->mString);
|
||||
else
|
||||
strcat_s(tkbase, tkident);
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(ntkident);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(ntkident);
|
||||
|
||||
n = strlen(tkbase);
|
||||
while (n > 0 && tkbase[n - 1] == ' ')
|
||||
n--;
|
||||
tkbase[n] = 0;
|
||||
if (def)
|
||||
strcat_s(tkbase, def->mString);
|
||||
else
|
||||
strcat_s(tkbase, tkident);
|
||||
|
||||
mTokenIdent = Ident::Unique(tkbase);
|
||||
n = strlen(tkbase);
|
||||
while (n > 0 && tkbase[n - 1] == ' ')
|
||||
n--;
|
||||
tkbase[n] = 0;
|
||||
|
||||
while (mTokenChar == ' ')
|
||||
NextChar();
|
||||
|
||||
} while (mTokenChar == '#' && mLine[mOffset] == '#');
|
||||
|
||||
ptrdiff_t n = strlen(tkbase);
|
||||
char* str = new char[n + 1];
|
||||
strcpy_s(str, n + 1, tkbase);
|
||||
|
||||
MacroExpansion* ex = new MacroExpansion();
|
||||
ex->mDefinedArguments = mDefineArguments;
|
||||
|
||||
ex->mLine = mLine;
|
||||
ex->mOffset = mOffset;
|
||||
ex->mLink = mMacroExpansion;
|
||||
ex->mChar = mTokenChar;
|
||||
|
||||
mMacroExpansion = ex;
|
||||
mMacroExpansionDepth++;
|
||||
if (mMacroExpansionDepth > 1024)
|
||||
mErrors->Error(mLocation, EFATAL_MACRO_EXPANSION_DEPTH, "Maximum macro expansion depth exceeded", mTokenIdent);
|
||||
mLine = str;
|
||||
mOffset = 0;
|
||||
NextChar();
|
||||
}
|
||||
|
||||
return;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1176,7 +1225,7 @@ void Scanner::NextSkipRawToken(void)
|
|||
|
||||
if (mTokenChar == '#')
|
||||
{
|
||||
if (mOffset == 1 || mStartOfLine)
|
||||
if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1 || mStartOfLine)
|
||||
{
|
||||
int n = 0;
|
||||
char tkprep[128];
|
||||
|
@ -1784,6 +1833,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_ASM;
|
||||
else if (!strcmp(tkident, "__assume"))
|
||||
mToken = TK_ASSUME;
|
||||
else if (!strcmp(tkident, "static_assert"))
|
||||
mToken = TK_STATIC_ASSERT;
|
||||
else if (!strcmp(tkident, "__interrupt"))
|
||||
mToken = TK_INTERRUPT;
|
||||
else if (!strcmp(tkident, "__hwinterrupt"))
|
||||
|
@ -1798,6 +1849,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_ZEROPAGE;
|
||||
else if (!strcmp(tkident, "__noinline"))
|
||||
mToken = TK_NOINLINE;
|
||||
else if (!strcmp(tkident, "__forceinline"))
|
||||
mToken = TK_FORCEINLINE;
|
||||
else if (!strcmp(tkident, "__striped"))
|
||||
mToken = TK_STRIPED;
|
||||
else if (!strcmp(tkident, "__dynstack"))
|
||||
|
@ -1830,6 +1883,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_CONSTEXPR;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename"))
|
||||
mToken = TK_TYPENAME;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "decltype"))
|
||||
mToken = TK_DECLTYPE;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
||||
{
|
||||
NextRawToken();
|
||||
|
@ -1959,7 +2014,7 @@ void Scanner::NextRawToken(void)
|
|||
|
||||
default:
|
||||
// dirty little hack to implement token preview, got to fix
|
||||
// this with an infinit preview sequence at one point
|
||||
// this with an infinite preview sequence at one point
|
||||
mUngetToken = mToken;
|
||||
mToken = TK_OPERATOR;
|
||||
return;
|
||||
|
|
|
@ -49,6 +49,7 @@ enum Token
|
|||
TK_EXTERN,
|
||||
TK_INLINE,
|
||||
TK_ASSUME,
|
||||
TK_STATIC_ASSERT,
|
||||
|
||||
TK_ASM,
|
||||
TK_INTERRUPT,
|
||||
|
@ -58,6 +59,7 @@ enum Token
|
|||
TK_EXPORT,
|
||||
TK_ZEROPAGE,
|
||||
TK_NOINLINE,
|
||||
TK_FORCEINLINE,
|
||||
TK_STRIPED,
|
||||
TK_DYNSTACK,
|
||||
|
||||
|
@ -171,6 +173,7 @@ enum Token
|
|||
TK_FRIEND,
|
||||
TK_CONSTEXPR,
|
||||
TK_TYPENAME,
|
||||
TK_DECLTYPE,
|
||||
|
||||
NUM_TOKENS
|
||||
};
|
||||
|
@ -189,11 +192,12 @@ public:
|
|||
void SetString(const char* str, ptrdiff_t length);
|
||||
void AddArgument(const Ident * ident);
|
||||
|
||||
const Ident* mIdent;
|
||||
const char* mString;
|
||||
int mNumArguments;
|
||||
const Ident * mArguments[32];
|
||||
MacroDict* mScope;
|
||||
const Ident * mIdent;
|
||||
const char * mString;
|
||||
int mNumArguments;
|
||||
const Ident * mArguments[32];
|
||||
MacroDict * mScope;
|
||||
bool mVariadic;
|
||||
};
|
||||
|
||||
typedef Macro* MacroPtr;
|
||||
|
@ -313,7 +317,7 @@ protected:
|
|||
Token mUngetToken;
|
||||
|
||||
const TokenSequence* mReplay;
|
||||
TokenSequence* mRecord, * mRecordLast;
|
||||
TokenSequence* mRecord, * mRecordLast, * mRecordPrev;
|
||||
|
||||
void StringToken(char terminator, char mode);
|
||||
void CharToken(char mode);
|
||||
|
|
|
@ -76,7 +76,7 @@ int main2(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.31.252");
|
||||
strcpy(strProductVersion, "1.31.261");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
@ -111,38 +111,12 @@ int main2(int argc, const char** argv)
|
|||
GrowingArray<const char*> dataFiles(nullptr);
|
||||
GrowingArray<bool> dataFileCompressed(false);
|
||||
|
||||
bool emulate = false, profile = false, customCRT = false;
|
||||
int trace = 0;
|
||||
|
||||
compiler->mPreprocessor->AddPath(basePath);
|
||||
strcpy_s(includePath, basePath);
|
||||
{
|
||||
FILE* crtFile;
|
||||
char crtFileNamePath[FILENAME_MAX];
|
||||
crtFileNamePath[FILENAME_MAX - 1] = '\0';
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/");
|
||||
else
|
||||
{
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/oscar64/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/oscar64/");
|
||||
else
|
||||
{
|
||||
printf("Could not locate Oscar64 includes under %s\n", basePath);
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
fclose(crtFile);
|
||||
}
|
||||
compiler->mPreprocessor->AddPath(includePath);
|
||||
strcpy_s(crtPath, includePath);
|
||||
strcat_s(crtPath, "crt.c");
|
||||
|
||||
bool emulate = false, profile = false;
|
||||
int trace = 0;
|
||||
strcat_s(includePath, "include");
|
||||
|
||||
targetPath[0] = 0;
|
||||
diskPath[0] = 0;
|
||||
|
@ -185,6 +159,10 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mPreprocessor->AddPath(arg + 3);
|
||||
}
|
||||
else if (arg[1] == 'i' && arg[2] == 'i' && arg[3] == '=')
|
||||
{
|
||||
strcpy_s(includePath, arg + 4);
|
||||
}
|
||||
else if (arg[1] == 'f' && arg[2] == '=')
|
||||
{
|
||||
dataFiles.Push(arg + 3);
|
||||
|
@ -206,6 +184,7 @@ int main2(int argc, const char** argv)
|
|||
else if (arg[1] == 'r' && arg[2] == 't' && arg[3] == '=')
|
||||
{
|
||||
strcpy_s(crtPath, arg + 4);
|
||||
customCRT = true;
|
||||
}
|
||||
else if (arg[1] == 'd' && arg[2] == '6' && arg[3] == '4' && arg[4] == '=')
|
||||
{
|
||||
|
@ -225,42 +204,50 @@ int main2(int argc, const char** argv)
|
|||
strcpy_s(cid, arg + 5);
|
||||
compiler->mCartridgeID = atoi(cid);
|
||||
}
|
||||
else if (arg[1] == 'n')
|
||||
else if (arg[1] == 'n' && arg[2] == 0)
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_NATIVE;
|
||||
}
|
||||
else if (arg[1] == 'b' && arg[2] == 'c')
|
||||
else if (arg[1] == 'b' && arg[2] == 'c' && arg[3] == 0)
|
||||
{
|
||||
compiler->mCompilerOptions &= ~COPT_NATIVE;
|
||||
}
|
||||
else if (arg[1] == 'p' && arg[2] == 's' && arg[3] == 'c' && arg[4] == 'i')
|
||||
else if (arg[1] == 'p' && arg[2] == 's' && arg[3] == 'c' && arg[4] == 'i' && arg[5] == 0)
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_PETSCII;
|
||||
}
|
||||
else if (arg[1] == 'O')
|
||||
{
|
||||
if (arg[2] == '0')
|
||||
if (arg[2] == '0' && !arg[3])
|
||||
compiler->mCompilerOptions &= ~(COPT_OPTIMIZE_ALL);
|
||||
else if (arg[1] == '1' || arg[1] == 0)
|
||||
else if (arg[2] == '1' && !arg[3] || arg[2] == 0)
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_DEFAULT;
|
||||
else if (arg[2] == '2')
|
||||
else if (arg[2] == '2' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_SPEED;
|
||||
else if (arg[2] == '3')
|
||||
else if (arg[2] == '3' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_ALL;
|
||||
else if (arg[2] == 's')
|
||||
else if (arg[2] == 's' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_SIZE;
|
||||
else if (arg[2] == 'a')
|
||||
else if (arg[2] == 'a' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_ASSEMBLER;
|
||||
else if (arg[2] == 'i')
|
||||
else if (arg[2] == 'i' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_INLINE;
|
||||
else if (arg[2] == 'z')
|
||||
else if (arg[2] == 'i' && arg[3] == 'i' && !arg[4])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_INLINE_ALL;
|
||||
else if (arg[2] == 'z' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_ZEROPAGE;
|
||||
else if (arg[2] == 'p')
|
||||
else if (arg[2] == 'p' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_CONST_PARAMS;
|
||||
else if (arg[2] == 'g')
|
||||
else if (arg[2] == 'g' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_GLOBAL;
|
||||
else if (arg[2] == 'm')
|
||||
else if (arg[2] == 'm' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_MERGE_CALLS;
|
||||
else if (arg[2] == 'o' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_OUTLINE;
|
||||
else if (arg[2] == 'x' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_PAGE_CROSSING;
|
||||
else
|
||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
||||
}
|
||||
else if (arg[1] == 'e')
|
||||
{
|
||||
|
@ -291,26 +278,44 @@ int main2(int argc, const char** argv)
|
|||
else
|
||||
compiler->AddDefine(Ident::Unique(def), "");
|
||||
}
|
||||
else if (arg[1] == 'g')
|
||||
else if (arg[1] == 'g' && !arg[2])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_DEBUGINFO;
|
||||
}
|
||||
else if (arg[1] == 'g' && arg[2] == 'p' && !arg[3])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_DEBUGINFO | COPT_PROFILEINFO;
|
||||
}
|
||||
else if (arg[1] == 'v')
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_VERBOSE;
|
||||
if (arg[2] == '2')
|
||||
if (arg[2] == '1')
|
||||
;
|
||||
else if (arg[2] == '2')
|
||||
compiler->mCompilerOptions |= COPT_VERBOSE2;
|
||||
else if (arg[2] == '3')
|
||||
compiler->mCompilerOptions |= COPT_VERBOSE2 | COPT_VERBOSE3;
|
||||
else if (arg[2])
|
||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
||||
}
|
||||
else if (arg[1] == 'x' && arg[2] == 'z')
|
||||
else if (arg[1] == 'x' && arg[2] == 'z' && !arg[3])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_EXTENDED_ZERO_PAGE;
|
||||
}
|
||||
else if (arg[1] == 'p' && arg[2] == 'p')
|
||||
else if (arg[1] == 'p' && arg[2] == 'p' && !arg[3])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_CPLUSPLUS;
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus__"), "1");
|
||||
}
|
||||
else if (arg[1] == 's' && arg[2] == 't' && arg[3] == 'r' && arg[4] == 'i' && arg[5] == 'c' && arg[6] == 't' && !arg[7])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_STRICT;
|
||||
compiler->AddDefine(Ident::Unique("__strict__"), "1");
|
||||
}
|
||||
else if (arg[1] == 'r' && arg[2] == 'm' && arg[3] == 'p' && !arg[4])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_ERROR_FILES;
|
||||
}
|
||||
else
|
||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
||||
|
@ -325,6 +330,7 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mCompilerOptions |= COPT_CPLUSPLUS;
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus__"), "1");
|
||||
}
|
||||
|
||||
compiler->mCompilationUnits->AddUnit(loc, argv[i], nullptr);
|
||||
|
@ -421,6 +427,12 @@ int main2(int argc, const char** argv)
|
|||
compiler->mTargetMachine = TMACH_PLUS4;
|
||||
compiler->AddDefine(Ident::Unique("__PLUS4__"), "1");
|
||||
}
|
||||
else if (!strcmp(targetMachine, "mega65"))
|
||||
{
|
||||
strcpy_s(basicStart, "0x2001");
|
||||
compiler->mTargetMachine = TMACH_MEGA65;
|
||||
compiler->AddDefine(Ident::Unique("__MEGA65__"), "1");
|
||||
}
|
||||
else if (!strcmp(targetMachine, "x16"))
|
||||
{
|
||||
strcpy_s(basicStart, "0x0801");
|
||||
|
@ -524,6 +536,8 @@ int main2(int argc, const char** argv)
|
|||
printf("Starting %s %s\n", strProductName, strProductVersion);
|
||||
}
|
||||
|
||||
compiler->RemoveErrorFile(targetPath);
|
||||
|
||||
{
|
||||
char dstring[100], tstring[100];
|
||||
time_t now = time(NULL);
|
||||
|
@ -537,12 +551,41 @@ int main2(int argc, const char** argv)
|
|||
strftime(dstring, sizeof(tstring) - 1, "\"%b %d %Y\"", &t);
|
||||
strftime(tstring, sizeof(dstring) - 1, "\"%H:%M:%S\"", &t);
|
||||
|
||||
compiler->AddDefine(Ident::Unique("__DATE__"), dstring);
|
||||
compiler->AddDefine(Ident::Unique("__TIME__"), tstring);
|
||||
compiler->AddDefine(Ident::Unique("__DATE__"), _strdup(dstring));
|
||||
compiler->AddDefine(Ident::Unique("__TIME__"), _strdup(tstring));
|
||||
}
|
||||
|
||||
// Add runtime module
|
||||
|
||||
compiler->mPreprocessor->AddPath(includePath);
|
||||
|
||||
if (!customCRT)
|
||||
{
|
||||
FILE* crtFile;
|
||||
char crtFileNamePath[FILENAME_MAX];
|
||||
crtFileNamePath[FILENAME_MAX - 1] = '\0';
|
||||
strcpy_s(crtFileNamePath, includePath);
|
||||
strcat_s(crtFileNamePath, "/crt.h");
|
||||
|
||||
if (fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
{
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/oscar64/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/oscar64/");
|
||||
else
|
||||
{
|
||||
printf("Could not locate Oscar64 includes under %s\n", basePath);
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
fclose(crtFile);
|
||||
|
||||
strcpy_s(crtPath, includePath);
|
||||
strcat_s(crtPath, "/crt.c");
|
||||
}
|
||||
|
||||
if (crtPath[0])
|
||||
compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr);
|
||||
|
||||
|
@ -579,6 +622,10 @@ int main2(int argc, const char** argv)
|
|||
if (emulate)
|
||||
compiler->ExecuteCode(profile, trace);
|
||||
}
|
||||
else if (compiler->mCompilerOptions & COPT_ERROR_FILES)
|
||||
{
|
||||
compiler->WriteErrorFile(targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (compiler->mErrors->mErrorCount != 0)
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,31,252,0
|
||||
PRODUCTVERSION 1,31,252,0
|
||||
FILEVERSION 1,31,261,0
|
||||
PRODUCTVERSION 1,31,261,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.31.252.0"
|
||||
VALUE "FileVersion", "1.31.261.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.31.252.0"
|
||||
VALUE "ProductVersion", "1.31.261.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -189,6 +189,7 @@
|
|||
<ClCompile Include="Linker.cpp" />
|
||||
<ClCompile Include="MachineTypes.cpp" />
|
||||
<ClCompile Include="NativeCodeGenerator.cpp" />
|
||||
<ClCompile Include="NativeCodeOutliner.cpp" />
|
||||
<ClCompile Include="NumberSet.cpp" />
|
||||
<ClCompile Include="oscar64.cpp" />
|
||||
<ClCompile Include="Parser.cpp" />
|
||||
|
@ -218,6 +219,7 @@
|
|||
<ClInclude Include="Linker.h" />
|
||||
<ClInclude Include="MachineTypes.h" />
|
||||
<ClInclude Include="NativeCodeGenerator.h" />
|
||||
<ClInclude Include="NativeCodeOutliner.h" />
|
||||
<ClInclude Include="NumberSet.h" />
|
||||
<ClInclude Include="Parser.h" />
|
||||
<ClInclude Include="Preprocessor.h" />
|
||||
|
|
|
@ -87,6 +87,9 @@
|
|||
<ClCompile Include="Compression.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NativeCodeOutliner.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Array.h">
|
||||
|
@ -170,6 +173,9 @@
|
|||
<ClInclude Include="Compression.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NativeCodeOutliner.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="oscar64.rc">
|
||||
|
|
|
@ -220,12 +220,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_23B2892D4F99800BBD8DB9210ECF6B0F"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_24F2466589154E2DAA108C2EDB3BB432"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -286,12 +280,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_31D185B4E4448BB9122BE23BE0C259A8"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -412,6 +400,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4B482689C546CDFC92F367BA507E7ADE"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4B8FC526E6CC47FC8321D0191BFDBEDC"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -430,6 +424,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4E94486A43C1D1C032A05ED1E6F1FCEF"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4E9503F4F8F343739E4685C2066B3AD0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -454,12 +454,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_55D2A0DA296A07FFD056F9B0C3671317"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -484,6 +478,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_5C4D0F37C6784D198C3199B0610F60E5"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_6094F07357CC41E39D165B0A81E5AD4C"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -526,6 +526,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_65687B00DD49EEBBFFECE831614822A9"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_67C8F824E02B4211B315AB32AB7ABBB1"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -628,12 +634,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_7E4677138841AB7F15DEADCDE137C3A1"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -718,12 +718,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_8F9D1B22CCDDE3C1C2E92F178E8AD418"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_90171C7FE48D426E8664B043F5E75D6B"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -802,6 +796,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A1455504C259EDA9662CE90C07369CC5"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -826,6 +826,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A2F68033370E18CD792ECD1F91357C1B"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A32310DEFD4E41118CD7D36A8614C0D4"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -838,12 +844,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A3FC19061EE356D91CA54089DF69D2ED"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A566398810C1458E8E063A81FA88D46F"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -886,6 +886,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_AD3AED76152E705799261747B7FD2015"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_AE023AEA6C444140B19CD627DDC2CB87"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -952,12 +958,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_BB6C841EC4662FACDA8C15CBE509E50F"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_BBECB7DB41D84A34B2837C5E7EC7FAD4"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -982,6 +982,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_C0E88FBB7B883ED27FFB3C60DBE114B8"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_C239EFB1C3A646809AD2740ABDE747B0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -1078,7 +1084,13 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_CF200F5BD2D7FF90606D390FBF182D8D"
|
||||
"MsmKey" = "8:_D04F8D80984DFA3EA342FE8FA1B7CC91"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_D057B4CD935875ECE7F0A91620660D07"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
|
@ -1336,12 +1348,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_FA51546D227188A30196C2FBB877CF97"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -2131,26 +2137,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_23B2892D4F99800BBD8DB9210ECF6B0F"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_24F2466589154E2DAA108C2EDB3BB432"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\oscar.c"
|
||||
|
@ -2351,26 +2337,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_31D185B4E4448BB9122BE23BE0C259A8"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c"
|
||||
|
@ -2771,6 +2737,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4B482689C546CDFC92F367BA507E7ADE"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4B8FC526E6CC47FC8321D0191BFDBEDC"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\resources\\scifiglyph.bin"
|
||||
|
@ -2831,6 +2817,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E94486A43C1D1C032A05ED1E6F1FCEF"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E9503F4F8F343739E4685C2066B3AD0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\plus4\\ted.c"
|
||||
|
@ -2911,26 +2917,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_55D2A0DA296A07FFD056F9B0C3671317"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\sprites\\make.bat"
|
||||
|
@ -3011,6 +2997,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5C4D0F37C6784D198C3199B0610F60E5"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\memmap\\easyflashcall.cpp"
|
||||
"TargetName" = "8:easyflashcall.cpp"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_A62A71A6A08941C5964B90112D87731F"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6094F07357CC41E39D165B0A81E5AD4C"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\sprites\\joycontrol.c"
|
||||
|
@ -3151,6 +3157,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_65687B00DD49EEBBFFECE831614822A9"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_67C8F824E02B4211B315AB32AB7ABBB1"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\games\\breakout.c"
|
||||
|
@ -3491,26 +3517,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E4677138841AB7F15DEADCDE137C3A1"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\kernalio\\filewrite.c"
|
||||
|
@ -3791,26 +3797,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8F9D1B22CCDDE3C1C2E92F178E8AD418"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_90171C7FE48D426E8664B043F5E75D6B"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\c128\\mmu.c"
|
||||
|
@ -4071,6 +4057,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A1455504C259EDA9662CE90C07369CC5"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A14BC161099E420286E6A1595596D0F0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\opp\\ofstream.h"
|
||||
|
@ -4151,6 +4157,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A2F68033370E18CD792ECD1F91357C1B"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A32310DEFD4E41118CD7D36A8614C0D4"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\limits.h"
|
||||
|
@ -4191,26 +4217,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A3FC19061EE356D91CA54089DF69D2ED"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A566398810C1458E8E063A81FA88D46F"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\stddef.h"
|
||||
|
@ -4351,6 +4357,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AD3AED76152E705799261747B7FD2015"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AE023AEA6C444140B19CD627DDC2CB87"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\cx16\\vera.h"
|
||||
|
@ -4571,26 +4597,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BB6C841EC4662FACDA8C15CBE509E50F"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BBECB7DB41D84A34B2837C5E7EC7FAD4"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\hires\\make.bat"
|
||||
|
@ -4671,6 +4677,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C0E88FBB7B883ED27FFB3C60DBE114B8"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C239EFB1C3A646809AD2740ABDE747B0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\c64\\types.h"
|
||||
|
@ -4991,10 +5017,30 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CF200F5BD2D7FF90606D390FBF182D8D"
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D04F8D80984DFA3EA342FE8FA1B7CC91"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D057B4CD935875ECE7F0A91620660D07"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
|
@ -5851,26 +5897,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FA51546D227188A30196C2FBB877CF97"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FCF3696486DC430EA7BFACA8BE9731E7"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\ctype.c"
|
||||
|
@ -6284,15 +6310,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{FF988B8B-91E4-4D25-80EB-324160BC3146}"
|
||||
"PackageCode" = "8:{F8604441-6C5B-4EBA-91A3-157C75F673A8}"
|
||||
"ProductCode" = "8:{1B9A0E10-DEA6-4276-AC91-17782FE44D94}"
|
||||
"PackageCode" = "8:{51BFE576-50D1-4F8F-AE7A-9FF07396F53D}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.31.252"
|
||||
"ProductVersion" = "8:1.31.261"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
|
|
@ -29,7 +29,7 @@ const char MissileChars[] = {
|
|||
#define Charset ((char *)0xd800)
|
||||
|
||||
// Joystick and crosshair control
|
||||
int CrossX = 160, CrossY = 100;
|
||||
volatile int CrossX = 160, CrossY = 100;
|
||||
bool CrossP = false;
|
||||
char CrossDelay = 0;
|
||||
|
||||
|
@ -553,20 +553,22 @@ __interrupt void joy_interrupt()
|
|||
joy_poll(0);
|
||||
|
||||
// Move crosshair coordinates
|
||||
CrossX += 2 * joyx[0]; CrossY += 2 * joyy[0];
|
||||
int cx = CrossX + 2 * joyx[0], cy = CrossY + 2 * joyy[0];
|
||||
|
||||
// Stop at edges of screen
|
||||
if (CrossX < 8)
|
||||
CrossX = 8;
|
||||
else if (CrossX > 312)
|
||||
CrossX = 312;
|
||||
if (CrossY < 20)
|
||||
CrossY = 20;
|
||||
else if (CrossY > 172)
|
||||
CrossY = 172;
|
||||
if (cx < 8)
|
||||
cx = 8;
|
||||
else if (cx > 312)
|
||||
cx = 312;
|
||||
if (cy < 20)
|
||||
cy = 20;
|
||||
else if (cy > 172)
|
||||
cy = 172;
|
||||
|
||||
// Move crosshair sprite
|
||||
spr_move(0, CrossX + 14, CrossY + 40);
|
||||
spr_move(0, cx + 14, cy + 40);
|
||||
CrossX = cx;
|
||||
CrossY = cy;
|
||||
|
||||
// Check button
|
||||
if (joyb[0])
|
||||
|
@ -697,15 +699,17 @@ void game_play(void)
|
|||
// Check if fire request
|
||||
if (CrossP)
|
||||
{
|
||||
int cx = CrossX, cy = CrossY;
|
||||
|
||||
// Find launch site
|
||||
int sx = 160;
|
||||
if (CrossX < 120)
|
||||
if (cx < 120)
|
||||
sx = 24;
|
||||
else if (CrossX > 200)
|
||||
else if (cx > 200)
|
||||
sx = 296;
|
||||
|
||||
// Fire missile
|
||||
missile_start(sx, 184, CrossX, CrossY);
|
||||
missile_start(sx, 184, cx, cy);
|
||||
|
||||
// Reset request
|
||||
CrossP = false;
|
||||
|
|
|
@ -48,7 +48,7 @@ struct Point
|
|||
};
|
||||
|
||||
|
||||
Point tcorners[8], pcorners[8];
|
||||
__striped Point tcorners[8], pcorners[8];
|
||||
|
||||
void drawCube(void)
|
||||
{
|
||||
|
@ -77,6 +77,45 @@ void hideCube(void)
|
|||
}
|
||||
}
|
||||
|
||||
void xorCube(void)
|
||||
{
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
if (!(i & 1))
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 1].x, tcorners[i | 1].y, 0xff, LINOP_XOR);
|
||||
if (!(i & 2))
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 2].x, tcorners[i | 2].y, 0xff, LINOP_XOR);
|
||||
if (!(i & 4))
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 4].x, tcorners[i | 4].y, 0xff, LINOP_XOR);
|
||||
pcorners[i] = tcorners[i];
|
||||
}
|
||||
}
|
||||
|
||||
void xor2Cube(void)
|
||||
{
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
if (!(i & 1))
|
||||
{
|
||||
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 1].x, pcorners[i | 1].y, 0xff, LINOP_XOR);
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 1].x, tcorners[i | 1].y, 0xff, LINOP_XOR);
|
||||
}
|
||||
if (!(i & 2))
|
||||
{
|
||||
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 2].x, pcorners[i | 2].y, 0xff, LINOP_XOR);
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 2].x, tcorners[i | 2].y, 0xff, LINOP_XOR);
|
||||
}
|
||||
if (!(i & 4))
|
||||
{
|
||||
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 4].x, pcorners[i | 4].y, 0xff, LINOP_XOR);
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 4].x, tcorners[i | 4].y, 0xff, LINOP_XOR);
|
||||
}
|
||||
}
|
||||
|
||||
for(char i=0; i<8; i++)
|
||||
pcorners[i] = tcorners[i];
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
F12Vector3 corners[8];
|
||||
|
@ -112,8 +151,15 @@ int main(void)
|
|||
tcorners[i].y = lmuldiv16s(vd.v[1], 140, vd.v[2] + 4 * FIX12_ONE) + 100;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (k)
|
||||
xor2Cube();
|
||||
else
|
||||
xorCube();
|
||||
#else
|
||||
hideCube();
|
||||
drawCube();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ void init(void)
|
|||
// Install IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
cia_init();
|
||||
|
||||
// All RAM
|
||||
mmap_set(MMAP_RAM);
|
||||
|
||||
|
@ -60,7 +62,6 @@ void init(void)
|
|||
spr_move(1, 24, 50);
|
||||
|
||||
// Disable system interrupt and init mouse
|
||||
cia_init();
|
||||
mouse_init();
|
||||
|
||||
bm_init(&sbm, Hires, 40, 25);
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
../../bin/oscar64 easyflash.c -n -tf=crt
|
||||
../../bin/oscar64 easyflashreloc.c -n -tf=crt
|
||||
../../bin/oscar64 easyflashshared.c -n -tf=crt
|
||||
../../bin/oscar64 easyflashcall.cpp -n -tf=crt
|
||||
../../bin/oscar64 tsr.c -n -dNOFLOAT -dNOLONG
|
||||
../../bin/oscar64 overlay.c -n -d64=overlay.d64
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
#include <c64/memmap.h>
|
||||
#include <c64/charwin.h>
|
||||
#include <c64/cia.h>
|
||||
#include <c64/vic.h>
|
||||
#include <c64/easyflash.h>
|
||||
|
||||
// Shared code/data region, copied from easyflash bank 0 to ram during startup
|
||||
|
||||
#pragma region( main, 0x0900, 0x8000, , , { code, data, bss, heap, stack } )
|
||||
|
||||
// Section and region for first easyflash bank
|
||||
|
||||
#pragma section( bcode1, 0 )
|
||||
#pragma section( bdata1, 0 )
|
||||
#pragma region(bank1, 0x8000, 0xc000, , 1, { bcode1, bdata1 } )
|
||||
|
||||
// Section and region for second easyflash bank
|
||||
|
||||
#pragma section( bcode2, 0 )
|
||||
#pragma section( bdata2, 0 )
|
||||
#pragma region(bank2, 0x8000, 0xc000, , 2, { bcode2, bdata2 } )
|
||||
|
||||
#pragma section( bcode3, 0 )
|
||||
#pragma section( bdata3, 0 )
|
||||
#pragma region(bank3, 0x8000, 0xc000, , 3, { bcode3, bdata3 } )
|
||||
|
||||
#pragma section( bcode4, 0 )
|
||||
#pragma section( bdata4, 0 )
|
||||
#pragma region(bank4, 0x8000, 0xc000, , 4, { bcode4, bdata4 } )
|
||||
|
||||
#pragma section( bcode5, 0 )
|
||||
#pragma section( bdata5, 0 )
|
||||
#pragma region(bank5, 0x8000, 0xc000, , 5, { bcode5, bdata5 } )
|
||||
|
||||
#pragma section( bcode6, 0 )
|
||||
#pragma section( bdata6, 0 )
|
||||
#pragma region(bank6, 0x8000, 0xc000, , 6, { bcode6, bdata6 } )
|
||||
|
||||
// Charwin in shared memory section
|
||||
|
||||
CharWin cw;
|
||||
|
||||
// Now switch code generation to bank 1
|
||||
|
||||
#pragma code ( bcode1 )
|
||||
#pragma data ( bdata1 )
|
||||
|
||||
// Print into shared charwin
|
||||
|
||||
void print1_p(void)
|
||||
{
|
||||
cwin_put_string(&cw, p"This is first bank", 7);
|
||||
cwin_cursor_newline(&cw);
|
||||
}
|
||||
|
||||
// Now switch code generation to bank 2
|
||||
|
||||
#pragma code ( bcode2 )
|
||||
#pragma data ( bdata2 )
|
||||
|
||||
void print2_p(const char * p)
|
||||
{
|
||||
cwin_put_string(&cw, p"This is second bank:", 7);
|
||||
cwin_put_string(&cw, p, 1);
|
||||
cwin_cursor_newline(&cw);
|
||||
}
|
||||
|
||||
#pragma code ( bcode3 )
|
||||
#pragma data ( bdata3 )
|
||||
|
||||
void print3_p(void)
|
||||
{
|
||||
cwin_put_string(&cw, p"This is third bank", 7);
|
||||
cwin_cursor_newline(&cw);
|
||||
}
|
||||
|
||||
#pragma code ( bcode4 )
|
||||
#pragma data ( bdata4 )
|
||||
|
||||
void print4_p(int x, int y)
|
||||
{
|
||||
cwin_cursor_move(&cw, x, y);
|
||||
cwin_put_string(&cw, p"This is fourth bank", 7);
|
||||
cwin_cursor_newline(&cw);
|
||||
}
|
||||
|
||||
#pragma code ( bcode5 )
|
||||
#pragma data ( bdata5 )
|
||||
|
||||
void print5_p(void)
|
||||
{
|
||||
cwin_put_string(&cw, p"This is fifth bank", 7);
|
||||
cwin_cursor_newline(&cw);
|
||||
}
|
||||
|
||||
void print5a_p(void)
|
||||
{
|
||||
cwin_put_string(&cw, p"This is fifth bank second", 14);
|
||||
cwin_cursor_newline(&cw);
|
||||
}
|
||||
|
||||
// Switching code generation back to shared section
|
||||
|
||||
#pragma code ( code )
|
||||
#pragma data ( data )
|
||||
|
||||
|
||||
EF_CALL(print1);
|
||||
EF_CALL(print2);
|
||||
EF_CALL(print3);
|
||||
EF_CALL(print4);
|
||||
EF_CALL(print5);
|
||||
EF_CALL(print5a);
|
||||
|
||||
#pragma code ( bcode6 )
|
||||
#pragma data ( bdata6 )
|
||||
|
||||
void print6_p(void)
|
||||
{
|
||||
cwin_put_string(&cw, p"This is sixth bank", 7);
|
||||
cwin_cursor_newline(&cw);
|
||||
print5a();
|
||||
cwin_put_string(&cw, p"This is sixth bank again", 7);
|
||||
}
|
||||
|
||||
#pragma code ( code )
|
||||
#pragma data ( data )
|
||||
|
||||
EF_CALL(print6);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Enable ROM
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
// Init CIAs (no kernal rom was executed so far)
|
||||
cia_init();
|
||||
|
||||
// Init VIC
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1800);
|
||||
|
||||
// Prepare output window
|
||||
cwin_init(&cw, (char *)0x0400, 0, 0, 40, 25);
|
||||
cwin_clear(&cw);
|
||||
|
||||
print1();
|
||||
print2("hello");
|
||||
print3();
|
||||
print4(5, 8);
|
||||
print5();
|
||||
print6();
|
||||
|
||||
// Loop forever
|
||||
while (true)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -9,6 +9,7 @@ call ..\..\bin\oscar64 easyflash.c -n -tf=crt
|
|||
call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt
|
||||
call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt
|
||||
call ..\..\bin\oscar64 easyflashlow.c -n -tf=crt
|
||||
call ..\..\bin\oscar64 easyflashcall.cpp -n -tf=crt
|
||||
call ..\..\bin\oscar64 tsr.c -n -dNOFLOAT -dNOLONG
|
||||
call ..\..\bin\oscar64 overlay.c -n -d64=overlay.d64
|
||||
call ..\..\bin\oscar64 magicdesk.c -n -tf=crt8 -cid=19
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
call ..\..\bin\oscar64 -n fireworks_ptr.c
|
||||
call ..\..\bin\oscar64 -n fireworks_hires.c
|
||||
call ..\..\bin\oscar64 -n fireworks_stripe.c
|
||||
call ..\..\bin\oscar64 -n fireworks_stripe.c -O2
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ __interrupt void doscroll(void)
|
|||
vic.color_border++;
|
||||
|
||||
// Update raster IRQ for scroll line with new horizontal scroll offset
|
||||
rirq_data(&scroll, 0, 7 - (x & 7));
|
||||
rirq_data(&scroll, 1, 7 - (x & 7));
|
||||
// Copy scrolled version of text when switching over char border
|
||||
if ((x & 7) == 0)
|
||||
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
|
||||
|
@ -37,11 +37,13 @@ int main(void)
|
|||
rirq_init(true);
|
||||
|
||||
// Build switch to scroll line IRQ
|
||||
rirq_build(&scroll, 1);
|
||||
rirq_build(&scroll, 2);
|
||||
// Delay for one line to get to right border
|
||||
rirq_delay(&scroll, 11);
|
||||
// Change control register two with this IRQ
|
||||
rirq_write(&scroll, 0, &vic.ctrl2, 0);
|
||||
rirq_write(&scroll, 1, &vic.ctrl2, 0);
|
||||
// Put it onto the scroll line
|
||||
rirq_set(0, 50 + 24 * 8, &scroll);
|
||||
rirq_set(0, 49 + 24 * 8, &scroll);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&restore, 2);
|
||||
|
|
|
@ -20,11 +20,13 @@ int main(void)
|
|||
rirq_init(true);
|
||||
|
||||
// Build switch to scroll line IRQ
|
||||
rirq_build(&scroll, 1);
|
||||
rirq_build(&scroll, 2);
|
||||
// Delay for one line to get to right border
|
||||
rirq_delay(&scroll, 11);
|
||||
// Change control register two with this IRQ
|
||||
rirq_write(&scroll, 0, &vic.ctrl2, 0);
|
||||
rirq_write(&scroll, 1, &vic.ctrl2, 0);
|
||||
// Put it onto the scroll line
|
||||
rirq_set(0, 50 + 24 * 8, &scroll);
|
||||
rirq_set(0, 49 + 24 * 8, &scroll);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&bottom, 1);
|
||||
|
@ -46,7 +48,7 @@ int main(void)
|
|||
// wait for raster reaching bottom of screen
|
||||
rirq_wait();
|
||||
// Update raster IRQ for scroll line with new horizontal scroll offset
|
||||
rirq_data(&scroll, 0, 7 - (x & 7));
|
||||
rirq_data(&scroll, 1, 7 - (x & 7));
|
||||
// Copy scrolled version of text when switching over char border
|
||||
if ((x & 7) == 0)
|
||||
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
|
||||
|
|
|
@ -27,7 +27,7 @@ ScreenRow * const color = (ScreenRow *)0xd800;
|
|||
// Move the screen one character to the left
|
||||
void scrollLeft(void)
|
||||
{
|
||||
// Loop horizontaly
|
||||
// Loop horizontally
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
// Unroll vertical loop 16 times
|
||||
|
|
|
@ -64,6 +64,7 @@ const char * scrolltext[] = {
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
||||
|
||||
|
@ -198,7 +199,7 @@ int main(void)
|
|||
// Update interrupt position
|
||||
for(char i=0; i<5; i++)
|
||||
{
|
||||
int ty = 48 * i + 46 + oy;
|
||||
int ty = 48 * i + 45 + oy;
|
||||
|
||||
// No interrupts below screen bottom
|
||||
if (ty < 250)
|
||||
|
@ -246,7 +247,7 @@ int main(void)
|
|||
case 42:
|
||||
readline(line, lpos);
|
||||
lpos++;
|
||||
if (lpos == 28)
|
||||
if (lpos == 27)
|
||||
lpos = 0;
|
||||
break;
|
||||
case 45:
|
||||
|
|
Loading…
Reference in New Issue