Compare commits

..

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

245 changed files with 14397 additions and 83107 deletions

10
.gitignore vendored
View File

@ -343,14 +343,12 @@ make/oscar64
*.int *.int
*.bcs *.bcs
*.crt *.crt
**/*.d64 *.crt
*.d64
*.tlog *.tlog
*.res *.res
*.recipe *.recipe
*.exe *.exe
*.d64
*.d64
*.dbj *.dbj
*.json
*.mapd
*.idb
oscar64/Releasex64/oscar64.vcxproj.FileListAbsolute.txt
/oscar64/Debugx64

View File

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

1242
README.md

File diff suppressed because it is too large Load Diff

View File

@ -1,152 +0,0 @@
#include <assert.h>
int t, n, m, k;
struct C1
{
int a;
C1(void);
~C1(void);
C1(const C1 & c);
C1 & operator=(const C1 & c);
};
struct C2
{
C1 nc[10], mc[20];
};
C1::C1(void)
{
a = 1;
n++;
t++;
}
C1::C1(const C1 & c)
{
a = c.a;
k++;
t++;
}
C1 & C1::operator=(const C1 & c)
{
a = c.a;
m++;
return *this;
}
C1::~C1(void)
{
t--;
}
void test_local_init(void)
{
n = 0;
{
C1 c[10];
}
assert(n == 10 && t == 0);
}
void test_member_init(void)
{
n = 0;
{
C2 d;
}
assert(n == 30 && t == 0);
}
void test_member_array_init(void)
{
n = 0;
{
C2 d[5];
}
assert(n == 150 && t == 0);
}
void test_local_copy(void)
{
n = 0;
k = 0;
{
C1 c[10];
C1 d(c[4]);
}
assert(n == 10 && k == 1 && t == 0);
}
void test_member_copy(void)
{
n = 0;
k = 0;
{
C2 d;
C2 e(d);
}
assert(n == 30 && k == 30 && t == 0);
}
void test_local_assign(void)
{
n = 0;
k = 0;
m = 0;
{
C1 c[10];
C1 d[5];
d[4] = c[2];
}
assert(n == 15 && k == 0 && m == 1 && t == 0);
}
void test_member_assign(void)
{
n = 0;
k = 0;
m = 0;
{
C2 d;
C2 e;
e = d;
}
assert(n == 60 && k == 0 && m == 30 && t == 0);
}
int main(void)
{
test_local_init();
test_member_init();
test_member_array_init();
test_local_copy();
test_member_copy();
test_local_assign();
test_member_assign();
return 0;
}

View File

@ -16,7 +16,7 @@ int main(void)
put(j, j); put(j, j);
int s = -45; int s = -45;
for(int j=0; j<10; j++) for(int j=0; j<10; j++)
s += get(j); s += get[j];
return s; return s;
} }

View File

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

View File

@ -1,75 +1,6 @@
rem @echo off rem @echo off
@call :test rolrortest.cpp @call :test stdlibtest.c
@if %errorlevel% neq 0 goto :error
@call :test bitfields.cpp
@if %errorlevel% neq 0 goto :error
@call :testn autorefreturn.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_string.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_array.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_vector.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_static_vector.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_vector_string.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_string_init.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_streamtest.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_pairtest.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_parts.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_list.cpp
@if %errorlevel% neq 0 goto :error
@call :testn opp_functional.cpp
@if %errorlevel% neq 0 goto :error
@call :testh operatoroverload.cpp
@if %errorlevel% neq 0 goto :error
@call :testh virtualdestruct.cpp
@if %errorlevel% neq 0 goto :error
@call :testh vcalltest.cpp
@if %errorlevel% neq 0 goto :error
@call :testh vcalltree.cpp
@if %errorlevel% neq 0 goto :error
@call :testh constructortest.cpp
@if %errorlevel% neq 0 goto :error
@call :testn copyconstructor.cpp
@if %errorlevel% neq 0 goto :error
@call :testh copyassign.cpp
@if %errorlevel% neq 0 goto :error
@call :testh arrayconstruct.cpp
@if %errorlevel% neq 0 goto :error
@call :testh stdlibtest.c
@if %errorlevel% neq 0 goto :error
@call :test mathtest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test testint16.c @call :test testint16.c
@ -90,15 +21,9 @@ rem @echo off
@call :test recursiontest.c @call :test recursiontest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test copyinitmove.c
@if %errorlevel% neq 0 goto :error
@call :test fastcalltest.c @call :test fastcalltest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test strlen.c
@if %errorlevel% neq 0 goto :error
@call :test strcmptest.c @call :test strcmptest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -123,18 +48,12 @@ rem @echo off
@call :test floatmultest.c @call :test floatmultest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test floatinttest.c
@if %errorlevel% neq 0 goto :error
@call :test staticconsttest.c @call :test staticconsttest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test arrayinittest.c @call :test arrayinittest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test arrayindexintrangecheck.c
@if %errorlevel% neq 0 goto :error
@call :test array2stringinittest.c @call :test array2stringinittest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -165,9 +84,6 @@ rem @echo off
@call :test qsorttest.c @call :test qsorttest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testn plasma.c
@if %errorlevel% neq 0 goto :error
@call :test loopdomtest.c @call :test loopdomtest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -195,12 +111,6 @@ rem @echo off
@call :test divmodtest.c @call :test divmodtest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test divmod32test.c
@if %errorlevel% neq 0 goto :error
@call :test fixmathtest.c
@if %errorlevel% neq 0 goto :error
@call :test enumswitch.c @call :test enumswitch.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -252,149 +162,77 @@ rem @echo off
@call :testn stripedarraytest.c @call :testn stripedarraytest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testn mmultest.c
@if %errorlevel% neq 0 goto :error
@call :test tileexpand.cpp
@if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0
:error :error
echo Failed with error #%errorlevel%. echo Failed with error #%errorlevel%.
exit /b %errorlevel% exit /b %errorlevel%
:testh
..\bin\oscar64 -e -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error
..\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
..\bin\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -bc %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n -dHEAPCHECK %~1
@if %errorlevel% neq 0 goto :error
@exit /b 0
:test :test
..\bin\oscar64 -e -bc %~1 ..\release\oscar64 -e %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -n %~1 ..\release\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -bc %~1 ..\release\oscar64 -e -O2 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -n %~1 ..\release\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -bc %~1 ..\release\oscar64 -e -O0 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -n %~1 ..\release\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -bc %~1 ..\release\oscar64 -e -Os %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -n %~1 ..\release\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -bc %~1 ..\release\oscar64 -e -O3 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n %~1 ..\release\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\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 @if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0
:testb :testb
..\bin\oscar64 -e -bc %~1 ..\release\oscar64 -e %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -O2 %~1 ..\release\oscar64 -e -O2 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -O0 %~1 ..\release\oscar64 -e -O0 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -Os %~1 ..\release\oscar64 -e -Os %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -bc -O3 %~1 ..\release\oscar64 -e -O3 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0
:testn :testn
..\bin\oscar64 -e -n %~1 ..\release\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -n %~1 ..\release\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O0 -n %~1 ..\release\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -Os -n %~1 ..\release\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O3 -n %~1 ..\release\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\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 @if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0

View File

@ -1,354 +0,0 @@
#include <assert.h>
struct A
{
char x : 4;
char y : 1;
char z : 3;
};
A a = {7, 1, 2};
void test_char_fit(void)
{
assert(a.x == 7);
assert(a.y == 1);
assert(a.z == 2);
assert(sizeof(A) == 1);
for(int i=0; i<16; i++)
{
a.x = i;
a.y = 0;
a.z = 3;
assert(a.x == i);
assert(a.y == 0);
assert(a.z == 3);
}
}
struct B
{
char x : 6;
char y : 6;
char z : 6;
char w : 6;
};
B b = {11, 22, 33, 44};
void test_char_cross(void)
{
assert(b.x == 11);
assert(b.y == 22);
assert(b.z == 33);
assert(b.w == 44);
assert(sizeof(B) == 3);
for(int i=0; i<64; i++)
{
b.x = i * 1;
b.y = i * 3;
b.z = i * 5;
b.w = i * 7;
assert(b.x == ((i * 1) & 0x3f));
assert(b.y == ((i * 3) & 0x3f));
assert(b.z == ((i * 5) & 0x3f));
assert(b.w == ((i * 7) & 0x3f));
}
}
struct C
{
unsigned x : 4;
unsigned y : 1;
unsigned z : 3;
};
C c = {7, 1, 2};
void test_word_fit(void)
{
assert(c.x == 7);
assert(c.y == 1);
assert(c.z == 2);
assert(sizeof(C) == 1);
for(int i=0; i<16; i++)
{
c.x = i;
c.y = 0;
c.z = 3;
assert(c.x == i);
assert(c.y == 0);
assert(c.z == 3);
}
}
struct D
{
unsigned x : 10;
unsigned y : 10;
unsigned z : 10;
unsigned w : 10;
};
D d = {111, 222, 333, 444};
void test_word_cross(void)
{
assert(d.x == 111);
assert(d.y == 222);
assert(d.z == 333);
assert(d.w == 444);
assert(sizeof(D) == 5);
for(int i=0; i<1024; i++)
{
d.x = i * 1;
d.y = i * 3;
d.z = i * 5;
d.w = i * 7;
assert(d.x == ((i * 1) & 0x3ff));
assert(d.y == ((i * 3) & 0x3ff));
assert(d.z == ((i * 5) & 0x3ff));
assert(d.w == ((i * 7) & 0x3ff));
}
}
struct E
{
unsigned long x : 4;
unsigned long y : 1;
unsigned long z : 3;
};
E e = {7, 1, 2};
void test_dword_fit(void)
{
assert(e.x == 7);
assert(e.y == 1);
assert(e.z == 2);
assert(sizeof(E) == 1);
for(int i=0; i<16; i++)
{
e.x = i;
e.y = 0;
e.z = 3;
assert(e.x == i);
assert(e.y == 0);
assert(e.z == 3);
}
}
struct F
{
unsigned long x : 20;
unsigned long y : 20;
unsigned long z : 20;
unsigned long w : 20;
};
F f = {111111UL, 222222UL, 333333UL, 444444UL};
void test_dword_cross(void)
{
assert(f.x == 111111UL);
assert(f.y == 222222UL);
assert(f.z == 333333UL);
assert(f.w == 444444UL);
assert(sizeof(F) == 10);
for(int i=0; i<1024; i++)
{
f.x = i * 11UL;
f.y = i * 33UL;
f.z = i * 55UL;
f.w = i * 77UL;
assert(f.x == ((i * 11UL) & 0xfffffUL));
assert(f.y == ((i * 33UL) & 0xfffffUL));
assert(f.z == ((i * 55UL) & 0xfffffUL));
assert(f.w == ((i * 77UL) & 0xfffffUL));
}
}
struct G
{
signed char x : 1;
signed char y : 5;
signed char z : 2;
};
G g = {0, -1, -2};
void test_char_signed(void)
{
assert(g.x == 0);
assert(g.y == -1);
assert(g.z == -2);
assert(sizeof(G) == 1);
for(int i=-16; i<16; i++)
{
g.x = -1;
g.y = i;
g.z = 1;
assert(g.x == -1);
assert(g.y == i);
assert(g.z == 1);
}
}
struct H
{
int x : 10;
int y : 10;
int z : 10;
int w : 10;
};
H h = {111, -222, -333, 444};
void test_word_signed(void)
{
assert(h.x == 111);
assert(h.y == -222);
assert(h.z == -333);
assert(h.w == 444);
assert(sizeof(H) == 5);
for(int i=-32; i<32; i++)
{
h.x = i * 1;
h.y = i * 3;
h.z = i * 5;
h.w = i * 7;
assert(h.x == i * 1);
assert(h.y == i * 3);
assert(h.z == i * 5);
assert(h.w == i * 7);
}
}
void test_inc_char_fit(void)
{
A ai;
ai.x = 7;
ai.y = 1;
ai.z = 2;
for(int i=0; i<16; i++)
{
assert(ai.x == ((7 + i) & 15));
assert(ai.y == ((1 + i) & 1));
assert(ai.z == ((2 + i) & 7));
ai.x++;
ai.y++;
ai.z++;
}
}
void test_inc_char_cross(void)
{
B bi;
bi.x = 11;
bi.y = 22;
bi.z = 33;
bi.w = 44;
for(int i=0; i<64; i++)
{
assert(bi.x == ((11 + i) & 0x3f));
assert(bi.y == ((22 + i) & 0x3f));
assert(bi.z == ((33 + i) & 0x3f));
assert(bi.w == ((44 + i) & 0x3f));
bi.x++;
bi.y++;
bi.z++;
bi.w++;
}
}
void test_add_char_cross(void)
{
B bi= {0};
bi.x = 11;
bi.y = 22;
bi.z = 33;
bi.w = 44;
for(int i=0; i<64; i++)
{
assert(bi.x == ((11 + 5 * i) & 0x3f));
assert(bi.y == ((22 + 21 * i) & 0x3f));
assert(bi.z == ((33 - 4 * i) & 0x3f));
assert(bi.w == ((44 - 11 * i) & 0x3f));
bi.x += 5;
bi.y += 21;
bi.z -= 4;
bi.w -= 11;
}
}
void test_add_word_fit(void)
{
C ci = {0};
ci.x = 7;
ci.y = 1;
ci.z = 2;
for(int i=0; i<16; i++)
{
assert(ci.x == ((7 + 5 * i) & 15));
assert(ci.y == ((1 + 21 * i) & 1));
assert(ci.z == ((2 - 4 * i) & 7));
ci.x += 5;
ci.y += 21;
ci.z -= 4;
}
}
void test_add_word_cross(void)
{
D di = {0};
di.x = 111;
di.y = 222;
di.z = 333;
di.w = 444;
for(int i=0; i<1024; i++)
{
assert(di.x == ((111 + 5 * i) & 0x3ff));
assert(di.y == ((222 + 21 * i) & 0x3ff));
assert(di.z == ((333 - 4 * i) & 0x3ff));
assert(di.w == ((444 - 11 * i) & 0x3ff));
di.x += 5;
di.y += 21;
di.z -= 4;
di.w -= 11;
}
}
int main(void)
{
test_char_fit();
test_char_cross();
test_word_fit();
test_word_cross();
test_dword_fit();
test_dword_cross();
test_char_signed();
test_word_signed();
test_inc_char_fit();
test_inc_char_cross();
test_add_char_cross();
test_add_word_fit();
test_add_word_cross();
return 0;
}

View File

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

View File

@ -1,165 +0,0 @@
#include <assert.h>
int t, n;
struct C1
{
int a;
C1(int x);
~C1(void);
};
C1::C1(int x) : a(x)
{
t += a;
n++;
}
C1::~C1(void)
{
t -= a;
}
void test_base(void)
{
n = 0;
{
C1 x(2);
C1 y(1);
}
assert(t == 0 && n == 2);
}
void test_base_loop(void)
{
n = 0;
for(int i=0; i<10; i++)
{
C1 x(2);
C1 y(1);
}
assert(t == 0 && n == 20);
}
struct C2
{
C1 c, d;
C2(void);
};
C2::C2(void)
: c(7), d(11)
{
}
void test_member(void)
{
n = 0;
{
C2 x();
C2 y();
}
assert(t == 0 && n == 4);
}
void test_member_loop(void)
{
n = 0;
for(int i=0; i<10; i++)
{
C2 x();
C2 y();
}
assert(t == 0 && n == 40);
}
struct C3
{
C2 x, y;
};
void test_default(void)
{
n = 0;
{
C3 x();
C3 y();
}
assert(t == 0 && n == 8);
}
void test_default_loop(void)
{
n = 0;
for(int i=0; i<10; i++)
{
C3 x();
C3 y();
}
assert(t == 0 && n == 80);
}
inline void test_inline_x(void)
{
C1 x(1), y(2);
}
void test_inline(void)
{
n = 0;
test_inline_x();
assert(t == 0 && n == 2);
}
inline void test_inline_xr(void)
{
C1 x(1), y(2);
{
C1 x(3);
return;
}
}
void test_inline_return(void)
{
n = 0;
test_inline_xr();
assert(t == 0 && n == 3);
}
int main(void)
{
test_base();
test_base_loop();
test_member();
test_member_loop();
test_default();
test_default_loop();
test_inline();
test_inline_return();
return 0;
}

View File

@ -1,126 +0,0 @@
#include <assert.h>
int t, n;
struct C0
{
int u;
C0(int a);
~C0(void);
};
C0::C0(int a) : u(a)
{
t += u;
n++;
}
C0::~C0(void)
{
t -= u;
}
struct C1
{
int u;
C1(int a);
~C1(void);
C1(const C1 & c);
C1 & operator=(const C1 & c);
};
C1::C1(int a) : u(a)
{
t += u;
n++;
}
C1::~C1(void)
{
t -= u;
}
C1::C1(const C1 & c) : u(c.u)
{
t += u;
n++;
}
C1 & C1::operator=(const C1 & c)
{
t -= u;
u = c.u;
t += u;
return *this;
}
void test_assign(void)
{
n = 0;
{
C1 c(4);
C1 d(5);
c = d;
}
assert(n == 2 && t == 0);
}
struct C2
{
C1 a, b;
C2(int x, int y) : a(x), b(y)
{}
};
void test_assign_deflt(void)
{
n = 0;
{
C2 c(2, 3);
C2 d(5, 10);
c = d;
}
assert(n == 4 && t == 0);
}
int k;
C2 test_ret_v(void)
{
C2 c(5, 10);
return c;
}
C2 & test_ret_r(C2 & r)
{
return r;
}
void test_assign_return_value(void)
{
n = 0;
{
C2 c(2, 3);
c = test_ret_v();
}
assert(n == 6 && t == 0);
}
int main(void)
{
test_assign();
test_assign_deflt();
test_assign_return_value();
return 0;
}

View File

@ -1,215 +0,0 @@
#include <assert.h>
#include <stdio.h>
int t, n;
struct C0
{
int u;
C0(int a);
~C0(void);
};
C0::C0(int a) : u(a)
{
t += u;
n++;
}
C0::~C0(void)
{
t -= u;
}
struct C1
{
int u;
C1(int a);
~C1(void);
C1(const C1 & c);
};
C1::C1(int a) : u(a)
{
t += u;
n++;
}
C1::~C1(void)
{
t -= u;
}
C1::C1(const C1 & c) : u(c.u)
{
t += u;
n++;
}
void test_dcopy_init(void)
{
n = 0;
{
C0 x(4);
C0 y(x);
}
assert(n == 1 && t == -4);
t = 0;
}
void test_copy_init(void)
{
n = 0;
{
C1 x(4);
C1 y(x);
}
assert(n == 2 && t == 0);
}
struct C2
{
C1 a, b;
C2(void);
};
C2::C2(void) : a(1), b(3)
{}
void test_minit(void)
{
n = 0;
{
C2 x;
}
assert(n == 2 && t == 0);
}
void test_minit_copy(void)
{
n = 0;
{
C2 x;
C2 y(x);
}
assert(n == 4 && t == 0);
}
int k;
void test_param_fv(C2 c)
{
k += c.a.u;
}
void test_param_fr(C2 & c)
{
k += c.a.u;
}
void test_param_value(void)
{
n = 0;
{
C2 x;
test_param_fv(x);
}
assert(n == 4 && t == 0);
}
void test_param_ref(void)
{
n = 0;
{
C2 x;
test_param_fr(x);
}
assert(n == 2 && t == 0);
}
C2 test_ret_v(void)
{
C2 c;
return c;
}
C2 & test_ret_r(C2 & r)
{
return r;
}
void test_return_value(void)
{
n = 0;
{
C2 c(test_ret_v());
}
assert(n == 6 && t == 0);
}
void test_return_reference(void)
{
n = 0;
{
C2 d;
C2 c(test_ret_r(d));
}
assert(n == 2 && t == 0);
}
void test_retparam_value(void)
{
n = 0;
{
test_param_fv(test_ret_v());
}
assert(n == 6 && t == 0);
}
void test_retparam_reference(void)
{
n = 0;
{
test_param_fr(test_ret_v());
}
assert(n == 4 && t == 0);
}
int main(void)
{
test_dcopy_init();
test_copy_init();
test_minit();
test_minit_copy();
test_param_value();
test_param_ref();
test_return_value();
test_retparam_value();
test_retparam_reference();
return 0;
}

View File

@ -1,27 +0,0 @@
int val(char * c)
{
return c[0];
}
void set(char * c, int a)
{
c[0] = a;
}
int main(void)
{
int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
for(int i=0; i<10; i++)
{
char t[10] = {1};
sum0 += val(t);
sum2 += t[0];
set(t, i);
sum1 += val(t);
sum3 += t[0];
}
return (sum1 - 45) | (sum0 - 10) | (sum3 - 45) | (sum2 - 10);
}

View File

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

View File

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

View File

@ -65,7 +65,7 @@ int main(void)
cmpflt( 1.0, 0.0, false, false, true); cmpflt( 1.0, 0.0, false, false, true);
cmpflt(-1.0, 0.0, false, true, false); cmpflt(-1.0, 0.0, false, true, false);
#if 1
cmpflt( 1.0, 1.0, true, false, false); cmpflt( 1.0, 1.0, true, false, false);
cmpflt( 1.0, 2.0, false, true, false); cmpflt( 1.0, 2.0, false, true, false);
cmpflt( 2.0, 1.0, false, false, true); cmpflt( 2.0, 1.0, false, false, true);
@ -94,6 +94,7 @@ int main(void)
cmpflt( -1.0, -1.000001, false, false, true); cmpflt( -1.0, -1.000001, false, false, true);
cmpflt( -1.000001, -1.0, false, true, false); cmpflt( -1.000001, -1.0, false, true, false);
cmpflt( -1.000001, -1.000001, true, false, false); cmpflt( -1.000001, -1.000001, true, false, false);
#endif
return 0; return 0;
} }

View File

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

View File

@ -15,7 +15,7 @@ int main(void)
ftoa(x, xb); float xr = atof(xb); ftoa(x, xb); float xr = atof(xb);
ftoa(y, yb); float yr = atof(yb); ftoa(y, yb); float yr = atof(yb);
printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, yr, fabs(x - xr) / x, fabs(y - yr) / y); printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, y, fabs(x - xr) / x, fabs(y - yr) / y);
if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001) if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001)
return -1; return -1;

View File

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

View File

@ -1,43 +0,0 @@
#include <gfx/vector3d.h>
#include <assert.h>
#include <stdio.h>
Matrix4 ml, mr;
int main(void)
{
for(char i=0; i<16; i++)
{
for(char j=0; j<16; j++)
{
for(char k=0; k<16; k++)
{
ml.m[k] = (i == k) ? 1.0 : 0.0;
mr.m[k] = (j == k) ? 1.0 : 0.0;
}
mat4_mmul(&ml, &mr);
#if 0
printf("%d, %d\n", i, j);
for(char k=0; k<16; k++)
printf("%f ", ml.m[k]);
printf("\n");
#endif
for(char k=0; k<16; k++)
{
char ix = i & 3, iy = i >> 2;
char jx = j & 3, jy = j >> 2;
char kx = k & 3, ky = k >> 2;
if (ky == jy && kx == ix && jx == iy)
assert(ml.m[k] == 1.0);
else
assert(ml.m[k] == 0.0);
}
}
}
return 0;
}

View File

@ -1,90 +0,0 @@
#include <assert.h>
struct A
{
int n;
A(int n_)
: n(n_) {}
A(const A & a)
: n(a.n) {}
A operator+(const A & a) const
{
return A(n + a.n);
}
A operator-(const A & a) const
{
return A(n - a.n);
}
A & operator+=(const A & a)
{
n += a.n;
return *this;
}
A & operator-=(const A & a)
{
n -= a.n;
return *this;
}
A operator-(void) const
{
return A(-n);
}
A & operator++(void)
{
n++;
return *this;
}
A & operator--(void)
{
n--;
return *this;
}
A operator++(int);
A operator--(int);
};
A A::operator++(int)
{
A a(*this);
n++;
return a;
}
A A::operator--(int)
{
A a(*this);
n--;
return a;
}
int main(void)
{
A a(7), b(8), c(9);
assert((++a).n == 8);
assert(a.n == 8);
assert((--a).n == 7);
assert(a.n == 7);
assert((a++).n == 7);
assert(a.n == 8);
assert((a--).n == 8);
assert(a.n == 7);
assert((a + b - c + -a + -b - -c).n == 0);
return 0;
}

View File

@ -1,23 +0,0 @@
#include <opp/array.h>
#include <assert.h>
int main(void)
{
opp::array<int, 10> a10;
opp::array<int, 20> a20;
for(int i=0; i<10; i++)
a10[i] = i;
for(int i=0; i<20; i++)
a20[i] = i;
int s = 0;
for(int i=0; i<10; i++)
s += a10[i];
for(int i=10; i<20; i++)
s -= a20[i];
assert(s == -100);
return 0;
}

View File

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

View File

@ -1,57 +0,0 @@
#include <opp/list.h>
#include <opp/algorithm.h>
#include <assert.h>
#include <opp/iostream.h>
int main(void)
{
opp::list<int> a;
for(int i=0; i<10; i++)
a.push_back(i);
int s = 0;
for(auto i : a)
s += i;
assert(s == 45);
auto li = a.begin();
for(int i=0; i<5; i++)
{
li = a.erase(li);
li++;
}
s = 0;
for(auto i : a)
s += i;
assert(s == 1 + 3 + 5 + 7 + 9);
opp::list<int> b;
b = a;
s = 0;
for(auto i : b)
s += i;
assert(s == 1 + 3 + 5 + 7 + 9);
opp::list<int> c = opp::list<int>(b);
s = 0;
for(auto i : c)
s += i;
assert(s == 1 + 3 + 5 + 7 + 9);
s = 0;
for(auto i : b)
s += i;
assert(s == 1 + 3 + 5 + 7 + 9);
return 0;
}

View File

@ -1,28 +0,0 @@
#include <assert.h>
#include <opp/vector.h>
#include <opp/utility.h>
#include <opp/iostream.h>
using namespace opp;
int main(void)
{
vector<pair<int, int> > vii;
for(int i=0; i<100; i++)
vii.push_back(make_pair(i, i * i));
int sum1 = 0;
long sum2 = 0;
for(const auto & v : vii)
{
sum1 += v.first;
sum2 += v.second;
}
assert(sum1 == 4950);
assert(sum2 == 328350l);
return 0;
}

View File

@ -1,2 +0,0 @@
#include "opp_part1.h"

View File

@ -1,40 +0,0 @@
#pragma once
#include <opp/vector.h>
class A
{
protected:
int a, b;
public:
A(int a_, int b_)
: a(a_), b(b_)
{}
int sum(void) const
{
return a * b;
}
};
class AS
{
protected:
opp::vector<A> va;
public:
AS(const opp::vector<A> & v)
: va(v)
{}
int sum(void)
{
int s = 0;
for(const auto & a : va)
s += a.sum();
return s;
}
};
#pragma compile("opp_part1.cpp")

View File

@ -1,13 +0,0 @@
#include "opp_part2.h"
BS::BS(const opp::vector<A> & v)
: va(v)
{}
int BS::sum(void)
{
int s = 0;
for(const auto & a : va)
s += a.sum();
return s;
}

View File

@ -1,16 +0,0 @@
#pragma once
#include "opp_part1.h"
class BS
{
protected:
opp::vector<A> va;
public:
BS(const opp::vector<A> & v);
int sum(void);
};
#pragma compile("opp_part2.cpp")

View File

@ -1,25 +0,0 @@
#include <assert.h>
#include "opp_part1.h"
#include "opp_part2.h"
int main(void)
{
opp::vector<A> va;
va.push_back(A(1, 2));
va.push_back(A(3, 4));
va.push_back(A(6, 4));
va.push_back(A(0, 9));
AS as(va);
va.push_back(A(7, 1));
BS bs(va);
assert(bs.sum() == 2 + 12 + 24 + 7);
assert(as.sum() == 2 + 12 + 24);
return 0;
}

View File

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

View File

@ -1,83 +0,0 @@
#include <opp/string.h>
#include <stdlib.h>
#include <assert.h>
#include <opp/sstream.h>
#include <math.h>
using opp::ostringstream;
using opp::istringstream;
using opp::endl;
float fdist(float a, float b)
{
float d = fabs(a - b);
a = fabs(a);
b = fabs(b);
return d / (a > b ? a : b);
}
int main(void)
{
ostringstream os;
for(int i=0; i<40; i++)
{
os << i << endl;
}
istringstream is(os.str());
int j = 0, k = 47;
#if 1
while (is >> k)
{
assert(k == j++);
}
assert(j == 40);
#endif
os.str(opp::string());
#if 0
cout << "[" << os.str() << "]" << endl;
os << "HELLO";
cout << "[" << os.str() << "]" << endl;
#endif
#if 1
float f = 1.0, g = 1.0;
for(int i=0; i<10; i++)
{
os << f << " " << g << endl;
// cout << os.str();
f *= 5.1;
g *= 0.12;
}
is.str(os.str());
f = 1.0, g = 1.0;
float fr, gr;
j = 0;
while (is >> fr >> gr)
{
// cout << f << " " << fr << ", " << g << " " << gr << ", " << fdist(fr, f) << endl;
assert(fdist(fr, f) < 1.0e-5);
assert(fdist(gr, g) < 1.0e-5);
f *= 5.1;
g *= 0.12;
j++;
}
assert(j == 10);
#endif
return 0;
}

View File

@ -1,103 +0,0 @@
#include <opp/string.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
using opp::string;
static const char HelloWorld[] = "Hello World";
static const char AndBeyond[] = "And Beyond";
static const char And[] = "And";
static const char HelloWorldAndBeyond[] = "Hello World And Beyond";
__noinline void test_create(void)
{
string s1();
string s2(HelloWorld);
string s3(s2);
string s4('a');
assert(!strcmp(s2.tocstr(), HelloWorld));
assert(!strcmp(s3.tocstr(), HelloWorld));
assert(s4.size() == 1 && s4[0] == 'a');
}
__noinline void test_concat(void)
{
string s1();
string s2(HelloWorld);
string s3(AndBeyond);
string s4 = s1 + s2;
string s5 = s2 + " " + s3;
string s6 = s2 + " " + AndBeyond;
assert(!strcmp(s4.tocstr(), HelloWorld));
assert(!strcmp(s5.tocstr(), HelloWorldAndBeyond));
assert(!strcmp(s6.tocstr(), HelloWorldAndBeyond));
}
__noinline void test_find(void)
{
string s1(HelloWorldAndBeyond);
string s2(And);
assert(s1.find(HelloWorld) == 0);
assert(s1.find(AndBeyond) == 12);
assert(s1.find(And) == 12);
assert(s1.find(s2) == 12);
assert(s1.find(' ') == 5);
assert(s1.find(' ', 6) == 11);
}
__noinline void test_assign(void)
{
string s1(HelloWorld);
string s2(AndBeyond);
string s3;
s3 = s1;
s3 = s2;
s3 = s1;
s3 += " ";
s3 += s2;
assert(!strcmp(s3.tocstr(), HelloWorldAndBeyond));
s3 <<= 12;
assert(!strcmp(s3.tocstr(), AndBeyond));
s3 = HelloWorldAndBeyond;
assert(!strcmp(s3.tocstr(), HelloWorldAndBeyond));
s3 >>= 11;
assert(!strcmp(s3.tocstr(), HelloWorld));
}
static char * test;
int main(void)
{
test = new char;
unsigned avail = heapfree();
test_create();
assert(avail == heapfree());
test_concat();
assert(avail == heapfree());
test_find();
assert(avail == heapfree());
test_assign();
assert(avail == heapfree());
delete test;
return 0;
}

View File

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

View File

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

View File

@ -1,38 +0,0 @@
#include <opp/vector.h>
#include <opp/string.h>
#include <assert.h>
#include <stdlib.h>
#include <opp/iostream.h>
using opp::string;
using opp::vector;
string join(const vector<string> & vs)
{
string sj;
for(int i=0; i<vs.size(); i++)
sj += vs[i];
return sj;
}
int main(void)
{
vector<string> vs;
string a;
for(int i=0; i<10; i++)
{
vs.push_back(a);
a += "x";
}
int s = 0;
for(int i=0; i<10; i++)
s += vs[i].size();
assert(s == 45);
assert(join(vs).size() == 45);
return 0;
}

View File

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

View File

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

View File

@ -51,15 +51,16 @@ void heapcheck(void)
for(i=0; i<s; i++) for(i=0; i<s; i++)
{ {
if (p[i] != n) if (p[i] != n)
{
printf("MemError %d at %d:%d != %d\n", k, i, n, p[i]);
exit(-2); exit(-2);
}
} }
free(memp[n]); free(memp[n]);
s = rand() % 100 + 3; s = rand() % 100 + 3;
mems[n] = s; mems[n] = s;
memp[n] = malloc(s); memp[n] = malloc(s);
if (!memp[n])
exit(-3);
memset(memp[n], n, s); memset(memp[n], n, s);
} }
} }

View File

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

View File

@ -5,11 +5,6 @@ void testmuli(long a, long b, long ab)
assert (a * b == ab); assert (a * b == ab);
} }
void testmulu(unsigned long a, unsigned long b, unsigned long ab)
{
assert (a * b == ab);
}
void testdivi(long a, long b, long ab) void testdivi(long a, long b, long ab)
{ {
assert (a / b == ab); assert (a / b == ab);
@ -59,6 +54,7 @@ long sieve(long size)
int main(void) int main(void)
{ {
testmuli(0, 0, 0); testmuli(0, 0, 0);
testmuli(1, 0, 0); testmuli(1, 0, 0);
testmuli(0, 1, 0); testmuli(0, 1, 0);
@ -85,26 +81,6 @@ int main(void)
testmuli( -1024, 1237, -1266688l); testmuli( -1024, 1237, -1266688l);
testmuli( -1024,-1237, 1266688l); testmuli( -1024,-1237, 1266688l);
testmulu(0x00000001, 0x0000003c, 0x0000003c);
testmulu(0x00000100, 0x0000003c, 0x00003c00);
testmulu(0x00010000, 0x0000003c, 0x003c0000);
testmulu(0x01000000, 0x0000003c, 0x3c000000);
testmulu(0x0000003c, 0x00000001, 0x0000003c);
testmulu(0x0000003c, 0x00000100, 0x00003c00);
testmulu(0x0000003c, 0x00010000, 0x003c0000);
testmulu(0x0000003c, 0x01000000, 0x3c000000);
testmulu(0x0000004b, 0x0000003c, 0x00001194);
testmulu(0x00004b00, 0x0000003c, 0x00119400);
testmulu(0x004b0000, 0x0000003c, 0x11940000);
testmulu(0x4b000000, 0x0000003c, 0x94000000);
testmulu(0x0000003c, 0x0000004b, 0x00001194);
testmulu(0x0000003c, 0x00004b00, 0x00119400);
testmulu(0x0000003c, 0x004b0000, 0x11940000);
testmulu(0x0000003c, 0x4b000000, 0x94000000);
testdivi( 1, 1, 1); testdivi( 1, 1, 1);
testdivi(-1, 1, -1); testdivi(-1, 1, -1);
testdivi( 1, -1, -1); testdivi( 1, -1, -1);
@ -135,6 +111,7 @@ int main(void)
assert(sieve(200) == 47); assert(sieve(200) == 47);
assert(sieve(1000) == 169); assert(sieve(1000) == 169);
long a = 0, b = 0; long a = 0, b = 0;
for(long i=0; i<10000; i++) for(long i=0; i<10000; i++)
{ {

View File

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

View File

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

View File

@ -1,93 +0,0 @@
#include <assert.h>
struct A
{
virtual int f(int x);
};
struct B : A
{
virtual int f(int x);
};
struct C : A
{
virtual int f(int x);
virtual int g(int y, int z);
};
struct D : B
{
virtual int f(int x);
};
struct E : C
{
virtual int f(int x);
virtual int g(int y, int z);
};
struct F : C
{
virtual int g(int y, int z);
};
int A::f(int x)
{
return x * 1;
}
int B::f(int x)
{
return x * 2;
}
int C::f(int x)
{
return x * 3;
}
int C::g(int y, int z)
{
return (y + z) * 3;
}
int D::f(int x)
{
return x * 4;
}
int E::f(int x)
{
return x * 5;
}
int E::g(int y, int z)
{
return (y + z) * 5;
}
int F::g(int y, int z)
{
return (y + z) * 6;
}
int main(void)
{
A a;
B b;
C c;
D d;
E e;
F f;
assert(a.f(3) == c.f(1));
assert(b.f(4) == d.f(2));
assert(e.f(2) == b.f(5));
assert(f.f(5) == e.f(3));
assert(c.g(3, 2) == e.g(1, 2));
assert(c.g(1, 5) == f.g(0, 3));
return 0;
}

View File

@ -1,79 +0,0 @@
#include <assert.h>
struct Node
{
virtual float eval(void)
{
return 1.0e6;
}
};
struct ConstNode : Node
{
float c;
ConstNode(float c_)
: c(c_) {}
virtual float eval(void)
{
return c;
}
};
struct BinopNode : Node
{
Node * left, * right;
BinopNode(Node * left_, Node * right_)
: left(left_), right(right_)
{}
};
struct AddNode : BinopNode
{
AddNode(Node * left_, Node * right_)
: BinopNode(left_, right_)
{}
virtual float eval(void)
{
return left->eval() + right->eval();
}
};
struct SubNode : BinopNode
{
SubNode(Node * left_, Node * right_)
: BinopNode(left_, right_)
{}
virtual float eval(void)
{
return left->eval() - right->eval();
}
};
struct MulNode : BinopNode
{
MulNode(Node * left_, Node * right_)
: BinopNode(left_, right_)
{}
virtual float eval(void)
{
return left->eval() * right->eval();
}
};
int main(void)
{
Node * n =
new SubNode(
new MulNode(new ConstNode(4), new ConstNode(5)),
new AddNode(new ConstNode(12), new ConstNode(7)));
assert(n->eval() == 1.0);
return 0;
}

View File

@ -1,63 +0,0 @@
#include <assert.h>
int a, b, c;
struct A
{
A(void)
{
a++;
}
virtual ~A(void)
{
a--;
}
};
struct B : A
{
B(void)
{
b++;
}
virtual ~B(void)
{
b--;
}
};
struct C : B
{
C(void)
{
c++;
}
virtual ~C(void)
{
c--;
}
};
int main()
{
A * t[3];
t[0] = new A();
t[1] = new B();
t[2] = new C();
assert(a == 3 && b == 2 && c == 1);
delete t[0];
delete t[1];
delete t[2];
assert(a == 0 && b == 0 && c == 0);
return 0;
}

View File

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

View File

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

View File

@ -10,22 +10,22 @@ void bnk1_init(void);
#pragma code(bnk1code) #pragma code(bnk1code)
__noinline char bnk1_readb(volatile char * p); char bnk1_readb(volatile char * p);
__noinline unsigned bnk1_readw(volatile unsigned * p); unsigned bnk1_readw(volatile unsigned * p);
__noinline unsigned long bnk1_readl(volatile unsigned long * p); unsigned long bnk1_readl(volatile unsigned long * p);
__noinline void bnk1_readm(char * dp, volatile char * sp, unsigned size); void bnk1_readm(char * dp, volatile char * sp, unsigned size);
__noinline void bnk1_writeb(volatile char * p, char b); void bnk1_writeb(volatile char * p, char b);
__noinline void bnk1_writew(volatile unsigned * p, unsigned w); void bnk1_writew(volatile unsigned * p, unsigned w);
__noinline void bnk1_writel(volatile unsigned long * p, unsigned long l); void bnk1_writel(volatile unsigned long * p, unsigned long l);
__noinline void bnk1_writem(volatile char * dp, const char * sp, unsigned size); void bnk1_writem(volatile char * dp, const char * sp, unsigned size);
#pragma code(code) #pragma code(code)

View File

@ -1,8 +1 @@
#include "mmu.h" #include "mmu.h"
inline char mmu_set(char cr)
{
char pcr = mmu.cr;
mmu.cr = cr;
return pcr;
}

View File

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

View File

@ -4,17 +4,16 @@
inline void vdc_reg(VDCRegister reg) inline void vdc_reg(VDCRegister reg)
{ {
vdc.addr = reg; vdc.addr = reg;
do {} while (vdc.addr < 128);
} }
inline void vdc_write(byte data) inline void vdc_write(byte data)
{ {
do {} while (vdc.addr < 128);
vdc.data = data; vdc.data = data;
} }
inline byte vdc_read(void) inline byte vdc_read(void)
{ {
do {} while (vdc.addr < 128);
return vdc.data; return vdc.data;
} }
@ -34,11 +33,8 @@ byte vdc_reg_read(VDCRegister reg)
void vdc_mem_addr(unsigned addr) void vdc_mem_addr(unsigned addr)
{ {
#pragma callinline()
vdc_reg_write(VDCR_ADDRH, addr >> 8); vdc_reg_write(VDCR_ADDRH, addr >> 8);
#pragma callinline()
vdc_reg_write(VDCR_ADDRL, addr); vdc_reg_write(VDCR_ADDRL, addr);
#pragma callinline()
vdc_reg(VDCR_DATA); vdc_reg(VDCR_DATA);
} }
@ -55,14 +51,12 @@ inline char vdc_mem_read(void)
void vdc_mem_write_at(unsigned addr, char data) void vdc_mem_write_at(unsigned addr, char data)
{ {
#pragma callinline()
vdc_mem_addr(addr); vdc_mem_addr(addr);
vdc_write(data); vdc_write(data);
} }
char vdc_mem_read_at(unsigned addr) char vdc_mem_read_at(unsigned addr)
{ {
#pragma callinline()
vdc_mem_addr(addr); vdc_mem_addr(addr);
return vdc_read(); return vdc_read();
} }

View File

@ -19,10 +19,10 @@ inline byte asm_zp(byte * ip, AsmIns ins, byte addr)
return 2; return 2;
} }
inline byte asm_rl(byte * ip, AsmIns ins, sbyte addr) inline byte asm_rl(byte * ip, AsmIns ins, byte addr)
{ {
ip[0] = ins & 0xff; ip[0] = ins & 0xff;
ip[1] = (byte)addr; ip[1] = addr;
return 2; return 2;
} }

View File

@ -97,7 +97,7 @@ inline byte asm_ac(byte * ip, AsmIns ins);
inline byte asm_zp(byte * ip, AsmIns ins, byte addr); inline byte asm_zp(byte * ip, AsmIns ins, byte addr);
// relative branch // relative branch
inline byte asm_rl(byte * ip, AsmIns ins, sbyte addr); inline byte asm_rl(byte * ip, AsmIns ins, byte addr);
// immediate // immediate
inline byte asm_im(byte * ip, AsmIns ins, byte value); inline byte asm_im(byte * ip, AsmIns ins, byte value);

View File

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

View File

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

View File

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

View File

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

View File

@ -1,353 +0,0 @@
#include "iecbus.h"
#include <c64/cia.h>
#include <c64/vic.h>
IEC_STATUS iec_status;
char iec_queue;
#define CIA2B_ATNOUT 0x08
#define CIA2B_CLKOUT 0x10
#define CIA2B_DATAOUT 0x20
#define CIA2B_CLKIN 0x40
#define CIA2B_DATAIN 0x80
#pragma optimize(push)
#pragma optimize(1)
// multiples of 5us
static void delay(char n)
{
__asm {
ldx n
l1:
dex
bne l1
}
}
static inline void data_true(void)
{
cia2.pra &= ~CIA2B_DATAOUT;
}
static inline void data_false(void)
{
cia2.pra |= CIA2B_DATAOUT;
}
static inline void clock_true(void)
{
cia2.pra &= ~CIA2B_CLKOUT;
}
static inline void cdata_true(void)
{
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
}
static inline void clock_false(void)
{
cia2.pra |= CIA2B_CLKOUT;
}
static inline void atn_true(void)
{
cia2.pra &= ~CIA2B_ATNOUT;
}
static inline void atn_false(void)
{
cia2.pra |= CIA2B_ATNOUT;
}
static inline bool data_in(void)
{
return (cia2.pra & CIA2B_DATAIN) != 0;
}
static inline bool clock_in(void)
{
return (cia2.pra & CIA2B_CLKIN) != 0;
}
static bool data_check(void)
{
char cnt = 200;
while (cnt > 0 && data_in())
{
delay(5);
cnt--;
}
if (cnt)
return true;
else
{
iec_status = IEC_DATA_CHECK;
return false;
}
}
static bool iec_eoib(void)
{
clock_true();
while (!data_in());
delay(40);
return data_check();
}
static void iec_writeb(char b)
{
clock_true();
while (!data_in());
delay(5);
for(char i=0; i<8; i++)
{
clock_false();
delay(5);
if (b & 1)
data_true();
else
data_false();
clock_true();
b >>= 1;
delay(5);
}
clock_false();
data_true();
}
bool iec_write(char b)
{
if (iec_status == IEC_QUEUED)
{
__asm
{
php
sei
}
iec_status = IEC_OK;
iec_writeb(iec_queue);
__asm
{
plp
}
data_check();
}
if (iec_status < IEC_ERROR)
{
iec_queue = b;
iec_status = IEC_QUEUED;
return true;
}
return false;
}
char iec_read(void)
{
while (!clock_in());
__asm
{
php
sei
}
data_true();
char cnt = 100;
while (cnt > 0 && clock_in())
cnt--;
if (cnt == 0)
{
iec_status = IEC_EOF;
data_false();
delay(10);
data_true();
cnt = 200;
while (cnt > 0 && clock_in())
cnt--;
if (cnt == 0)
{
iec_status = IEC_TIMEOUT;
__asm
{
plp
}
return 0;
}
}
char b = 0;
for(char i=0; i<8; i++)
{
char c;
while (!((c = cia2.pra) & CIA2B_CLKIN))
;
b >>= 1;
b |= c & 0x80;
while (cia2.pra & CIA2B_CLKIN)
;
}
data_false();
__asm
{
plp
}
return b;
}
void iec_atn(char dev, char sec)
{
clock_true();
data_true();
atn_false();
clock_false();
delay(200);
while (data_in());
iec_writeb(dev);
data_check();
if (sec != 0xff)
{
iec_writeb(sec);
data_check();
}
atn_true();
}
void iec_talk(char dev, char sec)
{
iec_status = IEC_OK;
iec_atn(dev | 0x40, sec | 0x60);
data_false();
__asm
{
php
sei
}
clock_true();
char cnt = 200;
while (cnt > 0 && clock_in())
cnt--;
__asm
{
plp
}
delay(10);
}
void iec_untalk(void)
{
iec_atn(0x5f, 0xff);
}
void iec_listen(char dev, char sec)
{
iec_status = IEC_OK;
iec_atn(dev | 0x20, sec | 0x60);
}
void iec_unlisten(void)
{
__asm
{
php
sei
}
if (iec_status == IEC_QUEUED)
{
iec_status = IEC_OK;
iec_eoib();
iec_writeb(iec_queue);
data_check();
}
iec_atn(0x3f, 0xff);
clock_true();
__asm
{
plp
}
}
void iec_open(char dev, char sec, const char * fname)
{
iec_status = IEC_OK;
iec_atn(dev | 0x20, sec | 0xf0);
char i = 0;
while (fname[i])
{
iec_write(fname[i]);
i++;
}
iec_unlisten();
}
void iec_close(char dev, char sec)
{
iec_atn(dev | 0x20, sec | 0xe0);
iec_unlisten();
}
int iec_write_bytes(const char * data, int num)
{
for(int i=0; i<num; i++)
{
if (!iec_write(data[i]))
return i;
}
return num;
}
int iec_read_bytes(char * data, int num)
{
int i = 0;
while (i < num)
{
char ch = iec_read();
if (iec_status < IEC_ERROR)
data[i++] = ch;
if (iec_status != IEC_OK)
return i;
}
return num;
}
#pragma optimize(pop)

View File

@ -1,43 +0,0 @@
#ifndef C64_IECBUS_H
#define C64_IECBUS_H
enum IEC_STATUS
{
IEC_OK = 0x00,
IEC_EOF = 0x01,
IEC_QUEUED = 0x02,
IEC_ERROR = 0x80,
IEC_TIMEOUT,
IEC_DATA_CHECK,
};
extern IEC_STATUS iec_status;
bool iec_write(char b);
char iec_read(void);
void iec_atn(char dev, char sec);
void iec_talk(char dev, char sec);
void iec_untalk(void);
void iec_listen(char dev, char sec);
void iec_unlisten(void);
void iec_open(char dev, char sec, const char * fname);
void iec_close(char dev, char sec);
int iec_write_bytes(const char * data, int num);
int iec_read_bytes(char * data, int num);
#pragma compile("iecbus.c")
#endif

View File

@ -2,32 +2,7 @@
krnioerr krnio_pstatus[16]; krnioerr krnio_pstatus[16];
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__) void krnio_setnam(const char * name)
void krnio_setbnk(char filebank, char namebank)
{
__asm
{
lda filebank
ldx namebank
jsr $ff68 // setbnk
}
}
#pragma native(krnio_setbnk)
#endif
#if defined(__PLUS4__)
#pragma code(lowcode)
#define BANKIN sta 0xff3e
#define BANKOUT sta 0xff3f
#define BANKINLINE __noinline
#else
#define BANKIN
#define BANKOUT
#define BANKINLINE
#endif
BANKINLINE void krnio_setnam(const char * name)
{ {
__asm __asm
{ {
@ -42,41 +17,22 @@ BANKINLINE void krnio_setnam(const char * name)
tya tya
W1: ldx name W1: ldx name
ldy name + 1 ldy name + 1
BANKIN
jsr $ffbd // setnam jsr $ffbd // setnam
BANKOUT
} }
} }
#pragma native(krnio_setnam) #pragma native(krnio_setnam)
BANKINLINE void krnio_setnam_n(const char * name, char len) bool krnio_open(char fnum, char device, char channel)
{
__asm
{
lda len
ldx name
ldy name + 1
BANKIN
jsr $ffbd // setnam
BANKOUT
}
}
#pragma native(krnio_setnam_n)
BANKINLINE bool krnio_open(char fnum, char device, char channel)
{ {
krnio_pstatus[fnum] = KRNIO_OK; krnio_pstatus[fnum] = KRNIO_OK;
return char(__asm __asm
{ {
lda #0 lda #0
sta accu sta accu
sta accu + 1 sta accu + 1
BANKIN
lda fnum lda fnum
ldx device ldx device
ldy channel ldy channel
@ -91,48 +47,46 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
W1: W1:
lda #1 lda #1
sta accu sta accu
BANKOUT
E2: E2:
}); }
} }
#pragma native(krnio_open) #pragma native(krnio_open)
BANKINLINE void krnio_close(char fnum) void krnio_close(char fnum)
{ {
__asm __asm
{ {
BANKIN
lda fnum lda fnum
jsr $ffc3 // close jsr $ffc3 // close
BANKOUT
} }
} }
#pragma native(krnio_close) #pragma native(krnio_close)
BANKINLINE krnioerr krnio_status(void) krnioerr krnio_status(void)
{ {
return __asm __asm
{ {
BANKIN
jsr $ffb7 // readst jsr $ffb7 // readst
BANKOUT
sta accu sta accu
lda #0 lda #0
sta accu + 1 sta accu + 1
}; }
} }
#pragma native(krnio_status) #pragma native(krnio_status)
BANKINLINE bool krnio_load(char fnum, char device, char channel) bool krnio_load(char fnum, char device, char channel)
{ {
return char(__asm __asm
{ {
BANKIN lda #0
sta accu
sta accu + 1
lda fnum lda fnum
ldx device ldx device
ldy channel ldy channel
@ -141,123 +95,89 @@ BANKINLINE bool krnio_load(char fnum, char device, char channel)
lda #0 lda #0
ldx #0 ldx #0
ldy #0 ldy #0
jsr $FFD5 // load jsr $FFD5 // open
BANKOUT bcc W1
lda #0 lda #0
rol jmp E2
eor #1 W1:
sta accu lda #1
}); sta accu
E2:
}
} }
#pragma native(krnio_load) #pragma native(krnio_load)
BANKINLINE bool krnio_save(char device, const char* start, const char* end) bool krnio_chkout(char fnum)
{ {
return char(__asm __asm
{ {
BANKIN
lda #0
ldx device
ldy #0
jsr $ffba // setlfs
lda #start
ldx end
ldy end+1
jsr $FFD8 // save
BANKOUT
lda #0
rol
eor #1
sta accu
});
}
#pragma native(krnio_save)
BANKINLINE bool krnio_chkout(char fnum)
{
return char(__asm
{
BANKIN
ldx fnum ldx fnum
jsr $ffc9 // chkout jsr $ffc9 // chkout
BANKOUT
lda #0 lda #0
rol sta accu + 1
eor #1 bcs W1
sta accu lda #1
}); W1: sta accu
}
} }
#pragma native(krnio_chkout) #pragma native(krnio_chkout)
BANKINLINE bool krnio_chkin(char fnum) bool krnio_chkin(char fnum)
{ {
return char(__asm __asm
{ {
BANKIN
ldx fnum ldx fnum
jsr $ffc6 // chkin jsr $ffc6 // chkin
BANKOUT
lda #0 lda #0
rol sta accu + 1
eor #1 bcs W1
sta accu lda #1
}); W1: sta accu
}
} }
#pragma native(krnio_chkin) #pragma native(krnio_chkin)
BANKINLINE void krnio_clrchn(void) void krnio_clrchn(void)
{ {
__asm __asm
{ {
BANKIN
jsr $ffcc // clrchn jsr $ffcc // clrchn
BANKOUT
} }
} }
#pragma native(krnio_clrchn) #pragma native(krnio_clrchn)
BANKINLINE bool krnio_chrout(char ch) bool krnio_chrout(char ch)
{ {
return char(__asm __asm
{ {
BANKIN
lda ch lda ch
jsr $ffd2 // chrout jsr $ffd2 // chrout
sta accu sta accu
BANKOUT lda #0
}); sta accu + 1
}
} }
#pragma native(krnio_chrout) #pragma native(krnio_chrout)
BANKINLINE char krnio_chrin(void) int krnio_chrin(void)
{ {
return __asm __asm
{ {
BANKIN
jsr $ffcf // chrin jsr $ffcf // chrin
sta accu sta accu
BANKOUT lda #0
}; sta accu + 1
}
} }
#pragma native(krnio_chrin) #pragma native(krnio_chrin)
#if defined(__PLUS4__)
#pragma code(code)
#endif
int krnio_getch(char fnum) int krnio_getch(char fnum)
{ {
if (krnio_pstatus[fnum] == KRNIO_EOF) if (krnio_pstatus[fnum] == KRNIO_EOF)
@ -421,7 +341,7 @@ int krnio_gets(char fnum, char * data, int num)
if (krnio_chkin(fnum)) if (krnio_chkin(fnum))
{ {
krnioerr err = KRNIO_OK; krnioerr err;
int i = 0; int i = 0;
int ch; int ch;
while (i + 1 < num) while (i + 1 < num)

View File

@ -1,5 +1,5 @@
#ifndef C64_KERNALIO_H #ifndef C64_KERNALIO_H
#define C64_KERNALIO_H #ifndef C64_KERNALIO_H
// Error and status codes returned by krnio_status // Error and status codes returned by krnio_status
@ -18,18 +18,11 @@ enum krnioerr
extern krnioerr krnio_pstatus[16]; extern krnioerr krnio_pstatus[16];
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
// C128: Set bank for load/save and filename for next file operations
void krnio_setbnk(char filebank, char namebank);
#endif
// Set filename for next krnio_open operation, make sure // Set filename for next krnio_open operation, make sure
// that the string is still valid when calling krnio_open // that the string is still valid when calling krnio_open
void krnio_setnam(const char * name); void krnio_setnam(const char * name);
void krnio_setnam_n(const char * name, char len);
// open a kernal file/stream/io channel, returns true on success // open a kernal file/stream/io channel, returns true on success
bool krnio_open(char fnum, char device, char channel); bool krnio_open(char fnum, char device, char channel);
@ -44,8 +37,6 @@ krnioerr krnio_status(void);
bool krnio_load(char fnum, char device, char channel); bool krnio_load(char fnum, char device, char channel);
bool krnio_save(char device, const char* start, const char* end);
// select the given file for stream output // select the given file for stream output
bool krnio_chkout(char fnum); bool krnio_chkout(char fnum);
@ -64,7 +55,7 @@ bool krnio_chrout(char ch);
// read a single byte from the current input channel // read a single byte from the current input channel
char krnio_chrin(void); int krnio_chrin(void);
// read a single byte from the given file/channel, returns // read a single byte from the given file/channel, returns
// a negative result on failure. If this was the last byte // a negative result on failure. If this was the last byte

View File

@ -1,8 +1,11 @@
#include "memmap.h" #include "memmap.h"
volatile char PLAShadow;
__asm DoneTrampoline __asm DoneTrampoline
{ {
stx $01 lda PLAShadow
sta $01
pla pla
tax tax
pla pla
@ -14,6 +17,8 @@ __asm IRQTrampoline
pha pha
txa txa
pha pha
lda #$36
sta $01
lda #>DoneTrampoline lda #>DoneTrampoline
pha pha
@ -22,10 +27,7 @@ __asm IRQTrampoline
tsx tsx
lda $0105, x lda $0105, x
pha pha
ldx $01 jmp ($fffa)
lda #$36
sta $01
jmp ($fffe)
} }
__asm NMITrampoline __asm NMITrampoline
@ -33,6 +35,8 @@ __asm NMITrampoline
pha pha
txa txa
pha pha
lda #$36
sta $01
lda #>DoneTrampoline lda #>DoneTrampoline
pha pha
@ -41,23 +45,19 @@ __asm NMITrampoline
tsx tsx
lda $0105, x lda $0105, x
pha pha
ldx $01 jmp ($fffe)
lda #$36
sta $01
jmp ($fffa)
} }
void mmap_trampoline(void) void mmap_trampoline(void)
{ {
*((void **)0xfffa) = NMITrampoline; *((void **)0xfffa) = IRQTrampoline;
*((void **)0xfffe) = IRQTrampoline; *((void **)0xfffe) = NMITrampoline;
} }
#pragma native(mmap_trampoline) #pragma native(mmap_trampoline)
char mmap_set(char pla) void mmap_set(char pla)
{ {
char ppla = *((char *)0x01); PLAShadow = pla;
*((volatile char *)0x01) = pla; *((volatile char *)0x01) = pla;
return ppla;
} }

View File

@ -18,9 +18,9 @@
void mmap_trampoline(void); void mmap_trampoline(void);
// Set the memory map in a way that is compatible with the IRQ // Set the memory map in a way that is compatible with the IRQ
// trampoline, returns the previous state // trampoline
inline char mmap_set(char pla); inline void mmap_set(char pla);
#pragma compile("memmap.c") #pragma compile("memmap.c")

View File

@ -7,20 +7,20 @@ bool mouse_lb, mouse_rb;
static char mouse_px, mouse_py; static char mouse_px, mouse_py;
static char mouse_port; static char mouse_port;
inline signed char dpos(char * old, char mnew) inline signed char dpos(char * old, char new)
{ {
mnew = (mnew & 0x7f) >> 1; new = (new & 0x7f) >> 1;
char diff = (mnew - *old) & 0x3f; char diff = (new - *old) & 0x3f;
if (diff >= 0x20) if (diff >= 0x20)
{ {
*old = mnew; *old = new;
return diff | 0xe0; return diff | 0xe0;
} }
else if (diff) else if (diff)
{ {
*old = mnew; *old = new;
return diff; return diff;
} }

View File

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

View File

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

View File

@ -1,11 +1,8 @@
#include "sprites.h" #include "sprites.h"
#include "rasterirq.h" #include "rasterirq.h"
static volatile char * vspriteScreen; static char * vspriteScreen;
#ifdef VSPRITE_BSS
#pragma bss(VSPRITE_BSS)
#endif
void spr_init(char * screen) void spr_init(char * screen)
{ {
@ -111,22 +108,6 @@ void spr_color(char sp, char color)
vic.spr_color[sp] = color; vic.spr_color[sp] = color;
} }
void spr_expand(char sp, bool xexpand, bool yexpand)
{
__assume (sp < 8);
char m = 1 << sp;
if (xexpand)
vic.spr_expand_x |= m;
else
vic.spr_expand_x &= ~m;
if (yexpand)
vic.spr_expand_y |= m;
else
vic.spr_expand_y &= ~m;
}
static char vspriteYLow[VSPRITES_MAX], vspriteXLow[VSPRITES_MAX], vspriteXHigh[VSPRITES_MAX]; static char vspriteYLow[VSPRITES_MAX], vspriteXLow[VSPRITES_MAX], vspriteXHigh[VSPRITES_MAX];
static char vspriteImage[VSPRITES_MAX], vspriteColor[VSPRITES_MAX]; static char vspriteImage[VSPRITES_MAX], vspriteColor[VSPRITES_MAX];
@ -146,11 +127,7 @@ void vspr_init(char * screen)
for(int i=0; i<VSPRITES_MAX - 8; i++) for(int i=0; i<VSPRITES_MAX - 8; i++)
{ {
#ifdef VSPRITE_REVERSE
int j = (i & 7) ^ 7;
#else
int j = i & 7; int j = i & 7;
#endif
rirq_build(spirq + i, 5); rirq_build(spirq + i, 5);
rirq_write(spirq + i, 0, &vic.spr_color[j], 0); rirq_write(spirq + i, 0, &vic.spr_color[j], 0);
@ -171,21 +148,6 @@ void vspr_init(char * screen)
} }
} }
void vspr_shutdown(void)
{
for(int i=0; i<VSPRITES_MAX - 7; i++)
rirq_clear(i);
}
void vspr_screen(char * screen)
{
vspriteScreen = screen + 0x3f8;
char hi = (unsigned)vspriteScreen >> 8;
#pragma unroll(8)
for(int i=0; i<VSPRITES_MAX - 8; i++)
rirq_addrhi(spirq + i, 3, hi);
}
#pragma native(vspr_init) #pragma native(vspr_init)
void vspr_set(char sp, int xpos, int ypos, char image, char color) void vspr_set(char sp, int xpos, int ypos, char image, char color)
@ -214,21 +176,6 @@ void vspr_move(char sp, int xpos, int ypos)
vspriteXHigh[sp] = (char)(xpos >> 8); vspriteXHigh[sp] = (char)(xpos >> 8);
} }
void vspr_movex(char sp, int xpos)
{
vspriteXLow[sp] = (char)xpos;
vspriteXHigh[sp] = (char)(xpos >> 8);
}
void vspr_movey(char sp, int ypos)
{
char yp = (char)ypos;
if (ypos & 0xff00)
yp = 0xff;
vspriteYLow[sp] = yp;
}
void vspr_image(char sp, char image) void vspr_image(char sp, char image)
{ {
vspriteImage[sp] = image; vspriteImage[sp] = image;
@ -246,30 +193,22 @@ void vspr_hide(char sp)
void vspr_sort(void) void vspr_sort(void)
{ {
byte rm = vspriteYLow[spriteOrder[0]]; spriteYPos[1] = vspriteYLow[spriteOrder[0]];
spriteYPos[1] = rm;
for(char i = 1; i<VSPRITES_MAX; i++) for(char i = 1; i<VSPRITES_MAX; i++)
{ {
byte ri = spriteOrder[i]; byte ri = spriteOrder[i];
byte rr = vspriteYLow[ri]; byte rr = vspriteYLow[ri];
if (rr < rm) byte j = i, rj = spriteYPos[j];
while (rr < rj)
{ {
byte j = i, rj = rm; spriteYPos[j + 1] = rj;
do { spriteOrder[j] = spriteOrder[j - 1];
spriteYPos[j + 1] = rj; rj = spriteYPos[j - 1];
spriteOrder[j] = spriteOrder[j - 1]; j--;
rj = spriteYPos[j - 1];
j--;
} while (rr < rj);
spriteOrder[j] = ri;
spriteYPos[j + 1] = rr;
}
else
{
spriteYPos[i + 1] = rr;
rm = rr;
} }
spriteOrder[j] = ri;
spriteYPos[j + 1] = rr;
} }
} }
@ -278,68 +217,48 @@ void vspr_sort(void)
void vspr_update(void) void vspr_update(void)
{ {
char xymask = 0; char xymask = 0;
volatile char * vsprs = vspriteScreen; char * vsprs = vspriteScreen;
// char sypos[VSPRITES_MAX];
#pragma unroll(full) #pragma unroll(full)
for(char ui=0; ui<8; ui++) for(char ui=0; ui<8; ui++)
{ {
byte ri = spriteOrder[ui]; byte ri = spriteOrder[ui];
#ifdef VSPRITE_REVERSE
char uj = ui ^ 7;
#else
char uj = ui;
#endif
vic.spr_color[uj] = vspriteColor[ri]; vic.spr_color[ui] = vspriteColor[ri];
vsprs[uj] = vspriteImage[ri]; vsprs[ui] = vspriteImage[ri];
#ifdef VSPRITE_REVERSE
xymask = (xymask << 1) | (vspriteXHigh[ri] & 1);
#else
xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1; xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1;
#endif vic.spr_pos[ui].x = vspriteXLow[ri];
vic.spr_pos[uj].x = vspriteXLow[ri]; vic.spr_pos[ui].y = vspriteYLow[ri];
vic.spr_pos[uj].y = spriteYPos[ui + 1];
// sypos[ui] = vspriteYLow[ri];
} }
vic.spr_msbx = xymask; vic.spr_msbx = xymask;
#pragma unroll(full) if (spriteYPos[8] < 230)
bool done = false;
for(char ti=0; ti<VSPRITES_MAX - 8; ti++)
{ {
if (!done && spriteYPos[ti + 9] < 250) #pragma unroll(full)
for(char ti=0; ti<VSPRITES_MAX - 8; ti++)
{ {
byte ri = spriteOrder[ti + 8];
rirq_move(ti, spriteYPos[ti + 1] + 23);
#ifdef VSPRITE_REVERSE
char m = 0x80 >> (ti & 7);
#else
char m = 1 << (ti & 7); char m = 1 << (ti & 7);
#endif
byte ri = spriteOrder[ti + 8];
xymask |= m; xymask |= m;
if (!(vspriteXHigh[ri] & 1)) if (!vspriteXHigh[ri])
xymask ^= m; xymask ^= m;
rirq_data(spirq + ti, 2, spriteYPos[ti + 9]);
rirq_data(spirq + ti, 0, vspriteColor[ri]); rirq_data(spirq + ti, 0, vspriteColor[ri]);
rirq_data(spirq + ti, 1, vspriteXLow[ri]); rirq_data(spirq + ti, 1, vspriteXLow[ri]);
rirq_data(spirq + ti, 2, vspriteYLow[ri]);
rirq_data(spirq + ti, 3, vspriteImage[ri]); rirq_data(spirq + ti, 3, vspriteImage[ri]);
rirq_data(spirq + ti, 4, xymask); rirq_data(spirq + ti, 4, xymask);
// spriteYPos[ti + 9] = vspriteYLow[ri]; rirq_move(ti, spriteYPos[ti + 1] + 23);
} }
else }
{ else
{
for(char ti=0; ti<VSPRITES_MAX - 8; ti++)
rirq_clear(ti); rirq_clear(ti);
done = true;
}
} }
} }

View File

@ -39,10 +39,6 @@ inline void spr_image(char sp, char image);
inline void spr_color(char sp, char color); inline void spr_color(char sp, char color);
// change the image of a sprite
inline void spr_expand(char sp, bool xexpand, bool yexpand);
// The virtual sprite system works with the rasterirq library to multiplex // The virtual sprite system works with the rasterirq library to multiplex
// 16 virtual sprites onto the actual eight hardware sprites. It uses the slots // 16 virtual sprites onto the actual eight hardware sprites. It uses the slots
// 0 to 8 of the rasterirq library to switch the sprites mid screen. The // 0 to 8 of the rasterirq library to switch the sprites mid screen. The
@ -68,10 +64,6 @@ inline void spr_expand(char sp, bool xexpand, bool yexpand);
void vspr_init(char * screen); void vspr_init(char * screen);
void vspr_shutdown(void);
void vspr_screen(char * screen);
// set one sprite with the given attribute // set one sprite with the given attribute
void vspr_set(char sp, int xpos, int ypos, char image, char color); void vspr_set(char sp, int xpos, int ypos, char image, char color);
@ -80,11 +72,6 @@ void vspr_set(char sp, int xpos, int ypos, char image, char color);
inline void vspr_move(char sp, int xpos, int ypos); inline void vspr_move(char sp, int xpos, int ypos);
inline void vspr_movex(char sp, int xpos);
inline void vspr_movey(char sp, int ypos);
// change the image of a virtual sprite // change the image of a virtual sprite
inline void vspr_image(char sp, char image); inline void vspr_image(char sp, char image);

View File

@ -21,7 +21,7 @@ int vic_sprgetx(byte s)
return vic.spr_pos[s].x | ((vic.spr_msbx & (1 << s)) ? 256 : 0); return vic.spr_pos[s].x | ((vic.spr_msbx & (1 << s)) ? 256 : 0);
} }
void vic_setmode(VicMode mode, const char * text, const char * font) void vic_setmode(VicMode mode, char * text, char * font)
{ {
switch (mode) switch (mode)
{ {
@ -73,15 +73,6 @@ void vic_waitFrame(void)
; ;
} }
void vic_waitFrames(char n)
{
while (n > 0)
{
vic_waitFrame();
n--;
}
}
void vic_waitLine(int line) void vic_waitLine(int line)
{ {
char upper = (char)(line >> 1) & VIC_CTRL1_RST8; char upper = (char)(line >> 1) & VIC_CTRL1_RST8;
@ -94,41 +85,4 @@ void vic_waitLine(int line)
} while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper); } while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper);
} }
void vic_waitBelow(int line)
{
char upper = (char)(line >> 1) & VIC_CTRL1_RST8;
char lower = (char)line;
if (upper)
{
do
{
while (vic.raster <= lower)
;
} while (!(vic.ctrl1 & VIC_CTRL1_RST8));
}
else
{
while (vic.raster <= lower)
;
}
}
void vic_waitRange(char below, char above)
{
while (vic.ctrl1 & VIC_CTRL1_RST8)
;
if (vic.raster >= above)
{
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
;
while (vic.ctrl1 & VIC_CTRL1_RST8)
;
}
while (vic.raster < below)
;
}
#pragma native(vic_waitLine) #pragma native(vic_waitLine)

View File

@ -91,7 +91,7 @@ enum VicMode
// set the display mode and base address. This will also // set the display mode and base address. This will also
// adapt the bank. // adapt the bank.
void vic_setmode(VicMode mode, const char * text, const char * font); void vic_setmode(VicMode mode, char * text, char * font);
// put a sprite at the given x/y location, taking care of the // put a sprite at the given x/y location, taking care of the
// x MSB // x MSB
@ -109,18 +109,9 @@ inline void vic_waitTop(void);
// wait for the top of the frame and then for the bottom of the visual area // wait for the top of the frame and then for the bottom of the visual area
inline void vic_waitFrame(void); inline void vic_waitFrame(void);
// wait for n frames
void vic_waitFrames(char n);
// wait for a specific raster line // wait for a specific raster line
void vic_waitLine(int line); 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 // reference to the VIC chip
#define vic (*((struct VIC *)0xd000)) #define vic (*((struct VIC *)0xd000))

View File

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

View File

@ -18,95 +18,32 @@ extern IOCharMap giocharmap;
void iocharmap(IOCharMap chmap); void iocharmap(IOCharMap chmap);
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
void dispmode40col(void);
void dispmode80col(void);
#endif
#define PETSCII_CURSOR_LEFT 0x9d int kbhit(void);
#define PETSCII_CURSOR_RIGHT 0x1d
#define PETSCII_CURSOR_UP 0x91
#define PETSCII_CURSOR_DOWN 0x11
#define PETSCII_HOME 0x13
#define PETSCII_CLEAR 0x94
#define PETSCII_DEL 0x14
#define PETSCII_INSERT 0x94
#define PETSCII_STOP 0x03
#define PETSCII_RETURN 0x0d
#define PETSCII_F1 0x85 int getche(void);
#define PETSCII_F2 0x89
#define PETSCII_F3 0x86
#define PETSCII_F4 0x8a
#define PETSCII_F5 0x87
#define PETSCII_F6 0x8b
#define PETSCII_F7 0x88
#define PETSCII_F8 0x8c
enum ConioColors int getch(void);
{
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);
char getch(void);
// like getch but does not wait, returns zero if no // like getch but does not wait, returns zero if no
// key is pressed // key is pressed
char getchx(void); int getchx(void);
void putch(char c); void putch(int c);
void clrscr(void); void clrscr(void);
void gotoxy(char x, char y); void gotoxy(int x, int y);
inline void textcolor(char c); void textcolor(int c);
inline void bgcolor(char c); int wherex(void);
inline void bordercolor(char c); int wherey(void);
inline void revers(char r);
inline char wherex(void);
inline char wherey(void);
// show or hide the text cursor // show or hide the text cursor
inline void textcursor(bool show); void textcursor(bool show);
#pragma compile("conio.c") #pragma compile("conio.c")

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,5 +1,4 @@
#include "ctype.h" #include "ctype.h"
#include "conio.h"
#define CC_CTRL 0x00 #define CC_CTRL 0x00
#define CC_BREAK 0x01 #define CC_BREAK 0x01
@ -87,19 +86,3 @@ bool isxdigit(char c)
{ {
return (c < 128) && (_cinfo[c] & CC_HEX); return (c < 128) && (_cinfo[c] & CC_HEX);
} }
char tolower(char c)
{
if (c >= 'A' && c <= 'Z')
return c + ('a' - 'A');
else
return c;
}
char toupper(char c)
{
if (c >= 'a' && c <= 'z')
return c + ('A' - 'a');
else
return c;
}

View File

@ -25,9 +25,6 @@ inline bool isdigit(char c);
inline bool isxdigit(char c); inline bool isxdigit(char c);
char tolower(char c);
char toupper(char c);
#pragma compile("ctype.c") #pragma compile("ctype.c")

View File

@ -1,166 +0,0 @@
#include "vera.h"
void vram_addr(unsigned long addr)
{
vera.ctrl &= ~VERA_CTRL_ADDRSEL;
vera.addr = (unsigned)addr;
vera.addrh = (char)((addr >> 16) & 1) | 0x10;
}
void vram_addr0(unsigned long addr)
{
vera.ctrl &= ~VERA_CTRL_ADDRSEL;
vera.addr = (unsigned)addr;
vera.addrh = (char)((addr >> 16) & 1) | 0x00;
}
void vram_addr2(unsigned long addr)
{
vera.ctrl &= ~VERA_CTRL_ADDRSEL;
vera.addr = (unsigned)addr;
vera.addrh = (char)((addr >> 16) & 1) | 0x20;
}
void vram_put(char data)
{
vera.data0 = data;
}
void vram_putw(unsigned data)
{
vera.data0 = data & 0xff;
vera.data0 = data >> 8;
}
char vram_get(void)
{
return vera.data0;
}
unsigned vram_getw(void)
{
unsigned l = vera.data0;
unsigned h = vera.data0;
return (h << 8) | l;
}
void vram_put_at(unsigned long addr, char data)
{
vram_addr(addr);
vram_put(data);
}
char vram_get_at(unsigned long addr)
{
vram_addr(addr);
return vram_get();;
}
void vram_putn(unsigned long addr, const char * data, unsigned size)
{
vram_addr(addr);
while(size > 0)
{
vram_put(*data++);
size--;
}
}
void vram_getn(unsigned long addr, char * data, unsigned size)
{
vram_addr(addr);
while(size > 0)
{
*data++ = vram_get();
size--;
}
}
void vram_fill(unsigned long addr, char data, unsigned size)
{
vram_addr(addr);
while(size > 0)
{
vram_put(data);
size--;
}
}
void vera_spr_set(char spr, unsigned addr32, VERASpriteMode mode8, VERASpriteSize w, VERASpriteSize h, VERASpritePriority z, char pal)
{
__assume(spr < 128);
vram_addr(0x1fc00UL + spr * 8);
vram_putw(addr32 | (mode8 ? 0x8000 : 0x0000));
vram_putw(0);
vram_putw(0);
vram_put(z << 2);
vram_put((h << 6) | (w << 4) | pal);
}
void vera_spr_flip(char spr, bool fliph, bool flipv)
{
__assume(spr < 128);
vram_addr0(0x1fc00UL + spr * 8 + 6);
char b = vram_get() & 0xfc;
if (fliph) b |= 0x01;
if (flipv) b |= 0x02;
vram_put(b);
}
void vera_spr_move(char spr, int x, int y)
{
__assume(spr < 128);
vram_addr(0x1fc00UL + spr * 8 + 2);
vram_putw(x);
vram_putw(y);
}
void vera_spr_image(char spr, unsigned addr32)
{
__assume(spr < 128);
vram_addr(0x1fc00UL + spr * 8);
vram_put(addr32 & 0xff);
vera.addrh &= 0x0f;
char b = vram_get() & 0x80;
vram_put((addr32 >> 8) | b);
}
void vera_pal_put(char index, unsigned color)
{
vram_addr(0x1fa00ul + 2 * index);
vram_putw(color);
}
unsigned vera_pal_get(char index)
{
vram_addr(0x1fa00ul + 2 * index);
return vram_getw();
}
void vera_pal_putn(char index, const unsigned * color, unsigned size)
{
vram_addr(0x1fa00ul + 2 * index);
while (size > 0)
{
vram_putw(*color++);
size--;
}
}
void vera_pal_getn(char index, unsigned * color, unsigned size)
{
vram_addr(0x1fa00ul + 2 * index);
while (size > 0)
{
*color++ = vram_getw();
size--;
}
}

View File

@ -1,157 +0,0 @@
#ifndef CX16_VERA_H
#define CX16_VERA_H
// Thanks to crisps for providing the initial code for this library
#include <c64/types.h>
#define VERA_ADDRH_DECR 0x08
#define VERA_ADDRH_INC 0xf0
#define VERA_CTRL_RESET 0x80
#define VERA_CTRL_DCSEL 0x02
#define VERA_CTRL_ADDRSEL 0x01
#define VERA_IRQ_LINE_8 0x80
#define VERA_IRQ_AFLOW 0x08
#define VERA_IRQ_SPRCOL 0x04
#define VERA_IRQ_LINE 0x02
#define VERA_IRQ_VSYNC 0x01
#define VERA_DCVIDEO_MODE_OFF 0x00
#define VERA_DCVIDEO_MODE_VGA 0x01
#define VERA_DCVIDEO_MODE_NTSC 0x02
#define VERA_DCVIDEO_MODE_RGBI 0x03
#define VERA_DCVIDEO_NCHROMA 0x04
#define VERA_DCVIDEO_LAYER0 0x10
#define VERA_DCVIDEO_LAYER1 0x20
#define VERA_DCVIDEO_SPRITES 0x40
#define VERA_LAYER_DEPTH_1 0x00
#define VERA_LAYER_DEPTH_2 0x01
#define VERA_LAYER_DEPTH_4 0x02
#define VERA_LAYER_DEPTH_8 0x03
#define VERA_LAYER_BITMAP 0x04
#define VERA_LAYER_T256C 0x08
#define VERA_LAYER_WIDTH_32 0x00
#define VERA_LAYER_WIDTH_64 0x10
#define VERA_LAYER_WIDTH_128 0x20
#define VERA_LAYER_WIDTH_256 0x30
#define VERA_LAYER_HEIGHT_32 0x00
#define VERA_LAYER_HEIGHT_64 0x40
#define VERA_LAYER_HEIGHT_128 0x80
#define VERA_LAYER_HEIGHT_256 0xc0
#define VERA_TILE_WIDTH_8 0x00
#define VERA_TILE_WIDTH_16 0x01
#define VERA_TILE_HEIGHT_8 0x00
#define VERA_TILE_HEIGHT_16 0x02
struct VERA
{
volatile word addr;
volatile byte addrh;
volatile byte data0, data1;
volatile byte ctrl;
volatile byte ien;
volatile byte isr;
volatile byte irqline;
volatile byte dcvideo;
volatile byte dchscale;
volatile byte dcvscale;
volatile byte dcborder;
volatile byte l0config;
volatile byte l0mapbase;
volatile byte l0tilebase;
volatile word l0hscroll;
volatile word l0vscroll;
volatile byte l1config;
volatile byte l1mapbase;
volatile byte l1tilebase;
volatile word l1hscroll;
volatile word l1vscroll;
volatile byte audioctrl;
volatile byte audiorate;
volatile byte audiodata;
volatile byte spidata;
volatile byte spictrl;
};
enum VERASpriteMode
{
VSPRMODE_4,
VSPRMODE_8
};
enum VERASpriteSize
{
VSPRSZIZE_8,
VSPRSZIZE_16,
VSPRSZIZE_32,
VSPRSZIZE_64
};
enum VERASpritePriority
{
VSPRPRI_OFF,
VSPRPRI_BACK,
VSPRPRI_MIDDLE,
VSPRPRI_FRONT
};
#define VERA_COLOR(r, g, b) (((unsigned)(r) << 8) | ((unsigned)(g) << 4) | (unsigned)(b))
#define vera (*(VERA *)0x9f20)
inline void vram_addr(unsigned long addr);
inline void vram_addr0(unsigned long addr);
inline void vram_addr2(unsigned long addr);
inline void vram_put(char data);
inline void vram_putw(unsigned data);
inline char vram_get(void);
inline unsigned vram_getw(void);
inline void vram_put_at(unsigned long addr, char data);
inline char vram_get_at(unsigned long addr);
void vram_putn(unsigned long addr, const char * data, unsigned size);
void vram_getn(unsigned long addr, char * data, unsigned size);
void vram_fill(unsigned long addr, char data, unsigned size);
void vera_spr_set(char spr, unsigned addr32, VERASpriteMode mode8, VERASpriteSize w, VERASpriteSize h, VERASpritePriority z, char pal);
void vera_spr_flip(char spr, bool fliph, bool flipv);
void vera_spr_move(char spr, int x, int y);
void vera_spr_image(char spr, unsigned addr32);
void vera_pal_put(char index, unsigned color);
unsigned vera_pal_get(char index);
void vera_pal_putn(char index, const unsigned * color, unsigned size);
void vera_pal_getn(char index, unsigned * color, unsigned size);
#pragma compile("vera.c")
#endif

View File

@ -116,38 +116,31 @@ int lmul4f12s(int x, int y)
{ {
__asm __asm
{ {
sec bit y + 1
lda x bpl W0
ror
sta accu
sec
lda #0
sbc y
sta y
lda #0
sbc y + 1
sta y + 1
sec
lda #0
sbc x
sta x
lda #0
sbc x + 1
sta x + 1
W0:
ldx #15
lda #0 lda #0
sta accu + 1 sta accu + 1
bcc W4 L1: lsr x + 1
L2: ror x
tay
clc
lda accu + 1
adc y
sta accu + 1
tya
adc y + 1
W4:
ror
ror accu + 1
lsr accu
bcc W4
bne L2
ldx x + 1
stx accu
ldx #7
lsr accu
L1:
bcc W1 bcc W1
tay tay
clc clc
@ -163,31 +156,23 @@ W1:
dex dex
bne L1 bne L1
lsr x
bcc W2 bcc W2
tay tay
// sec ; we know it is set here sec
lda accu + 1 lda accu + 1
sbc y sbc y
sta accu + 1 sta accu + 1
tya tya
sbc y + 1 sbc y + 1
sec
W2: W2:
ror ror
ror accu + 1 ror accu + 1
ror accu ror accu
bit y + 1
bpl W3
tax
sec
lda accu + 1
sbc x
sta accu + 1
txa
sbc x + 1
W3:
lsr lsr
ror accu + 1 ror accu + 1
ror accu ror accu
@ -285,17 +270,15 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
__asm __asm
{ {
lda #0 lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2 sta __tmp + 2
sta __tmp + 3 sta __tmp + 3
lda a ldx #16
sec L1: lsr a + 1
T1: ror a
ldy #8
L1:
ror
bcc W1 bcc W1
tax
clc clc
lda __tmp + 2 lda __tmp + 2
adc b adc b
@ -303,38 +286,20 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3 lda __tmp + 3
adc b + 1 adc b + 1
sta __tmp + 3 sta __tmp + 3
txa
W1: W1:
ror __tmp + 3 ror __tmp + 3
ror __tmp + 2 ror __tmp + 2
dey ror __tmp + 1
ror __tmp
dex
bne L1 bne L1
ror
bcc T2
sta __tmp + 0 lda #0
lda a + 1 sta accu
clc sta accu + 1
bcc T1
T2: ldx #17
sec
L3:
sta __tmp + 1
ldx #8
L2: L2:
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
bcc W3
lda __tmp + 2
sbc c
tay
lda __tmp + 3
sbc c + 1
sec
bcs W4
W3:
sec sec
lda __tmp + 2 lda __tmp + 2
sbc c sbc c
@ -342,23 +307,33 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3 lda __tmp + 3
sbc c + 1 sbc c + 1
bcc W2 bcc W2
W4:
sta __tmp + 3 sta __tmp + 3
sty __tmp + 2 sty __tmp + 2
W2: W2:
dex rol accu
bne L2 rol accu + 1
lda __tmp + 1
rol asl __tmp
bcc T3 rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
dex
beq E2
bcc L2
lda __tmp + 2
sbc c
sta __tmp + 2
lda __tmp + 3
sbc c + 1
sta __tmp + 3
sec
bcs W2
E2:
sta accu + 1
lda __tmp + 0
clc
bcc L3
T3:
sta accu
} }
} }
int lmuldiv16s(int a, int b, int c) int lmuldiv16s(int a, int b, int c)
@ -383,17 +358,15 @@ int lmuldiv16s(int a, int b, int c)
__asm __asm
{ {
lda #0 lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2 sta __tmp + 2
sta __tmp + 3 sta __tmp + 3
lda a ldx #16
sec L1: lsr a + 1
T1: ror a
ldy #8
L1:
ror
bcc W1 bcc W1
tax
clc clc
lda __tmp + 2 lda __tmp + 2
adc b adc b
@ -401,38 +374,20 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3 lda __tmp + 3
adc b + 1 adc b + 1
sta __tmp + 3 sta __tmp + 3
txa
W1: W1:
ror __tmp + 3 ror __tmp + 3
ror __tmp + 2 ror __tmp + 2
dey ror __tmp + 1
ror __tmp
dex
bne L1 bne L1
ror
bcc T2
sta __tmp + 0 lda #0
lda a + 1 sta accu
clc sta accu + 1
bcc T1
T2: ldx #17
sec
L3:
sta __tmp + 1
ldx #8
L2: L2:
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
bcc W3
lda __tmp + 2
sbc c
tay
lda __tmp + 3
sbc c + 1
sec
bcs W4
W3:
sec sec
lda __tmp + 2 lda __tmp + 2
sbc c sbc c
@ -440,23 +395,30 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3 lda __tmp + 3
sbc c + 1 sbc c + 1
bcc W2 bcc W2
W4:
sta __tmp + 3 sta __tmp + 3
sty __tmp + 2 sty __tmp + 2
W2: W2:
rol accu
rol accu + 1
asl __tmp
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
dex dex
bne L2 beq E2
lda __tmp + 1 bcc L2
rol
bcc T3
sta accu + 1
lda __tmp + 0
clc
bcc L3
T3:
sta accu
lda __tmp + 2
sbc c
sta __tmp + 2
lda __tmp + 3
sbc c + 1
sta __tmp + 3
sec
bcs W2
E2:
lda sign lda sign
beq E1 beq E1
@ -623,289 +585,3 @@ int lmuldiv16sby8(int a, char b, char c)
else else
return lmuldiv16by8(a, b, c); return lmuldiv16by8(a, b, c);
} }
unsigned usqrt(unsigned n)
{
unsigned p, q, r, h;
p = 0;
r = n;
#assign q 0x4000
#repeat
{
h = p | q;
p >>= 1;
if (r >= h)
{
p |= q;
r -= h;
}
}
#assign q q >> 2
#until q == 0
#undef q
return p;
}
unsigned long lmul16f16(unsigned long x, unsigned long y)
{
unsigned long hh = lmul16u(x >> 16, y >> 16);
unsigned long lh = lmul16u(x, y >> 16);
unsigned long hl = lmul16u(x >> 16, y);
unsigned long ll = lmul16u(x, y);
if (ll & 0x8000)
lh++;
ll >>= 16;
ll |= hh << 16;
ll += lh;
ll += hl;
return ll;
}
#if 1
long lmul16f16s(long x, long y)
{
__asm
{
lda #0
// fractional
sta __tmp + 0
sta __tmp + 1
// result
sta __accu + 0
sta __accu + 1
sta __accu + 2
sta __accu + 3
lda x + 0
ora x + 1
ora y + 0
ora y + 1
bne w0b
l2:
lsr x + 2
bcc ws1
clc
lda y + 2
adc __accu + 2
sta __accu + 2
lda y + 3
adc __accu + 3
sta __accu + 3
ws1:
lsr x + 3
bcc ws2
clc
lda y + 2
adc __accu + 3
sta __accu + 3
ws2:
asl y + 2
rol y + 3
lda x + 2
ora x + 3
bne l2
rts
w0b:
lda y + 3
and #$80
beq w0
lda #$ff
w0:
// overflow
sta __tmp + 2
sta __tmp + 3
lda x + 3
bpl w0a
sec
lda #0
sbc y + 0
sta __accu + 2
lda #0
sbc y + 1
sta __accu + 3
w0a:
ldx #8
l1:
lsr x + 0
bcc w1
clc
lda y + 0
adc __tmp + 0
sta __tmp + 0
lda y + 1
adc __tmp + 1
sta __tmp + 1
lda y + 2
adc __accu + 0
sta __accu + 0
lda y + 3
adc __accu + 1
sta __accu + 1
lda __tmp + 2
adc __accu + 2
sta __accu + 2
lda __tmp + 3
adc __accu + 3
sta __accu + 3
w1:
lsr x + 1
bcc w2
clc
lda y + 0
adc __tmp + 1
sta __tmp + 1
lda y + 1
adc __accu + 0
sta __accu + 0
lda y + 2
adc __accu + 1
sta __accu + 1
lda y + 3
adc __accu + 2
sta __accu + 2
lda __tmp + 2
adc __accu + 3
sta __accu + 3
w2:
lsr x + 2
bcc w3
clc
lda y + 0
adc __accu + 0
sta __accu + 0
lda y + 1
adc __accu + 1
sta __accu + 1
lda y + 2
adc __accu + 2
sta __accu + 2
lda y + 3
adc __accu + 3
sta __accu + 3
w3:
lsr x + 3
bcc w4
clc
lda y + 0
adc __accu + 1
sta __accu + 1
lda y + 1
adc __accu + 2
sta __accu + 2
lda y + 2
adc __accu + 3
sta __accu + 3
w4:
asl y + 0
rol y + 1
rol y + 2
rol y + 3
rol __tmp + 2
rol __tmp + 3
dex
beq w5
jmp l1
w5:
}
}
#else
__native long lmul16f16s(long x, long y)
{
unsigned lox = x;
int hix = x >> 16;
unsigned loy = y;
int hiy = y >> 16;
long r = (long)(hix * hiy) << 16;
if (lox)
{
r += lmul16u(lox, hiy);
if (hiy < 0)
r -= (unsigned long)lox << 16;
}
if (loy)
{
r += lmul16u(loy, hix);
if (hix < 0)
r -= (unsigned long)loy << 16;
}
if (lox && loy)
{
r += lmul16u(lox, loy) >> 16;
}
return r;
}
#endif
__native unsigned long ldiv16f16(unsigned long x, unsigned long y)
{
unsigned long k = x >> 16, d = 0;
x <<= 16;
for(char i=0; i<32; i++)
{
d <<= 1;
k <<= 1;
k |= (x >> 31);
x <<= 1;
if (k >= y)
{
k -= y;
d |= 1;
}
}
return d;
}
__native long ldiv16f16s(long x, long y)
{
bool sign = false;
if (x < 0)
{
x = -x;
sign = true;
}
if (y < 0)
{
y = -y;
sign = !sign;
}
x = ldiv16f16(x, y);
if (sign)
return -x;
else
return x;
}

View File

@ -1,7 +1,7 @@
#ifndef FIXMATH_H #ifndef FIXMATH_H
#define FIXMATH_H #define FIXMATH_H
// Multiply two unsigned 16bit numbers and return a 32bit result // Multiply two unsinged 16bit numbers and return a 32bit result
__native unsigned long lmul16u(unsigned x, unsigned y); __native unsigned long lmul16u(unsigned x, unsigned y);
// Multiply two signed 16bit numbers and return a signed 32bit result // Multiply two signed 16bit numbers and return a signed 32bit result
@ -48,17 +48,6 @@ inline int lmuldiv16sby8(int a, char b, char c);
__native unsigned lmuldiv8by8(char a, char b, char c); __native unsigned lmuldiv8by8(char a, char b, char c);
__native unsigned usqrt(unsigned n);
__native unsigned long lmul16f16(unsigned long x, unsigned long y);
__native long lmul16f16s(long x, long y);
__native unsigned long ldiv16f16(unsigned long x, unsigned long y);
__native long ldiv16f16s(long x, long y);
#pragma compile("fixmath.c") #pragma compile("fixmath.c")
#endif #endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -30,18 +30,6 @@ bool isfinite(float f);
#pragma intrinsic(floor) #pragma intrinsic(floor)
#pragma intrinsic(ceil) #pragma intrinsic(ceil)
#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") #pragma compile("math.c")

View File

@ -1,6 +1,7 @@
#ifndef NES_MMC1_H #ifndef NES_MMC1_H
#define NES_MMC1_H #define NES_MMC1_H
#include <c64/types.h> #include <c64/types.h>
enum MMC1Mirror enum MMC1Mirror

View File

@ -94,7 +94,7 @@ int main(void)
ppu.scroll = 0x00; ppu.scroll = 0x00;
ppu.oamaddr = 0x00; ppu.oamaddr = 0x00;
// detect PAL or NTSC based on Blarg code. // detech PAL or NTSC based on Blarg code.
ppu_wait_nmi(); ppu_wait_nmi();

View File

@ -1,11 +0,0 @@
#pragma once
#include "stddef.h"
namespace std
{
void * operator new(size_t size);
void * operator new(void * ptr, size_t size);
}

View File

@ -1,84 +0,0 @@
#ifndef OPP_ALGORITHM_H
#define OPP_ALGORITHM_H
#include "utility.h"
namespace opp {
template<class T, class LT>
void sort(T s, T e)
{
while (s != e)
{
auto p = s;
auto q = s;
q++;
while (q != e)
{
if (LT(*q, *p))
{
swap(*q, *p);
p++;
swap(*q, *p);
}
q++;
}
sort<T, LT>(s, p);
p++;
s = p;
}
}
template<class T, class LF>
void sort(T s, T e, LF lt)
{
while (s != e)
{
auto p = s;
auto q = s;
q++;
while (q != e)
{
if (lt(*q, *p))
{
swap(*q, *p);
p++;
swap(*q, *p);
}
q++;
}
sort(s, p, lt);
p++;
s = p;
}
}
template<class II, class OI>
OI copy(II first, II last, OI result)
{
while (first != last)
{
*result = *first;
++result; ++first;
}
return result;
}
template<class II, class T>
II find (II first, II last, const T& val)
{
while (first != last)
{
if (*first == val) return first;
++first;
}
return last;
}
}
#endif

View File

@ -1,120 +0,0 @@
#ifndef OPP_ARRAY_H
#define OPP_ARRAY_H
namespace opp {
template <class T, int n>
class array
{
protected:
T _data[n];
public:
typedef T element_type;
int size(void) const
{
return n;
}
int max_size(void) const
{
return n;
}
bool empty(void) const
{
return n == 0;
}
const T & at(int at) const
{
return _data[at];
}
T & at(int at)
{
return _data[at];
}
T & operator[] (int at)
{
return _data[at];
}
const T & operator[] (int at) const
{
return _data[at];
}
T * begin(void)
{
return _data;
}
const T * begin(void) const
{
return _data;
}
const T * cbegin(void) const
{
return _data;
}
T * end(void)
{
return _data + n;
}
const T * end(void) const
{
return _data + n;
}
const T * cend(void) const
{
return _data + n;
}
T & back(void)
{
return _data[n - 1];
}
const T & back(void) const
{
return _data[n - 1];
}
T & front(void)
{
return _data[0];
}
const T & front(void) const
{
return _data[0];
}
T * data(void)
{
return _data;
}
const T * data(void) const
{
return _data;
}
void fill(const T & t)
{
for(int i=0; i<n; i++)
_data[i] = t;
}
};
}
#endif

View File

@ -1,207 +0,0 @@
#ifndef OPP_BIDXLIST_H
#ifndef OPP_BIDXLIST_H
template <class T, int n>
class bindexlist
{
public:
char _free;
char _pred[n], _succ[n];
T _data[n];
class iterator
{
public:
bindexlist * _l;
char _i;
iterator(void) : _l(nullptr) {}
iterator(bindexlist * l, char i)
: _l(l), _i(i) {}
iterator(const iterator & li) : _l(li._l), _i(li._i) {}
iterator & operator=(const iterator & li)
{
_l = li._l;
_i = li._i;
return *this;
}
T & operator*()
{
return _l->_data[_i];
}
T * operator->()
{
return _l->_data + _i;
}
iterator & operator++(void)
{
_i = _l->_succ[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_succ[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator+=(char n)
{
while (n--)
_i = _l->_succ[_i];
return *this;
}
iterator & operator--(void)
{
_i = _l->_pred[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_pred[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator-=(char n)
{
while (n--)
_i = _l->_pred[_i];
return *this;
}
bool operator==(const iterator & li)
{
return _i == li._i;
}
bool operator!=(const iterator & li)
{
return _i != li._i;
}
};
public:
typedef T element_type;
typedef iterator iterator_type;
bindexlist(void)
{
_succ[0] = 0;
_pred[0] = 0;
for(char i=1; i<n; i++)
_succ[i] = i + 1;
_free = 1;
}
~bindexlist(void)
{
}
iterator begin(void)
{
return iterator(this, _succ[0]);
}
iterator end(void)
{
return iterator(this, 0);
}
T & front(void)
{
return _data[_succ[0]];
}
const T & front(void) const
{
return _data[_succ[0]];
}
T & back(void)
{
return _data[_pred[0]];
}
const T & back(void) const
{
return _data[_pred[0]];
}
iterator erase(iterator it)
{
char s = _succ[it._i];
_succ[_pred[it._i]] = _pred[it._i];
_pred[_succ[it._i]] = s;
_succ[it._i] = _free;
_free = it._i;
return iterator(this, s);
}
iterator erase(iterator first, iterator last)
{
char s = _succ[last._i];
_succ[_pred[last._i]] = _pred[first._i];
_pred[_succ[first._i]] = s;
_succ[last._i] = _free;
_free = first._i;
return iterator(this, s);
}
void pop_front(void)
{
char i = _succ[0];
char s = _succ[i];
_pred[s] = 0;
_succ[0] = s;
_succ[i] = _free;
_free = i;
}
void pop_back(void)
{
char i = _pred[0];
char p = _pred[i];
_succ[p] = 0;
_pred[0] = p;
_pred[i] = _free;
_free = i;
}
void push_back(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_pred[i] = _pred[0];
_succ[_pred[0]] = i;
_pred[0] = i;
}
void push_front(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_succ[i] = _succ[0];
_pred[_succ[0]] = i;
_succ[0] = i;
}
};
#endif

View File

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

View File

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

View File

@ -1,24 +0,0 @@
#include "ifstream.h"
#include <c64/kernalio.h>
namespace opp {
ifstream::ifstream(char fnum, char device, char channel, const string & name)
{
this->fnum = fnum;
krnio_setnam(name.tocstr());
krnio_open(fnum, device, channel);
}
ifstream::~ifstream(void)
{
krnio_close(fnum);
}
void ifstream::refill(void)
{
mBufferPos = 0;
mBufferFill = krnio_read(fnum, mBuffer, 32);
}
}

View File

@ -1,25 +0,0 @@
#ifndef OPP_IFSTREAM_H
#define OPP_IFSTREAM_H
#include "iostream.h"
#include "string.h"
namespace opp {
class ifstream : public istream
{
public:
ifstream(char fnum, char device, char channel, const string & name);
~ifstream(void);
protected:
virtual void refill(void);
char fnum;
};
}
#pragma compile("ifstream.cpp")
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,217 +0,0 @@
#ifndef OPP_IOSTREAM_H
#define OPP_IOSTREAM_H
#include <opp/string.h>
namespace opp {
class ios
{
public:
constexpr ios(void);
virtual ~ios(void);
char fill() const;
char fill(char cillch);
char width() const;
char width(char wide);
char precision() const;
char precision(char prec);
enum fmtflags
{
boolalpha = 0x0001,
dec = 0x0002,
fixed = 0x0004,
hex = 0x0008,
internal = 0x0010,
left = 0x0020,
oct = 0x0040,
right = 0x0080,
scientific = 0x0100,
showbase = 0x0200,
showpoint = 0x0400,
showpos = 0x0800,
skipws = 0x1000,
unitbuf = 0x2000,
uppercase = 0x4000,
adjustfield = 0x00b0,
basefield = 0x004a,
floatfield = 0x0104
};
enum statebits
{
goodbit = 0,
badbit = 1,
eofbit = 2,
failbit = 4,
};
fmtflags flags(void) const;
fmtflags flags(fmtflags f);
fmtflags setf(fmtflags f);
fmtflags setf(fmtflags f, fmtflags m);
fmtflags unsetf(fmtflags f);
bool good(void) const;
bool eof(void) const;
bool fail(void) const;
bool bad(void) const;
bool operator!(void) const;
operator bool(void);
statebits rdstate(void) const;
void clear(void);
protected:
fmtflags mFlags;
statebits mState;
char mWidth;
char mPrecision;
char mFill;
};
class ostream;
typedef ostream & (* manip)(ostream &);
class ostream : public ios
{
public:
constexpr ostream(void);
ostream & put(char c);
ostream & write(const char * s, int n);
ostream & operator<<(bool val);
ostream & operator<<(char val);
ostream & operator<<(int val);
ostream & operator<<(unsigned val);
ostream & operator<<(long val);
ostream & operator<<(unsigned long val);
ostream & operator<<(float val);
ostream & operator<<(const char * p);
ostream & operator<<(const string & s);
ostream & operator<<(manip m);
protected:
void putnum(const char * buffer, char prefix, char size);
void numput(unsigned n, char sign);
void numput(unsigned long n, char sign);
virtual void bput(char ch);
};
class istream : public ios
{
public:
char get(void);
istream & get(char & c);
istream & get(char * s, char size);
istream & get(char * s, char size, char delim);
istream & getline(char * s, char size);
istream & getline(char * s, char size, char delim);
istream & ignore(char size);
istream & ignore(char size, char delim);
istream & putback(char c);
istream & unget(void);
istream & operator>>(char & val);
istream & operator>>(bool & val);
istream & operator>>(int & val);
istream & operator>>(unsigned & val);
istream & operator>>(long & val);
istream & operator>>(unsigned long & val);
istream & operator>>(float & val);
istream & operator>>(char * p);
istream & operator>>(string & s);
istream(void);
protected:
char mBuffer[32];
char mBufferPos, mBufferFill;
virtual void refill(void);
unsigned getnum(void);
unsigned long getnuml(void);
float getnumf(void);
void doskipws(void);
};
class costream : public ostream
{
public:
constexpr costream(void);
protected:
void bput(char ch);
};
class cistream : public istream
{
public:
cistream(void);
protected:
void refill(void);
};
ostream & endl(ostream & os);
struct iosetf {
ios::fmtflags flags;
iosetf(ios::fmtflags flags_) : flags(flags_) {}
};
ostream & operator<<(ostream & os, const iosetf & s);
iosetf setf(ios::fmtflags flags);
struct iosetw {
char width;
iosetw(char width_) : width(width_) {}
};
iosetw setw(char width);
ostream & operator<<(ostream & os, const iosetw & s);
struct iosetprecision {
char precision;
iosetprecision(char precision_) : precision(precision_) {}
};
iosetprecision setprecision(char precision);
ostream & operator<<(ostream & os, const iosetprecision & s);
struct iosetfill {
char fill;
iosetfill(char fill_) : fill(fill_) {}
};
iosetfill setfill(char fill);
ostream & operator<<(ostream & os, const iosetfill & s);
extern cistream cin;
extern costream cout;
}
#pragma compile("iostream.cpp");
#endif

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