├── include ├── c64 │ ├── sid.c │ ├── types.h │ ├── joystick.h │ ├── joystick.c │ ├── cia.c │ ├── cia.h │ ├── mouse.h │ ├── memmap.h │ ├── iecbus.h │ ├── mouse.c │ ├── easyflash.h │ ├── asm6502.c │ └── reu.h ├── nes │ ├── nes.c │ ├── mmc1.h │ ├── mmc3.c │ ├── mmc3.h │ ├── mmc1.c │ └── nes.h ├── vic20 │ ├── vic.c │ └── vic.h ├── petscii.h ├── assert.c ├── assert.h ├── c128 │ ├── mmu.c │ ├── mmu.h │ ├── bank1.h │ ├── bank1.c │ ├── vdc.c │ └── vdc.h ├── gfx │ └── tinyfont.h ├── new ├── time.h ├── stdbool.h ├── stddef.h ├── stdarg.h ├── limits.h ├── iso646.h ├── setjmp.h ├── opp │ ├── ifstream.h │ ├── ifstream.cpp │ ├── ofstream.h │ ├── utility.h │ ├── ofstream.cpp │ ├── sstream.h │ ├── boundint.h │ ├── algorithm.h │ ├── slab.h │ ├── functional.h │ ├── sstream.cpp │ └── array.h ├── inttypes.c ├── audio │ └── sidfx.h ├── ctype.h ├── oscar.h ├── time.c ├── math.h ├── string.h ├── stdio.h ├── plus4 │ └── ted.c ├── stdlib.h └── inttypes.h ├── autotest ├── opp_part1.cpp ├── opp_part2.cpp ├── strcmptest.c ├── floortest.c ├── opp_part2.h ├── arrparam.c ├── optiontest.c ├── randsumtest.c ├── byteindextest.c ├── arrayoffsetindex.c ├── structoffsettest2.c ├── arrayindexintrangecheck.c ├── staticconsttest.c ├── incvector.c ├── enumswitch.c ├── copyintvec.c ├── fastcalltest.c ├── arraytestfloat.c ├── loopdomtest.c ├── autotest.h ├── testint16mul.c ├── opp_array.cpp ├── funcarraycall.c ├── opp_parts.cpp ├── testsigned16mul.c ├── bsstest.c ├── copyinitmove.c ├── arrayinittest.c ├── structassigntest.c ├── testsigned16div.c ├── linetest.c ├── longcodetest.c ├── opp_pairtest.cpp ├── strlen.c ├── floatmultest.c ├── maskcheck.c ├── ptrinittest.c ├── opp_part1.h ├── ptrarraycmptest.c ├── floatstringtest.c ├── mathtest.c ├── structmembertest.c ├── opp_vector_string.cpp ├── structarraycopy.c ├── divmodtest.c ├── virtualdestruct.cpp ├── switchlooptest.c ├── mmultest.c ├── opp_list.cpp ├── andmultest.cpp ├── opp_functional.cpp ├── divmod32test.c ├── memmovetest.c ├── mixsigncmptest.c ├── testinterval.c ├── autorefreturn.cpp ├── opp_numeric.cpp ├── opp_optional.cpp ├── charwintest.c ├── array2stringinittest.c ├── operatoroverload.cpp ├── vcalltest.cpp ├── funcvartest.c ├── qsorttest.c ├── vcalltree.cpp ├── opp_streamtest.cpp ├── loopboundtest.c ├── recursiontest.c ├── opp_span.cpp ├── opp_vector.cpp ├── opp_static_vector.cpp ├── copyassign.cpp ├── floatinttest.c ├── cplxstructtest.c ├── rolrortest.cpp ├── scrolltest.c ├── fixmathtest.c ├── asmtest.c └── arraytest.c ├── samples ├── stdio │ ├── make.bat │ ├── build.sh │ ├── helloworld.c │ └── makefile ├── games │ ├── lander.png │ ├── maze3d.png │ ├── missile.png │ ├── breakout.png │ ├── connectfour.png │ ├── hscrollshmup.png │ ├── build.sh │ ├── make.bat │ └── makefile ├── hires │ ├── bitblit.png │ ├── func3d.png │ ├── fractaltree.png │ ├── build.sh │ ├── make.bat │ ├── makefile │ ├── fractaltree.c │ ├── lines.c │ ├── polygon.c │ └── bitblit.c ├── hiresmc │ ├── polygon.png │ ├── build.sh │ ├── make.bat │ ├── makefile │ ├── floodfill.c │ └── polygon.c ├── resources │ ├── mouse.spd │ ├── blumba2.bin │ ├── charset.bin │ ├── ballsprite.bin │ ├── scifiglyph.bin │ ├── breakoutchars.bin │ ├── connect4chars.bin │ ├── digitsprites.bin │ ├── friendlybear.bin │ ├── landersprites.bin │ ├── maze3dchars.bin │ ├── missilechars.bin │ ├── breakoutsprites.bin │ ├── connect4sprites.bin │ ├── missilesprites.bin │ ├── hscrollshmupchars.bin │ ├── hscrollshmuptiles.bin │ ├── hscrollshmupsprites.bin │ └── hscrollshmupmap.bin ├── fractals │ ├── mbmulti3d.png │ ├── build.sh │ ├── make.bat │ ├── makefile │ ├── mbtext.c │ └── mbhires.c ├── scrolling │ ├── bigfont.png │ ├── build.sh │ ├── make.bat │ └── makefile ├── sprites │ ├── creditroll.png │ ├── sprmux32.png │ ├── sprmux64.png │ ├── multiplexer.png │ ├── build.sh │ ├── make.bat │ ├── makefile │ ├── joycontrol.c │ └── multiplexer.c ├── rasterirq │ ├── colorbars.png │ ├── build.sh │ ├── make.bat │ ├── makefile │ ├── colorbars.c │ ├── textcrawler.c │ ├── autocrawler.c │ └── movingbars.c ├── particles │ ├── build.sh │ ├── make.bat │ └── makefile ├── kernalio │ ├── build.sh │ ├── makefile │ ├── make.bat │ ├── charwrite.c │ ├── charread.c │ ├── filewrite.c │ ├── fileread.c │ ├── hiresread.c │ ├── diskdir.c │ ├── hiresfload.c │ └── hireswrite.c ├── build.sh ├── make.bat ├── memmap │ ├── build.sh │ ├── charsethi.c │ ├── make.bat │ ├── largemem.c │ ├── charsetlo.c │ ├── easyflashlow.c │ ├── charsetload.c │ ├── makefile │ ├── allmem.c │ ├── tsr.c │ ├── charsetcopy.c │ └── charsetexpand.c └── makefile ├── .gitattributes ├── oscar64 ├── Compression.h ├── MachineTypes.cpp ├── resource.h ├── DiskImage.h ├── Ident.h ├── CompilationUnits.h ├── Compression.cpp ├── Emulator.h ├── Disassembler.h ├── GlobalAnalyzer.h ├── GlobalOptimizer.h ├── Compiler.h ├── NativeCodeOutliner.h └── Errors.cpp ├── makezip.bat └── .github └── workflows └── check.yaml /include/c64/sid.c: -------------------------------------------------------------------------------- 1 | #include "sid.h" 2 | 3 | -------------------------------------------------------------------------------- /include/nes/nes.c: -------------------------------------------------------------------------------- 1 | #include "nes.h" 2 | 3 | -------------------------------------------------------------------------------- /include/vic20/vic.c: -------------------------------------------------------------------------------- 1 | #include "vic.h" 2 | 3 | -------------------------------------------------------------------------------- /autotest/opp_part1.cpp: -------------------------------------------------------------------------------- 1 | #include "opp_part1.h" 2 | 3 | -------------------------------------------------------------------------------- /samples/stdio/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 helloworld.c 2 | -------------------------------------------------------------------------------- /samples/stdio/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 helloworld.c 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /samples/games/lander.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/games/lander.png -------------------------------------------------------------------------------- /samples/games/maze3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/games/maze3d.png -------------------------------------------------------------------------------- /samples/games/missile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/games/missile.png -------------------------------------------------------------------------------- /samples/hires/bitblit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/hires/bitblit.png -------------------------------------------------------------------------------- /samples/hires/func3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/hires/func3d.png -------------------------------------------------------------------------------- /samples/games/breakout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/games/breakout.png -------------------------------------------------------------------------------- /samples/hiresmc/polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/hiresmc/polygon.png -------------------------------------------------------------------------------- /samples/resources/mouse.spd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/mouse.spd -------------------------------------------------------------------------------- /samples/fractals/mbmulti3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/fractals/mbmulti3d.png -------------------------------------------------------------------------------- /samples/games/connectfour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/games/connectfour.png -------------------------------------------------------------------------------- /samples/games/hscrollshmup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/games/hscrollshmup.png -------------------------------------------------------------------------------- /samples/hires/fractaltree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/hires/fractaltree.png -------------------------------------------------------------------------------- /samples/resources/blumba2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/blumba2.bin -------------------------------------------------------------------------------- /samples/resources/charset.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/charset.bin -------------------------------------------------------------------------------- /samples/scrolling/bigfont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/scrolling/bigfont.png -------------------------------------------------------------------------------- /samples/sprites/creditroll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/sprites/creditroll.png -------------------------------------------------------------------------------- /samples/sprites/sprmux32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/sprites/sprmux32.png -------------------------------------------------------------------------------- /samples/sprites/sprmux64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/sprites/sprmux64.png -------------------------------------------------------------------------------- /include/petscii.h: -------------------------------------------------------------------------------- 1 | /* petscii upper charset */ 2 | 3 | #pragma charmap(97, 65, 26) 4 | #pragma charmap(65, 97, 26) 5 | 6 | -------------------------------------------------------------------------------- /samples/rasterirq/colorbars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/rasterirq/colorbars.png -------------------------------------------------------------------------------- /samples/resources/ballsprite.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/ballsprite.bin -------------------------------------------------------------------------------- /samples/resources/scifiglyph.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/scifiglyph.bin -------------------------------------------------------------------------------- /samples/sprites/multiplexer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/sprites/multiplexer.png -------------------------------------------------------------------------------- /samples/resources/breakoutchars.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/breakoutchars.bin -------------------------------------------------------------------------------- /samples/resources/connect4chars.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/connect4chars.bin -------------------------------------------------------------------------------- /samples/resources/digitsprites.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/digitsprites.bin -------------------------------------------------------------------------------- /samples/resources/friendlybear.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/friendlybear.bin -------------------------------------------------------------------------------- /samples/resources/landersprites.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/landersprites.bin -------------------------------------------------------------------------------- /samples/resources/maze3dchars.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/maze3dchars.bin -------------------------------------------------------------------------------- /samples/resources/missilechars.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/missilechars.bin -------------------------------------------------------------------------------- /samples/resources/breakoutsprites.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/breakoutsprites.bin -------------------------------------------------------------------------------- /samples/resources/connect4sprites.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/connect4sprites.bin -------------------------------------------------------------------------------- /samples/resources/missilesprites.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/missilesprites.bin -------------------------------------------------------------------------------- /include/assert.c: -------------------------------------------------------------------------------- 1 | #include "assert.h" 2 | #include 3 | 4 | void assert(bool b) 5 | { 6 | if (!b) 7 | exit(-1); 8 | } 9 | -------------------------------------------------------------------------------- /samples/resources/hscrollshmupchars.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/hscrollshmupchars.bin -------------------------------------------------------------------------------- /samples/resources/hscrollshmuptiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/hscrollshmuptiles.bin -------------------------------------------------------------------------------- /include/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSERT_H 2 | #define ASSERT_H 3 | 4 | void assert(bool b); 5 | 6 | #pragma compile("assert.c") 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /samples/resources/hscrollshmupsprites.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drmortalwombat/oscar64/HEAD/samples/resources/hscrollshmupsprites.bin -------------------------------------------------------------------------------- /oscar64/Compression.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CompilerTypes.h" 4 | 5 | int CompressLZO(uint8* dst, const uint8* source, int size); 6 | 7 | -------------------------------------------------------------------------------- /include/c128/mmu.c: -------------------------------------------------------------------------------- 1 | #include "mmu.h" 2 | 3 | inline char mmu_set(char cr) 4 | { 5 | char pcr = mmu.cr; 6 | mmu.cr = cr; 7 | return pcr; 8 | } 9 | -------------------------------------------------------------------------------- /include/gfx/tinyfont.h: -------------------------------------------------------------------------------- 1 | #ifndef TINYFONT_H 2 | #define TINYFONT_H 3 | 4 | extern const char TinyFont[]; 5 | 6 | #pragma compile("tinyfont.c") 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /samples/stdio/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | putchar(14); 6 | printf(p"Hello World\n"); 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /samples/particles/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 -n fireworks_ptr.c 3 | ../../bin/oscar64 -n fireworks_hires.c 4 | ../../bin/oscar64 -n fireworks_stripe.c 5 | 6 | -------------------------------------------------------------------------------- /samples/hiresmc/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 func3d.c -n 3 | ../../bin/oscar64 polygon.c -n 4 | ../../bin/oscar64 floodfill.c -n 5 | ../../bin/oscar64 paint.c -n 6 | -------------------------------------------------------------------------------- /samples/hiresmc/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 floodfill.c -n 2 | call ..\..\bin\oscar64 polygon.c -n 3 | call ..\..\bin\oscar64 func3d.c -n 4 | call ..\..\bin\oscar64 paint.c -n 5 | -------------------------------------------------------------------------------- /samples/particles/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 -n fireworks_ptr.c 2 | call ..\..\bin\oscar64 -n fireworks_hires.c 3 | call ..\..\bin\oscar64 -n fireworks_stripe.c -O2 4 | 5 | -------------------------------------------------------------------------------- /samples/rasterirq/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 colorbars.c 3 | ../../bin/oscar64 openborder.c 4 | ../../bin/oscar64 textcrawler.c 5 | ../../bin/oscar64 movingbars.c -n 6 | -------------------------------------------------------------------------------- /include/new: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stddef.h" 4 | 5 | namespace std 6 | { 7 | 8 | void * operator new(size_t size); 9 | void * operator new(void * ptr, size_t size); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /include/time.h: -------------------------------------------------------------------------------- 1 | #ifndef TIME_H 2 | #define TIME_H 3 | 4 | typedef long clock_t; 5 | 6 | #define CLOCKS_PER_SEC 60L 7 | 8 | clock_t clock(void); 9 | 10 | #pragma compile("time.c") 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /samples/stdio/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: helloworld.prg 6 | 7 | clean: 8 | @$(RM) *.asm *.int *.lbl *.map *.prg *.bcs 9 | -------------------------------------------------------------------------------- /samples/scrolling/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 bigfont.c -n 3 | ../../bin/oscar64 tunnel.c -n 4 | ../../bin/oscar64 grid2d.c -n 5 | ../../bin/oscar64 colorram.c -n 6 | ../../bin/oscar64 cgrid8way.c -n 7 | -------------------------------------------------------------------------------- /include/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifndef STDBOOL_H 2 | #define STDBOOL_H 3 | 4 | #define bool _Bool 5 | #define true (0 == 0) 6 | #define false (0 != 0) 7 | 8 | #define __bool_true_false_are_defined 1 9 | 10 | #endif 11 | 12 | -------------------------------------------------------------------------------- /samples/scrolling/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 bigfont.c -n 2 | call ..\..\bin\oscar64 tunnel.c -n 3 | call ..\..\bin\oscar64 grid2d.c -n 4 | call ..\..\bin\oscar64 colorram.c -n 5 | call ..\..\bin\oscar64 cgrid8way.c -n 6 | -------------------------------------------------------------------------------- /include/c64/types.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_TYPES_H 2 | #define C64_TYPES_H 3 | 4 | typedef unsigned char byte; 5 | typedef unsigned int word; 6 | typedef unsigned long dword; 7 | 8 | typedef signed char sbyte; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /samples/rasterirq/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 colorbars.c 2 | call ..\..\bin\oscar64 openborder.c 3 | call ..\..\bin\oscar64 textcrawler.c 4 | call ..\..\bin\oscar64 movingbars.c -n 5 | call ..\..\bin\oscar64 autocrawler.c -n 6 | -------------------------------------------------------------------------------- /samples/hiresmc/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: func3d.prg polygon.prg floodfill.prg paint.prg 6 | 7 | clean: 8 | @$(RM) *.asm *.int *.lbl *.map *.prg 9 | -------------------------------------------------------------------------------- /autotest/opp_part2.cpp: -------------------------------------------------------------------------------- 1 | #include "opp_part2.h" 2 | 3 | BS::BS(const opp::vector & v) 4 | : va(v) 5 | {} 6 | 7 | int BS::sum(void) 8 | { 9 | int s = 0; 10 | for(const auto & a : va) 11 | s += a.sum(); 12 | return s; 13 | } 14 | -------------------------------------------------------------------------------- /include/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef STDDEF_H 2 | #define STDDEF_H 3 | 4 | #define NULL nullptr 5 | 6 | typedef unsigned int size_t; 7 | typedef signed int ptrdiff_t; 8 | 9 | #define offsetof(st, m) ((size_t)&(((st *)0)->m)) 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /makezip.bat: -------------------------------------------------------------------------------- 1 | mkdir r:\oscar64 2 | mkdir r:\oscar64\bin 3 | mkdir r:\oscar64\include 4 | 5 | xcopy /y bin\oscar64.exe r:\oscar64\bin 6 | xcopy /y /e include r:\oscar64\include 7 | 8 | tar -caf r:\oscar64.zip r:\oscar64 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /samples/particles/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: fireworks_ptr.prg fireworks_hires.prg fireworks_stripe.prg 6 | 7 | clean: 8 | @$(RM) *.asm *.int *.lbl *.map *.prg 9 | -------------------------------------------------------------------------------- /samples/scrolling/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: bigfont.prg tunnel.prg grid2d.prg colorram.prg cgrid8way.prg 6 | 7 | clean: 8 | @$(RM) *.asm *.int *.lbl *.map *.prg 9 | -------------------------------------------------------------------------------- /samples/sprites/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 joycontrol.c 3 | ../../bin/oscar64 multiplexer.c -n 4 | ../../bin/oscar64 creditroll.c -n 5 | ../../bin/oscar64 -n sprmux32.c -O2 -dVSPRITES_MAX=32 -dNUM_IRQS=28 6 | ../../bin/oscar64 -n sprmux64.c 7 | -------------------------------------------------------------------------------- /samples/fractals/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 mbtext.c -n 3 | ../../bin/oscar64 mbhires.c -n 4 | ../../bin/oscar64 mbmulti.c -n 5 | ../../bin/oscar64 mbmulti3d.c -n 6 | ../../bin/oscar64 mbfixed.c -n -O3 7 | ../../bin/oscar64 mbzoom.c -n -O3 8 | 9 | -------------------------------------------------------------------------------- /autotest/strcmptest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | assert(strcmp("ABCD", "ABCD") == 0); 7 | assert(strcmp("ABCE", "ABCD") == 1); 8 | assert(strcmp("ABCD", "ABCE") == -1); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /samples/fractals/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 mbtext.c -n 2 | call ..\..\bin\oscar64 mbhires.c -n 3 | call ..\..\bin\oscar64 mbmulti.c -n 4 | call ..\..\bin\oscar64 mbmulti3d.c -n 5 | call ..\..\bin\oscar64 mbfixed.c -n -O3 6 | call ..\..\bin\oscar64 mbzoom.c -n -O3 7 | -------------------------------------------------------------------------------- /samples/sprites/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 joycontrol.c 2 | call ..\..\bin\oscar64 multiplexer.c -n 3 | call ..\..\bin\oscar64 creditroll.c -n 4 | call ..\..\bin\oscar64 -n sprmux32.c -O2 -dVSPRITES_MAX=32 -dNUM_IRQS=28 5 | call ..\..\bin\oscar64 -n sprmux64.c 6 | -------------------------------------------------------------------------------- /autotest/floortest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | for(int y=1; y<100; y++) 7 | { 8 | float fz = 100.0 / (float)y; 9 | printf("%d %f %f\n", y, floor(fz * 100.0), fz * 100.0); 10 | } 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /autotest/opp_part2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "opp_part1.h" 4 | 5 | class BS 6 | { 7 | protected: 8 | opp::vector va; 9 | public: 10 | BS(const opp::vector & v); 11 | int sum(void); 12 | }; 13 | 14 | 15 | 16 | #pragma compile("opp_part2.cpp") 17 | -------------------------------------------------------------------------------- /samples/kernalio/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 diskdir.c 3 | ../../bin/oscar64 filewrite.c 4 | ../../bin/oscar64 fileread.c 5 | ../../bin/oscar64 charwrite.c 6 | ../../bin/oscar64 charread.c 7 | ../../bin/oscar64 hireswrite.c 8 | ../../bin/oscar64 hiresread.c 9 | -------------------------------------------------------------------------------- /autotest/arrparam.c: -------------------------------------------------------------------------------- 1 | 2 | int a(char p[100]) 3 | { 4 | int s = 0; 5 | for(int i=0; i<100; i++) 6 | s += p[i]; 7 | return s; 8 | } 9 | 10 | int main(void) 11 | { 12 | char c[100]; 13 | for(int i=0; i<100; i++) 14 | c[i] = i; 15 | return a(c) - 4950; 16 | } 17 | -------------------------------------------------------------------------------- /autotest/optiontest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int option(bool a, int b, int c) 5 | { 6 | return a ? b : c; 7 | } 8 | 9 | int main(void) 10 | { 11 | assert(option(true, 1, 2) == 1); 12 | assert(option(false, 1, 2) == 2); 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /autotest/randsumtest.c: -------------------------------------------------------------------------------- 1 | // randsumtest 2 | 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | long lsum = 0; 9 | for(unsigned i=0; i<1000; i++) 10 | lsum += rand(); 11 | 12 | assert(lsum == 32157742L); 13 | 14 | return 0; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /samples/kernalio/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: diskdir.prg filewrite.prg fileread.prg charwrite.prg charread.prg hireswrite.prg hiresread.prg 6 | 7 | clean: 8 | @$(RM) *.asm *.int *.lbl *.map *.prg *.bcs 9 | -------------------------------------------------------------------------------- /samples/games/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 snake.c 3 | ../../bin/oscar64 lander.c -n 4 | ../../bin/oscar64 maze3d.c -n 5 | ../../bin/oscar64 missile.c -O3 -n 6 | ../../bin/oscar64 breakout.c -n 7 | ../../bin/oscar64 connectfour.c -n 8 | ../../bin/oscar64 hscrollshmup.c -O2 -n 9 | 10 | -------------------------------------------------------------------------------- /autotest/byteindextest.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | char a[20]; 6 | 7 | int main(void) 8 | { 9 | for(char i=0; i<20; i++) 10 | a[i] = i; 11 | char x = 0; 12 | for(char i=0; i<20; i++) 13 | x += a[i]; 14 | 15 | assert(x == 190); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /include/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef STDARG_H 2 | #define STDARG_H 3 | 4 | typedef void *va_list; 5 | 6 | #define va_start(list, name) (void) (list = &name + 1) 7 | 8 | #define va_arg(list, mode) ((mode *)(list = (char *)list + sizeof (mode)))[-1] 9 | 10 | #define va_end(list) (void)0 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /samples/games/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 snake.c 2 | call ..\..\bin\oscar64 -n lander.c 3 | call ..\..\bin\oscar64 -n maze3d.c 4 | call ..\..\bin\oscar64 -n -O3 missile.c 5 | call ..\..\bin\oscar64 -n breakout.c 6 | call ..\..\bin\oscar64 -n connectfour.c 7 | call ..\..\bin\oscar64 -n -O2 hscrollshmup.c 8 | -------------------------------------------------------------------------------- /samples/hires/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 splitscreen.c 3 | ../../bin/oscar64 func3d.c -n 4 | ../../bin/oscar64 lines.c -n 5 | ../../bin/oscar64 polygon.c -n 6 | ../../bin/oscar64 bitblit.c -n 7 | ../../bin/oscar64 cube3d.c -n 8 | ../../bin/oscar64 fractaltree.c -n 9 | ../../bin/oscar64 qsort.c -n 10 | -------------------------------------------------------------------------------- /autotest/arrayoffsetindex.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int a(int * p, int x) 4 | { 5 | int y = x + 3; 6 | 7 | p[y] = 1; 8 | p[y + 1] = 2; 9 | p[y + 2] = 3; 10 | p[y + 3] = 4; 11 | 12 | return p[y] + p[y + 1] + p[y + 2] + p[y + 3]; 13 | } 14 | 15 | int main(void) 16 | { 17 | int t[16]; 18 | 19 | return a(t, 4) - 10; 20 | } 21 | -------------------------------------------------------------------------------- /autotest/structoffsettest2.c: -------------------------------------------------------------------------------- 1 | struct A 2 | { 3 | int x; 4 | struct B 5 | { 6 | int m; 7 | struct C 8 | { 9 | int w; 10 | } c; 11 | } b; 12 | } q; 13 | 14 | int test(A * a) 15 | { 16 | a->b.c.w = 1; 17 | return a->b.c.w; 18 | } 19 | 20 | int main(void) 21 | { 22 | return test(&q) - 1; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /samples/hires/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 splitscreen.c 2 | call ..\..\bin\oscar64 func3d.c -n 3 | call ..\..\bin\oscar64 lines.c -n 4 | call ..\..\bin\oscar64 polygon.c -n 5 | call ..\..\bin\oscar64 bitblit.c -n 6 | call ..\..\bin\oscar64 cube3d.c -n 7 | call ..\..\bin\oscar64 fractaltree.c -n 8 | call ..\..\bin\oscar64 qsort.c -n 9 | -------------------------------------------------------------------------------- /autotest/arrayindexintrangecheck.c: -------------------------------------------------------------------------------- 1 | int a[10]; 2 | 3 | int get(int i) 4 | { 5 | return a[i]; 6 | } 7 | 8 | void put(int i, int x) 9 | { 10 | a[i] = x; 11 | } 12 | 13 | int main(void) 14 | { 15 | for(int j=0; j<10; j++) 16 | put(j, j); 17 | int s = -45; 18 | for(int j=0; j<10; j++) 19 | s += get(j); 20 | return s; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /samples/rasterirq/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: colorbars.prg openborder.prg textcrawler.prg movingbars.prg 6 | 7 | movingbars.prg: movingbars.c 8 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -n 9 | 10 | clean: 11 | @$(RM) *.asm *.int *.lbl *.map *.prg *.bcs 12 | -------------------------------------------------------------------------------- /autotest/staticconsttest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static const int size = 100; 5 | 6 | int main(void) 7 | { 8 | int a[size]; 9 | 10 | for(int i=0; i 2 | #include 3 | 4 | int p1(int a, int b) 5 | { 6 | return a + b; 7 | } 8 | 9 | int p2(int a, int b) 10 | { 11 | return a * b; 12 | } 13 | 14 | int c1(int x) 15 | { 16 | return x; 17 | } 18 | 19 | int c2(int x) 20 | { 21 | return c1(x); 22 | } 23 | 24 | int main(void) 25 | { 26 | return p1(5, p2(c2(2), c2(4))) - 13; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /include/c64/joystick.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_JOYSTICK_H 2 | #define C64_JOYSTICK_H 3 | 4 | #include "types.h" 5 | 6 | extern sbyte joyx[2], joyy[2]; 7 | extern bool joyb[2]; 8 | 9 | // poll joystick input for joystick 0 or 1 and place 10 | // the x/y direction and the button status into the joyx/y/b 11 | // arrays for 12 | 13 | void joy_poll(char n); 14 | 15 | #pragma compile("joystick.c") 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /autotest/arraytestfloat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | float sum(float * a, int s) 5 | { 6 | float sum = 0; 7 | for(int i=0; i 2 | #include 3 | 4 | 5 | int main(void) 6 | { 7 | int a[10][10]; 8 | 9 | for(int i=0; i<10; i++) 10 | { 11 | for(int j=0; j<10; j++) 12 | { 13 | a[i][j] = i + j; 14 | } 15 | } 16 | 17 | int s = 0; 18 | 19 | for(int i=0; i<10; i++) 20 | { 21 | s += a[i][i]; 22 | } 23 | 24 | 25 | assert(s == 90); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /autotest/autotest.h: -------------------------------------------------------------------------------- 1 | #ifndef AUTOTEST_H 2 | #define AUTOTEST_H 3 | 4 | struct TestIO 5 | { 6 | volatile char cnt0, cnt1; 7 | volatile unsigned dmaddr; 8 | volatile char dmdata; 9 | volatile char mirror0, mirror1, mirror2; 10 | volatile long cycles; 11 | volatile char scratch[4]; 12 | }; 13 | 14 | #define testio (*((struct TestIO *)0xdd80)) 15 | #define testio2 (*((struct TestIO *)0xdd90)) 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /autotest/testint16mul.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int mul[32][32]; 4 | 5 | int main(void) 6 | { 7 | for(int i=0; i<32; i++) 8 | for(int j=0; j<32; j++) 9 | mul[i][j] = i * j; 10 | #assign xi 0 11 | #repeat 12 | 13 | for(int j=0; j<32; j++) 14 | { 15 | assert(mul[xi][j] == xi * j); 16 | assert(mul[j][xi] == j * xi); 17 | } 18 | 19 | #assign xi xi + 1 20 | #until xi == 32 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /oscar64/MachineTypes.cpp: -------------------------------------------------------------------------------- 1 | #include "MachineTypes.h" 2 | 3 | uint8 BC_REG_WORK = 0x03; 4 | uint8 BC_REG_WORK_Y = 0x02; 5 | uint8 BC_REG_FPARAMS = 0x0d; 6 | uint8 BC_REG_FPARAMS_END = 0x19; 7 | 8 | uint8 BC_REG_IP = 0x19; 9 | uint8 BC_REG_ACCU = 0x1b; 10 | uint8 BC_REG_ADDR = 0x1f; 11 | uint8 BC_REG_STACK = 0x23; 12 | uint8 BC_REG_LOCALS = 0x25; 13 | 14 | uint8 BC_REG_TMP = 0x43; 15 | uint8 BC_REG_TMP_SAVED = 0x53; 16 | 17 | -------------------------------------------------------------------------------- /samples/fractals/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: mbtext.prg mbtext.prg mbhires.prg mbmulti.prg mbmulti3d.prg mbfixed.prg mbzoom.prg 6 | 7 | mbfixed.prg: mbfixed.c 8 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) -O3 $< 9 | 10 | mbzoom.prg: mbzoom.c 11 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) -O3 $< 12 | 13 | clean: 14 | @$(RM) *.asm *.int *.lbl *.map *.prg 15 | -------------------------------------------------------------------------------- /samples/sprites/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: joycontrol.prg multiplexer.prg creditroll.prg sprmux32.prg sprmux64.prg 6 | 7 | joycontrol.prg: joycontrol.c 8 | @$(OSCAR64_CC) $< 9 | 10 | sprmux32.prg: sprmux32.c 11 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -O2 -dVSPRITES_MAX=32 -dNUM_IRQS=28 12 | 13 | clean: 14 | @$(RM) *.asm *.int *.lbl *.map *.prg *.bcs 15 | -------------------------------------------------------------------------------- /autotest/opp_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | opp::array a10; 7 | opp::array a20; 8 | 9 | for(int i=0; i<10; i++) 10 | a10[i] = i; 11 | for(int i=0; i<20; i++) 12 | a20[i] = i; 13 | 14 | int s = 0; 15 | for(int i=0; i<10; i++) 16 | s += a10[i]; 17 | for(int i=10; i<20; i++) 18 | s -= a20[i]; 19 | 20 | assert(s == -100); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /samples/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ( cd fractals ; ./build.sh ) 4 | 5 | ( cd games ; ./build.sh ) 6 | 7 | ( cd hires ; ./build.sh ) 8 | 9 | ( cd hiresmc ; ./build.sh ) 10 | 11 | ( cd particles ; ./build.sh ) 12 | 13 | ( cd kernalio ; ./build.sh ) 14 | 15 | ( cd memmap ; ./build.sh ) 16 | 17 | ( cd rasterirq ; ./build.sh ) 18 | 19 | ( cd scrolling ; ./build.sh ) 20 | 21 | ( cd sprites ; ./build.sh ) 22 | 23 | ( cd stdio ; ./build.sh ) 24 | 25 | -------------------------------------------------------------------------------- /include/setjmp.h: -------------------------------------------------------------------------------- 1 | #ifndef SETJMP_H 2 | #define SETJMP_H 3 | 4 | struct _jmp_buf 5 | { 6 | void * sp, * ip, * fp; 7 | char tmps[32]; 8 | char cpup; 9 | char stack[48]; 10 | }; 11 | 12 | typedef struct _jmp_buf jmp_buf[1]; 13 | 14 | __dynstack int setjmp(jmp_buf env); 15 | 16 | __dynstack int setjmpsp(jmp_buf env, void * sp); 17 | 18 | __dynstack void longjmp(jmp_buf env, int value); 19 | 20 | 21 | #pragma compile("setjmp.c") 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /oscar64/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by oscar64.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /include/c64/joystick.c: -------------------------------------------------------------------------------- 1 | #include "joystick.h" 2 | 3 | sbyte joyx[2], joyy[2]; 4 | bool joyb[2]; 5 | 6 | void joy_poll(char n) 7 | { 8 | char b = ((volatile char *)0xdc00)[n]; 9 | 10 | if (!(b & 1)) 11 | joyy[n] = -1; 12 | else if (!(b & 2)) 13 | joyy[n] = 1; 14 | else 15 | joyy[n] = 0; 16 | 17 | if (!(b & 4)) 18 | joyx[n] = -1; 19 | else if (!(b & 8)) 20 | joyx[n] = 1; 21 | else 22 | joyx[n] = 0; 23 | 24 | joyb[n] = (b & 0x10) == 0; 25 | } 26 | -------------------------------------------------------------------------------- /include/opp/ifstream.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_IFSTREAM_H 2 | #define OPP_IFSTREAM_H 3 | 4 | #include "iostream.h" 5 | #include "string.h" 6 | 7 | namespace opp { 8 | 9 | class ifstream : public istream 10 | { 11 | public: 12 | ifstream(char fnum, char device, char channel, const string & name); 13 | ~ifstream(void); 14 | 15 | protected: 16 | virtual void refill(void); 17 | 18 | char fnum; 19 | }; 20 | 21 | } 22 | 23 | #pragma compile("ifstream.cpp") 24 | 25 | #endif -------------------------------------------------------------------------------- /autotest/funcarraycall.c: -------------------------------------------------------------------------------- 1 | 2 | int (*funcs[10])(int); 3 | 4 | #assign x 0 5 | #repeat 6 | int f##x(int i) 7 | { 8 | return i + x; 9 | } 10 | #assign x x + 1 11 | #until x == 10 12 | 13 | int test(int k) 14 | { 15 | for(char i=0; i<10; i++) 16 | k = funcs[i](k); 17 | return k; 18 | } 19 | 20 | int main(void) 21 | { 22 | #assign x 0 23 | #repeat 24 | funcs[x] = f##x; 25 | #assign x x + 1 26 | #until x == 10 27 | 28 | int k = test(-45); 29 | return k; 30 | } 31 | -------------------------------------------------------------------------------- /autotest/opp_parts.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "opp_part1.h" 4 | #include "opp_part2.h" 5 | 6 | 7 | int main(void) 8 | { 9 | opp::vector va; 10 | va.push_back(A(1, 2)); 11 | va.push_back(A(3, 4)); 12 | va.push_back(A(6, 4)); 13 | va.push_back(A(0, 9)); 14 | 15 | AS as(va); 16 | 17 | va.push_back(A(7, 1)); 18 | 19 | BS bs(va); 20 | 21 | assert(bs.sum() == 2 + 12 + 24 + 7); 22 | assert(as.sum() == 2 + 12 + 24); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /autotest/testsigned16mul.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int multab[32]; 4 | 5 | void fill_mulli(int m) 6 | { 7 | #pragma unroll(full) 8 | for(int i=-16; i<16; i++) 9 | multab[i + 16] = m * i; 10 | } 11 | 12 | void check_mulli(int m) 13 | { 14 | for(int i=-16; i<16; i++) 15 | assert(multab[i + 16] == m * i); 16 | } 17 | 18 | int main(void) 19 | { 20 | for(int i=-1024; i<=1024; i++) 21 | { 22 | fill_mulli(i); 23 | check_mulli(i); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /autotest/bsstest.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | char ch[100]; 5 | char p[] = "HELLO"; 6 | int v[10]; 7 | int w[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 8 | 9 | int sum(int * k) 10 | { 11 | int s = 0; 12 | for(int i=0; i<10; i++) 13 | s += k[i]; 14 | return s; 15 | } 16 | 17 | int main(void) 18 | { 19 | strcpy(ch, p); 20 | strcat(ch, " WORLD"); 21 | 22 | for(int i=0; i<10; i++) 23 | v[i] = w[i]; 24 | 25 | return strcmp(ch, "HELLO WORLD") + sum(v) - 55; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /autotest/copyinitmove.c: -------------------------------------------------------------------------------- 1 | 2 | int val(char * c) 3 | { 4 | return c[0]; 5 | } 6 | 7 | void set(char * c, int a) 8 | { 9 | c[0] = a; 10 | } 11 | 12 | int main(void) 13 | { 14 | int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0; 15 | 16 | for(int i=0; i<10; i++) 17 | { 18 | char t[10] = {1}; 19 | sum0 += val(t); 20 | sum2 += t[0]; 21 | set(t, i); 22 | sum1 += val(t); 23 | sum3 += t[0]; 24 | } 25 | 26 | return (sum1 - 45) | (sum0 - 10) | (sum3 - 45) | (sum2 - 10); 27 | } 28 | -------------------------------------------------------------------------------- /include/c64/cia.c: -------------------------------------------------------------------------------- 1 | #include "cia.h" 2 | 3 | byte ciaa_pra_def; 4 | 5 | void cia_init(void) 6 | { 7 | cia1.icr = 0x7f; 8 | cia2.icr = 0x7f; 9 | cia1.pra = 0x7f; 10 | cia1.cra = 0x08; 11 | cia1.crb = 0x08; 12 | cia2.cra = 0x08; 13 | cia2.crb = 0x08; 14 | 15 | cia1.ddrb = 0x00; 16 | cia2.ddrb = 0x00; 17 | cia1.ddra = 0xff; 18 | 19 | cia2.pra = 0x07; 20 | cia2.ddra = 0x3f; 21 | 22 | char i0 = cia1.icr; 23 | char i1 = cia2.icr; 24 | 25 | ciaa_pra_def = 0x7f; 26 | } 27 | -------------------------------------------------------------------------------- /autotest/arrayinittest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int fg[15] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610}; 5 | 6 | int main(void) 7 | { 8 | int fl[15] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610}; 9 | 10 | int sg = 0, sl = 0; 11 | 12 | for(int i=0; i<15; i++) 13 | { 14 | sl += fl[i]; 15 | sg += fg[i]; 16 | } 17 | 18 | assert(sl == 1596); 19 | assert(sg == 1596); 20 | 21 | printf("%d %d\n", sl, sg); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /samples/games/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: snake.prg lander.prg maze3d.prg missile.prg breakout.prg connectfour.prg hscrollshmup.prg 6 | 7 | snake.prg: snake.c 8 | @$(OSCAR64_CC) $< 9 | 10 | missile.prg: missile.c 11 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) -O3 $< 12 | 13 | hscrollshmup.prg: hscrollshmup.c 14 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) -O2 $< 15 | 16 | clean: 17 | @$(RM) *.asm *.int *.lbl *.map *.prg *.bcs 18 | -------------------------------------------------------------------------------- /autotest/structassigntest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Vec3 4 | { 5 | float x, y, z; 6 | }; 7 | 8 | Vec3 v; 9 | 10 | Vec3 vadd(Vec3 s1, Vec3 s2) 11 | { 12 | Vec3 r; 13 | r.x = s1.x + s2.x; 14 | r.y = s1.y + s2.y; 15 | r.z = s1.z + s2.z; 16 | return r; 17 | } 18 | 19 | 20 | int main(void) 21 | { 22 | Vec3 m = {1, 2, -3}, u = {4, 5, -9}, t = {7, -2, -5}; 23 | 24 | v.x = 99; 25 | v.y = 100; 26 | v.z = 101; 27 | 28 | v = vadd(m, vadd(u, t)); 29 | 30 | return v.x + v.y + v.z; 31 | } 32 | -------------------------------------------------------------------------------- /include/opp/ifstream.cpp: -------------------------------------------------------------------------------- 1 | #include "ifstream.h" 2 | #include 3 | 4 | namespace opp { 5 | 6 | ifstream::ifstream(char fnum, char device, char channel, const string & name) 7 | { 8 | this->fnum = fnum; 9 | krnio_setnam(name.tocstr()); 10 | krnio_open(fnum, device, channel); 11 | } 12 | 13 | ifstream::~ifstream(void) 14 | { 15 | krnio_close(fnum); 16 | } 17 | 18 | void ifstream::refill(void) 19 | { 20 | mBufferPos = 0; 21 | mBufferFill = krnio_read(fnum, mBuffer, 32); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /autotest/testsigned16div.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int multab[32]; 4 | 5 | void fill_mulli(int m) 6 | { 7 | #pragma unroll(full) 8 | for(int i=-16; i<16; i++) 9 | if (i != 0) 10 | multab[i + 16] = m / i; 11 | } 12 | 13 | void check_mulli(int m) 14 | { 15 | for(int i=-16; i<16; i++) 16 | if (i != 0) 17 | assert(multab[i + 16] == m / i); 18 | } 19 | 20 | int main(void) 21 | { 22 | for(int i=-1024; i<=1024; i++) 23 | { 24 | fill_mulli(i); 25 | check_mulli(i); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /include/opp/ofstream.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_OFSTREAM_H 2 | #define OPP_OFSTREAM_H 3 | 4 | #include "iostream.h" 5 | #include "string.h" 6 | 7 | namespace opp { 8 | 9 | class ofstream : public ostream 10 | { 11 | public: 12 | ofstream(char fnum, char device, char channel, const string & name); 13 | ~ofstream(void); 14 | 15 | protected: 16 | virtual void bput(char ch); 17 | 18 | char mBuffer[32]; 19 | char mBufferFill; 20 | 21 | char fnum; 22 | }; 23 | 24 | } 25 | 26 | #pragma compile("ofstream.cpp") 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /autotest/linetest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | char * const Hires = (char *)0x4000; 6 | Bitmap Screen; 7 | ClipRect cr = {0, 0, 320, 200}; 8 | 9 | 10 | 11 | int main(void) 12 | { 13 | bm_init(&Screen, Hires, 40, 25); 14 | 15 | bmu_rect_clear(&Screen, 0, 0, 320, 200); 16 | 17 | bm_line(&Screen, &cr, 0, 0, 199, 199, 0xff, LINOP_SET); 18 | 19 | for(int i=0; i<200; i++) 20 | { 21 | assert(Hires[(i & 7) + 320 * (i >> 3) + (i & ~7)] == 0x80 >> (i & 7)); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /include/inttypes.c: -------------------------------------------------------------------------------- 1 | #include "inttypes.h" 2 | #include "stdlib.h" 3 | 4 | 5 | intmax_t imaxabs(intmax_t n) 6 | { 7 | return n < 0 ? -n : n; 8 | } 9 | 10 | imaxdiv_t imaxdiv(intmax_t l, intmax_t r) 11 | { 12 | imaxdiv_t t; 13 | t.quot = l / r; 14 | t.rem = l % r; 15 | return t; 16 | } 17 | 18 | inline intmax_t strtoimax(const char * s, char ** endp, int base) 19 | { 20 | return strtol(s, endp, base); 21 | } 22 | 23 | inline uintmax_t strtoumax(const char * s, char ** endp, int base) 24 | { 25 | return strtoul(s, endp, base); 26 | } 27 | -------------------------------------------------------------------------------- /autotest/longcodetest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char a[200], b[200]; 4 | bool ok = true; 5 | 6 | int main(void) 7 | { 8 | #assign ni 0 9 | #repeat 10 | a[ni] = ni & 255; 11 | #assign ni ni + 1 12 | #until ni == 200 13 | 14 | #assign ni 0 15 | #repeat 16 | if (ok) 17 | b[ni] = ni & 255; 18 | #assign ni ni + 1 19 | #until ni == 200 20 | 21 | int asum = 0, bsum = 0, csum = 0; 22 | for(int i=0; i<200; i++) 23 | { 24 | asum += a[i]; 25 | bsum += b[i]; 26 | csum += i & 255; 27 | } 28 | 29 | return asum + bsum - 2 * csum; 30 | } 31 | -------------------------------------------------------------------------------- /autotest/opp_pairtest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace opp; 7 | 8 | int main(void) 9 | { 10 | vector > vii; 11 | 12 | for(int i=0; i<100; i++) 13 | vii.push_back(make_pair(i, i * i)); 14 | 15 | int sum1 = 0; 16 | long sum2 = 0; 17 | for(const auto & v : vii) 18 | { 19 | sum1 += v.first; 20 | sum2 += v.second; 21 | } 22 | 23 | 24 | assert(sum1 == 4950); 25 | assert(sum2 == 328350l); 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /autotest/strlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char lstr[1025]; 5 | 6 | int main(void) 7 | { 8 | #if 1 9 | assert(strlen("") == 0); 10 | assert(strlen("1") == 1); 11 | assert(strlen("12") == 2); 12 | assert(strlen("123") == 3); 13 | assert(strlen("1234") == 4); 14 | assert(strlen("12345") == 5); 15 | assert(strlen("123456") == 6); 16 | #endif 17 | #if 1 18 | char * dp = lstr; 19 | for(int i=0; i<1024; i++) 20 | { 21 | *dp = 0; 22 | assert(strlen(lstr) == i); 23 | *dp++ = 'a'; 24 | } 25 | #endif 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /include/c64/cia.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_CIA 2 | #define C64_CIA 3 | 4 | #include "types.h" 5 | 6 | struct CIA 7 | { 8 | volatile byte pra, prb; 9 | volatile byte ddra, ddrb; 10 | volatile word ta, tb; 11 | volatile byte todt, tods, todm, todh; 12 | volatile byte sdr; 13 | volatile byte icr; 14 | volatile byte cra, crb; 15 | }; 16 | 17 | #define cia1 (*((struct CIA *)0xdc00)) 18 | #define cia2 (*((struct CIA *)0xdd00)) 19 | 20 | extern byte ciaa_pra_def; 21 | 22 | void cia_init(void); 23 | 24 | #pragma compile("cia.c") 25 | 26 | #endif 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /include/vic20/vic.h: -------------------------------------------------------------------------------- 1 | #ifndef VIC20_VIC 2 | #define VIC20_VIC 3 | 4 | #include 5 | 6 | struct VICI 7 | { 8 | volatile byte hpos; 9 | volatile byte vpos; 10 | volatile byte ncols; 11 | volatile byte nrows; 12 | volatile byte beam; 13 | volatile byte mempos; 14 | 15 | volatile byte hlpen, vlpen; 16 | volatile byte xpaddle, ypaddle; 17 | volatile byte oscfreq[4]; 18 | volatile byte volcol; 19 | volatile byte color; 20 | }; 21 | 22 | #define vici (*((struct VICI *)0x9000)) 23 | 24 | #pragma compile("vic.c") 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /autotest/floatmultest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | float c = 1.25; 6 | float d = 1.0001; 7 | 8 | int main(void) 9 | { 10 | int i; 11 | float a = 0.0; 12 | 13 | for(i=0; i<50; i++) 14 | { 15 | printf("%d %f %f %f\n", i, i * c, a, i * c - a); 16 | assert(i * c == a); 17 | a += c; 18 | } 19 | 20 | a = d; 21 | 22 | for(i=1; i<50; i++) 23 | { 24 | printf("%d %f %f %f\n", i, i * d, a, fabs(i * d - a) / i); 25 | assert(fabs(i * d - a) < i * 1.0e-6); 26 | a += d; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /autotest/maskcheck.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | 5 | void check_byte(char a) 6 | { 7 | char b1[8] = {0}, n1[8] = {0}, b0[8] = {0}, n0[8] = {0}; 8 | 9 | #for(i, 8) if ((a & (1 << i)) == (1 << i)) b1[i]++; 10 | #for(i, 8) if ((a & (1 << i)) != (1 << i)) n1[i]++; 11 | #for(i, 8) if ((a & (1 << i)) == 0) b0[i]++; 12 | #for(i, 8) if ((a & (1 << i)) != 0) n0[i]++; 13 | 14 | for(char i=0; i<8; i++) 15 | { 16 | assert(b0[i] == n1[i]); 17 | assert(b1[i] == n0[i]); 18 | } 19 | } 20 | 21 | int main(void) 22 | { 23 | for(int i=0; i<256; i++) 24 | check_byte(i); 25 | } -------------------------------------------------------------------------------- /samples/make.bat: -------------------------------------------------------------------------------- 1 | cd fractals 2 | call make.bat 3 | cd .. 4 | 5 | cd games 6 | call make.bat 7 | cd .. 8 | 9 | cd hires 10 | call make.bat 11 | cd .. 12 | 13 | cd hiresmc 14 | call make.bat 15 | cd .. 16 | 17 | cd particles 18 | call make.bat 19 | cd .. 20 | 21 | cd kernalio 22 | call make.bat 23 | cd .. 24 | 25 | cd memmap 26 | call make.bat 27 | cd .. 28 | 29 | cd rasterirq 30 | call make.bat 31 | cd .. 32 | 33 | cd scrolling 34 | call make.bat 35 | cd .. 36 | 37 | cd sprites 38 | call make.bat 39 | cd .. 40 | 41 | cd stdio 42 | call make.bat 43 | cd .. 44 | 45 | -------------------------------------------------------------------------------- /samples/kernalio/charwrite.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | // Set name for file and open it with replace on drive 9 7 | krnio_setnam("@0:CHARS,P,W"); 8 | if (krnio_open(2, 9, 2)) 9 | { 10 | // Write 128 bytes to the file, it would be more efficient 11 | // to set the output channel with krnio_chkout() for the file and 12 | // write the bytes using krnio_chrout() 13 | 14 | for(char i=0; i<128; i++) 15 | krnio_putch(2, i); 16 | 17 | // Close the file again 18 | krnio_close(2); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /autotest/ptrinittest.c: -------------------------------------------------------------------------------- 1 | #if 1 2 | 3 | const struct A { 4 | char w; 5 | int b[5]; 6 | struct { 7 | int c[5]; 8 | } o; 9 | } a = {22, 10 | {4, 5, 6, 7, 8}, 11 | { 12 | {4, 5, 6, 7, 8} 13 | } 14 | }; 15 | 16 | const int * t[4] = { 17 | a.b + 1 + 1 18 | }; 19 | 20 | const int * v[4] = { 21 | a.o.c + 1 + 1 22 | }; 23 | 24 | int q[5] = {4, 5, 6, 7, 8}; 25 | 26 | const int * u[4] = { 27 | q + 2 28 | }; 29 | 30 | int main(void) 31 | { 32 | return 33 | u[0][0] + (q + 2)[2] - 6 - 8 + 34 | v[0][0] + (a.o.c + 2)[2] - 6 - 8 + 35 | t[0][0] + (a.b + 2)[2] - 6 - 8; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /include/c64/mouse.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_MOUSE_H 2 | #define C64_MOUSE_H 3 | 4 | #include "types.h" 5 | 6 | extern sbyte mouse_dx, mouse_dy; 7 | extern bool mouse_lb, mouse_rb; 8 | 9 | 10 | void mouse_init(void); 11 | 12 | // arm the potentiometer input for the selected mouse input 13 | // needs ~4ms to stabilize 14 | 15 | void mouse_arm(char n); 16 | 17 | // poll mouse input for selected mouse, but the relative 18 | // movement into mouse_dx/dy and the button state into 19 | // mouse_lb/mouse_rb 20 | 21 | void mouse_poll(void); 22 | 23 | #pragma compile("mouse.c") 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /autotest/opp_part1.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class A 6 | { 7 | protected: 8 | int a, b; 9 | 10 | public: 11 | A(int a_, int b_) 12 | : a(a_), b(b_) 13 | {} 14 | 15 | int sum(void) const 16 | { 17 | return a * b; 18 | } 19 | }; 20 | 21 | class AS 22 | { 23 | protected: 24 | opp::vector va; 25 | public: 26 | AS(const opp::vector & v) 27 | : va(v) 28 | {} 29 | 30 | int sum(void) 31 | { 32 | int s = 0; 33 | for(const auto & a : va) 34 | s += a.sum(); 35 | return s; 36 | } 37 | }; 38 | 39 | #pragma compile("opp_part1.cpp") 40 | 41 | -------------------------------------------------------------------------------- /include/audio/sidfx.h: -------------------------------------------------------------------------------- 1 | #ifndef SIDFX_H 2 | #define SIDFX_H 3 | 4 | #include 5 | 6 | struct SIDFX 7 | { 8 | unsigned freq, pwm; 9 | byte ctrl, attdec, susrel; 10 | int dfreq, dpwm; 11 | byte time1, time0; 12 | byte priority; 13 | }; 14 | 15 | void sidfx_init(void); 16 | 17 | inline bool sidfx_idle(byte chn); 18 | 19 | inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt); 20 | 21 | void sidfx_stop(byte chn); 22 | 23 | char sidfx_cnt(byte chn); 24 | 25 | void sidfx_loop(void); 26 | 27 | void sidfx_loop_2(void); 28 | 29 | #pragma compile("sidfx.c") 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /samples/memmap/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ../../bin/oscar64 largemem.c 3 | ../../bin/oscar64 allmem.c 4 | ../../bin/oscar64 charsetlo.c 5 | ../../bin/oscar64 charsethi.c 6 | ../../bin/oscar64 charsetcopy.c 7 | ../../bin/oscar64 charsetexpand.c 8 | ../../bin/oscar64 charsetload.c -d64=charsetload.d64 -fz=../resources/charset.bin 9 | ../../bin/oscar64 easyflash.c -n -tf=crt 10 | ../../bin/oscar64 easyflashreloc.c -n -tf=crt 11 | ../../bin/oscar64 easyflashshared.c -n -tf=crt 12 | ../../bin/oscar64 easyflashcall.cpp -n -tf=crt 13 | ../../bin/oscar64 tsr.c -n -dNOFLOAT -dNOLONG 14 | ../../bin/oscar64 overlay.c -n -d64=overlay.d64 15 | -------------------------------------------------------------------------------- /samples/kernalio/charread.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | // Set name for file and open it on drive 9 7 | krnio_setnam("@0:CHARS,P,R"); 8 | if (krnio_open(2, 9, 2)) 9 | { 10 | // Read bytes until failure 11 | int ch, k = 0; 12 | while ((ch = krnio_getch(2)) >= 0) 13 | { 14 | // Print the value of the byte 15 | printf("%d : %d\n", k, ch); 16 | k++; 17 | 18 | // Exit the loop if this was the last byte of the file 19 | if (ch & 0x100) 20 | break; 21 | } 22 | 23 | // Close the file 24 | krnio_close(2); 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /samples/kernalio/filewrite.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Score 5 | { 6 | char name[5]; 7 | unsigned score; 8 | }; 9 | 10 | Score score[] = { 11 | {"AAA", 10000}, 12 | {"BBB", 9000}, 13 | {"CCC", 8000}, 14 | {"DDD", 4000} 15 | }; 16 | 17 | int main(void) 18 | { 19 | // Set name for file and open it with replace on drive 9 20 | krnio_setnam("@0:HIGHSCORE,P,W"); 21 | if (krnio_open(2, 9, 2)) 22 | { 23 | // Fill the file with the score array 24 | krnio_write(2, (char*)score, sizeof(score)); 25 | 26 | // Close the file 27 | krnio_close(2); 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /samples/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @$(MAKE) -C fractals 3 | @$(MAKE) -C games 4 | @$(MAKE) -C hires 5 | @$(MAKE) -C hiresmc 6 | @$(MAKE) -C particles 7 | @$(MAKE) -C kernalio 8 | @$(MAKE) -C memmap 9 | @$(MAKE) -C rasterirq 10 | @$(MAKE) -C scrolling 11 | @$(MAKE) -C sprites 12 | @$(MAKE) -C stdio 13 | 14 | clean: 15 | @$(MAKE) -C fractals $@ 16 | @$(MAKE) -C games $@ 17 | @$(MAKE) -C hires $@ 18 | @$(MAKE) -C hiresmc $@ 19 | @$(MAKE) -C particles $@ 20 | @$(MAKE) -C kernalio $@ 21 | @$(MAKE) -C memmap $@ 22 | @$(MAKE) -C rasterirq $@ 23 | @$(MAKE) -C scrolling $@ 24 | @$(MAKE) -C sprites $@ 25 | @$(MAKE) -C stdio $@ 26 | -------------------------------------------------------------------------------- /include/ctype.h: -------------------------------------------------------------------------------- 1 | #ifndef CTYPE_H 2 | #define CTYPE_H 3 | 4 | inline bool isctrnl(char c); 5 | 6 | inline bool isprint(char c); 7 | 8 | inline bool isspace(char c); 9 | 10 | inline bool isblank(char c); 11 | 12 | inline bool isgraph(char c); 13 | 14 | inline bool ispunct(char c); 15 | 16 | inline bool isalnum(char c); 17 | 18 | inline bool isalpha(char c); 19 | 20 | inline bool isupper(char c); 21 | 22 | inline bool islower(char c); 23 | 24 | inline bool isdigit(char c); 25 | 26 | inline bool isxdigit(char c); 27 | 28 | char tolower(char c); 29 | 30 | char toupper(char c); 31 | 32 | #pragma compile("ctype.c") 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /autotest/ptrarraycmptest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct X 4 | { 5 | int a; 6 | }; 7 | 8 | X x[5] = { 9 | {1}, {2}, {3}, {4}, {5} 10 | }; 11 | 12 | X * y; 13 | 14 | int main(void) 15 | { 16 | y = x; 17 | assert(y == x); 18 | y = x + 1; 19 | assert(y == x + 1); 20 | y = &(x[2]); 21 | assert(y == x + 2); 22 | y = x + 3; 23 | assert(y == &(x[3])); 24 | y = x ; 25 | assert(y == (struct X*)x); 26 | 27 | y = x; 28 | assert(x == y); 29 | y = x + 1; 30 | assert(x + 1 == y); 31 | y = &(x[2]); 32 | assert(x + 2 == y); 33 | y = x + 3; 34 | assert(&(x[3]) == y); 35 | y = x ; 36 | assert((struct X*)x == y); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /autotest/floatstringtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | printf("%f\n", 0.0); 8 | 9 | 10 | float x = 1.0, y = 1.0; 11 | 12 | char xb[20], yb[20]; 13 | for(int i=0; i<40; i++) 14 | { 15 | ftoa(x, xb); float xr = atof(xb); 16 | ftoa(y, yb); float yr = atof(yb); 17 | 18 | printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, yr, fabs(x - xr) / x, fabs(y - yr) / y); 19 | 20 | if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001) 21 | return -1; 22 | 23 | x *= 2.5; 24 | y *= 0.8; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /include/opp/utility.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_UTILITY_H 2 | #define OPP_UTILITY_H 3 | 4 | namespace opp { 5 | 6 | template 7 | inline T && move(T && m) 8 | { 9 | return (T &&)m; 10 | } 11 | 12 | template 13 | inline void swap(T & x, T & y) 14 | { 15 | T t(x); x = y; y = move(t); 16 | } 17 | 18 | 19 | template 20 | struct pair 21 | { 22 | T1 first; 23 | T2 second; 24 | 25 | pair(T1 && t1, T2 && t2) 26 | : first(t1), second(t2) 27 | {} 28 | }; 29 | 30 | template 31 | constexpr pair make_pair(T1 && t1, T2 && t2) 32 | { 33 | return pair(t1, t2); 34 | } 35 | 36 | } 37 | 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /samples/memmap/charsethi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | // space for our custom charset from c800 7 | 8 | #pragma section( charset, 0) 9 | 10 | #pragma region( charset, 0xc800, 0xd000, , , {charset} ) 11 | 12 | #pragma data(charset) 13 | 14 | char charset[2048] = { 15 | #embed "../resources/charset.bin" 16 | }; 17 | 18 | #pragma data(data) 19 | 20 | #define Screen ((char *)0xc000) 21 | 22 | 23 | int main(void) 24 | { 25 | // map the vic to the new charset 26 | 27 | vic_setmode(VICM_TEXT, Screen, charset); 28 | 29 | for(int i=0; i<1000; i++) 30 | Screen[i] = (char)i; 31 | 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /samples/kernalio/fileread.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Score 5 | { 6 | char name[5]; 7 | unsigned score; 8 | }; 9 | 10 | Score score[4]; 11 | 12 | int main(void) 13 | { 14 | // Set name for file and open it on drive 9 15 | krnio_setnam("HIGHSCORE,P,R"); 16 | if (krnio_open(2, 9, 2)) 17 | { 18 | // Read the content of the file into the score arrayx 19 | krnio_read(2, (char*)score, sizeof(score)); 20 | 21 | // Close the file 22 | krnio_close(2); 23 | } 24 | 25 | // Print the result to stdout 26 | for(int i=0; i<4; i++) 27 | { 28 | printf("%s : %u\n", score[i].name, score[i].score); 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /include/opp/ofstream.cpp: -------------------------------------------------------------------------------- 1 | #include "ofstream.h" 2 | #include 3 | 4 | namespace opp { 5 | 6 | ofstream::ofstream(char fnum, char device, char channel, const string & name) 7 | { 8 | this->fnum = fnum; 9 | krnio_setnam(name.tocstr()); 10 | krnio_open(fnum, device, channel); 11 | 12 | mBufferFill = 0; 13 | } 14 | 15 | ofstream::~ofstream(void) 16 | { 17 | if (mBufferFill > 0) 18 | krnio_write(fnum, mBuffer, mBufferFill); 19 | krnio_close(fnum); 20 | } 21 | 22 | void ofstream::bput(char ch) 23 | { 24 | mBuffer[mBufferFill++] = ch; 25 | if (mBufferFill == 32) 26 | { 27 | krnio_write(fnum, mBuffer, mBufferFill); 28 | mBufferFill = 0; 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /autotest/mathtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | for(int i=0; i<1000; i++) 8 | { 9 | float w = 0.0123 * i; 10 | float co = cos(w), si = sin(w); 11 | 12 | float r = co * co + si * si; 13 | 14 | assert(fabs(r - 1) < 0.001); 15 | 16 | assert(fabs(sqrt(w * w) - w) < 0.001); 17 | 18 | float aw = atan2(si, co); 19 | 20 | float co2 = cos(aw), si2 = sin(aw); 21 | 22 | assert(fabs(co2 - co) < 0.001); 23 | assert(fabs(si2 - si) < 0.001); 24 | 25 | float ex = exp(w), em = exp(-w); 26 | 27 | assert(fabs(log(ex) - w) < 0.001); 28 | assert(fabs(log(em) + w) < 0.001); 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /autotest/structmembertest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A 4 | { 5 | int x[100], y[100]; 6 | }; 7 | 8 | struct V 9 | { 10 | int x, y, z; 11 | }; 12 | 13 | 14 | void copy(A * a) 15 | { 16 | for(int i=0; i<100; i++) 17 | a->x[i] = a->y[i]; 18 | } 19 | 20 | void shuffle(V * v) 21 | { 22 | for(int i=0; i<100; i++) 23 | v[i].x = v[i].y; 24 | } 25 | 26 | int main(void) 27 | { 28 | A a; 29 | V v[100]; 30 | 31 | for(int i=0; i<100; i++) 32 | { 33 | a.y[i] = i; 34 | v[i].y = i; 35 | } 36 | 37 | copy(&a); 38 | shuffle(v); 39 | 40 | for(int i=0; i<100; i++) 41 | { 42 | assert(a.x[i] == i); 43 | assert(v[i].x == i); 44 | } 45 | 46 | return 0; 47 | } 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /autotest/opp_vector_string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using opp::string; 8 | using opp::vector; 9 | 10 | string join(const vector & vs) 11 | { 12 | string sj; 13 | for(int i=0; i vs; 21 | string a; 22 | 23 | for(int i=0; i<10; i++) 24 | { 25 | vs.push_back(a); 26 | a += "x"; 27 | } 28 | 29 | int s = 0; 30 | for(int i=0; i<10; i++) 31 | s += vs[i].size(); 32 | 33 | assert(s == 45); 34 | 35 | assert(join(vs).size() == 45); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /include/nes/mmc1.h: -------------------------------------------------------------------------------- 1 | #ifndef NES_MMC1_H 2 | #define NES_MMC1_H 3 | 4 | #include 5 | 6 | enum MMC1Mirror 7 | { 8 | MMC1M_LOWER, 9 | MMC1M_UPPER, 10 | MMC1M_VERTICAL, 11 | MMC1M_HORIZONTAL 12 | }; 13 | 14 | enum MMC1MPrgMode 15 | { 16 | MMC1P_32K, 17 | MMC1P_32Kx, 18 | MMC1P_16K_UPPER, 19 | MMC1P_16K_LOWER 20 | }; 21 | 22 | enum MMC1MChrMode 23 | { 24 | MMC1C_8K, 25 | MMC1C_4Kx, 26 | }; 27 | 28 | void mmc1_reset(void); 29 | 30 | void mmc1_config(MMC1Mirror mirror, MMC1MPrgMode pmode, MMC1MChrMode cmode); 31 | 32 | void mmc1_bank_prg(char bank); 33 | 34 | void mmc1_bank_chr0(char bank); 35 | 36 | void mmc1_bank_chr1(char bank); 37 | 38 | #pragma compile("mmc1.c") 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/c128/mmu.h: -------------------------------------------------------------------------------- 1 | #ifndef C128_MMU_H 2 | #define C128_MMU_H 3 | 4 | #include 5 | 6 | struct MMU 7 | { 8 | volatile __memmap byte cr; 9 | volatile __memmap byte bank0; 10 | volatile __memmap byte bank1; 11 | volatile __memmap byte bank14; 12 | volatile __memmap byte bankx; 13 | }; 14 | 15 | struct XMMU 16 | { 17 | volatile byte cr; 18 | volatile byte pcr[4]; 19 | volatile byte mcr; 20 | volatile byte rcr; 21 | volatile word page0; 22 | volatile word page1; 23 | volatile byte vr; 24 | }; 25 | 26 | #define mmu (*((struct MMU *)0xff00)) 27 | 28 | #define xmmu (*((struct XMMU *)0xd500)) 29 | 30 | inline char mmu_set(char cr); 31 | 32 | #pragma compile("mmu.c") 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /oscar64/DiskImage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MachineTypes.h" 4 | 5 | class DiskImage 6 | { 7 | public: 8 | DiskImage(const char * name); 9 | ~DiskImage(void); 10 | 11 | bool WriteImage(const char* fname); 12 | 13 | bool OpenFile(const char* fname); 14 | void CloseFile(void); 15 | 16 | int WriteBytes(const uint8* data, ptrdiff_t size); 17 | bool WriteFile(const char* fname, bool compressed, int interleave); 18 | 19 | protected: 20 | uint8 mSectors[41][21][256]; 21 | 22 | void MarkBAMSector(int track, int sector); 23 | int AllocBAMSector(int track, int sector); 24 | int AllocBAMTrack(int track); 25 | 26 | uint8 * mDirEntry; 27 | int mTrack, mSector, mBytes, mInterleave; 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /samples/fractals/mbtext.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define Screen ((char *)0x0400) 4 | #define Color ((char *)0xd800) 5 | 6 | int main(void) 7 | { 8 | memset(Screen, 160, 1024); 9 | 10 | int py, px; 11 | 12 | for(py=0; py<25; py++) 13 | { 14 | for(px=0; px<40; px++) 15 | { 16 | float xz = (float)px * (3.5 / 40.0)- 2.5; 17 | float yz = (float)py * (2.0 / 25.0) - 1.0; 18 | 19 | float x = 0.0, y = 0.0; 20 | int i; 21 | for(i=0; i<=14; i++) 22 | { 23 | if (x * x + y * y > 4.0) break; 24 | 25 | float xt = x * x - y * y + xz; 26 | y = 2 * x * y + yz; 27 | x = xt; 28 | } 29 | i--; 30 | 31 | Color[py * 40 + px] = i; 32 | } 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /samples/resources/hscrollshmupmap.bin: -------------------------------------------------------------------------------- 1 | !!#  2 |  #  !!!  3 |   4 |  5 |   6 |  $ 7 |   8 |   9 | $$ 10 |  11 | 12 | 13 | # 14 | 15 | #  16 | " #   17 |  " " "   #  18 | 19 | 20 |  " "   " -------------------------------------------------------------------------------- /autotest/structarraycopy.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct Point 4 | { 5 | int x, y; 6 | }; 7 | 8 | 9 | Point tcorners[8], pcorners[8]; 10 | 11 | int bm_line(void) 12 | { 13 | return 0; 14 | } 15 | 16 | void drawCube(void) 17 | { 18 | for(char i=0; i<8; i++) 19 | { 20 | if (!(i & 1)) 21 | bm_line(); 22 | if (!(i & 2)) 23 | bm_line(); 24 | if (!(i & 4)) 25 | bm_line(); 26 | 27 | pcorners[i] = tcorners[i]; 28 | } 29 | } 30 | 31 | int main(void) 32 | { 33 | for(int i=0; i<8; i++) 34 | { 35 | tcorners[i].x = (i + 1) * 3; 36 | tcorners[i].y = (i + 1) * 7; 37 | } 38 | 39 | drawCube(); 40 | 41 | int sum = 0; 42 | for(int i=0; i<8; i++) 43 | { 44 | sum += pcorners[i].x; 45 | sum -= tcorners[i].y; 46 | } 47 | 48 | return sum + 144; 49 | } -------------------------------------------------------------------------------- /autotest/divmodtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | for(unsigned i=0; i<256; i+=11) 6 | { 7 | for(unsigned j=1; j<256; j++) 8 | { 9 | unsigned q = i / j, r = i % j; 10 | 11 | assert(q * j + r == i); 12 | assert(r >= 0 && r < j); 13 | } 14 | } 15 | 16 | for(unsigned i=0; i<7000; i+=11) 17 | { 18 | for(unsigned j=1; j= 0 && r < j); 24 | } 25 | } 26 | 27 | for(unsigned i=0; i<64000; i+=121) 28 | { 29 | for(unsigned j=1; j= 0 && r < j); 35 | } 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /samples/rasterirq/colorbars.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Prepare small 14 color bars and one IRQ for back to normal 6 | RIRQCode bars[15]; 7 | 8 | int main(void) 9 | { 10 | // initialize raster IRQ 11 | rirq_init(true); 12 | 13 | for(int i=0; i<15; i++) 14 | { 15 | // Build color change raster IRQ 16 | rirq_build(bars + i, 2); 17 | // Change border color 18 | rirq_write(bars + i, 0, &vic.color_border, i); 19 | // Change background color 20 | rirq_write(bars + i, 1, &vic.color_back, i); 21 | // Place it on screen 22 | rirq_set(i, 80 + 8 * i, bars + i); 23 | } 24 | 25 | // Sort all raster IRQs 26 | rirq_sort(); 27 | 28 | // Start raster IRQs 29 | rirq_start(); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /include/nes/mmc3.c: -------------------------------------------------------------------------------- 1 | #include "mmc3.h" 2 | 3 | char mmc3_shadow; 4 | 5 | void mmc3_reset(void) 6 | { 7 | mmc3_shadow = 0; 8 | } 9 | 10 | void mmc3_config(MMC3MPrgMode pmode, MMC3MChrMode cmode) 11 | { 12 | mmc3_shadow = (pmode << 6) | (cmode << 7); 13 | *(volatile char *)0x8000 = mmc3_shadow; 14 | } 15 | 16 | void mmc3_bank(MMC3BankReg reg, char bank) 17 | { 18 | *(volatile char *)0x8000 = reg | mmc3_shadow; 19 | *(volatile char *)0x8001 = bank; 20 | } 21 | 22 | void mmc3_bank_prg(char bank) 23 | { 24 | mmc3_bank(MMC3B_PRG0, bank * 2 + 0); 25 | mmc3_bank(MMC3B_PRG1, bank * 2 + 1); 26 | } 27 | 28 | void mmc3_bank_chr0(char bank) 29 | { 30 | mmc3_bank(MMC3B_CHR0, bank); 31 | } 32 | 33 | void mmc3_bank_chr1(char bank) 34 | { 35 | mmc3_bank(MMC3B_CHR1, bank); 36 | } 37 | -------------------------------------------------------------------------------- /autotest/virtualdestruct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int a, b, c; 4 | 5 | struct A 6 | { 7 | A(void) 8 | { 9 | a++; 10 | } 11 | 12 | virtual ~A(void) 13 | { 14 | a--; 15 | } 16 | }; 17 | 18 | struct B : A 19 | { 20 | B(void) 21 | { 22 | b++; 23 | } 24 | 25 | virtual ~B(void) 26 | { 27 | b--; 28 | } 29 | }; 30 | 31 | 32 | struct C : B 33 | { 34 | C(void) 35 | { 36 | c++; 37 | } 38 | 39 | virtual ~C(void) 40 | { 41 | c--; 42 | } 43 | }; 44 | 45 | 46 | int main() 47 | { 48 | A * t[3]; 49 | 50 | t[0] = new A(); 51 | t[1] = new B(); 52 | t[2] = new C(); 53 | 54 | assert(a == 3 && b == 2 && c == 1); 55 | 56 | delete t[0]; 57 | delete t[1]; 58 | delete t[2]; 59 | 60 | assert(a == 0 && b == 0 && c == 0); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /samples/memmap/make.bat: -------------------------------------------------------------------------------- 1 | call ..\..\bin\oscar64 largemem.c 2 | call ..\..\bin\oscar64 allmem.c 3 | call ..\..\bin\oscar64 charsetlo.c 4 | call ..\..\bin\oscar64 charsethi.c 5 | call ..\..\bin\oscar64 charsetcopy.c 6 | call ..\..\bin\oscar64 charsetexpand.c 7 | call ..\..\bin\oscar64 charsetload.c -d64=charsetload.d64 -fz=../resources/charset.bin 8 | call ..\..\bin\oscar64 easyflash.c -n -tf=crt 9 | call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt 10 | call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt 11 | call ..\..\bin\oscar64 easyflashlow.c -n -tf=crt 12 | call ..\..\bin\oscar64 easyflashcall.cpp -n -tf=crt 13 | call ..\..\bin\oscar64 tsr.c -n -dNOFLOAT -dNOLONG 14 | call ..\..\bin\oscar64 overlay.c -n -d64=overlay.d64 15 | call ..\..\bin\oscar64 magicdesk.c -n -tf=crt8 -cid=19 16 | -------------------------------------------------------------------------------- /autotest/switchlooptest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | char text[14]; 8 | 9 | for(char i=0; i<12; i++) 10 | { 11 | switch (i) 12 | { 13 | case 0: 14 | text[i] = 'H'; 15 | break; 16 | case 1: 17 | text[i] = 'E'; 18 | break; 19 | case 2: 20 | case 3: 21 | case 9: 22 | text[i] = 'L'; 23 | break; 24 | case 4: 25 | case 7: 26 | text[i] = 'O'; 27 | break; 28 | case 5: 29 | text[i] = ' '; 30 | break; 31 | case 6: 32 | text[i] = 'W'; 33 | break; 34 | case 8: 35 | text[i] = 'R'; 36 | break; 37 | case 10: 38 | text[i] = 'D'; 39 | break; 40 | default: 41 | text[i] = 0; 42 | } 43 | } 44 | 45 | printf("<%s>\n", text); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /samples/memmap/largemem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // make space until 0xd000 by extending the default region 6 | 7 | #pragma region( main, 0x0a00, 0xd000, , , {code, data, bss, heap, stack} ) 8 | 9 | int main(void) 10 | { 11 | // Hide the basic ROM, must be first instruction 12 | 13 | mmap_set(MMAP_NO_BASIC); 14 | 15 | // Allocate all memory 16 | 17 | unsigned total = 0; 18 | while (char * data = malloc(1024)) 19 | { 20 | total += 1024; 21 | 22 | printf("ALLOCATED %5u AT %04x\n", total, (unsigned)data); 23 | 24 | // Fill it with trash 25 | 26 | for(unsigned i=0; i<1024; i++) 27 | data[i] = 0xaa; 28 | } 29 | 30 | // Return basic ROM to normal state 31 | 32 | mmap_set(MMAP_ROM); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /include/opp/sstream.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_SSTREAM_H 2 | #define OPP_SSTREAM_H 3 | 4 | #include "iostream.h" 5 | 6 | namespace opp { 7 | 8 | class ostringstream : public ostream 9 | { 10 | public: 11 | ostringstream(void); 12 | ~ostringstream(void); 13 | 14 | string str(void) const; 15 | void str(const string & str); 16 | protected: 17 | void bput(char ch); 18 | 19 | char * mBuffer; 20 | char mBFill, mBSize; 21 | }; 22 | 23 | class istringstream : public istream 24 | { 25 | public: 26 | istringstream(const string & str); 27 | ~istringstream(void); 28 | 29 | string str(void) const; 30 | void str(const string & str); 31 | protected: 32 | virtual void refill(void); 33 | 34 | string mString; 35 | char mSPos; 36 | }; 37 | 38 | } 39 | 40 | #pragma compile("sstream.cpp") 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /include/c64/memmap.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMMAP_H 2 | #define MEMMAP_H 3 | 4 | #include "types.h" 5 | 6 | #define MMAP_ROM 0x37 7 | #define MMAP_NO_BASIC 0x36 8 | #define MMAP_NO_ROM 0x35 9 | #define MMAP_RAM 0x30 10 | #define MMAP_CHAR_ROM 0x31 11 | #define MMAP_ALL_ROM 0x33 12 | 13 | // Install an IRQ an NMI trampoline, that routes the kernal interrupts 14 | // through an intermediate trampoline when the kernal ROM is not paged 15 | // in. The trampoline enables the ROM, executes the interrupt and 16 | // restores the memory map setting before returning. 17 | 18 | void mmap_trampoline(void); 19 | 20 | // Set the memory map in a way that is compatible with the IRQ 21 | // trampoline, returns the previous state 22 | 23 | inline char mmap_set(char pla); 24 | 25 | #pragma compile("memmap.c") 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/nes/mmc3.h: -------------------------------------------------------------------------------- 1 | #ifndef NES_MMC3_H 2 | #define NES_MMC3_H 3 | 4 | #include 5 | 6 | 7 | enum MMC3MPrgMode 8 | { 9 | MMC3P_8K_LOWER, 10 | MMC3P_8K_UPPER 11 | }; 12 | 13 | enum MMC3MChrMode 14 | { 15 | MMC3C_2K_LOWER, 16 | MMC3C_2K_HIGHER, 17 | }; 18 | 19 | enum MMC3BankReg 20 | { 21 | MMC3B_CHR0, 22 | MMC3B_CHR1, 23 | MMC3B_CHR2, 24 | MMC3B_CHR3, 25 | MMC3B_CHR4, 26 | MMC3B_CHR5, 27 | 28 | MMC3B_PRG0, 29 | MMC3B_PRG1 30 | }; 31 | 32 | extern char mmc3_shadow; 33 | 34 | void mmc3_reset(void); 35 | 36 | void mmc3_config(MMC3MPrgMode pmode, MMC3MChrMode cmode); 37 | 38 | inline void mmc3_bank(MMC3BankReg reg, char bank); 39 | 40 | void mmc3_bank_prg(char bank); 41 | 42 | void mmc3_bank_chr0(char bank); 43 | 44 | void mmc3_bank_chr1(char bank); 45 | 46 | #pragma compile("mmc3.c") 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/oscar.h: -------------------------------------------------------------------------------- 1 | #ifndef OSCAR_H 2 | #define OSCAR_H 3 | 4 | 5 | __native const char * oscar_expand_lzo(char * dp, const char * sp); 6 | 7 | __native const char * oscar_expand_rle(char * dp, const char * sp); 8 | 9 | // Same as oscar_expand_lzo, but does not need read access to the 10 | // target memory area. On the downside, it uses 256 bytes of stack 11 | // memory as buffer 12 | __native const char * oscar_expand_lzo_buf(char * dp, const char * sp); 13 | 14 | // Write a breakpoint instruction into the .lbl file for vice. This 15 | // intrinsic function will change the behaviour of the optimizer to ensure 16 | // that the breakpoint is not move around into wild places. 17 | void breakpoint(void); 18 | 19 | #pragma intrinsic(breakpoint) 20 | 21 | void debugcrash(void); 22 | 23 | #pragma compile("oscar.c") 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/c64/iecbus.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_IECBUS_H 2 | #define C64_IECBUS_H 3 | 4 | enum IEC_STATUS 5 | { 6 | IEC_OK = 0x00, 7 | IEC_EOF = 0x01, 8 | IEC_QUEUED = 0x02, 9 | 10 | IEC_ERROR = 0x80, 11 | IEC_TIMEOUT, 12 | IEC_DATA_CHECK, 13 | }; 14 | 15 | extern IEC_STATUS iec_status; 16 | 17 | bool iec_write(char b); 18 | 19 | char iec_read(void); 20 | 21 | void iec_atn(char dev, char sec); 22 | 23 | void iec_talk(char dev, char sec); 24 | 25 | void iec_untalk(void); 26 | 27 | void iec_listen(char dev, char sec); 28 | 29 | void iec_unlisten(void); 30 | 31 | void iec_open(char dev, char sec, const char * fname); 32 | 33 | void iec_close(char dev, char sec); 34 | 35 | int iec_write_bytes(const char * data, int num); 36 | 37 | int iec_read_bytes(char * data, int num); 38 | 39 | 40 | #pragma compile("iecbus.c") 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /oscar64/Ident.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Ident 4 | { 5 | public: 6 | ~Ident(); 7 | 8 | char * mString; 9 | unsigned int mHash; 10 | 11 | static const Ident* Unique(const char* str); 12 | static const Ident* Unique(const char* str, int id); 13 | const Ident* Mangle(const char* str) const; 14 | const Ident* PreMangle(const char* str) const; 15 | protected: 16 | Ident(const char* str, unsigned int hash); 17 | }; 18 | 19 | class IdentDict 20 | { 21 | public: 22 | IdentDict(void); 23 | ~IdentDict(void); 24 | 25 | void Insert(const Ident* ident, const char * str); 26 | const char * Lookup(const Ident* ident); 27 | 28 | protected: 29 | void InsertCopy(const Ident* ident, char* str); 30 | 31 | struct Entry 32 | { 33 | const Ident* mIdent; 34 | char* mString; 35 | }; 36 | Entry* mHash; 37 | int mHashSize, mHashFill; 38 | }; -------------------------------------------------------------------------------- /autotest/mmultest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | Matrix4 ml, mr; 6 | 7 | int main(void) 8 | { 9 | for(char i=0; i<16; i++) 10 | { 11 | for(char j=0; j<16; j++) 12 | { 13 | for(char k=0; k<16; k++) 14 | { 15 | ml.m[k] = (i == k) ? 1.0 : 0.0; 16 | mr.m[k] = (j == k) ? 1.0 : 0.0; 17 | } 18 | 19 | mat4_mmul(&ml, &mr); 20 | 21 | #if 0 22 | printf("%d, %d\n", i, j); 23 | for(char k=0; k<16; k++) 24 | printf("%f ", ml.m[k]); 25 | printf("\n"); 26 | #endif 27 | 28 | for(char k=0; k<16; k++) 29 | { 30 | char ix = i & 3, iy = i >> 2; 31 | char jx = j & 3, jy = j >> 2; 32 | char kx = k & 3, ky = k >> 2; 33 | 34 | if (ky == jy && kx == ix && jx == iy) 35 | assert(ml.m[k] == 1.0); 36 | else 37 | assert(ml.m[k] == 0.0); 38 | } 39 | } 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /samples/memmap/charsetlo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // make space until 0x2000 for code and data 6 | 7 | #pragma region( lower, 0x0a00, 0x2000, , , {code, data} ) 8 | 9 | // then space for our custom charset 10 | 11 | #pragma section( charset, 0) 12 | 13 | #pragma region( charset, 0x2000, 0x2800, , , {charset} ) 14 | 15 | // everything beyond will be code, data, bss and heap to the end 16 | 17 | #pragma region( main, 0x2800, 0xa000, , , {code, data, bss, heap, stack} ) 18 | 19 | 20 | #pragma data(charset) 21 | 22 | char charset[2048] = { 23 | #embed "../resources/charset.bin" 24 | }; 25 | 26 | #pragma data(data) 27 | 28 | int main(void) 29 | { 30 | // map the vic to the new charset 31 | 32 | vic_setmode(VICM_TEXT, (char *)0x0400, charset); 33 | 34 | for(int i=0; i<10; i++) 35 | printf(p"%D Hello World\n", i); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /samples/memmap/easyflashlow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma section( startup, 0 ) 8 | 9 | #pragma region( startup, 0x0100, 0x0200, , , { startup } ) 10 | 11 | #pragma region( main, 0x0400, 0x8000, , , { code, data, bss, heap, stack } ) 12 | 13 | CharWin cw; 14 | 15 | int main(void) 16 | { 17 | // Copy Char ROM 18 | mmap_set(MMAP_ALL_ROM); 19 | 20 | memcpy((char *)0xd000, (char *)0xd000, 0x1000); 21 | 22 | // Enable ROM 23 | mmap_set(MMAP_ROM); 24 | 25 | // Init CIAs (no kernal rom was executed so far) 26 | cia_init(); 27 | 28 | // Init VIC 29 | vic_setmode(VICM_TEXT, (char *)0xc000, (char *)0xd800); 30 | 31 | // Prepare output window 32 | cwin_init(&cw, (char *)0xc000, 0, 0, 40, 25); 33 | cwin_clear(&cw); 34 | 35 | cwin_put_string(&cw, p"Hello World", 7); 36 | 37 | while (true) ; 38 | } 39 | -------------------------------------------------------------------------------- /include/c128/bank1.h: -------------------------------------------------------------------------------- 1 | #ifndef C128_BANK1_H 2 | #define C128_BANK1_H 3 | 4 | 5 | #pragma section( bnk1code, 0) 6 | 7 | #pragma region( bnk1code, 0xf000, 0xf300, , , {bnk1code}, 0xfc00 ) 8 | 9 | void bnk1_init(void); 10 | 11 | #pragma code(bnk1code) 12 | 13 | __noinline char bnk1_readb(volatile char * p); 14 | 15 | __noinline unsigned bnk1_readw(volatile unsigned * p); 16 | 17 | __noinline unsigned long bnk1_readl(volatile unsigned long * p); 18 | 19 | __noinline void bnk1_readm(char * dp, volatile char * sp, unsigned size); 20 | 21 | 22 | __noinline void bnk1_writeb(volatile char * p, char b); 23 | 24 | __noinline void bnk1_writew(volatile unsigned * p, unsigned w); 25 | 26 | __noinline void bnk1_writel(volatile unsigned long * p, unsigned long l); 27 | 28 | __noinline void bnk1_writem(volatile char * dp, const char * sp, unsigned size); 29 | 30 | #pragma code(code) 31 | 32 | #pragma compile("bank1.c") 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/time.c: -------------------------------------------------------------------------------- 1 | #include "time.h" 2 | 3 | clock_t clock(void) 4 | { 5 | __asm 6 | { 7 | #if defined(__PLUS4__) 8 | lda $a5 9 | sta accu + 0 10 | lda $a4 11 | sta accu + 1 12 | lda $a3 13 | sta accu + 2 14 | lda #0 15 | sta accu + 3 16 | #elif defined(__CBMPET__) 17 | lda $8f 18 | sta accu + 0 19 | lda $8e 20 | sta accu + 1 21 | lda $8d 22 | sta accu + 2 23 | lda #0 24 | sta accu + 3 25 | #elif defined(__ATARI__) 26 | loop: 27 | lda $14 28 | ldx $13 29 | ldy $12 30 | cmp $14 31 | bne loop 32 | 33 | sta accu + 0 34 | stx accu + 1 35 | sty accu + 2 36 | lda #0 37 | sta accu + 3 38 | #elif defined(__X16__) 39 | jsr $ffde 40 | sta accu + 0 41 | stx accu + 1 42 | sty accu + 2 43 | lda #0 44 | sta accu + 3 45 | #else 46 | lda $a2 47 | sta accu + 0 48 | lda $a1 49 | sta accu + 1 50 | lda $a0 51 | sta accu + 2 52 | lda #0 53 | sta accu + 3 54 | #endif 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /autotest/opp_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | opp::list a; 9 | 10 | for(int i=0; i<10; i++) 11 | a.push_back(i); 12 | 13 | int s = 0; 14 | for(auto i : a) 15 | s += i; 16 | 17 | assert(s == 45); 18 | 19 | auto li = a.begin(); 20 | for(int i=0; i<5; i++) 21 | { 22 | li = a.erase(li); 23 | li++; 24 | } 25 | 26 | s = 0; 27 | for(auto i : a) 28 | s += i; 29 | 30 | assert(s == 1 + 3 + 5 + 7 + 9); 31 | 32 | opp::list b; 33 | 34 | b = a; 35 | 36 | s = 0; 37 | for(auto i : b) 38 | s += i; 39 | 40 | assert(s == 1 + 3 + 5 + 7 + 9); 41 | 42 | opp::list c = opp::list(b); 43 | 44 | s = 0; 45 | for(auto i : c) 46 | s += i; 47 | 48 | assert(s == 1 + 3 + 5 + 7 + 9); 49 | 50 | s = 0; 51 | for(auto i : b) 52 | s += i; 53 | 54 | assert(s == 1 + 3 + 5 + 7 + 9); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /autotest/andmultest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | void checkmul(void) 5 | { 6 | __striped static const unsigned r[256] = { 7 | #for(i, 256) i * n, 8 | }; 9 | 10 | for(unsigned i=0; i> 1] << 1); 14 | assert((i & ~3) * n == r[i >> 2] << 2); 15 | assert((i & ~7) * n == r[i >> 3] << 3); 16 | assert((i & ~15) * n == r[i >> 4] << 4); 17 | } 18 | for(unsigned i=0; i<256; i++) 19 | { 20 | assert((i & ~0) * n == r[i]); 21 | assert((i & ~1) * n == r[i >> 1] << 1); 22 | assert((i & ~3) * n == r[i >> 2] << 2); 23 | assert((i & ~7) * n == r[i >> 3] << 3); 24 | assert((i & ~15) * n == r[i >> 4] << 4); 25 | } 26 | } 27 | 28 | int main(void) 29 | { 30 | checkmul<3, 170>(); 31 | checkmul<4, 128>(); 32 | checkmul<5, 204>(); 33 | checkmul<6, 170>(); 34 | checkmul<7, 128>(); 35 | checkmul<8, 64>(); 36 | checkmul<9, 170>(); 37 | } 38 | -------------------------------------------------------------------------------- /samples/memmap/charsetload.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define Screen ((char *)0xcc00) 7 | #define Charset ((char *)0xc000) 8 | 9 | int main(void) 10 | { 11 | // Set name for file and open it on drive 9 12 | krnio_setnam("CHARSET,P,R"); 13 | if (krnio_open(2, 8, 2)) 14 | { 15 | // Read the content of the file into the charset buffer, 16 | // decompressing on the fly 17 | krnio_read_lzo(2, Charset); 18 | 19 | // Close the file 20 | krnio_close(2); 21 | } 22 | 23 | // Change display address to new screen and charset 24 | 25 | vic_setmode(VICM_TEXT, Screen, Charset); 26 | 27 | for(int i=0; i<1000; i++) 28 | Screen[i] = (char)i; 29 | 30 | // wait for keypress 31 | 32 | getchar(); 33 | 34 | // restore VIC 35 | 36 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 37 | 38 | // restore basic ROM 39 | mmap_set(MMAP_ROM); 40 | 41 | return 0; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /include/math.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_H 2 | #define MATH_H 3 | 4 | #define PI 3.141592653 5 | 6 | 7 | float fabs(float f); 8 | float floor(float f); 9 | float ceil(float f); 10 | 11 | float cos(float f); 12 | float sin(float f); 13 | float tan(float f); 14 | float acos(float f); 15 | float asin(float f); 16 | float atan(float f); 17 | float atan2(float p, float q); 18 | 19 | float exp(float f); 20 | float log(float f); 21 | float log10(float f); 22 | 23 | float pow(float p, float q); 24 | float sqrt(float f); 25 | 26 | bool isinf(float f); 27 | bool isfinite(float f); 28 | 29 | #pragma intrinsic(fabs) 30 | #pragma intrinsic(floor) 31 | #pragma intrinsic(ceil) 32 | 33 | #pragma intrinsic(sin) 34 | #pragma intrinsic(cos) 35 | #pragma intrinsic(tan) 36 | #pragma intrinsic(atan) 37 | #pragma intrinsic(atan2) 38 | 39 | #pragma intrinsic(log) 40 | #pragma intrinsic(exp) 41 | 42 | #pragma intrinsic(pow) 43 | #pragma intrinsic(sqrt) 44 | 45 | #pragma compile("math.c") 46 | 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /samples/memmap/makefile: -------------------------------------------------------------------------------- 1 | %.prg: %.c 2 | @echo "Compiling sample file" $< 3 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< 4 | 5 | all: largemem.prg allmem.prg charsetlo.prg charsethi.prg charsetcopy.prg charsetexpand.prg \ 6 | charsetload.prg easyflash.crt easyflashreloc.crt easyflashshared.crt tsr.prg overlay.prg 7 | 8 | charsetload.prg: charsetload.c ../resources/charset.bin 9 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -d64=charsetload.d64 -fz=../resources/charset.bin 10 | 11 | easyflash.crt: easyflash.c 12 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -n -tf=crt 13 | 14 | easyflashreloc.crt: easyflashreloc.c 15 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -n -tf=crt 16 | 17 | easyflashshared.crt: easyflashshared.c 18 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -n -tf=crt 19 | 20 | tsr.prg: tsr.c 21 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -n -dNOFLOAT -dNOLONG 22 | 23 | overlay.prg: overlay.c 24 | @$(OSCAR64_CC) $(OSCAR64_CFLAGS) $< -n -d64=overlay.d64 25 | 26 | clean: 27 | @$(RM) *.asm *.int *.lbl *.map *.prg *.bcs *.d64 *.crt 28 | -------------------------------------------------------------------------------- /autotest/opp_functional.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Node 4 | { 5 | public: 6 | virtual int eval(void) const = 0; 7 | }; 8 | 9 | class ConstNode : public Node 10 | { 11 | private: 12 | int v; 13 | public: 14 | ConstNode(int v_) : v(v_) {} 15 | virtual int eval(void) const 16 | { 17 | return v; 18 | } 19 | }; 20 | 21 | class BinaryNode : public Node 22 | { 23 | private: 24 | opp::function op; 25 | Node * left, * right; 26 | public: 27 | BinaryNode(opp::function op_, Node * left_, Node * right_); 28 | 29 | virtual int eval(void) const 30 | { 31 | return op(left->eval(), right->eval()); 32 | } 33 | }; 34 | 35 | inline BinaryNode::BinaryNode(opp::function op_, Node * left_, Node * right_) 36 | : op(op_), left(left_), right(right_) {} 37 | 38 | int main(void) 39 | { 40 | Node * s1 = 41 | new BinaryNode([=](int a, int b){return a + b;}, 42 | new ConstNode(7), new ConstNode(11) 43 | ); 44 | 45 | return s1->eval() - 18; 46 | } 47 | -------------------------------------------------------------------------------- /autotest/divmod32test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void check(unsigned long l, unsigned long r) 4 | { 5 | unsigned long d = l / r, m = l % r; 6 | 7 | assert(d * r + m == l); 8 | assert(m < r); 9 | } 10 | 11 | int main(void) 12 | { 13 | for(char i=0; i<28; i++) 14 | { 15 | for(char j=0; j<28; j++) 16 | { 17 | check(0xb3ul << i, 0x2bul << j); 18 | check(0xb3ul << i, 0x01ul << j); 19 | check(0x01ul << i, 0xc2ul << j); 20 | check(0xb31ful << i, 0x2bul << j); 21 | check(0xb354ul << i, 0x01ul << j); 22 | check(0xb3ul << i, 0x2b1cul << j); 23 | check(0xb3ul << i, 0x013ful << j); 24 | check(0xb31ful << i, 0x2b23ul << j); 25 | check(0xb354ul << i, 0x0145ul << j); 26 | check(0xb31f24ul << i, 0x2bul << j); 27 | check(0xb35421ul << i, 0x01ul << j); 28 | check(0xb31f24ul << i, 0x2b23ul << j); 29 | check(0xb35421ul << i, 0x0145ul << j); 30 | check(0xb31f24ul << i, 0x2b2356ul << j); 31 | check(0xb35421ul << i, 0x0145a7ul << j); 32 | } 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /autotest/memmovetest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | unsigned b[4096]; 6 | 7 | void testfwd(unsigned sz) 8 | { 9 | for(unsigned i=0; i<4096; i++) 10 | b[i] = i; 11 | 12 | memmove(b + 100, b + 101, 2 * sz); 13 | 14 | for(unsigned i=0; i<100; i++) 15 | assert(b[i] == i); 16 | for(unsigned i=100; i<100 + sz; i++) 17 | assert(b[i] == i + 1); 18 | for(unsigned i=100 + sz; i<4096; i++) 19 | assert(b[i] == i); 20 | } 21 | 22 | void testback(unsigned sz) 23 | { 24 | for(unsigned i=0; i<4096; i++) 25 | b[i] = i; 26 | 27 | memmove(b + 101, b + 100, 2 * sz); 28 | 29 | for(unsigned i=0; i<101; i++) 30 | assert(b[i] == i); 31 | for(unsigned i=101; i<101 + sz; i++) 32 | assert(b[i] == i - 1); 33 | for(unsigned i=101 + sz; i<4096; i++) 34 | assert(b[i] == i); 35 | } 36 | 37 | int main(void) 38 | { 39 | for(unsigned i=1; i<2048; i *= 2) 40 | { 41 | testfwd(i - 1); 42 | testfwd(i); 43 | testback(i); 44 | testback(i - 1); 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /include/c64/mouse.c: -------------------------------------------------------------------------------- 1 | #include "mouse.h" 2 | #include "sid.h" 3 | #include "cia.h" 4 | 5 | sbyte mouse_dx, mouse_dy; 6 | bool mouse_lb, mouse_rb; 7 | static char mouse_px, mouse_py; 8 | static char mouse_port; 9 | 10 | inline signed char dpos(char * old, char mnew) 11 | { 12 | mnew = (mnew & 0x7f) >> 1; 13 | 14 | char diff = (mnew - *old) & 0x3f; 15 | 16 | if (diff >= 0x20) 17 | { 18 | *old = mnew; 19 | return diff | 0xe0; 20 | } 21 | else if (diff) 22 | { 23 | *old = mnew; 24 | return diff; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | void mouse_poll(void) 31 | { 32 | char b = ((volatile char *)0xdc00)[mouse_port]; 33 | mouse_rb = (b & 0x01) == 0; 34 | mouse_lb = (b & 0x10) == 0; 35 | 36 | char x = sid.potx, y = sid.poty; 37 | 38 | mouse_dx = dpos(&mouse_px, x); 39 | mouse_dy = dpos(&mouse_py, y); 40 | } 41 | 42 | void mouse_arm(char n) 43 | { 44 | mouse_port = n; 45 | cia1.pra = ciaa_pra_def = n ? 0x7f : 0xbf; 46 | } 47 | 48 | void mouse_init(void) 49 | { 50 | mouse_arm(1); 51 | mouse_poll(); 52 | } 53 | -------------------------------------------------------------------------------- /autotest/mixsigncmptest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | unsigned n1, n0; 6 | 7 | n1 = 0; n0 = 0; 8 | for(int i=-1000; i<2000; i+=37) 9 | { 10 | for(char j=0; j<255; j++) 11 | { 12 | if (i < j) 13 | n1++; 14 | else 15 | n0++; 16 | } 17 | } 18 | 19 | assert(n1 == 7893 && n0 == 13017); 20 | 21 | n1 = 0; n0 = 0; 22 | for(int i=-1000; i<2000; i+=37) 23 | { 24 | for(char j=0; j<255; j++) 25 | { 26 | if (i <= j) 27 | n1++; 28 | else 29 | n0++; 30 | } 31 | } 32 | 33 | assert(n1 == 7899 && n0 == 13011); 34 | 35 | n1 = 0; n0 = 0; 36 | for(int i=-1000; i<2000; i+=37) 37 | { 38 | for(char j=0; j<255; j++) 39 | { 40 | if (i >= j) 41 | n1++; 42 | else 43 | n0++; 44 | } 45 | } 46 | 47 | assert(n0 == 7893 && n1 == 13017); 48 | 49 | n1 = 0; n0 = 0; 50 | for(int i=-1000; i<2000; i+=37) 51 | { 52 | for(char j=0; j<255; j++) 53 | { 54 | if (i > j) 55 | n1++; 56 | else 57 | n0++; 58 | } 59 | } 60 | 61 | assert(n0 == 7899 && n1 == 13011); 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /autotest/testinterval.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void testint0(void) 4 | { 5 | int a0n = 0, an0 = 0; 6 | int b0n = 0, bn0 = 0; 7 | 8 | for(int i=-1000; i<1000; i++) 9 | { 10 | if (i >= 0 && i < 500) 11 | a0n += 1; 12 | if (i < 500 && i >= 0) 13 | an0 += 1; 14 | if (i >= 0 && i <= 499) 15 | b0n += 1; 16 | if (i <= 499 && i >= 0) 17 | bn0 += 1; 18 | } 19 | 20 | assert(a0n == 500); 21 | assert(an0 == 500); 22 | assert(b0n == 500); 23 | assert(bn0 == 500); 24 | } 25 | 26 | typedef signed char int8; 27 | 28 | void testbyte0(void) 29 | { 30 | int8 a0n = 0, an0 = 0; 31 | int8 b0n = 0, bn0 = 0; 32 | 33 | for(int8 i=-100; i<100; i++) 34 | { 35 | if (i >= 0 && i < 50) 36 | a0n += 1; 37 | if (i < 50 && i >= 0) 38 | an0 += 1; 39 | if (i >= 0 && i <= 49) 40 | b0n += 1; 41 | if (i <= 49 && i >= 0) 42 | bn0 += 1; 43 | } 44 | 45 | assert(a0n == 50); 46 | assert(an0 == 50); 47 | assert(b0n == 50); 48 | assert(bn0 == 50); 49 | } 50 | 51 | int main(void) 52 | { 53 | testint0(); 54 | testbyte0(); 55 | 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /include/opp/boundint.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_BOUNDINT_H 2 | #define OPP_BOUNDINT_H 3 | 4 | namespace opp { 5 | 6 | template 7 | constexpr auto boundinttype(void) 8 | { 9 | if constexpr (tmin >= 0 && tmax <= 255) 10 | return (char)0; 11 | else if constexpr (tmin >= -128 && tmax <= 127) 12 | return (signed char)0; 13 | else 14 | return (int)0; 15 | } 16 | 17 | template 18 | class boundint 19 | { 20 | protected: 21 | decltype(boundinttype()) v; 22 | public: 23 | boundint(int i) 24 | : v(i) 25 | { 26 | 27 | } 28 | 29 | void operator=(int k) 30 | { 31 | __assume(k >= tmin && k <= tmax); 32 | v = k; 33 | } 34 | 35 | void operator+=(int k) 36 | { 37 | k += v; 38 | __assume(k >= tmin && k <= tmax); 39 | v = k; 40 | } 41 | 42 | void operator-=(int k) 43 | { 44 | k = v - k; 45 | __assume(k >= tmin && k <= tmax); 46 | v = k; 47 | } 48 | 49 | operator int() const 50 | { 51 | int k = v; 52 | __assume(k >= tmin && k <= tmax); 53 | return k; 54 | } 55 | }; 56 | 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /samples/memmap/allmem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // make space until 0x1000 by for the stack 6 | 7 | #pragma stacksize(0x0600) 8 | 9 | #pragma region( stack, 0x0a00, 0x1000, , , {stack} ) 10 | 11 | // everything beyond will be code, data, bss and heap to the end 12 | 13 | #pragma region( main, 0x1000, 0xfff0, , , {code, data, bss, heap} ) 14 | 15 | int main(void) 16 | { 17 | // Install the IRQ trampoline 18 | 19 | mmap_trampoline(); 20 | 21 | // Hide the basic ROM, must be first instruction 22 | 23 | mmap_set(MMAP_RAM); 24 | 25 | // Allocate all memory 26 | 27 | unsigned total = 0; 28 | while (char * data = malloc(1024)) 29 | { 30 | total += 1024; 31 | 32 | // Swap in kernal for print 33 | 34 | mmap_set(MMAP_NO_BASIC); 35 | printf("ALLOCATED %5u AT %04x\n", total, (unsigned)data); 36 | mmap_set(MMAP_RAM); 37 | 38 | // Fill it with trash 39 | 40 | for(unsigned i=0; i<1024; i++) 41 | data[i] = 0xaa; 42 | } 43 | 44 | // Return basic ROM to normal state 45 | 46 | mmap_set(MMAP_ROM); 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /autotest/autorefreturn.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct X 5 | { 6 | char t; 7 | long l; 8 | }; 9 | 10 | __striped X xs[16]; 11 | X xf[16]; 12 | char xp; 13 | 14 | __noinline long tt(long n) 15 | { 16 | return n; 17 | } 18 | 19 | inline auto & tas(void) 20 | { 21 | return xs[xp].l; 22 | } 23 | 24 | inline auto & taf(void) 25 | { 26 | return xf[xp].l; 27 | } 28 | 29 | long ts(char n) 30 | { 31 | return tt(tas()); 32 | } 33 | 34 | long tf(char n) 35 | { 36 | return tt(taf()); 37 | } 38 | 39 | inline auto bas(void) 40 | { 41 | return xs[xp].l; 42 | } 43 | 44 | inline auto baf(void) 45 | { 46 | return xs[xp].l; 47 | } 48 | 49 | long bs(char n) 50 | { 51 | return tt(bas()); 52 | } 53 | 54 | long bf(char n) 55 | { 56 | return tt(baf()); 57 | } 58 | 59 | int main(void) 60 | { 61 | for(char i=0; i<16; i++) 62 | { 63 | xs[i].l = i * i; 64 | xf[i].l = i * i; 65 | } 66 | 67 | for(char i=0; i<16; i++) 68 | { 69 | xp = i; 70 | assert(ts(0) == i * i); 71 | assert(tf(0) == i * i); 72 | assert(bs(0) == i * i); 73 | assert(bf(0) == i * i); 74 | } 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /autotest/opp_numeric.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using opp::string, opp::cout; 10 | 11 | int main(void) 12 | { 13 | opp::array v; 14 | 15 | opp::iota(v.begin(), v.end(), 10); 16 | 17 | string s = opp::accumulate( 18 | opp::next(v.begin()), v.end(), opp::to_string(v[0]), 19 | [](const opp::string & ws, int k) {return ws + "-" + opp::to_string(k);}); 20 | 21 | assert(s == "10-11-12-13-14-15-16-17-18-19"); 22 | 23 | opp::ostringstream osstr; 24 | opp::inclusive_scan(v.begin(), v.end(), opp::ostream_iterator(osstr, ", ")); 25 | assert(osstr.str() == "10, 21, 33, 46, 60, 75, 91, 108, 126, 145, "); 26 | 27 | osstr.str(""); 28 | opp::exclusive_scan(v.begin(), v.end(), opp::ostream_iterator(osstr, ", "), 0); 29 | assert(osstr.str() == "0, 10, 21, 33, 46, 60, 75, 91, 108, 126, "); 30 | 31 | opp::array w; 32 | 33 | opp::iota(w.begin(), w.end(), 1); 34 | 35 | assert(opp::inner_product(v.begin(), v.end(), w.begin(), 0) == 880); 36 | } -------------------------------------------------------------------------------- /autotest/opp_optional.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using opp::optional; 9 | using opp::string; 10 | 11 | optional isqrt(int i) 12 | { 13 | if (i < 0) 14 | return optional(); 15 | else 16 | return i; 17 | } 18 | 19 | optional ssqrt(int i) 20 | { 21 | if (i < 0) 22 | return optional(); 23 | else 24 | return opp::to_string(i); 25 | } 26 | 27 | int main(void) 28 | { 29 | int sum = 0; 30 | for(int i=-10; i<=10; i++) 31 | { 32 | for (auto s : isqrt(i)) 33 | sum += s; 34 | } 35 | assert(sum == 55); 36 | 37 | sum = 0; 38 | for(int i=-10; i<=10; i++) 39 | { 40 | if (auto s = ssqrt(i)) 41 | sum += s->to_int(); 42 | } 43 | assert(sum == 55); 44 | 45 | sum = 0; 46 | for(int i=-10; i<=10; i++) 47 | { 48 | for (auto s : ssqrt(i)) 49 | sum += s.to_int(); 50 | } 51 | assert(sum == 55); 52 | 53 | sum = 0; 54 | for(int i=-10; i<=10; i++) 55 | { 56 | auto s = ssqrt(i); 57 | auto t = s; 58 | 59 | if (t) 60 | sum += t->to_int(); 61 | } 62 | assert(sum == 55); 63 | } 64 | -------------------------------------------------------------------------------- /oscar64/CompilationUnits.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Declaration.h" 4 | #include "Errors.h" 5 | #include "Linker.h" 6 | 7 | class CompilationUnit 8 | { 9 | public: 10 | Location mLocation; 11 | char mFileName[200]; 12 | CompilationUnit * mNext; 13 | bool mCompiled; 14 | }; 15 | 16 | class CompilationUnits 17 | { 18 | public: 19 | CompilationUnits(Errors * errors); 20 | ~CompilationUnits(void); 21 | 22 | DeclarationScope* mScope, * mVTableScope, * mTemplateScope; 23 | CompilationUnit* mCompilationUnits, * mPendingUnits; 24 | 25 | Declaration* mStartup; 26 | Declaration* mByteCodes[256]; 27 | GrowingArray mReferenced; 28 | 29 | DeclarationScope* mRuntimeScope; 30 | 31 | LinkerSection* mSectionCode, * mSectionData, * mSectionBSS, * mSectionHeap, * mSectionStack, * mSectionZeroPage, * mSectionLowCode, * mSectionBoot; 32 | Linker* mLinker; 33 | 34 | int mUniqueID; 35 | 36 | int UniqueID(void); 37 | 38 | bool AddUnit(Location & location, const char* name, const char * from); 39 | CompilationUnit* PendingUnit(void); 40 | 41 | void AddReferenced(Declaration* ref); 42 | 43 | protected: 44 | Errors* mErrors; 45 | }; 46 | 47 | -------------------------------------------------------------------------------- /oscar64/Compression.cpp: -------------------------------------------------------------------------------- 1 | #include "Compression.h" 2 | 3 | int CompressLZO(uint8* dst, const uint8* source, int size) 4 | { 5 | int csize = 0; 6 | 7 | int pos = 0; 8 | while (pos < size) 9 | { 10 | int pi = 0; 11 | while (pi < 127 && pos < size) 12 | { 13 | int bi = pi, bj = 0; 14 | for (int i = 1; i <= (pos < 255 ? pos : 255); i++) 15 | { 16 | int j = 0; 17 | while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j]) 18 | j++; 19 | 20 | if (j > bj) 21 | { 22 | bi = i; 23 | bj = j; 24 | } 25 | } 26 | 27 | if (bj >= 4) 28 | { 29 | if (pi > 0) 30 | { 31 | dst[csize++] = pi; 32 | for (int i = 0; i < pi; i++) 33 | dst[csize++] = source[pos - pi + i]; 34 | pi = 0; 35 | } 36 | 37 | dst[csize++] = 128 + bj; 38 | dst[csize++] = bi; 39 | pos += bj; 40 | } 41 | else 42 | { 43 | pos++; 44 | pi++; 45 | } 46 | } 47 | 48 | if (pi > 0) 49 | { 50 | dst[csize++] = pi; 51 | for (int i = 0; i < pi; i++) 52 | dst[csize++] = source[pos - pi + i]; 53 | } 54 | } 55 | 56 | dst[csize++] = 0; 57 | 58 | return csize; 59 | } 60 | -------------------------------------------------------------------------------- /autotest/charwintest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | CharWin cw; 8 | 9 | cwin_init(&cw, (char *)0x0400, 2, 2, 32, 20); 10 | 11 | cwin_clear(&cw); 12 | 13 | for(int y=0; y<20; y++) 14 | { 15 | for(int x=0; x<32; x++) 16 | { 17 | assert(cwin_getat_char_raw(&cw, x, y) == ' '); 18 | } 19 | } 20 | 21 | for(int y=0; y<20; y++) 22 | { 23 | for(int x=0; x<32; x++) 24 | { 25 | cwin_putat_char(&cw, x, y, p'a' - 1 + x, 7); 26 | } 27 | } 28 | 29 | 30 | for(int y=0; y<20; y++) 31 | { 32 | for(int x=0; x<32; x++) 33 | { 34 | assert(cwin_getat_char(&cw, x, y) == p'a' -1 + x); 35 | } 36 | } 37 | 38 | 39 | for(int y=0; y<20; y++) 40 | { 41 | for(int x=0; x<32; x++) 42 | { 43 | cwin_putat_char(&cw, x, y, p'A' - 1 + x, 8); 44 | } 45 | } 46 | 47 | for(int y=0; y<20; y++) 48 | { 49 | for(int x=0; x<32; x++) 50 | { 51 | cwin_putat_char_raw(&cw, x, y, x + 32 * y, 8); 52 | } 53 | } 54 | 55 | for(int y=0; y<8; y++) 56 | { 57 | for(int x=0; x<32; x++) 58 | { 59 | assert(cwin_getat_char_raw(&cw, x, y) == x + 32 * y); 60 | } 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /oscar64/Emulator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Assembler.h" 4 | #include "MachineTypes.h" 5 | 6 | class Linker; 7 | 8 | static const int TRACEF_BYTECODE = 0x01; 9 | static const int TRACEF_NATIVE = 0x02; 10 | 11 | class Emulator 12 | { 13 | public: 14 | Emulator(Linker * linker); 15 | ~Emulator(void); 16 | 17 | uint8 mMemory[0x10000]; 18 | int mCycles[0x10000]; 19 | bool mCalls[0x100]; 20 | 21 | int mIP, mExitIP; 22 | uint8 mRegA, mRegX, mRegY, mRegS, mRegP; 23 | bool mJiffies, mUseIORange; 24 | int mCycleCount; 25 | 26 | struct IORange 27 | { 28 | uint8 mCount0, mCount1, mMirror; 29 | uint8 mScratch[4]; 30 | uint16 mDMAAddress; 31 | uint32 mCycleCount; 32 | } mIORange; 33 | 34 | Linker* mLinker; 35 | 36 | int Emulate(int startIP, int exitIP, int trace, bool iorange); 37 | void DumpProfile(void); 38 | bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles, bool cross, bool indexed); 39 | protected: 40 | void UpdateStatus(uint8 result); 41 | void UpdateStatusCarry(uint8 result, bool carry); 42 | void DumpCycles(void); 43 | void DumpCallstack(void); 44 | 45 | uint8 ReadMemory(uint16 addr); 46 | void WriteMemory(uint16 addr, uint8 data); 47 | }; -------------------------------------------------------------------------------- /samples/sprites/joycontrol.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char spdata[] = { 6 | #embed "../resources/friendlybear.bin" 7 | }; 8 | 9 | int spx, spy; 10 | 11 | #define SpriteData ((char *)0x0380) 12 | 13 | int main(void) 14 | { 15 | // Copy the sprite data 16 | memcpy(SpriteData, spdata, 128); 17 | 18 | // Initialize the sprite system 19 | spr_init((char*)0x0400); 20 | 21 | // Center screen position 22 | spx = 160; 23 | spy = 100; 24 | 25 | // Two sprites, one black in front hires and one multicolor in back 26 | spr_set(0, true, spx, spy, 0x03c0 / 64, VCOL_BLACK, false, false, false); 27 | spr_set(1, true, spx, spy, 0x0380 / 64, VCOL_ORANGE, true, false, false); 28 | 29 | // Multicolor sprite colors 30 | vic.spr_mcolor0 = VCOL_BROWN; 31 | vic.spr_mcolor1 = VCOL_WHITE; 32 | 33 | for(;;) 34 | { 35 | // Poll joytick 36 | joy_poll(0); 37 | 38 | // Change position according to joystick 39 | spx += joyx[0]; 40 | spy += joyy[0]; 41 | 42 | // Move sprites on screen 43 | spr_move(0, spx, spy); 44 | spr_move(1, spx, spy); 45 | 46 | // Wait for one frame iteration 47 | vic_waitFrame(); 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /autotest/array2stringinittest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | char s[25][41] = {"Q QQ QQQQQ QQQQQQQQQQQQQ", 7 | " QQQQQQQQQQQQQQQQQQQQQQQQQQ", 8 | "QQQQQQQQ", 9 | " QQQQQQQQQQQQQQQQQ", 10 | "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 11 | "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 12 | "", 13 | "", 14 | "", 15 | " QQQQQQQQQQQQQQQQQQQQQQQQ", 16 | "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 17 | "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 18 | "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 19 | "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 20 | "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ", 21 | "QQQQQQQQQ", 22 | "", 23 | "", 24 | "", 25 | "", 26 | "", 27 | "", 28 | "", 29 | "", 30 | " QQQQQQQQQQQQQQ"}; 31 | 32 | int main() 33 | { 34 | int i=0, sum = 0; 35 | for (unsigned char i = 0; i < 25; i++) 36 | { 37 | int j = 0; 38 | while (s[i][j]) 39 | { 40 | sum += s[i][j] & 3; 41 | j++; 42 | } 43 | } 44 | 45 | assert(sum == 391); 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /samples/kernalio/hiresread.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | Bitmap Screen; 9 | 10 | #define ScreenMem ((char *)0xe000) 11 | #define ColorMem ((char *)0xd000) 12 | 13 | int main(void) 14 | { 15 | // Install the IRQ trampoline 16 | mmap_trampoline(); 17 | 18 | // Initialize the display bitmap 19 | bm_init(&Screen, ScreenMem, 40, 25); 20 | 21 | // Clear the color memory with ROM and IO disabled 22 | mmap_set(MMAP_RAM); 23 | memset(ScreenMem, 0, 8000); 24 | memset(ColorMem, 0x70, 1000); 25 | mmap_set(MMAP_NO_ROM); 26 | 27 | // Switch VIC to hires mode 28 | vic_setmode(VICM_HIRES, ColorMem, ScreenMem); 29 | 30 | // Reenable the kernal rom 31 | mmap_set(MMAP_ROM); 32 | 33 | 34 | // Set name for file and open it with replace on drive 9 35 | krnio_setnam("TESTIMAGE,P,R"); 36 | if (krnio_open(2, 9, 2)) 37 | { 38 | // Read the bitmap image in one go 39 | krnio_read(2, ScreenMem, 8000); 40 | 41 | // Close the file 42 | krnio_close(2); 43 | } 44 | 45 | // Wait for a character 46 | getchar(); 47 | 48 | // Restore VIC 49 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef STRING_H 2 | #define STRING_H 3 | 4 | char * strcpy(char * dst, const char * src); 5 | 6 | char * strncpy(char * dst, const char * src, int n); 7 | 8 | signed char strcmp(const char * ptr1, const char * ptr2); 9 | 10 | signed char strncmp(const char * ptr1, const char * ptr2, int n); 11 | 12 | int strlen(const char * str); 13 | 14 | char * strcat(char * dst, const char * src); 15 | 16 | char * strncat(char * dst, const char * src, int n); 17 | 18 | char * strchr(const char * str, int ch); 19 | 20 | char * strrchr(const char * str, int ch); 21 | 22 | char * strstr(const char * str, const char * substr); 23 | 24 | char * cpycat(char * dst, const char * src); 25 | 26 | void * memclr(void * dst, int size); 27 | 28 | void * memset(void * dst, int value, int size); 29 | 30 | void * memcpy(void * dst, const void * src, int size); 31 | 32 | signed char memcmp(const void * ptr1, const void * ptr2, int size); 33 | 34 | void * memmove(void * dst, const void * src, int size); 35 | 36 | void * memchr(const void * ptr, int ch, int size); 37 | 38 | #pragma intrinsic(strcpy) 39 | 40 | #pragma intrinsic(memcpy) 41 | 42 | #pragma intrinsic(memset) 43 | 44 | #pragma intrinsic(memclr) 45 | 46 | #pragma compile("string.c") 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /samples/hires/fractaltree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | char * const Color = (char *)0xd000; 10 | char * const Hires = (char *)0xe000; 11 | 12 | Bitmap Screen; 13 | ClipRect Clip = {0, 0, 320, 200}; 14 | 15 | void init(void) 16 | { 17 | mmap_trampoline(); 18 | mmap_set(MMAP_RAM); 19 | 20 | memset(Color, 0x01, 1000); 21 | memset(Hires, 0x00, 8000); 22 | 23 | mmap_set(MMAP_NO_ROM); 24 | 25 | vic_setmode(VICM_HIRES, Color, Hires); 26 | 27 | vic.color_border = VCOL_WHITE; 28 | 29 | bm_init(&Screen, Hires, 40, 25); 30 | } 31 | 32 | void done(void) 33 | { 34 | mmap_set(MMAP_ROM); 35 | 36 | getch(); 37 | 38 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 39 | } 40 | 41 | void draw(float x, float y, float a, float s) 42 | { 43 | if (s < 6.0) 44 | return; 45 | 46 | float tx = x + cos(a) * s; 47 | float ty = y + sin(a) * s; 48 | 49 | bm_line(&Screen, &Clip, x, y, tx, ty, 0xff, LINOP_SET); 50 | 51 | draw(tx, ty, a + 0.3, s * 0.9); 52 | draw(tx, ty, a - 0.4, s * 0.8); 53 | } 54 | 55 | int main(void) 56 | { 57 | init(); 58 | 59 | draw(140, 199, PI * 1.5, 32); 60 | 61 | done(); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /include/c64/easyflash.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_EASYFLASH_H 2 | #define C64_EASYFLASH_H 3 | 4 | #include "types.h" 5 | 6 | struct EasyFlash 7 | { 8 | volatile __memmap byte bank; 9 | byte pad1; 10 | volatile byte control; 11 | }; 12 | 13 | #define EFCTRL_GAME 0x01 14 | #define EFCTRL_EXROM 0x02 15 | #define EFCTRL_MODE 0x04 16 | #define EFCTRL_LED 0x80 17 | 18 | 19 | #define eflash (*(EasyFlash *)0xde00) 20 | 21 | #ifdef __cplusplus 22 | 23 | #ifdef EFPROX_SECTION 24 | #pragma code(EFPROX_SECTION) 25 | #endif 26 | 27 | template 28 | __noinline auto ef_call_p(P... p) 29 | { 30 | if (back != __bankof(fn)) 31 | eflash.bank = __bankof(fn); 32 | auto r = fn(p...); 33 | if (back != 0xff && back != __bankof(fn)) 34 | eflash.bank = back; 35 | return r; 36 | } 37 | 38 | #ifdef EFPROX_SECTION 39 | #pragma code(code) 40 | #endif 41 | 42 | template 43 | class EFlashCall 44 | { 45 | public: 46 | template 47 | __forceinline auto operator()(P ... p) const 48 | { 49 | switch(__bankof(0)) 50 | { 51 | #for(i,64) case i: return ef_call_p(p...); 52 | default: 53 | return ef_call_p<0xff, fn, P...>(p...); 54 | } 55 | } 56 | }; 57 | 58 | #define EF_CALL(fn) EFlashCall fn 59 | 60 | #endif 61 | 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /samples/kernalio/diskdir.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | // Set name for directory 7 | 8 | krnio_setnam("$"); 9 | 10 | // Open #2 on drive 9 (or 8) 11 | 12 | if (krnio_open(2, 9, 0)) 13 | { 14 | // Switch input to file #2 15 | 16 | if (krnio_chkin(2)) 17 | { 18 | // Skip BASIC load address 19 | 20 | krnio_chrin(); 21 | krnio_chrin(); 22 | 23 | // Loop while we have more lines 24 | 25 | int ch; 26 | while((ch = krnio_chrin()) > 0) 27 | { 28 | unsigned line; 29 | char buff[40]; 30 | 31 | // Skip second basic link byte 32 | krnio_chrin(); 33 | 34 | // Read line number (size in blocks) 35 | ch = krnio_chrin(); 36 | line = ch; 37 | ch = krnio_chrin(); 38 | line += 256 * ch; 39 | 40 | // Read file name, reading till end of basic line 41 | int n = 0; 42 | while ((ch = krnio_chrin()) > 0) 43 | buff[n++] = ch; 44 | buff[n] = 0; 45 | 46 | // Print size and name 47 | 48 | printf("%u %s\n", line, buff); 49 | } 50 | 51 | // Reset channels 52 | 53 | krnio_clrchn(); 54 | } 55 | 56 | // Close file #2 57 | 58 | krnio_close(2); 59 | } 60 | else 61 | printf("FAIL OPEN %d\n", krnio_status()); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /samples/hiresmc/floodfill.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma region(main, 0x0a00, 0xc800, , , {code, data, bss, heap, stack} ) 10 | 11 | #define Color1 ((char *)0xc800) 12 | #define Color2 ((char *)0xd800) 13 | #define Hires ((char *)0xe000) 14 | 15 | Bitmap sbm; 16 | 17 | int main(void) 18 | { 19 | mmap_trampoline(); 20 | 21 | vic_setmode(VICM_HIRES_MC, Color1, Hires); 22 | 23 | mmap_set(MMAP_NO_ROM); 24 | 25 | vic.color_back = VCOL_BLACK; 26 | vic.color_border = VCOL_BLACK; 27 | 28 | memset(Color1, 0x67, 1000); 29 | memset(Color2, 0x02, 1000); 30 | memset(Hires, 0, 8000); 31 | 32 | bm_init(&sbm, Hires, 40, 25); 33 | 34 | ClipRect scr = { 0, 0, 320, 200 }; 35 | 36 | for(;;) 37 | { 38 | for(int i=0; i<20; i++) 39 | { 40 | bmmc_circle_fill(&sbm, &scr, rand() % 320, rand() % 200, 5 + rand() % 40, MixedColors[1][1]); 41 | } 42 | for(int i=0; i<20; i++) 43 | { 44 | bmmc_circle_fill(&sbm, &scr, rand() % 320, rand() % 200, 5 + rand() % 40, MixedColors[0][0]); 45 | } 46 | bmmc_flood_fill(&sbm, &scr, 210, 100, 2); 47 | bmmc_flood_fill(&sbm, &scr, 60, 140, 3); 48 | } 49 | 50 | mmap_set(MMAP_ROM); 51 | 52 | getch(); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /samples/kernalio/hiresfload.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | char * const Hires = (char *)0xe000; 10 | char * const Color = (char *)0xd800; 11 | char * const Screen = (char *)0xcc00; 12 | 13 | int main(void) 14 | { 15 | // Prepare fast loader in floppy memory 16 | flosskio_init(8); 17 | 18 | // Map filenames to track/sector addresses 19 | floss_blk blks[1]; 20 | flosskio_mapdir(p"blumba2", blks); 21 | 22 | // Clear screen 23 | memset(Hires, 0x00, 8000); 24 | memset(Screen, 0xff, 1000); 25 | memset(Color, 0x01, 1000); 26 | 27 | // Switch to multicolor hires 28 | vic_setmode(VICM_HIRES_MC, Screen, Hires); 29 | vic.color_back = VCOL_BLACK; 30 | vic.color_border = VCOL_BLACK; 31 | 32 | // Open file 33 | flosskio_open(blks[0].track, blks[0].sector); 34 | 35 | // Read compressed image 36 | flossiec_read_lzo(Hires, 8000); 37 | flossiec_read_lzo(Screen, 1000); 38 | flossiec_read_lzo(Color, 1000); 39 | 40 | // Close file 41 | flosskio_close(); 42 | 43 | // Remove drive code 44 | flosskio_shutdown(); 45 | 46 | // Wait for a character 47 | getchar(); 48 | 49 | // Restore VIC 50 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /include/opp/algorithm.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_ALGORITHM_H 2 | #define OPP_ALGORITHM_H 3 | 4 | #include "utility.h" 5 | namespace opp { 6 | 7 | template 8 | void sort(T s, T e) 9 | { 10 | while (s != e) 11 | { 12 | auto p = s; 13 | auto q = s; 14 | 15 | q++; 16 | while (q != e) 17 | { 18 | if (LT(*q, *p)) 19 | { 20 | swap(*q, *p); 21 | p++; 22 | swap(*q, *p); 23 | } 24 | q++; 25 | } 26 | 27 | sort(s, p); 28 | p++; 29 | s = p; 30 | } 31 | } 32 | 33 | template 34 | void sort(T s, T e, LF lt) 35 | { 36 | while (s != e) 37 | { 38 | auto p = s; 39 | auto q = s; 40 | 41 | q++; 42 | while (q != e) 43 | { 44 | if (lt(*q, *p)) 45 | { 46 | swap(*q, *p); 47 | p++; 48 | swap(*q, *p); 49 | } 50 | q++; 51 | } 52 | 53 | sort(s, p, lt); 54 | p++; 55 | s = p; 56 | } 57 | } 58 | 59 | template 60 | OI copy(II first, II last, OI result) 61 | { 62 | while (first != last) 63 | { 64 | *result = *first; 65 | ++result; ++first; 66 | } 67 | return result; 68 | } 69 | 70 | 71 | template 72 | II find (II first, II last, const T& val) 73 | { 74 | while (first != last) 75 | { 76 | if (*first == val) return first; 77 | ++first; 78 | } 79 | return last; 80 | } 81 | 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /autotest/operatoroverload.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A 4 | { 5 | int n; 6 | 7 | A(int n_) 8 | : n(n_) {} 9 | 10 | A(const A & a) 11 | : n(a.n) {} 12 | 13 | A operator+(const A & a) const 14 | { 15 | return A(n + a.n); 16 | } 17 | 18 | A operator-(const A & a) const 19 | { 20 | return A(n - a.n); 21 | } 22 | 23 | A & operator+=(const A & a) 24 | { 25 | n += a.n; 26 | return *this; 27 | } 28 | 29 | A & operator-=(const A & a) 30 | { 31 | n -= a.n; 32 | return *this; 33 | } 34 | 35 | A operator-(void) const 36 | { 37 | return A(-n); 38 | } 39 | 40 | A & operator++(void) 41 | { 42 | n++; 43 | return *this; 44 | } 45 | 46 | A & operator--(void) 47 | { 48 | n--; 49 | return *this; 50 | } 51 | 52 | A operator++(int); 53 | 54 | A operator--(int); 55 | 56 | }; 57 | 58 | A A::operator++(int) 59 | { 60 | A a(*this); 61 | n++; 62 | return a; 63 | } 64 | 65 | A A::operator--(int) 66 | { 67 | A a(*this); 68 | n--; 69 | return a; 70 | } 71 | 72 | int main(void) 73 | { 74 | A a(7), b(8), c(9); 75 | 76 | assert((++a).n == 8); 77 | assert(a.n == 8); 78 | 79 | assert((--a).n == 7); 80 | assert(a.n == 7); 81 | 82 | assert((a++).n == 7); 83 | assert(a.n == 8); 84 | assert((a--).n == 8); 85 | assert(a.n == 7); 86 | 87 | assert((a + b - c + -a + -b - -c).n == 0); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /autotest/vcalltest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct A 4 | { 5 | virtual int f(int x); 6 | }; 7 | 8 | struct B : A 9 | { 10 | virtual int f(int x); 11 | }; 12 | 13 | struct C : A 14 | { 15 | virtual int f(int x); 16 | virtual int g(int y, int z); 17 | }; 18 | 19 | struct D : B 20 | { 21 | virtual int f(int x); 22 | }; 23 | 24 | struct E : C 25 | { 26 | virtual int f(int x); 27 | virtual int g(int y, int z); 28 | }; 29 | 30 | struct F : C 31 | { 32 | virtual int g(int y, int z); 33 | }; 34 | 35 | int A::f(int x) 36 | { 37 | return x * 1; 38 | } 39 | 40 | int B::f(int x) 41 | { 42 | return x * 2; 43 | } 44 | 45 | int C::f(int x) 46 | { 47 | return x * 3; 48 | } 49 | 50 | int C::g(int y, int z) 51 | { 52 | return (y + z) * 3; 53 | } 54 | 55 | int D::f(int x) 56 | { 57 | return x * 4; 58 | } 59 | 60 | int E::f(int x) 61 | { 62 | return x * 5; 63 | } 64 | 65 | int E::g(int y, int z) 66 | { 67 | return (y + z) * 5; 68 | } 69 | 70 | int F::g(int y, int z) 71 | { 72 | return (y + z) * 6; 73 | } 74 | 75 | int main(void) 76 | { 77 | A a; 78 | B b; 79 | C c; 80 | D d; 81 | E e; 82 | F f; 83 | 84 | assert(a.f(3) == c.f(1)); 85 | assert(b.f(4) == d.f(2)); 86 | assert(e.f(2) == b.f(5)); 87 | assert(f.f(5) == e.f(3)); 88 | 89 | assert(c.g(3, 2) == e.g(1, 2)); 90 | assert(c.g(1, 5) == f.g(0, 3)); 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /oscar64/Disassembler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "MachineTypes.h" 5 | #include "Ident.h" 6 | 7 | class ByteCodeGenerator; 8 | class InterCodeProcedure; 9 | class Linker; 10 | class LinkerObject; 11 | 12 | class ByteCodeDisassembler 13 | { 14 | public: 15 | ByteCodeDisassembler(void); 16 | ~ByteCodeDisassembler(void); 17 | 18 | void Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker * linker); 19 | protected: 20 | const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker* linker); 21 | const char* AddrName(int addr, char* buffer, Linker* linker); 22 | }; 23 | 24 | class NativeCodeDisassembler 25 | { 26 | public: 27 | NativeCodeDisassembler(void); 28 | ~NativeCodeDisassembler(void); 29 | 30 | void Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker, const Ident* fident); 31 | void DumpMemory(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker, LinkerObject * lobj); 32 | protected: 33 | const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker* linker); 34 | const char* AddrName(int bank, int addr, char* buffer, InterCodeProcedure* proc, Linker* linker); 35 | }; 36 | 37 | 38 | -------------------------------------------------------------------------------- /autotest/funcvartest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | typedef float (*fop)(float a, float b); 7 | 8 | float fadd(float a, float b) 9 | { 10 | return a + b; 11 | } 12 | 13 | float fmul(float a, float b) 14 | { 15 | return a * b; 16 | } 17 | 18 | 19 | struct FNode 20 | { 21 | FNode * left, * right; 22 | float value; 23 | fop call; 24 | }; 25 | 26 | FNode * root; 27 | 28 | float fevalB(FNode * f) 29 | { 30 | if (f->call) 31 | return f->call(fevalB(f->left), fevalB(f->right)); 32 | else 33 | return f->value; 34 | } 35 | 36 | float fevalN(FNode * f) 37 | { 38 | if (f->call) 39 | return f->call(fevalN(f->left), fevalN(f->right)); 40 | else 41 | return f->value; 42 | } 43 | 44 | #pragma native(fevalN) 45 | 46 | FNode * bop(fop call, FNode * left, FNode * right) 47 | { 48 | FNode * f = (FNode *)malloc(sizeof(FNode)); 49 | f->call = call; 50 | f->left = left; 51 | f->right = right; 52 | return f; 53 | } 54 | 55 | FNode * bc(float value) 56 | { 57 | FNode * f = (FNode *)malloc(sizeof(FNode)); 58 | f->value = value; 59 | return f; 60 | } 61 | 62 | int main(void) 63 | { 64 | FNode * tree = bop(fadd, bop(fmul, bc(3), bc(5)), bc(6)); 65 | 66 | printf("Eval %f, %d\n", fevalB(tree), fevalN(tree)); 67 | 68 | assert(fevalB(tree) == 3 * 5 + 6); 69 | assert(fevalN(tree) == 3 * 5 + 6); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /autotest/qsorttest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Node 6 | { 7 | int a; 8 | char s[10]; 9 | }; 10 | 11 | void qsort(Node * n, int s) 12 | { 13 | if (s > 1) 14 | { 15 | Node pn = n[0]; 16 | int pi = 0; 17 | for(int i=1; i 2 | 3 | struct Node 4 | { 5 | virtual float eval(void) 6 | { 7 | return 1.0e6; 8 | } 9 | }; 10 | 11 | struct ConstNode : Node 12 | { 13 | float c; 14 | 15 | ConstNode(float c_) 16 | : c(c_) {} 17 | 18 | virtual float eval(void) 19 | { 20 | return c; 21 | } 22 | }; 23 | 24 | struct BinopNode : Node 25 | { 26 | Node * left, * right; 27 | 28 | BinopNode(Node * left_, Node * right_) 29 | : left(left_), right(right_) 30 | {} 31 | }; 32 | 33 | struct AddNode : BinopNode 34 | { 35 | AddNode(Node * left_, Node * right_) 36 | : BinopNode(left_, right_) 37 | {} 38 | 39 | virtual float eval(void) 40 | { 41 | return left->eval() + right->eval(); 42 | } 43 | }; 44 | 45 | struct SubNode : BinopNode 46 | { 47 | SubNode(Node * left_, Node * right_) 48 | : BinopNode(left_, right_) 49 | {} 50 | 51 | virtual float eval(void) 52 | { 53 | return left->eval() - right->eval(); 54 | } 55 | }; 56 | 57 | struct MulNode : BinopNode 58 | { 59 | MulNode(Node * left_, Node * right_) 60 | : BinopNode(left_, right_) 61 | {} 62 | 63 | virtual float eval(void) 64 | { 65 | return left->eval() * right->eval(); 66 | } 67 | }; 68 | 69 | int main(void) 70 | { 71 | Node * n = 72 | new SubNode( 73 | new MulNode(new ConstNode(4), new ConstNode(5)), 74 | new AddNode(new ConstNode(12), new ConstNode(7))); 75 | 76 | assert(n->eval() == 1.0); 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /samples/hires/lines.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | #define Color ((char *)0xd000) 9 | #define Hires ((char *)0xe000) 10 | 11 | Bitmap Screen; 12 | 13 | void init(void) 14 | { 15 | mmap_trampoline(); 16 | mmap_set(MMAP_RAM); 17 | 18 | memset(Color, 0x01, 1000); 19 | memset(Hires, 0x00, 8000); 20 | 21 | mmap_set(MMAP_NO_ROM); 22 | 23 | vic_setmode(VICM_HIRES, Color, Hires); 24 | 25 | vic.color_border = VCOL_WHITE; 26 | 27 | bm_init(&Screen, Hires, 40, 25); 28 | } 29 | 30 | void done(void) 31 | { 32 | mmap_set(MMAP_ROM); 33 | 34 | getch(); 35 | 36 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 37 | } 38 | 39 | void draw(ClipRect * cr, byte pattern) 40 | { 41 | for(int i=0; i<40; i ++) 42 | { 43 | bm_line(&Screen, cr, 8 * i, 0, 319, 5 * i, pattern, LINOP_SET); 44 | bm_line(&Screen, cr, 319, 5 * i, 319 - 8 * i, 199, pattern, LINOP_SET); 45 | bm_line(&Screen, cr, 319 - 8 * i, 199, 0, 199 - 5 * i, pattern, LINOP_SET); 46 | bm_line(&Screen, cr, 0, 199 - 5 * i, 8 * i, 0, pattern, LINOP_SET); 47 | } 48 | } 49 | 50 | int main(void) 51 | { 52 | init(); 53 | 54 | ClipRect cr = {0, 0, 320, 200}; 55 | 56 | draw(&cr, 0xff); 57 | draw(&cr, 0x00); 58 | 59 | draw(&cr, 0xff); 60 | draw(&cr, 0xaa); 61 | draw(&cr, 0x88); 62 | draw(&cr, 0x80); 63 | draw(&cr, 0x00); 64 | 65 | done(); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /include/opp/slab.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_SLAB_H 2 | #define OPP_SLAB_H 3 | 4 | template 5 | class slabptr 6 | { 7 | public: 8 | char index; 9 | 10 | slabptr(void) 11 | : index(N) 12 | {} 13 | 14 | slabptr(char i) 15 | : index(i) 16 | {} 17 | 18 | slabptr(const slabptr & i) 19 | : index(i.index) 20 | {} 21 | 22 | auto operator-> (); 23 | auto & operator* (); 24 | }; 25 | 26 | template 27 | class slab 28 | { 29 | protected: 30 | static __striped T buffer[N]; 31 | static char head; 32 | static char next[N]; 33 | 34 | public: 35 | typedef slabptr ptr; 36 | 37 | static void init(void); 38 | static auto alloc(void); 39 | static void free(ptr p); 40 | }; 41 | 42 | 43 | template 44 | inline auto slabptr::operator-> () 45 | { 46 | return slab::buffer + index; 47 | } 48 | 49 | template 50 | inline auto & slabptr::operator* () 51 | { 52 | return slab::buffer[index]; 53 | } 54 | 55 | 56 | template 57 | void slab::init(void) 58 | { 59 | head = 0; 60 | for(char i=0; i 65 | auto slab::alloc(void) 66 | { 67 | char i = head; 68 | head = next[head]; 69 | return slabptr(i); 70 | } 71 | 72 | template 73 | void slab::free(slabptr p) 74 | { 75 | next[p.index] = head; 76 | head = p.index; 77 | } 78 | 79 | #endif 80 | 81 | -------------------------------------------------------------------------------- /include/nes/mmc1.c: -------------------------------------------------------------------------------- 1 | #include "mmc1.h" 2 | 3 | 4 | void mmc1_reset(void) 5 | { 6 | *(volatile char *)0x8000 = 0x80; 7 | } 8 | 9 | void mmc1_config(MMC1Mirror mirror, MMC1MPrgMode pmode, MMC1MChrMode cmode) 10 | { 11 | char reg = mirror | (pmode << 2) | (cmode << 4); 12 | *(volatile char *)0x8000 = reg; 13 | reg >>= 1; 14 | *(volatile char *)0x8000 = reg; 15 | reg >>= 1; 16 | *(volatile char *)0x8000 = reg; 17 | reg >>= 1; 18 | *(volatile char *)0x8000 = reg; 19 | reg >>= 1; 20 | *(volatile char *)0x8000 = reg; 21 | } 22 | 23 | void mmc1_bank_prg(char bank) 24 | { 25 | *(volatile char *)0xe000 = bank; 26 | bank >>= 1; 27 | *(volatile char *)0xe000 = bank; 28 | bank >>= 1; 29 | *(volatile char *)0xe000 = bank; 30 | bank >>= 1; 31 | *(volatile char *)0xe000 = bank; 32 | bank >>= 1; 33 | *(volatile char *)0xe000 = bank; 34 | } 35 | 36 | void mmc1_bank_chr0(char bank) 37 | { 38 | *(volatile char *)0xa000 = bank; 39 | bank >>= 1; 40 | *(volatile char *)0xa000 = bank; 41 | bank >>= 1; 42 | *(volatile char *)0xa000 = bank; 43 | bank >>= 1; 44 | *(volatile char *)0xa000 = bank; 45 | bank >>= 1; 46 | *(volatile char *)0xa000 = bank; 47 | } 48 | 49 | void mmc1_bank_chr1(char bank) 50 | { 51 | *(volatile char *)0xc000 = bank; 52 | bank >>= 1; 53 | *(volatile char *)0xc000 = bank; 54 | bank >>= 1; 55 | *(volatile char *)0xc000 = bank; 56 | bank >>= 1; 57 | *(volatile char *)0xc000 = bank; 58 | bank >>= 1; 59 | *(volatile char *)0xc000 = bank; 60 | } 61 | -------------------------------------------------------------------------------- /include/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef STDIO_H 2 | #define STDIO_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | void putchar(char c); 9 | 10 | char getchar(void); 11 | 12 | void puts(const char * str); 13 | 14 | char * gets(char * str); 15 | 16 | char * gets_s(char * str, size_t n); 17 | 18 | void printf(const char * fmt, ...); 19 | 20 | int sprintf(char * str, const char * fmt, ...); 21 | 22 | void vprintf(const char * fmt, va_list vlist); 23 | 24 | int vsprintf(char * str, const char * fmt, va_list vlist); 25 | 26 | int scanf(const char * fmt, ...); 27 | 28 | int sscanf(const char * str, const char * fmt, ...); 29 | 30 | 31 | #define FOPEN_MAX 8 32 | #define FILENAME_MAX 16 33 | #define EOF -1 34 | 35 | struct FILE; 36 | 37 | extern FILE * stdin; 38 | extern FILE * stdout; 39 | 40 | FILE * fopen(const char * fname, const char * mode); 41 | 42 | int fclose(FILE * fp); 43 | 44 | int fgetc(FILE* stream); 45 | 46 | char* fgets(char* s, int n, FILE* stream); 47 | 48 | int fputc(int c, FILE* stream); 49 | 50 | int fputs(const char* s, FILE* stream); 51 | 52 | int feof(FILE * stream); 53 | 54 | size_t fread( void * buffer, size_t size, size_t count, FILE * stream ); 55 | 56 | size_t fwrite( const void* buffer, size_t size, size_t count, FILE* stream ); 57 | 58 | int fprintf( FILE * stream, const char* format, ... ); 59 | 60 | int fscanf( FILE *stream, const char *format, ... ); 61 | 62 | #pragma compile("stdio.c") 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /autotest/opp_streamtest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using opp::ostringstream; 8 | using opp::istringstream; 9 | using opp::endl; 10 | 11 | float fdist(float a, float b) 12 | { 13 | float d = fabs(a - b); 14 | a = fabs(a); 15 | b = fabs(b); 16 | return d / (a > b ? a : b); 17 | } 18 | 19 | int main(void) 20 | { 21 | ostringstream os; 22 | 23 | for(int i=0; i<40; i++) 24 | { 25 | os << i << endl; 26 | } 27 | 28 | istringstream is(os.str()); 29 | 30 | int j = 0, k = 47; 31 | #if 1 32 | 33 | while (is >> k) 34 | { 35 | assert(k == j++); 36 | } 37 | 38 | assert(j == 40); 39 | #endif 40 | os.str(opp::string()); 41 | 42 | #if 0 43 | cout << "[" << os.str() << "]" << endl; 44 | os << "HELLO"; 45 | cout << "[" << os.str() << "]" << endl; 46 | #endif 47 | #if 1 48 | 49 | float f = 1.0, g = 1.0; 50 | 51 | for(int i=0; i<10; i++) 52 | { 53 | os << f << " " << g << endl; 54 | // cout << os.str(); 55 | 56 | f *= 5.1; 57 | g *= 0.12; 58 | } 59 | 60 | 61 | is.str(os.str()); 62 | 63 | f = 1.0, g = 1.0; 64 | 65 | float fr, gr; 66 | 67 | j = 0; 68 | while (is >> fr >> gr) 69 | { 70 | // cout << f << " " << fr << ", " << g << " " << gr << ", " << fdist(fr, f) << endl; 71 | 72 | assert(fdist(fr, f) < 1.0e-5); 73 | assert(fdist(gr, g) < 1.0e-5); 74 | 75 | f *= 5.1; 76 | g *= 0.12; 77 | j++; 78 | } 79 | 80 | assert(j == 10); 81 | #endif 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /include/opp/functional.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_FUNCTIONAL_H 2 | #define OPP_FUNCTIONAL_H 3 | 4 | namespace opp 5 | { 6 | template 7 | class function; 8 | 9 | template 10 | class function 11 | { 12 | private: 13 | struct callif 14 | { 15 | virtual R call(P...) = 0; 16 | virtual ~callif() {} 17 | virtual callif * clone(void) const = 0; 18 | }; 19 | 20 | template 21 | struct callable : callif 22 | { 23 | CA ca; 24 | 25 | callable(CA ca_) : ca(ca_) {} 26 | 27 | R call(P... p) {return ca(p...);} 28 | 29 | callif * clone(void) const 30 | { 31 | return new callable(ca); 32 | } 33 | }; 34 | 35 | callif * c; 36 | public: 37 | template 38 | function(F f) 39 | { 40 | c = new callable(f); 41 | } 42 | 43 | function(const function & f) 44 | { 45 | c = f.c->clone(); 46 | } 47 | 48 | function(function && f) 49 | { 50 | c = f.c; 51 | f.c = nullptr; 52 | } 53 | 54 | function(void) 55 | { 56 | c = nullptr; 57 | } 58 | 59 | function & operator=(const function & f) 60 | { 61 | if (c != f.c) 62 | { 63 | delete c; 64 | c = f.c; 65 | } 66 | return *this; 67 | } 68 | 69 | function & operator=(function && f) 70 | { 71 | if (c != f.c) 72 | { 73 | c = f.c; 74 | f.c = nullptr; 75 | } 76 | return *this; 77 | } 78 | 79 | ~function(void) 80 | { 81 | delete c; 82 | } 83 | 84 | R operator()(P ... p) const 85 | { 86 | return c->call(p...); 87 | } 88 | }; 89 | 90 | 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /autotest/loopboundtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct S 4 | { 5 | int a[100]; 6 | }; 7 | 8 | int lts(S * s) 9 | { 10 | int x = 0; 11 | for(int i=0; i<100; i++) 12 | x += s->a[i]; 13 | return x; 14 | } 15 | 16 | int les(S * s) 17 | { 18 | int x = 0; 19 | for(int i=0; i<=99; i++) 20 | x += s->a[i]; 21 | return x; 22 | } 23 | 24 | int gts(S * s) 25 | { 26 | int x = 0; 27 | for(int i=100; i>0; i--) 28 | x += s->a[i-1]; 29 | return x; 30 | } 31 | 32 | int ges(S * s) 33 | { 34 | int x = 0; 35 | for(int i=99; i>=0; i--) 36 | x += s->a[i]; 37 | return x; 38 | } 39 | 40 | int ltu(S * s) 41 | { 42 | unsigned x = 0; 43 | for(int i=0; i<100; i++) 44 | x += s->a[i]; 45 | return x; 46 | } 47 | 48 | int leu(S * s) 49 | { 50 | unsigned x = 0; 51 | for(int i=0; i<=99; i++) 52 | x += s->a[i]; 53 | return x; 54 | } 55 | 56 | int gtu(S * s) 57 | { 58 | unsigned x = 0; 59 | for(int i=100; i>0; i--) 60 | x += s->a[i-1]; 61 | return x; 62 | } 63 | 64 | int geu(S * s) 65 | { 66 | unsigned x = 0; 67 | for(int i=100; i>=1; i--) 68 | x += s->a[i-1]; 69 | return x; 70 | } 71 | 72 | int main(void) 73 | { 74 | S s; 75 | 76 | int k = 0; 77 | for(int i=0; i<100; i++) 78 | { 79 | int t = (i & 15) + 3; 80 | s.a[i] = t; 81 | k += t; 82 | } 83 | 84 | assert(lts(&s) == k); 85 | assert(les(&s) == k); 86 | assert(gts(&s) == k); 87 | assert(ges(&s) == k); 88 | assert(ltu(&s) == k); 89 | assert(leu(&s) == k); 90 | assert(gtu(&s) == k); 91 | assert(geu(&s) == k); 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /autotest/recursiontest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int fib(int a) 7 | { 8 | if (a < 2) 9 | return a; 10 | else 11 | return fib(a - 1) + fib(a - 2); 12 | } 13 | 14 | struct Node 15 | { 16 | char value; 17 | Node * left, * right; 18 | }; 19 | 20 | typedef Node * NodePtr; 21 | 22 | 23 | NodePtr newnode(void) 24 | { 25 | return (NodePtr)malloc(sizeof(Node)); 26 | } 27 | 28 | Node * insert(Node * tree, char v) 29 | { 30 | if (tree) 31 | { 32 | if (v < tree->value) 33 | { 34 | tree->left = insert(tree->left, v); 35 | } 36 | else 37 | { 38 | tree->right = insert(tree->right, v); 39 | } 40 | } 41 | else 42 | { 43 | tree = newnode(); 44 | tree->value = v; 45 | tree->left = nullptr; 46 | tree->right = nullptr; 47 | } 48 | 49 | return tree; 50 | } 51 | 52 | char * collect(Node * tree, char * p) 53 | { 54 | if (tree) 55 | { 56 | p = collect(tree->left, p); 57 | *p++= tree->value; 58 | p = collect(tree->right, p); 59 | } 60 | 61 | return p; 62 | } 63 | 64 | void btest(void) 65 | { 66 | const char * str = "HELLO WORLD"; 67 | char buff[20]; 68 | 69 | int i = 0; 70 | Node * tree = nullptr; 71 | 72 | while (str[i]) 73 | { 74 | tree = insert(tree, str[i]); 75 | i++; 76 | } 77 | 78 | collect(tree, buff)[0] = 0; 79 | 80 | assert(strcmp(buff, " DEHLLLOORW") == 0); 81 | } 82 | 83 | int main(void) 84 | { 85 | assert(fib(23) == 28657); 86 | 87 | btest(); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /autotest/opp_span.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(void) 11 | { 12 | static const int test[] = {7, 6, 5, 4, 3, 2, 1}; 13 | 14 | opp::span st(test); 15 | opp::span sd(test, 7); 16 | 17 | auto st1 = st.subspan<1>(); 18 | auto sd1 = sd.subspan<1>(); 19 | 20 | auto st2 = st.subspan(2); 21 | auto sd2 = sd.subspan(2); 22 | 23 | auto st3 = st.subspan<1, 4>(); 24 | auto sd3 = sd.subspan<1, 4>(); 25 | 26 | auto st4 = st.subspan(2, 5); 27 | auto sd4 = sd.subspan(2, 5); 28 | 29 | auto st5 = st.last(5); 30 | auto sd5 = sd.last(5); 31 | 32 | assert(opp::accumulate(st.begin(), st.end(), 0) == 28); 33 | assert(opp::accumulate(sd.begin(), sd.end(), 0) == 28); 34 | 35 | assert(opp::accumulate(st1.begin(), st1.end(), 0) == 21); 36 | assert(opp::accumulate(sd1.begin(), sd1.end(), 0) == 21); 37 | 38 | assert(opp::accumulate(st2.begin(), st2.end(), 0) == 15); 39 | assert(opp::accumulate(sd2.begin(), sd2.end(), 0) == 15); 40 | 41 | assert(opp::accumulate(st3.begin(), st3.end(), 0) == 18); 42 | assert(opp::accumulate(sd3.begin(), sd3.end(), 0) == 18); 43 | 44 | assert(opp::accumulate(st4.begin(), st4.end(), 0) == 15); 45 | assert(opp::accumulate(sd4.begin(), sd4.end(), 0) == 15); 46 | 47 | assert(opp::accumulate(st5.begin(), st5.end(), 0) == 15); 48 | assert(opp::accumulate(sd5.begin(), sd5.end(), 0) == 15); 49 | } -------------------------------------------------------------------------------- /samples/fractals/mbhires.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // Address of hires buffer and color buffer 7 | #define Screen ((char *)0xe000) 8 | #define Color ((char *)0xc800) 9 | 10 | int main(void) 11 | { 12 | // Install the IRQ trampoline 13 | mmap_trampoline(); 14 | 15 | // Turn of the kernal ROM 16 | mmap_set(MMAP_NO_ROM); 17 | 18 | // Switch VIC into hires mode 19 | vic_setmode(VICM_HIRES, Color, Screen); 20 | 21 | // Clear the screen 22 | memset(Screen, 0, 8000); 23 | memset(Color, 0x10, 1000); 24 | 25 | // Loop over all pixels 26 | int py, px; 27 | 28 | for(py=0; py<200; py++) 29 | { 30 | for(px=0; px<320; px++) 31 | { 32 | // Value in the complex plane 33 | 34 | float xz = (float)px * (3.5 / 320.0)- 2.5; 35 | float yz = (float)py * (2.0 / 200.0) - 1.0; 36 | 37 | // Iterate up to 32 times 38 | float x = 0.0, y = 0.0; 39 | int i; 40 | for(i=0; i<32; i++) 41 | { 42 | if (x * x + y * y > 4.0) break; 43 | 44 | float xt = x * x - y * y + xz; 45 | y = 2 * x * y + yz; 46 | x = xt; 47 | } 48 | 49 | // Set a pixel if exceeds bound in less than 32 iterations 50 | if (i < 32) 51 | Screen[320 * (py >> 3) + (py & 7) + (px & ~7)] |= 0x80 >> (px & 7); 52 | } 53 | } 54 | 55 | // Re-enable the kernal 56 | mmap_set(MMAP_NO_BASIC); 57 | 58 | // Wait for key press 59 | getch(); 60 | 61 | // Restore VIC state 62 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /autotest/opp_vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | opp::vector a; 9 | 10 | for(int i=0; i<10; i++) 11 | a.push_back(i); 12 | 13 | int s = 0; 14 | for(int i=0; i v; 29 | 30 | for(int i=0; i<10; i++) 31 | v.push_back(i); 32 | 33 | assert(v.size() == 10); 34 | v.insert(0, 20); 35 | assert(v.size() == 11); 36 | v.insert(6, 21); 37 | assert(v.size() == 12); 38 | v.insert(12, 22); 39 | 40 | int * fi = opp::find(v.begin(), v.end(), 21); 41 | 42 | fi = v.insert(fi, 30); 43 | fi = v.insert(fi, 31); 44 | fi = v.insert(fi, 32); 45 | 46 | assert(v.size() == 16); 47 | assert(v[0] == 20); 48 | assert(v[15] == 22); 49 | assert(v[8] == 32); 50 | 51 | fi = opp::find(v.begin(), v.end(), 32); 52 | 53 | for(int i=0; i<30; i++) 54 | { 55 | fi = v.insert(fi, i + 40); 56 | } 57 | 58 | assert(v.size() == 46); 59 | assert(v[28] == 60); 60 | 61 | v.erase(10, 10); 62 | 63 | for(int i : v) 64 | opp::cout << i << ", "; 65 | opp::cout << "\n"; 66 | 67 | assert(v.size() == 36); 68 | assert(v[18] == 60); 69 | 70 | v.assign(42, 11); 71 | 72 | assert(v.size() == 42); 73 | assert(v[0] == 11); 74 | assert(v[15] == 11); 75 | assert(v[41] == 11); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /samples/memmap/tsr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Invoke resident section with "SYS 49152" from basic 6 | 7 | // not much space, so we go with a smaller stack size 8 | 9 | #pragma stacksize(256) 10 | 11 | // shrink size of startup section 12 | 13 | #pragma section(startup, 0); 14 | #pragma region(startup, 0x0801, 0x0870, , , { startup } ) 15 | 16 | // section for code copy 17 | 18 | #pragma section(rcode, 0) 19 | #pragma region(rcode, 0x0870, 0x0900, , , { rcode } ) 20 | 21 | // main section to stay resident, save three bytes at the 22 | // beginning to have space for an entry jump 23 | 24 | #pragma region(main, 0x0903, 0x1900, , , {code, data, bss, heap, stack}, 0xc003 ) 25 | 26 | // resident entry routine 27 | 28 | void tsr(void) 29 | { 30 | // Initialize stack pointer 31 | 32 | __asm { 33 | lda #$ff 34 | sta __sp 35 | lda #$cf 36 | sta __sp +1 37 | } 38 | 39 | // do something useless 40 | 41 | printf(p"Hello World\n"); 42 | 43 | // and done 44 | } 45 | 46 | // Now the copy code section 47 | 48 | #pragma code(rcode) 49 | 50 | int main(void) 51 | { 52 | // source and target address to copy, no memcpy as it is itself 53 | // not yet copied 54 | 55 | char * dp = (char *)0xc000; 56 | char * sp = (char *)0x0903; 57 | 58 | // A jmp to the code at the absolute address 0xc000 / 49152 59 | 60 | dp += asm_ab(dp, ASM_JMP, (unsigned)tsr); 61 | 62 | // then the code 63 | 64 | for(unsigned i=0; i<0xffd; i++) 65 | *dp++ = *sp++; 66 | 67 | // now we are done 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /include/c128/bank1.c: -------------------------------------------------------------------------------- 1 | #include "bank1.h" 2 | #include "mmu.h" 3 | #include 4 | 5 | void bnk1_init(void) 6 | { 7 | mmu.cr = 0x3e; 8 | memcpy((char *)0xfc00, (char *)0xf000, 0x0300); 9 | xmmu.rcr |= 0x0c; 10 | mmu.cr = 0x3f; 11 | } 12 | 13 | #pragma code(bnk1code) 14 | 15 | char bnk1_readb(volatile char * p) 16 | { 17 | mmu.bank1 = 0; 18 | char c = *p; 19 | mmu.bank0 = 0; 20 | return c; 21 | } 22 | 23 | unsigned bnk1_readw(volatile unsigned * p) 24 | { 25 | mmu.bank1 = 0; 26 | unsigned w = *p; 27 | mmu.bank0 = 1; 28 | return w; 29 | } 30 | 31 | unsigned long bnk1_readl(volatile unsigned long * p) 32 | { 33 | mmu.bank1 = 0; 34 | unsigned long l = *p; 35 | mmu.bank0 = 3; 36 | return l; 37 | } 38 | 39 | void bnk1_readm(char * dp, volatile char * sp, unsigned size) 40 | { 41 | while (size > 0) 42 | { 43 | mmu.bank1 = 0; 44 | char c = * sp++; 45 | mmu.bank0 = c; 46 | *dp++ = c; 47 | size--; 48 | } 49 | } 50 | 51 | void bnk1_writeb(volatile char * p, char b) 52 | { 53 | mmu.bank1 = b; 54 | *p = b; 55 | mmu.bank0 = b; 56 | } 57 | 58 | void bnk1_writew(volatile unsigned * p, unsigned w) 59 | { 60 | mmu.bank1 = w; 61 | *p = w; 62 | mmu.bank0 = w; 63 | } 64 | 65 | void bnk1_writel(volatile unsigned long * p, unsigned long l) 66 | { 67 | mmu.bank1 = l; 68 | *p = l; 69 | mmu.bank0 = l; 70 | } 71 | 72 | void bnk1_writem(volatile char * dp, const char * sp, unsigned size) 73 | { 74 | while (size > 0) 75 | { 76 | char c = * sp++; 77 | mmu.bank1 = c; 78 | *dp++ = c; 79 | mmu.bank0 = c; 80 | size--; 81 | } 82 | } 83 | 84 | #pragma code(code) 85 | -------------------------------------------------------------------------------- /autotest/opp_static_vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | opp::static_vector a; 9 | 10 | for(int i=0; i<10; i++) 11 | a.push_back(i); 12 | 13 | int s = 0; 14 | for(int i=0; i v; 29 | 30 | for(int i=0; i<10; i++) 31 | v.push_back(i); 32 | 33 | assert(v.size() == 10); 34 | v.insert(0, 20); 35 | assert(v.size() == 11); 36 | v.insert(6, 21); 37 | assert(v.size() == 12); 38 | v.insert(12, 22); 39 | 40 | int * fi = opp::find(v.begin(), v.end(), 21); 41 | 42 | fi = v.insert(fi, 30); 43 | fi = v.insert(fi, 31); 44 | fi = v.insert(fi, 32); 45 | 46 | assert(v.size() == 16); 47 | assert(v[0] == 20); 48 | assert(v[15] == 22); 49 | assert(v[8] == 32); 50 | 51 | fi = opp::find(v.begin(), v.end(), 32); 52 | 53 | for(int i=0; i<30; i++) 54 | { 55 | fi = v.insert(fi, i + 40); 56 | } 57 | 58 | assert(v.size() == 46); 59 | assert(v[28] == 60); 60 | 61 | v.erase(10, 10); 62 | 63 | for(int i : v) 64 | opp::cout << i << ", "; 65 | opp::cout << "\n"; 66 | 67 | assert(v.size() == 36); 68 | assert(v[18] == 60); 69 | 70 | v.assign(42, 11); 71 | 72 | assert(v.size() == 42); 73 | assert(v[0] == 11); 74 | assert(v[15] == 11); 75 | assert(v[41] == 11); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /samples/memmap/charsetcopy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // make space until 0xcc00 by extending the default region 8 | 9 | #pragma region( main, 0x0a00, 0xcc00, , , {code, data, bss, heap, stack} ) 10 | 11 | // space for our custom charset from c000 to c800, will be copied to 12 | // 0xd000 during startup to free space for stack and heap 13 | 14 | #pragma section( charset, 0) 15 | 16 | #pragma region( charset, 0xc000, 0xc800, , , {charset} ) 17 | 18 | // set initialized data segment to charset section 19 | 20 | #pragma data(charset) 21 | 22 | char charset[2048] = { 23 | #embed "../resources/charset.bin" 24 | }; 25 | 26 | // back to normal 27 | 28 | #pragma data(data) 29 | 30 | // pointers to charset and screen in memory 31 | 32 | #define Screen ((char *)0xcc00) 33 | #define Charset ((char *)0xd000) 34 | 35 | int main(void) 36 | { 37 | // Install the trampoline 38 | mmap_trampoline(); 39 | 40 | // make all of RAM visible to the CPU 41 | mmap_set(MMAP_RAM); 42 | 43 | // copy the font 44 | memcpy(Charset, charset, 2048); 45 | 46 | // make lower part of RAM visible to CPU 47 | mmap_set(MMAP_NO_BASIC); 48 | 49 | // map the vic to the new charset 50 | 51 | vic_setmode(VICM_TEXT, Screen, Charset); 52 | 53 | for(int i=0; i<1000; i++) 54 | Screen[i] = (char)i; 55 | 56 | // wait for keypress 57 | 58 | getchar(); 59 | 60 | // restore VIC 61 | 62 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 63 | 64 | // restore basic ROM 65 | mmap_set(MMAP_ROM); 66 | 67 | return 0; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /include/c128/vdc.c: -------------------------------------------------------------------------------- 1 | #include "vdc.h" 2 | 3 | 4 | inline void vdc_reg(VDCRegister reg) 5 | { 6 | vdc.addr = reg; 7 | } 8 | 9 | inline void vdc_write(byte data) 10 | { 11 | do {} while (vdc.addr < 128); 12 | vdc.data = data; 13 | } 14 | 15 | inline byte vdc_read(void) 16 | { 17 | do {} while (vdc.addr < 128); 18 | return vdc.data; 19 | } 20 | 21 | 22 | void vdc_reg_write(VDCRegister reg, byte data) 23 | { 24 | vdc_reg(reg); 25 | vdc_write(data); 26 | } 27 | 28 | byte vdc_reg_read(VDCRegister reg) 29 | { 30 | vdc_reg(reg); 31 | return vdc_read(); 32 | } 33 | 34 | 35 | void vdc_mem_addr(unsigned addr) 36 | { 37 | #pragma callinline() 38 | vdc_reg_write(VDCR_ADDRH, addr >> 8); 39 | #pragma callinline() 40 | vdc_reg_write(VDCR_ADDRL, addr); 41 | #pragma callinline() 42 | vdc_reg(VDCR_DATA); 43 | } 44 | 45 | inline void vdc_mem_write(char data) 46 | { 47 | vdc_write(data); 48 | } 49 | 50 | inline char vdc_mem_read(void) 51 | { 52 | return vdc_read(); 53 | } 54 | 55 | 56 | void vdc_mem_write_at(unsigned addr, char data) 57 | { 58 | #pragma callinline() 59 | vdc_mem_addr(addr); 60 | vdc_write(data); 61 | } 62 | 63 | char vdc_mem_read_at(unsigned addr) 64 | { 65 | #pragma callinline() 66 | vdc_mem_addr(addr); 67 | return vdc_read(); 68 | } 69 | 70 | 71 | void vdc_mem_write_buffer(unsigned addr, const char * data, char size) 72 | { 73 | vdc_mem_addr(addr); 74 | for(char i=0; i mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions, mTopoFunctions; 32 | GrowingArray mGlobalVariables; 33 | 34 | void AnalyzeInit(Declaration* mdec); 35 | int CallerInvokes(Declaration* called); 36 | int CallerInvokes(Declaration* caller, Declaration* called); 37 | 38 | Declaration* Analyze(Expression* exp, Declaration* procDec, uint32 flags); 39 | 40 | bool IsStackParam(const Declaration* pdec) const; 41 | bool MarkCycle(Declaration* rootDec, Declaration* procDec); 42 | 43 | uint64 GetProcFlags(Declaration* to) const; 44 | void RegisterCall(Declaration* from, Declaration* to); 45 | void RegisterProc(Declaration* to); 46 | void UndoParamReference(Expression* ex, Declaration* param); 47 | }; 48 | 49 | -------------------------------------------------------------------------------- /include/opp/sstream.cpp: -------------------------------------------------------------------------------- 1 | #include "sstream.h" 2 | #include 3 | 4 | namespace opp { 5 | 6 | ostringstream::ostringstream(void) 7 | { 8 | mBuffer = nullptr; 9 | mBFill = mBSize = 0; 10 | } 11 | 12 | ostringstream::~ostringstream(void) 13 | { 14 | free(mBuffer); 15 | } 16 | 17 | void ostringstream::bput(char ch) 18 | { 19 | if (!mBuffer) 20 | { 21 | mBSize = 15; 22 | mBFill = 0; 23 | mBuffer = (char *)malloc(15); 24 | } 25 | else if (mBFill == mBSize) 26 | { 27 | mBSize *= 2; 28 | char * b = (char *)malloc(mBSize); 29 | for(char i=0; i mBSize) 46 | { 47 | free(mBuffer); 48 | mBSize = mBFill; 49 | mBuffer = (char *)malloc(mBSize); 50 | } 51 | str.copyseg(mBuffer, 0, mBFill); 52 | } 53 | 54 | istringstream::istringstream(const string & str) 55 | : mString(str), mSPos(0) 56 | {} 57 | 58 | istringstream::~istringstream(void) 59 | {} 60 | 61 | string istringstream::str(void) const 62 | { 63 | return mString; 64 | } 65 | 66 | void istringstream::str(const string & str) 67 | { 68 | mState = goodbit; 69 | mString = str; 70 | mSPos = 0; 71 | } 72 | 73 | 74 | void istringstream::refill(void) 75 | { 76 | mBufferFill = 0; 77 | mBufferPos = 0; 78 | 79 | char ch; 80 | while (mSPos < mString.size() && mBufferFill < 32) 81 | { 82 | mBuffer[mBufferFill++] = mString[mSPos++]; 83 | } 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /samples/memmap/charsetexpand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // make space until 0xcc00 by extending the default region 9 | 10 | #pragma region( main, 0x0a00, 0xcc00, , , {code, data, bss, heap, stack} ) 11 | 12 | // space for our custom charset from c000 to c800, will be copied to 13 | // 0xd000 during startup to free space for stack and heap 14 | 15 | #pragma section( charset, 0) 16 | 17 | #pragma region( charset, 0xc000, 0xc800, , , {charset} ) 18 | 19 | // set initialized data segment to charset section 20 | 21 | #pragma data(charset) 22 | 23 | // lz compressed data 24 | char charset[] = { 25 | #embed 2048 0 lzo "../resources/charset.bin" 26 | }; 27 | 28 | // back to normal 29 | 30 | #pragma data(data) 31 | 32 | // pointers to charset and screen in memory 33 | 34 | #define Screen ((char *)0xcc00) 35 | #define Charset ((char *)0xd000) 36 | 37 | int main(void) 38 | { 39 | // Install the trampoline 40 | mmap_trampoline(); 41 | 42 | // make all of RAM visible to the CPU 43 | mmap_set(MMAP_RAM); 44 | 45 | // expand the font 46 | oscar_expand_lzo(Charset, charset); 47 | 48 | // make lower part of RAM visible to CPU 49 | mmap_set(MMAP_NO_BASIC); 50 | 51 | // map the vic to the new charset 52 | 53 | vic_setmode(VICM_TEXT, Screen, Charset); 54 | 55 | for(int i=0; i<1000; i++) 56 | Screen[i] = (char)i; 57 | 58 | // wait for keypress 59 | 60 | getchar(); 61 | 62 | // restore VIC 63 | 64 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 65 | 66 | // restore basic ROM 67 | mmap_set(MMAP_ROM); 68 | 69 | return 0; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /.github/workflows/check.yaml: -------------------------------------------------------------------------------- 1 | name: Run checks 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | check: 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | os: 17 | - macos-latest 18 | - ubuntu-24.04-arm 19 | - ubuntu-latest 20 | - windows-latest 21 | 22 | runs-on: "${{ matrix.os }}" 23 | 24 | defaults: 25 | run: 26 | shell: bash 27 | 28 | env: 29 | SCCACHE_GHA_ENABLED: "true" 30 | 31 | steps: 32 | - uses: actions/checkout@v5 33 | 34 | - name: Start sccache 35 | uses: mozilla-actions/sccache-action@v0.0.9 36 | 37 | - name: Set CXX var 38 | run: | 39 | case "$RUNNER_OS" in 40 | "Linux") echo "CXX=g++" >> "$GITHUB_ENV" ;; 41 | "macOS") echo "CXX=clang++" >> "$GITHUB_ENV" ;; 42 | "Windows") echo "CXX=g++" >> "$GITHUB_ENV" ;; 43 | esac 44 | 45 | - name: Determine number of cores 46 | run: | 47 | CORES=2 48 | case "$RUNNER_OS" in 49 | "Linux") CORES="$(nproc)" ;; 50 | "macOS") CORES="$(sysctl -n hw.ncpu)" ;; 51 | "Windows") CORES="$NUMBER_OF_PROCESSORS" ;; 52 | *) echo "Unknown OS, using default." ;; 53 | esac 54 | echo "NUMBER_OF_CORES=$CORES" >> "$GITHUB_ENV" 55 | echo "Using $CORES cores" 56 | 57 | - name: make compiler 58 | run: make -C make -j "$NUMBER_OF_CORES" compiler CXX="sccache ${CXX}" 59 | 60 | - name: make check 61 | run: make -C make -j "$NUMBER_OF_CORES" check 62 | -------------------------------------------------------------------------------- /include/plus4/ted.c: -------------------------------------------------------------------------------- 1 | #include "ted.h" 2 | 3 | void ted_waitBottom(void) 4 | { 5 | while (!(ted.vscan_high & 1)) 6 | ; 7 | } 8 | 9 | void ted_waitTop(void) 10 | { 11 | while (ted.vscan_high & 1) 12 | ; 13 | } 14 | 15 | void ted_waitFrame(void) 16 | { 17 | while (ted.vscan_high & 1) 18 | ; 19 | while (!(ted.vscan_high & 1)) 20 | ; 21 | } 22 | 23 | void ted_waitLine(int line) 24 | { 25 | char upper = (char)(line >> 8) & 1; 26 | char lower = (char)line; 27 | 28 | do 29 | { 30 | while (ted.vscan_low != lower) 31 | ; 32 | } while ((ted.vscan_high & 1) != upper); 33 | } 34 | 35 | void ted_setmode(TedMode mode, char * text, char * font) 36 | { 37 | switch (mode) 38 | { 39 | case TEDM_TEXT: 40 | ted.ctrl1 = TED_CTRL1_DEN | TED_CTRL1_RSEL | 3; 41 | ted.ctrl2 = TED_CTRL2_CSEL; 42 | break; 43 | case TEDM_TEXT_MC: 44 | ted.ctrl1 = TED_CTRL1_DEN | TED_CTRL1_RSEL | 3; 45 | ted.ctrl2 = TED_CTRL2_CSEL | TED_CTRL2_MCM; 46 | break; 47 | case TEDM_TEXT_ECM: 48 | ted.ctrl1 = TED_CTRL1_DEN | TED_CTRL1_ECM | TED_CTRL1_RSEL | 3; 49 | ted.ctrl2 = TED_CTRL2_CSEL; 50 | break; 51 | case TEDM_HIRES: 52 | ted.ctrl1 = TED_CTRL1_BMM | TED_CTRL1_DEN | TED_CTRL1_RSEL | 3; 53 | ted.ctrl2 = TED_CTRL2_CSEL; 54 | break; 55 | case TEDM_HIRES_MC: 56 | ted.ctrl1 = TED_CTRL1_BMM | TED_CTRL1_DEN | TED_CTRL1_RSEL | 3; 57 | ted.ctrl2 = TED_CTRL2_CSEL | TED_CTRL2_MCM; 58 | break; 59 | default: 60 | __assume(false); 61 | } 62 | 63 | ted.vid_ptr = (unsigned)text >> 8; 64 | 65 | if (mode < TEDM_HIRES) 66 | { 67 | ted.char_ptr = (unsigned)font >> 8; 68 | } 69 | else 70 | { 71 | ted.sound1_high = (ted.sound1_high & 0x3) | ((unsigned)font >> 10); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /include/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef STDLIB_H 2 | #define STDLIB_H 3 | 4 | #define RAND_MAX 65535u 5 | 6 | struct div_t 7 | { 8 | int quot; 9 | int rem; 10 | }; 11 | 12 | struct ldiv_t 13 | { 14 | long int quot; 15 | long int rem; 16 | }; 17 | 18 | extern const float tpow10[7]; 19 | 20 | void itoa(int n, char * s, unsigned radix); 21 | 22 | void utoa(unsigned int n, char * s, unsigned radix); 23 | 24 | void ftoa(float f, char * s); 25 | 26 | void ltoa(long n, char * s, unsigned radix); 27 | 28 | void ultoa(unsigned long n, char * s, unsigned radix); 29 | 30 | int atoi(const char * s); 31 | 32 | long atol(const char * s); 33 | 34 | float atof(const char * s); 35 | 36 | float strtof(const char *s, const char **endp); 37 | 38 | int strtoi(const char *s, const char **endp, char base); 39 | 40 | unsigned strtou(const char *s, const char **endp, char base); 41 | 42 | long strtol(const char *s, const char **endp, char base); 43 | 44 | unsigned long strtoul(const char *s, const char **endp, char base); 45 | 46 | int abs(int n); 47 | 48 | long labs(long n); 49 | 50 | div_t div(int numer, int denom); 51 | 52 | ldiv_t ldiv(long int numer, long int denom); 53 | 54 | void exit(int status); 55 | 56 | void abort(void); 57 | 58 | void * malloc(unsigned int size); 59 | 60 | void free(void * ptr); 61 | 62 | void * calloc(int num, int size); 63 | 64 | void * realloc(void * ptr, unsigned size); 65 | 66 | unsigned heapfree(void); 67 | 68 | unsigned int rand(void); 69 | 70 | void srand(unsigned int seed); 71 | 72 | unsigned long lrand(void); 73 | 74 | void lsrand(unsigned long seed); 75 | 76 | #pragma intrinsic(malloc) 77 | 78 | #pragma intrinsic(free) 79 | 80 | #pragma compile("stdlib.c") 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /include/c128/vdc.h: -------------------------------------------------------------------------------- 1 | #ifndef C128_VDC_H 2 | #define C128_VDC_H 3 | 4 | #include 5 | 6 | enum VDCRegister 7 | { 8 | VDCR_HTOTAL, 9 | VDCR_HDISPLAY, 10 | VDCR_HSYNC, 11 | VDCR_SYNCSIZE, 12 | 13 | VDCR_VTOTAL, 14 | VDCR_VADJUST, 15 | VDCR_VDISPLAY, 16 | VDCR_VSYNC, 17 | 18 | VDCR_LACE, 19 | VDCR_CSIZE, 20 | VDCR_CURSOR_START, 21 | VDCR_CURSOR_END, 22 | 23 | VDCR_DISP_ADDRH, 24 | VDCR_DISP_ADDRL, 25 | VDCR_CURSOR_ADDRH, 26 | VDCR_CURSOR_ADDRL, 27 | 28 | VDCR_LPEN_Y, 29 | VDCR_LPEN_X, 30 | VDCR_ADDRH, 31 | VDCR_ADDRL, 32 | 33 | VDCR_ATTR_ADDRH, 34 | VDCR_ATTR_ADDRL, 35 | VDCR_CWIDTH, 36 | VDCR_CHEIGHT, 37 | 38 | VDCR_VSCROLL, 39 | VDCR_HSCROLL, 40 | VDCR_COLOR, 41 | VDCR_ROWINC, 42 | 43 | VDCR_CHAR_ADDRH, 44 | VDCR_UNDERLINE, 45 | VDCR_DSIZE, 46 | VDCR_DATA, 47 | 48 | VDCR_BLOCK_ADDRH, 49 | VDCR_BLOCK_ADDRL, 50 | VDCR_HSTART, 51 | VDCR_HEND, 52 | 53 | VDCR_REFRESH 54 | }; 55 | 56 | struct VDC 57 | { 58 | volatile char addr; 59 | volatile char data; 60 | }; 61 | 62 | #define vdc (*((struct VDC *)0xd600)) 63 | 64 | inline void vdc_reg(VDCRegister reg); 65 | 66 | inline void vdc_write(byte data); 67 | 68 | inline byte vdc_read(void); 69 | 70 | 71 | void vdc_reg_write(VDCRegister reg, byte data); 72 | 73 | byte vdc_reg_read(VDCRegister reg); 74 | 75 | 76 | void vdc_mem_addr(unsigned addr); 77 | 78 | inline void vdc_mem_write(char data); 79 | 80 | inline char vdc_mem_read(void); 81 | 82 | 83 | void vdc_mem_write_at(unsigned addr, char data); 84 | 85 | char vdc_mem_read_at(unsigned addr); 86 | 87 | 88 | void vdc_mem_write_buffer(unsigned addr, const char * data, char size); 89 | 90 | void vdc_mem_read_buffer(unsigned addr, char * data, char size); 91 | 92 | 93 | #pragma compile("vdc.c") 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /autotest/copyassign.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int t, n; 4 | 5 | struct C0 6 | { 7 | int u; 8 | 9 | C0(int a); 10 | ~C0(void); 11 | }; 12 | 13 | C0::C0(int a) : u(a) 14 | { 15 | t += u; 16 | n++; 17 | } 18 | 19 | C0::~C0(void) 20 | { 21 | t -= u; 22 | } 23 | 24 | struct C1 25 | { 26 | int u; 27 | 28 | C1(int a); 29 | ~C1(void); 30 | C1(const C1 & c); 31 | C1 & operator=(const C1 & c); 32 | }; 33 | 34 | C1::C1(int a) : u(a) 35 | { 36 | t += u; 37 | n++; 38 | } 39 | 40 | C1::~C1(void) 41 | { 42 | t -= u; 43 | } 44 | 45 | C1::C1(const C1 & c) : u(c.u) 46 | { 47 | t += u; 48 | n++; 49 | } 50 | 51 | C1 & C1::operator=(const C1 & c) 52 | { 53 | t -= u; 54 | u = c.u; 55 | t += u; 56 | return *this; 57 | } 58 | 59 | void test_assign(void) 60 | { 61 | n = 0; 62 | 63 | { 64 | C1 c(4); 65 | C1 d(5); 66 | c = d; 67 | } 68 | 69 | assert(n == 2 && t == 0); 70 | } 71 | 72 | struct C2 73 | { 74 | C1 a, b; 75 | 76 | C2(int x, int y) : a(x), b(y) 77 | {} 78 | }; 79 | 80 | void test_assign_deflt(void) 81 | { 82 | n = 0; 83 | 84 | { 85 | C2 c(2, 3); 86 | C2 d(5, 10); 87 | c = d; 88 | } 89 | 90 | assert(n == 4 && t == 0); 91 | } 92 | 93 | int k; 94 | 95 | C2 test_ret_v(void) 96 | { 97 | C2 c(5, 10); 98 | return c; 99 | } 100 | 101 | C2 & test_ret_r(C2 & r) 102 | { 103 | return r; 104 | } 105 | 106 | void test_assign_return_value(void) 107 | { 108 | n = 0; 109 | 110 | { 111 | C2 c(2, 3); 112 | c = test_ret_v(); 113 | } 114 | 115 | assert(n == 6 && t == 0); 116 | } 117 | 118 | 119 | int main(void) 120 | { 121 | test_assign(); 122 | test_assign_deflt(); 123 | test_assign_return_value(); 124 | 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /autotest/floatinttest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main(void) 7 | { 8 | float a; 9 | int i; 10 | long li; 11 | unsigned u; 12 | unsigned long lu; 13 | 14 | a = 1.0; 15 | i = 1; 16 | for(int j=0; j<15; j++) 17 | { 18 | assert(i == (int)a); 19 | assert(a == (float)i); 20 | a *= 2.0; 21 | i <<= 1; 22 | } 23 | 24 | a = -1.0; 25 | i = -1; 26 | for(int j=0; j<15; j++) 27 | { 28 | assert(i == (int)a); 29 | assert(a == (float)i); 30 | a *= 2.0; 31 | i <<= 1; 32 | } 33 | 34 | a = 1.0; 35 | i = 1; 36 | for(int j=0; j<15; j++) 37 | { 38 | assert(i == (int)a); 39 | assert(a == (float)i); 40 | a *= 2.0; 41 | a += 1.0; 42 | i <<= 1; 43 | i += 1; 44 | } 45 | 46 | 47 | a = 1.0; 48 | u = 1; 49 | for(int j=0; j<16; j++) 50 | { 51 | assert(u == (unsigned)a); 52 | assert(a == (float)u); 53 | a *= 2.0; 54 | u <<= 1; 55 | } 56 | 57 | a = 1.0; 58 | u = 1; 59 | for(int j=0; j<16; j++) 60 | { 61 | assert(u == (unsigned)a); 62 | assert(a == (float)u); 63 | a *= 2.0; 64 | a += 1; 65 | u <<= 1; 66 | u += 1; 67 | } 68 | 69 | a = 1.0; 70 | li = 1; 71 | for(int j=0; j<31; j++) 72 | { 73 | assert(li == (long)a); 74 | assert(a == (float)li); 75 | a *= 2.0; 76 | li <<= 1; 77 | } 78 | 79 | a = -1.0; 80 | li = -1; 81 | for(int j=0; j<31; j++) 82 | { 83 | assert(li == (long)a); 84 | assert(a == (float)li); 85 | a *= 2.0; 86 | li <<= 1; 87 | } 88 | 89 | a = 1.0; 90 | lu = 1; 91 | for(int j=0; j<32; j++) 92 | { 93 | assert(lu == (unsigned long)a); 94 | assert(a == (float)lu); 95 | a *= 2.0; 96 | lu <<= 1; 97 | } 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /autotest/cplxstructtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct cplx 6 | { 7 | float r, i; 8 | }; 9 | 10 | cplx cplx_add(cplx a, cplx b) 11 | { 12 | cplx c; 13 | c.r = a.r + b.r; 14 | c.i = a.i + b.i; 15 | return c; 16 | } 17 | 18 | cplx cplx_sub(cplx a, cplx b) 19 | { 20 | cplx c; 21 | c.r = a.r - b.r; 22 | c.i = a.i - b.i; 23 | return c; 24 | } 25 | 26 | cplx cplx_mul(cplx a, cplx b) 27 | { 28 | cplx c; 29 | c.r = a.r * b.r - a.i * b.i; 30 | c.i = a.i * b.r + a.r * b.i; 31 | return c; 32 | } 33 | 34 | float cplx_abs(cplx a) 35 | { 36 | return sqrt(a.r * a.r + a.i * a.i); 37 | } 38 | 39 | cplx cplx_sum(cplx p, const cplx * a, int n) 40 | { 41 | cplx s = {0.0, 0.0}; 42 | cplx c = {1.0, 0.0}; 43 | 44 | for(int i=0; i 2 | #include 3 | #include 4 | 5 | const char * Text = 6 | S"LABORUM RERUM QUO. QUASI IN, SEQUI, TENETUR VOLUPTATEM RERUM " 7 | S"PORRO NON ET MAIORES ALIAS ODIO EST EOS. MAGNAM APERIAM CUM ET " 8 | S"ESSE TEMPORE ITAQUE TEMPORA VOLUPTAS ET IPSAM IPSAM EARUM. ID " 9 | S"SUSCIPIT QUIA RERUM REPREHENDERIT ERROR ET UT. DOLOR ID " 10 | S"CORPORIS, EOS? UNDE VERO ISTE QUIA? EAQUE EAQUE. IN. AUT ID " 11 | S"EXPEDITA ILLUM MOLESTIAS, "; 12 | 13 | // Raster interrupt command structure for change to scrolled and back 14 | 15 | RIRQCode scroll, bottom; 16 | 17 | int main(void) 18 | { 19 | // initialize raster IRQ 20 | rirq_init(true); 21 | 22 | // Build switch to scroll line IRQ 23 | rirq_build(&scroll, 2); 24 | // Delay for one line to get to right border 25 | rirq_delay(&scroll, 11); 26 | // Change control register two with this IRQ 27 | rirq_write(&scroll, 1, &vic.ctrl2, 0); 28 | // Put it onto the scroll line 29 | rirq_set(0, 49 + 24 * 8, &scroll); 30 | 31 | // Build the switch to normal IRQ 32 | rirq_build(&bottom, 1); 33 | // re-enable left and right column and reset horizontal scroll 34 | rirq_write(&bottom, 0, &vic.ctrl2, VIC_CTRL2_CSEL); 35 | // place this at the bottom 36 | rirq_set(1, 250, &bottom); 37 | 38 | // sort the raster IRQs 39 | rirq_sort(); 40 | 41 | // start raster IRQ processing 42 | rirq_start(); 43 | 44 | // Loop through text 45 | int x = 0; 46 | for(;;) 47 | { 48 | // wait for raster reaching bottom of screen 49 | rirq_wait(); 50 | // Update raster IRQ for scroll line with new horizontal scroll offset 51 | rirq_data(&scroll, 1, 7 - (x & 7)); 52 | // Copy scrolled version of text when switching over char border 53 | if ((x & 7) == 0) 54 | memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40); 55 | x++; 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /include/opp/array.h: -------------------------------------------------------------------------------- 1 | #ifndef OPP_ARRAY_H 2 | #define OPP_ARRAY_H 3 | 4 | #include 5 | 6 | namespace opp { 7 | 8 | template 9 | class array 10 | { 11 | protected: 12 | T _data[n]; 13 | public: 14 | typedef T element_type; 15 | 16 | size_t size(void) const 17 | { 18 | return n; 19 | } 20 | 21 | size_t max_size(void) const 22 | { 23 | return n; 24 | } 25 | 26 | bool empty(void) const 27 | { 28 | return n == 0; 29 | } 30 | 31 | const T & at(size_t at) const 32 | { 33 | return _data[at]; 34 | } 35 | 36 | T & at(size_t at) 37 | { 38 | return _data[at]; 39 | } 40 | 41 | T & operator[] (size_t at) 42 | { 43 | return _data[at]; 44 | } 45 | 46 | const T & operator[] (size_t at) const 47 | { 48 | return _data[at]; 49 | } 50 | 51 | T * begin(void) 52 | { 53 | return _data; 54 | } 55 | 56 | const T * begin(void) const 57 | { 58 | return _data; 59 | } 60 | 61 | const T * cbegin(void) const 62 | { 63 | return _data; 64 | } 65 | 66 | T * end(void) 67 | { 68 | return _data + n; 69 | } 70 | 71 | const T * end(void) const 72 | { 73 | return _data + n; 74 | } 75 | 76 | const T * cend(void) const 77 | { 78 | return _data + n; 79 | } 80 | 81 | T & back(void) 82 | { 83 | return _data[n - 1]; 84 | } 85 | 86 | const T & back(void) const 87 | { 88 | return _data[n - 1]; 89 | } 90 | 91 | T & front(void) 92 | { 93 | return _data[0]; 94 | } 95 | 96 | const T & front(void) const 97 | { 98 | return _data[0]; 99 | } 100 | 101 | T * data(void) 102 | { 103 | return _data; 104 | } 105 | 106 | const T * data(void) const 107 | { 108 | return _data; 109 | } 110 | 111 | void fill(const T & t) 112 | { 113 | for(int i=0; i mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions; 27 | ExpandingArray mGlobalVariables; 28 | 29 | void AnalyzeInit(Declaration* mdec); 30 | Declaration* Analyze(Expression* exp, Declaration* procDec, uint32 flags); 31 | 32 | void RegisterCall(Declaration* from, Declaration* to); 33 | void RegisterProc(Declaration* to); 34 | 35 | bool EstimateCost(Expression* exp, Declaration* vindex, int64& cycles, int64& bytes, bool& cconst); 36 | 37 | bool CheckConstFunction(Expression* exp); 38 | void RemoveValueReturn(Expression* exp); 39 | bool CheckUnusedReturns(Expression*& exp); 40 | bool CheckConstReturns(Expression*& exp); 41 | bool CheckUnusedLocals(Expression*& exp); 42 | void UndoParamReference(Expression* exp, Declaration* param); 43 | bool ReplaceParamConst(Expression* exp, Declaration* param); 44 | void PropagateCommas(Expression*& exp); 45 | void PropagateParamCommas(Expression *& fexp, Expression*& exp); 46 | bool ReplaceGlobalConst(Expression* exp); 47 | bool ReplaceConstCalls(Expression*& exp); 48 | bool UnrollLoops(Expression*& exp); 49 | 50 | bool CheckSplitAggregates(Declaration* func, Expression* exp); 51 | void SplitLocalAggregate(Expression* exp, Declaration* var, ExpandingArray & evars); 52 | }; 53 | -------------------------------------------------------------------------------- /samples/hires/polygon.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define Color ((char *)0xd000) 9 | #define Hires ((char *)0xe000) 10 | 11 | Bitmap Screen; 12 | 13 | void init(void) 14 | { 15 | mmap_trampoline(); 16 | mmap_set(MMAP_RAM); 17 | 18 | memset(Color, 0x10, 1000); 19 | memset(Hires, 0x00, 8000); 20 | 21 | mmap_set(MMAP_NO_ROM); 22 | 23 | vic_setmode(VICM_HIRES, Color, Hires); 24 | 25 | vic.color_border = VCOL_WHITE; 26 | 27 | bm_init(&Screen, Hires, 40, 25); 28 | } 29 | 30 | void done(void) 31 | { 32 | mmap_set(MMAP_ROM); 33 | 34 | getch(); 35 | 36 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 37 | } 38 | 39 | int main(void) 40 | { 41 | init(); 42 | 43 | bmu_rect_pattern(&Screen, 0, 0, 320, 200, NineShadesOfGrey[4]); 44 | bmu_rect_clear(&Screen, 14, 14, 304, 184); 45 | bmu_rect_fill(&Screen, 8, 8, 304, 184); 46 | bmu_rect_clear(&Screen, 10, 10, 300, 180); 47 | 48 | ClipRect cr = {11, 11, 309, 189}; 49 | 50 | float px[10], py[10]; 51 | 52 | for(int i=0; i<10; i++) 53 | { 54 | float w = i * PI / 5, c = cos(w), s = sin(w), r = (i & 1) ? 1.0 : 0.4; 55 | px[i] = r * c; py[i] = r * s; 56 | 57 | } 58 | 59 | for(int i=0; i<128; i++) 60 | { 61 | int rpx[10], rpy[10]; 62 | float r = i + 4; 63 | float w = i * PI / 16, c = r * cos(w), s = r * sin(w), cw = r * cos(w * 2.0), sw = r * sin(w * 2.0); 64 | 65 | for(int j=0; j<10; j++) 66 | { 67 | float fx = px[j], fy = py[j]; 68 | rpx[j] = 160 + cw + fx * c + fy * s; 69 | rpy[j] = 100 + sw - fx * s + fy * c; 70 | } 71 | 72 | bm_polygon_nc_fill(&Screen, &cr, rpx, rpy, 10, NineShadesOfGrey[i % 9]); 73 | for(int j=0; j<10; j++) 74 | { 75 | int k = (j + 1) % 10; 76 | bm_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0xff, LINOP_SET); 77 | } 78 | } 79 | 80 | done(); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /oscar64/Compiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Errors.h" 4 | #include "CompilationUnits.h" 5 | #include "Preprocessor.h" 6 | #include "ByteCodeGenerator.h" 7 | #include "NativeCodeGenerator.h" 8 | #include "InterCodeGenerator.h" 9 | #include "GlobalAnalyzer.h" 10 | #include "GlobalOptimizer.h" 11 | #include "Linker.h" 12 | #include "CompilerTypes.h" 13 | 14 | class Compiler 15 | { 16 | public: 17 | Compiler(void); 18 | ~Compiler(void); 19 | 20 | Errors* mErrors; 21 | Linker* mLinker; 22 | CompilationUnits* mCompilationUnits; 23 | Preprocessor* mPreprocessor; 24 | ByteCodeGenerator* mByteCodeGenerator; 25 | NativeCodeGenerator* mNativeCodeGenerator; 26 | InterCodeGenerator* mInterCodeGenerator; 27 | InterCodeModule* mInterCodeModule; 28 | GlobalAnalyzer* mGlobalAnalyzer; 29 | GlobalOptimizer* mGlobalOptimizer; 30 | 31 | GrowingArray mByteCodeFunctions; 32 | 33 | TargetMachine mTargetMachine; 34 | uint64 mCompilerOptions; 35 | uint16 mCartridgeID; 36 | uint8 mCartridgeSubType; 37 | char mCartridgeName[32]; 38 | char mVersion[32]; 39 | 40 | struct Define 41 | { 42 | const Ident* mIdent; 43 | const char* mValue; 44 | }; 45 | 46 | GrowingArray mDefines; 47 | 48 | bool BuildLZO(const char* targetPath); 49 | bool ParseSource(void); 50 | bool GenerateCode(void); 51 | bool WriteOutputFile(const char* targetPath, DiskImage * d64); 52 | bool WriteErrorFile(const char* targetPath); 53 | bool RemoveErrorFile(const char* targetPath); 54 | int ExecuteCode(bool profile, int trace, bool asserts, bool iorange); 55 | 56 | void AddDefine(const Ident* ident, const char* value); 57 | 58 | void RegisterRuntime(const Location& loc, const Ident* ident); 59 | 60 | void CompileProcedure(InterCodeProcedure* proc); 61 | void BuildVTables(void); 62 | void CompleteTemplateExpansion(void); 63 | 64 | bool WriteDbjFile(const char* filename); 65 | bool WriteCszFile(const char* filename); 66 | }; 67 | -------------------------------------------------------------------------------- /autotest/rolrortest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | __noinline unsigned long rollright32(unsigned long a) { 4 | unsigned long tmp = a & 1; 5 | return ( a >> 1) + (tmp << 31); 6 | } 7 | 8 | __noinline unsigned rollright16(unsigned a) { 9 | unsigned tmp = a & 1; 10 | return ( a >> 1) + (tmp << 15); 11 | } 12 | 13 | __noinline char rollright8(char a) { 14 | char tmp = a & 1; 15 | return ( a >> 1) + (tmp << 7); 16 | } 17 | 18 | __noinline unsigned long rollleft32(unsigned long a) { 19 | unsigned long tmp = (a >> 31) & 1; 20 | return ( a << 1) + tmp; 21 | } 22 | 23 | __noinline unsigned rollleft16(unsigned a) { 24 | unsigned tmp = (a >> 15) & 1; 25 | return ( a << 1) + tmp; 26 | } 27 | 28 | __noinline char rollleft8(char a) { 29 | char tmp = (a >> 7) & 1; 30 | return ( a << 1) + tmp; 31 | } 32 | 33 | int main() { 34 | unsigned long lv = 0x12345678ul; 35 | unsigned val = 0x1234; 36 | char c=0x12; 37 | 38 | unsigned long lvt[33]; 39 | unsigned valt[17]; 40 | char ct[9]; 41 | 42 | lvt[0] = lv; 43 | valt[0] = val; 44 | ct[0] = c; 45 | 46 | assert(rollleft8(rollright8(c)) == c); 47 | assert(rollleft16(rollright16(val)) == val); 48 | assert(rollleft32(rollright32(lv)) == lv); 49 | 50 | for(int i=0; i<32; i++) 51 | lvt[i + 1] = rollright32(lvt[i]); 52 | for(int i=0; i<16; i++) 53 | valt[i + 1] = rollright16(valt[i]); 54 | for(int i=0; i<8; i++) 55 | ct[i + 1] = rollright8(ct[i]); 56 | 57 | for(int i=0; i<=32; i++) 58 | { 59 | assert(lvt[32 - i] == lv); 60 | lv = rollleft32(lv); 61 | } 62 | 63 | for(int i=0; i<=16; i++) 64 | { 65 | assert(valt[16 - i] == val); 66 | val = rollleft16(val); 67 | } 68 | 69 | for(int i=0; i<=8; i++) 70 | { 71 | assert(ct[8 - i] == c); 72 | c = rollleft8(c); 73 | } 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /autotest/scrolltest.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define Screen ((char *)0x0400) 4 | 5 | void scroll_left(void) 6 | { 7 | char * dp = Screen; 8 | for(char y=0; y<25; y++) 9 | { 10 | for(char x=0; x<39; x++) 11 | { 12 | dp[x] = dp[x + 1]; 13 | } 14 | dp += 40; 15 | } 16 | } 17 | 18 | void scroll_right(void) 19 | { 20 | char * dp = Screen; 21 | for(char y=0; y<25; y++) 22 | { 23 | for(char x=39; x>0; x--) 24 | { 25 | dp[x] = dp[x - 1]; 26 | } 27 | dp += 40; 28 | } 29 | } 30 | 31 | void scroll_up(void) 32 | { 33 | char * dp = Screen, * sp = dp + 40; 34 | for(char y=0; y<24; y++) 35 | { 36 | for(char x=0; x<40; x++) 37 | { 38 | dp[x] = sp[x]; 39 | } 40 | dp = sp; 41 | sp += 40; 42 | } 43 | } 44 | 45 | void scroll_down(void) 46 | { 47 | char * dp = Screen + 24 * 40, * sp = dp - 40; 48 | for(char y=0; y<24; y++) 49 | { 50 | for(char x=0; x<40; x++) 51 | { 52 | dp[x] = sp[x]; 53 | } 54 | dp = sp; 55 | sp -= 40; 56 | } 57 | } 58 | 59 | void fill_screen(void) 60 | { 61 | for(char y=0; y<25; y++) 62 | { 63 | for(char x=0; x<40; x++) 64 | { 65 | Screen[40 * y + x] = 7 * y + x; 66 | } 67 | } 68 | } 69 | 70 | void check_screen(int dy, int dx) 71 | { 72 | for(int y=0; y<25; y++) 73 | { 74 | for(int x=0; x<40; x++) 75 | { 76 | int sy = y + dy; 77 | int sx = x + dx; 78 | 79 | char c = 7 * y + x; 80 | if (sy >= 0 && sy < 25 && sx >= 0 && sx < 40) 81 | c = 7 * sy + sx; 82 | 83 | assert(Screen[40 * y + x] == c); 84 | } 85 | } 86 | } 87 | 88 | int main(void) 89 | { 90 | fill_screen(); 91 | scroll_left(); 92 | check_screen(0, 1); 93 | 94 | fill_screen(); 95 | scroll_right(); 96 | check_screen(0, -1); 97 | 98 | fill_screen(); 99 | scroll_up(); 100 | check_screen(1, 0); 101 | 102 | fill_screen(); 103 | scroll_down(); 104 | check_screen(-1, 0); 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /include/nes/nes.h: -------------------------------------------------------------------------------- 1 | #ifndef NES_NES_H 2 | #define NES_NES_H 3 | 4 | #include 5 | 6 | #define PPU_CTRL_NT_2000 0b00000000 7 | #define PPU_CTRL_NT_2400 0b00000001 8 | #define PPU_CTRL_NT_2800 0b00000010 9 | #define PPU_CTRL_NT_2C00 0b00000011 10 | #define PPU_CTRL_INC_1 0b00000000 11 | #define PPU_CTRL_INC_32 0b00000100 12 | #define PPU_CTRL_SPR_0000 0b00000000 13 | #define PPU_CTRL_SPR_1000 0b00001000 14 | #define PPU_CTRL_BG_0000 0b00000000 15 | #define PPU_CTRL_BG_1000 0b00010000 16 | #define PPU_CTRL_SPR_8X8 0b00000000 17 | #define PPU_CTRL_SPR_8X16 0b00100000 18 | #define PPU_CTRL_NMI 0b10000000 19 | 20 | #define PPU_MASK_GREYSCALE 0b00000001 21 | #define PPU_MASK_BG8 0b00000010 22 | #define PPU_MASK_SPR8 0b00000100 23 | #define PPU_MASK_BG_ON 0b00001000 24 | #define PPU_MASK_SPR_ON 0b00010000 25 | #define PPU_MASK_EM_RED 0b00100000 26 | #define PPU_MASK_EM_GREEN 0b01000000 27 | #define PPU_MASK_EM_BLUE 0b10000000 28 | 29 | struct PPU 30 | { 31 | volatile byte control; 32 | volatile byte mask; 33 | volatile byte status; 34 | volatile byte oamaddr; 35 | volatile byte oamdata; 36 | volatile byte scroll; 37 | volatile byte addr; 38 | volatile byte data; 39 | }; 40 | 41 | #define ppu (*((struct PPU *)0x2000)) 42 | 43 | struct NESIO 44 | { 45 | volatile byte sq1_volume; 46 | volatile byte sq1_sweep; 47 | volatile word sq1_freq; 48 | 49 | volatile byte sq2_volume; 50 | volatile byte sq2_sweep; 51 | volatile word sq2_freq; 52 | 53 | volatile byte tri_volume; 54 | volatile byte tri_pad; 55 | volatile word tri_freq; 56 | 57 | volatile byte noise_volume; 58 | volatile byte noise_pad; 59 | volatile word noise_freq; 60 | 61 | volatile byte dmc_freq; 62 | volatile byte dmc_raw; 63 | volatile byte dmc_start; 64 | volatile byte dmc_length; 65 | 66 | volatile byte oamdma; 67 | volatile byte channels; 68 | volatile byte input[2]; 69 | }; 70 | 71 | #define nesio (*((struct NESIO *)0x4000)) 72 | 73 | #pragma compile("nes.c") 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /samples/hiresmc/polygon.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define Color1 ((char *)0xc800) 9 | #define Color2 ((char *)0xd800) 10 | #define Hires ((char *)0xe000) 11 | 12 | Bitmap Screen; 13 | 14 | void init(void) 15 | { 16 | mmap_trampoline(); 17 | mmap_set(MMAP_RAM); 18 | 19 | memset(Color1, 0x67, 1000); 20 | memset(Color2, 0x02, 1000); 21 | memset(Hires, 0x00, 8000); 22 | 23 | mmap_set(MMAP_NO_ROM); 24 | 25 | vic_setmode(VICM_HIRES_MC, Color1, Hires); 26 | 27 | vic.color_back = VCOL_BLACK; 28 | vic.color_border = VCOL_BLACK; 29 | 30 | bm_init(&Screen, Hires, 40, 25); 31 | } 32 | 33 | void done(void) 34 | { 35 | mmap_set(MMAP_ROM); 36 | 37 | getch(); 38 | 39 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 40 | } 41 | 42 | int main(void) 43 | { 44 | init(); 45 | 46 | bmmcu_rect_fill(&Screen, 0, 0, 320, 200, 1); 47 | bmmcu_rect_fill(&Screen, 8, 8, 304, 184, 2); 48 | bmmcu_rect_fill(&Screen, 10, 10, 300, 180, 0); 49 | 50 | ClipRect cr = {10, 10, 310, 190}; 51 | 52 | float px[10], py[10]; 53 | 54 | for(int i=0; i<10; i++) 55 | { 56 | float w = i * PI / 5, c = cos(w), s = sin(w), r = (i & 1) ? 1.0 : 0.4; 57 | px[i] = r * c; py[i] = r * s; 58 | 59 | } 60 | 61 | for(int i=0; i<128; i++) 62 | { 63 | int rpx[10], rpy[10]; 64 | float r = i + 4; 65 | float w = i * PI / 16, c = r * cos(w), s = r * sin(w), cw = r * cos(w * 2.0), sw = r * sin(w * 2.0); 66 | 67 | for(int j=0; j<10; j++) 68 | { 69 | float fx = px[j], fy = py[j]; 70 | rpx[j] = 160 + cw + fx * c + fy * s; 71 | rpy[j] = 100 + sw - fx * s + fy * c; 72 | } 73 | 74 | bmmc_polygon_nc_fill(&Screen, &cr, rpx, rpy, 10, MixedColors[i & 3][(i >> 2) & 3]); 75 | 76 | for(int j=0; j<10; j++) 77 | { 78 | int k = (j + 1) % 10; 79 | bmmc_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0); 80 | } 81 | } 82 | 83 | done(); 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /samples/rasterirq/autocrawler.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const char Text[] = 6 | S"LABORUM RERUM QUO. QUASI IN, SEQUI, TENETUR VOLUPTATEM RERUM " 7 | S"PORRO NON ET MAIORES ALIAS ODIO EST EOS. MAGNAM APERIAM CUM ET " 8 | S"ESSE TEMPORE ITAQUE TEMPORA VOLUPTAS ET IPSAM IPSAM EARUM. ID " 9 | S"SUSCIPIT QUIA RERUM REPREHENDERIT ERROR ET UT. DOLOR ID " 10 | S"CORPORIS, EOS? UNDE VERO ISTE QUIA? EAQUE EAQUE. IN. AUT ID " 11 | S"EXPEDITA ILLUM MOLESTIAS, "; 12 | 13 | // Raster interrupt command structure for change to scrolled and back 14 | 15 | RIRQCode scroll, restore; 16 | 17 | int x; 18 | 19 | // Loop through text 20 | __interrupt void doscroll(void) 21 | { 22 | vic.color_border++; 23 | 24 | // Update raster IRQ for scroll line with new horizontal scroll offset 25 | rirq_data(&scroll, 1, 7 - (x & 7)); 26 | // Copy scrolled version of text when switching over char border 27 | if ((x & 7) == 0) 28 | memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40); 29 | x++; 30 | 31 | vic.color_border--; 32 | } 33 | 34 | int main(void) 35 | { 36 | // initialize raster IRQ 37 | rirq_init(true); 38 | 39 | // Build switch to scroll line IRQ 40 | rirq_build(&scroll, 2); 41 | // Delay for one line to get to right border 42 | rirq_delay(&scroll, 11); 43 | // Change control register two with this IRQ 44 | rirq_write(&scroll, 1, &vic.ctrl2, 0); 45 | // Put it onto the scroll line 46 | rirq_set(0, 49 + 24 * 8, &scroll); 47 | 48 | // Build the switch to normal IRQ 49 | rirq_build(&restore, 2); 50 | // re-enable left and right column and reset horizontal scroll 51 | rirq_write(&restore, 0, &vic.ctrl2, VIC_CTRL2_CSEL); 52 | // call scroll copy code 53 | rirq_call(&restore, 1, doscroll); 54 | // place this at the top of the screen before the display starts 55 | rirq_set(1, 250, &restore); 56 | 57 | // sort the raster IRQs 58 | rirq_sort(); 59 | 60 | // start raster IRQ processing 61 | rirq_start(); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /include/c64/asm6502.c: -------------------------------------------------------------------------------- 1 | #include "asm6502.h" 2 | 3 | inline byte asm_np(byte * ip, AsmIns ins) 4 | { 5 | ip[0] = ins & 0xff; 6 | return 1; 7 | } 8 | 9 | inline byte asm_ac(byte * ip, AsmIns ins) 10 | { 11 | ip[0] = (ins & 0xff) | 0x08; 12 | return 1; 13 | } 14 | 15 | inline byte asm_zp(byte * ip, AsmIns ins, byte addr) 16 | { 17 | ip[0] = (ins & 0xff) | 0x04; 18 | ip[1] = addr; 19 | return 2; 20 | } 21 | 22 | inline byte asm_rl(byte * ip, AsmIns ins, sbyte addr) 23 | { 24 | ip[0] = ins & 0xff; 25 | ip[1] = (byte)addr; 26 | return 2; 27 | } 28 | 29 | inline byte asm_im(byte * ip, AsmIns ins, byte value) 30 | { 31 | ip[0] = (ins & 0xff) | ((ins & 0x01) << 3); 32 | ip[1] = value; 33 | return 2; 34 | } 35 | 36 | inline byte asm_zx(byte * ip, AsmIns ins, byte addr) 37 | { 38 | ip[0] = (ins & 0xff) | 0x05; 39 | ip[1] = addr; 40 | return 2; 41 | } 42 | 43 | inline byte asm_zy(byte * ip, AsmIns ins, byte addr) 44 | { 45 | ip[0] = (ins & 0xff) | 0x05; 46 | ip[1] = addr; 47 | return 2; 48 | } 49 | 50 | inline byte asm_ab(byte * ip, AsmIns ins, unsigned addr) 51 | { 52 | ip[0] = (ins & 0xff) ^ 0x0c; 53 | ip[1] = addr & 0xff; 54 | ip[2] = addr >> 8; 55 | return 3; 56 | } 57 | 58 | inline byte asm_in(byte * ip, AsmIns ins, unsigned addr) 59 | { 60 | ip[0] = (ins & 0xff) ^ 0x2c; 61 | ip[1] = addr & 0xff; 62 | ip[2] = addr >> 8; 63 | return 3; 64 | } 65 | 66 | inline byte asm_ax(byte * ip, AsmIns ins, unsigned addr) 67 | { 68 | ip[0] = (ins & 0xff) | 0x1c; 69 | ip[1] = addr & 0xff; 70 | ip[2] = addr >> 8; 71 | return 3; 72 | } 73 | 74 | inline byte asm_ay(byte * ip, AsmIns ins, unsigned addr) 75 | { 76 | ip[0] = (ins & 0xff) | 0x18; 77 | ip[1] = addr & 0xff; 78 | ip[2] = addr >> 8; 79 | return 3; 80 | } 81 | 82 | inline byte asm_ix(byte * ip, AsmIns ins, byte addr) 83 | { 84 | ip[0] = (ins & 0xff) | 0x00; 85 | ip[1] = addr; 86 | return 2; 87 | } 88 | 89 | inline byte asm_iy(byte * ip, AsmIns ins, byte addr) 90 | { 91 | ip[0] = (ins & 0xff) | 0x10; 92 | ip[1] = addr; 93 | return 2; 94 | } 95 | -------------------------------------------------------------------------------- /include/c64/reu.h: -------------------------------------------------------------------------------- 1 | #ifndef C64_REU_H 2 | #define C64_REU_H 3 | 4 | #include "types.h" 5 | 6 | #define REU_STAT_IRQ 0x80 7 | #define REU_STAT_EOB 0x40 8 | #define REU_STAT_FAULT 0x20 9 | #define REU_STAT_SIZE 0x10 10 | #define REU_STAT_VERSION 0x0f 11 | 12 | #define REU_CTRL_FIXL 0x80 13 | #define REU_CTRL_FIXR 0x40 14 | #define REU_CTRL_INCL 0x00 15 | #define REU_CTRL_INCR 0x00 16 | 17 | #define REU_IRQ_ENABLE 0x80 18 | #define REU_IRQ_EOB 0x40 19 | #define REU_IRQ_FAULT 0x20 20 | 21 | #define REU_CMD_EXEC 0x80 22 | #define REU_CMD_AUTO 0x20 23 | #define REU_CMD_FF00 0x10 24 | #define REU_CMD_STORE 0x00 25 | #define REU_CMD_LOAD 0x01 26 | #define REU_CMD_SWAP 0x02 27 | #define REU_CMD_VERIFY 0x03 28 | 29 | struct REU 30 | { 31 | volatile byte status; 32 | volatile byte cmd; 33 | 34 | volatile word laddr; 35 | volatile word raddr; 36 | volatile byte rbank; 37 | 38 | volatile word length; 39 | 40 | volatile byte irqmask; 41 | volatile byte ctrl; 42 | }; 43 | 44 | 45 | #define reu (*((struct REU *)0xdf00)) 46 | 47 | // Count the number of 64k pages in the REU, the test is destructive 48 | int reu_count_pages(void); 49 | 50 | // Copy an array of data from C64 memory to the REU memory 51 | inline void reu_store(unsigned long raddr, const volatile char * sp, unsigned length); 52 | 53 | // Copy an array of data from REU memory to the C64 memory 54 | inline void reu_load(unsigned long raddr, volatile char * dp, unsigned length); 55 | 56 | // Fill an array of data in the REU with a single value 57 | inline void reu_fill(unsigned long raddr, char c, unsigned length); 58 | 59 | // Copy a 2D array from REU memory to the C64 memory. The stride parameter 60 | // is the distance of two rows in REU memory 61 | inline void reu_load2d(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride); 62 | 63 | 64 | inline void reu_load2dpage(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride); 65 | 66 | #pragma compile("reu.c") 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /oscar64/NativeCodeOutliner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NativeCodeGenerator.h" 4 | #include "Array.h" 5 | 6 | class NativeCodeMapper 7 | { 8 | public: 9 | NativeCodeMapper(void); 10 | ~NativeCodeMapper(void); 11 | 12 | void Reset(void); 13 | 14 | int MapInstruction(const NativeCodeInstruction& ins, LinkerSection * ls); 15 | int MapBasicBlock(NativeCodeBasicBlock* block); 16 | 17 | ExpandingArray mIns; 18 | ExpandingArray mBlocks; 19 | protected: 20 | static const int HashSize = 256; 21 | 22 | struct InsNode 23 | { 24 | int mIndex; 25 | LinkerSection * mSection; 26 | InsNode* mNext; 27 | }; 28 | 29 | InsNode * mHash[HashSize]; 30 | }; 31 | 32 | struct SuffixSegment 33 | { 34 | NativeCodeBasicBlock * mBlock; 35 | int mStart, mEnd; 36 | }; 37 | 38 | class SuffixTree 39 | { 40 | public: 41 | const int * mSeg; 42 | int mSize; 43 | 44 | static const int HashSize = 32; 45 | 46 | SuffixTree* mNext, * mParent, ** mFirst; 47 | 48 | SuffixTree(const int* str, int s, SuffixTree* n); 49 | ~SuffixTree(void); 50 | 51 | void AddParents(SuffixTree* parent); 52 | 53 | void AddSuffix(const int* str, int s); 54 | void AddString(const int* str); 55 | 56 | void Print(FILE* file, NativeCodeMapper & map, int depth); 57 | void ParentPrint(FILE* file, NativeCodeMapper& map); 58 | int LongestMatch(NativeCodeMapper& map, int size, int isize, int & msize, SuffixTree *& mtree); 59 | void CollectSuffix(NativeCodeMapper& map, int offset, ExpandingArray& segs); 60 | int ParentCodeSize(NativeCodeMapper& map) const; 61 | void ParentCollect(NativeCodeMapper& map, NativeCodeBasicBlock * block); 62 | void ReplaceCalls(NativeCodeMapper& map, ExpandingArray & segs); 63 | void ChildReplaceCalls(NativeCodeMapper& map, SuffixTree * tree, int offset, ExpandingArray& segs); 64 | void ParentReplaceCalls(NativeCodeMapper& map, NativeCodeBasicBlock* block, int offset, int size, ExpandingArray& segs); 65 | 66 | }; -------------------------------------------------------------------------------- /autotest/fixmathtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | unsigned tval[] = { 6 | 1, 2, 16, 128, 255, 256, 4096, 32768, 65535 7 | }; 8 | 9 | void testmuldiv16u(void) 10 | { 11 | for (char i=0; i<9; i++) 12 | { 13 | assert(lmuldiv16u(tval[i], 0, tval[i]) == 0); 14 | assert(lmuldiv16u(0, tval[i], tval[i]) == 0); 15 | for(char j=0; j<9; j++) 16 | { 17 | assert(lmuldiv16u(tval[i], tval[j], tval[i]) == tval[j]); 18 | assert(lmuldiv16u(tval[j], tval[i], tval[i]) == tval[j]); 19 | } 20 | } 21 | 22 | for(int i=0; i<10000; i++) 23 | { 24 | unsigned a = rand(); 25 | unsigned b = rand(); 26 | unsigned c = rand(); 27 | if (c > 0) 28 | { 29 | unsigned long d = (unsigned long)a * (unsigned long) b / c; 30 | if (d < 0x10000l) 31 | assert(lmuldiv16u(a, b, c) == d); 32 | } 33 | } 34 | } 35 | 36 | unsigned ival[] = { 37 | 1, 2, 16, 128, 255, 256, 4096, 32767, 38 | -1, -2, -16, -128, -255, -256, -4096, -32767 39 | }; 40 | 41 | void testmuldiv16s(void) 42 | { 43 | for (char i=0; i<16; i++) 44 | { 45 | assert(lmuldiv16s(ival[i], 0, ival[i]) == 0); 46 | assert(lmuldiv16s(0, ival[i], ival[i]) == 0); 47 | for(char j=0; j<16; j++) 48 | { 49 | assert(lmuldiv16s(ival[i], ival[j], ival[i]) == ival[j]); 50 | assert(lmuldiv16s(ival[j], ival[i], ival[i]) == ival[j]); 51 | } 52 | } 53 | 54 | for(int i=0; i<10000; i++) 55 | { 56 | int a = rand(); 57 | int b = rand(); 58 | int c = rand(); 59 | 60 | if (c > 0) 61 | { 62 | long d = (long)a * (long)b / c; 63 | if (d >= -32768 && d <= 32767) 64 | assert(lmuldiv16s(a, b, c) == d); 65 | } 66 | } 67 | 68 | } 69 | 70 | void testlmul4f12s(void) 71 | { 72 | for(int i=0; i<20000; i++) 73 | { 74 | int a = rand(); 75 | int b = rand(); 76 | 77 | long d = ((long)a * (long)b) >> 12; 78 | if (d >= -32768 && d <= 32767) 79 | assert(lmul4f12s(a, b) == d); 80 | } 81 | } 82 | 83 | int main(void) 84 | { 85 | testlmul4f12s(); 86 | testmuldiv16u(); 87 | testmuldiv16s(); 88 | 89 | return 0; 90 | } -------------------------------------------------------------------------------- /autotest/asmtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int asum(int a, int b) 5 | { 6 | return __asm 7 | { 8 | clc 9 | lda a 10 | adc b 11 | sta accu 12 | lda a + 1 13 | adc b + 1 14 | sta accu + 1 15 | }; 16 | } 17 | 18 | int bsum(int a, int b) 19 | { 20 | puts("Hello\n"); 21 | 22 | return __asm 23 | { 24 | clc 25 | lda a 26 | adc b 27 | sta accu 28 | lda a + 1 29 | adc b + 1 30 | sta accu + 1 31 | }; 32 | } 33 | 34 | int b, t[10]; 35 | 36 | int bsome(int x) 37 | { 38 | return x; 39 | } 40 | 41 | 42 | int qsum(int a, int (* c)(int)) 43 | { 44 | char n = 0; 45 | b = 0; 46 | for(int i=0; iASMTEST_TARGET + 1 // = #$01 77 | sta [ASMTEST_ZP + 1] // = $f1 78 | ldx #1 79 | lda (ASMTEST_ZP, x) // = (0xf0, 1) 80 | pha 81 | 82 | lda # 2 | #include 3 | 4 | int sum(int * a, int s) 5 | { 6 | int sum = 0; 7 | for(int i=0; i 4 | #include 5 | 6 | Errors::Errors(void) 7 | : mErrorCount(0), mMinLevel(EINFO_GENERIC), mDisabled(EERR_GENERIC) 8 | { 9 | 10 | } 11 | 12 | ErrorID Errors::SetMinLevel(ErrorID id) 13 | { 14 | ErrorID pid = mMinLevel; 15 | mMinLevel = id; 16 | return pid; 17 | } 18 | 19 | void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2) 20 | { 21 | if (!info1) 22 | this->Error(loc, eid, msg); 23 | else if (!info2) 24 | this->Error(loc, eid, msg, info1->mString); 25 | else 26 | this->Error(loc, eid, msg, info1->mString, info2->mString); 27 | } 28 | 29 | 30 | void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char* info1, const char * info2) 31 | { 32 | if (eid >= mMinLevel && !(eid < EERR_GENERIC && mDisabled[eid])) 33 | { 34 | const char* level = "info"; 35 | if (eid >= EERR_GENERIC) 36 | { 37 | level = "error"; 38 | mErrorCount++; 39 | } 40 | else if (eid >= EWARN_GENERIC) 41 | { 42 | level = "warning"; 43 | } 44 | 45 | if (loc.mFileName) 46 | { 47 | if (!info1) 48 | fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg); 49 | else if (!info2) 50 | fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1); 51 | else 52 | fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2); 53 | 54 | if (loc.mFrom) 55 | Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here"); 56 | } 57 | else 58 | { 59 | if (!info1) 60 | fprintf(stderr, "oscar64: %s %d: %s\n", level, eid, msg); 61 | else if (!info2) 62 | fprintf(stderr, "oscar64: %s %d: %s '%s'\n", level, eid, msg, info1); 63 | else 64 | fprintf(stderr, "oscar64: %s %d: %s '%s' != '%s'\n", level, eid, msg, info1, info2); 65 | } 66 | 67 | if (mErrorCount > 10 || eid >= EFATAL_GENERIC) 68 | exit(20); 69 | } 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /include/inttypes.h: -------------------------------------------------------------------------------- 1 | #ifndef INTTYPES_H 2 | #define INTTYPES_H 3 | 4 | #include 5 | 6 | #define PRId8 "d" 7 | #define PRId16 "d" 8 | #define PRId32 "ld" 9 | 10 | #define PRIdLEAST8 "d" 11 | #define PRIdLEAST16 "d" 12 | #define PRIdLEAST32 "ld" 13 | 14 | #define PRIdFAST8 "d" 15 | #define PRIdFAST16 "d" 16 | #define PRIdFAST32 "ld" 17 | 18 | #define PRIdMAX "ld" 19 | #define PRIdPTR "d" 20 | 21 | 22 | #define PRIo8 "o" 23 | #define PRIo16 "o" 24 | #define PRIo32 "lo" 25 | 26 | #define PRIoLEAST8 "o" 27 | #define PRIoLEAST16 "o" 28 | #define PRIoLEAST32 "lo" 29 | 30 | #define PRIoFAST8 "o" 31 | #define PRIoFAST16 "o" 32 | #define PRIoFAST32 "lo" 33 | 34 | #define PRIoMAX "lo" 35 | #define PRIoPTR "o" 36 | 37 | #define PRIu8 "u" 38 | #define PRIu16 "u" 39 | #define PRIu32 "lu" 40 | 41 | #define PRIuLEAST8 "u" 42 | #define PRIuLEAST16 "u" 43 | #define PRIuLEAST32 "lu" 44 | 45 | #define PRIuFAST8 "u" 46 | #define PRIuFAST16 "u" 47 | #define PRIuFAST32 "lu" 48 | 49 | #define PRIuMAX "lu" 50 | #define PRIuPTR "u" 51 | 52 | 53 | #define PRIx8 "x" 54 | #define PRIx16 "x" 55 | #define PRIx32 "lx" 56 | 57 | #define PRIxLEAST8 "x" 58 | #define PRIxLEAST16 "x" 59 | #define PRIxLEAST32 "lx" 60 | 61 | #define PRIxFAST8 "x" 62 | #define PRIxFAST16 "x" 63 | #define PRIxFAST32 "lx" 64 | 65 | #define PRIxMAX "lx" 66 | #define PRIxPTR "x" 67 | 68 | 69 | #define PRIX8 "X" 70 | #define PRIX16 "X" 71 | #define PRIX32 "lX" 72 | 73 | #define PRIXLEAST8 "X" 74 | #define PRIXLEAST16 "X" 75 | #define PRIXLEAST32 "lX" 76 | 77 | #define PRIXFAST8 "X" 78 | #define PRIXFAST16 "X" 79 | #define PRIXFAST32 "lX" 80 | 81 | #define PRIXMAX "lX" 82 | #define PRIXPTR "X" 83 | 84 | 85 | typedef struct { 86 | intmax_t quot; 87 | intmax_t rem; 88 | } imaxdiv_t; 89 | 90 | intmax_t imaxabs(intmax_t n); 91 | imaxdiv_t imaxdiv(intmax_t l, intmax_t r); 92 | intmax_t strtoimax(const char * s, char ** endp, int base); 93 | uintmax_t strtoumax(const char * s, char ** endp, int base); 94 | 95 | 96 | #pragma compile("inttypes.c") 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /samples/hires/bitblit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define Color ((char *)0xd000) 9 | #define Hires ((char *)0xe000) 10 | 11 | Bitmap Screen, Brush; 12 | 13 | void init(void) 14 | { 15 | mmap_trampoline(); 16 | mmap_set(MMAP_RAM); 17 | 18 | memset(Color, 0x10, 1000); 19 | memset(Hires, 0x00, 8000); 20 | 21 | mmap_set(MMAP_NO_ROM); 22 | 23 | vic_setmode(VICM_HIRES, Color, Hires); 24 | 25 | vic.color_border = VCOL_WHITE; 26 | 27 | bm_init(&Screen, Hires, 40, 25); 28 | } 29 | 30 | void done(void) 31 | { 32 | mmap_set(MMAP_ROM); 33 | 34 | getch(); 35 | 36 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 37 | } 38 | 39 | int poly_x[] = {0, 32, 32, 24, 40, 32, 32, 64, 52, 42, 22, 12}; 40 | int poly_y[] = {64, 0, 20, 36, 36, 20, 0, 64, 64, 44, 44, 64}; 41 | 42 | struct BlitDemo 43 | { 44 | const char * name; 45 | BlitOp op; 46 | }; 47 | 48 | BlitDemo blitDemos[11] = { 49 | 50 | {"SET", BLTOP_SET}, 51 | {"RESET", BLTOP_RESET}, 52 | {"NOT", BLTOP_NOT}, 53 | 54 | {"XOR", BLTOP_XOR}, 55 | {"OR", BLTOP_OR}, 56 | {"AND", BLTOP_AND}, 57 | {"NAND", BLTOP_AND_NOT}, 58 | 59 | {"COPY", BLTOP_COPY}, 60 | {"NCOPY", BLTOP_NCOPY}, 61 | 62 | {"PATTERN", BLTOP_PATTERN}, 63 | {"MASKPAT", BLTOP_PATTERN_AND_SRC}, 64 | }; 65 | 66 | char pat[] = {0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00}; 67 | 68 | int main(void) 69 | { 70 | init(); 71 | 72 | bm_alloc(&Brush, 8, 8); 73 | bm_fill(&Brush, 0); 74 | 75 | ClipRect bcr = {0, 0, 64, 64}; 76 | 77 | bm_polygon_nc_fill(&Brush, &bcr, poly_x, poly_y, 12, NineShadesOfGrey[8]); 78 | 79 | bmu_rect_pattern(&Screen, 0, 0, 320, 200, NineShadesOfGrey[2]); 80 | 81 | ClipRect scr = {0, 0, 320, 200}; 82 | 83 | for(int i=0; i<11; i++) 84 | { 85 | int dx = 80 * ((i + 1) % 4); 86 | int dy = 66 * ((i + 1) / 4); 87 | 88 | bmu_bitblit(&Screen, dx + 8, dy + 1, &Brush, 0, 0, 64, 64, pat, blitDemos[i].op); 89 | bm_put_string(&Screen, &scr, dx + 8, dy + 20, blitDemos[i].name, BLTOP_COPY); 90 | } 91 | 92 | done(); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /samples/sprites/multiplexer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define Screen ((char *)0x400) 7 | 8 | // make space until 0x2000 for code and data 9 | 10 | #pragma region( lower, 0x0a00, 0x2000, , , {code, data} ) 11 | 12 | // then space for our sprite data 13 | 14 | #pragma section( spriteset, 0) 15 | 16 | #pragma region( spriteset, 0x2000, 0x2800, , , {spriteset} ) 17 | 18 | // everything beyond will be code, data, bss and heap to the end 19 | 20 | #pragma region( main, 0x2800, 0xa000, , , {code, data, bss, heap, stack} ) 21 | 22 | 23 | // spriteset at fixed location 24 | 25 | #pragma data(spriteset) 26 | 27 | char spriteset[2048] = { 28 | #embed "../resources/digitsprites.bin" 29 | }; 30 | 31 | #pragma data(data) 32 | 33 | // sinus table for circular movement 34 | 35 | int sintab[128]; 36 | 37 | int main(void) 38 | { 39 | // calculate sine table 40 | for(int i=0; i<128; i++) 41 | sintab[i] = (int)(70 * sin(i * PI / 64)); 42 | 43 | // enable raster interrupt via kernal path 44 | rirq_init(true); 45 | 46 | // initialize sprite multiplexer 47 | vspr_init(Screen); 48 | 49 | // initialize sprites 50 | for(int i=0; i<16; i++) 51 | { 52 | vspr_set(i, 30 + 16 * i, 220 - 8 * i, (unsigned)&(spriteset[0]) / 64 + i, (i & 7) + 8); 53 | } 54 | 55 | // initial sort and update 56 | vspr_sort(); 57 | vspr_update(); 58 | rirq_sort(); 59 | 60 | // start raster IRQ processing 61 | rirq_start(); 62 | 63 | // animation loop 64 | unsigned j = 0; 65 | for(;;) 66 | { 67 | // move sprites around 68 | char k = j >> 4; 69 | for(char i=0; i<16; i++) 70 | { 71 | vspr_move(i, 200 + sintab[(j + 8 * i) & 127] + sintab[k & 127], 150 + sintab[(j + 8 * i + 32) & 127] + sintab[(k + 32) & 127]); 72 | } 73 | j++; 74 | 75 | // sort virtual sprites by y position 76 | vspr_sort(); 77 | 78 | // wait for raster IRQ to reach and of frame 79 | rirq_wait(); 80 | 81 | // update sprites back to normal and set up raster IRQ for second set 82 | vspr_update(); 83 | 84 | // sort raster IRQs 85 | rirq_sort(); 86 | } 87 | 88 | return 0; 89 | 90 | } 91 | -------------------------------------------------------------------------------- /samples/kernalio/hireswrite.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | Bitmap Screen, Brush; 9 | char Buffer[200]; 10 | 11 | #define ScreenMem ((char *)0xe000) 12 | #define ColorMem ((char *)0xd000) 13 | 14 | int main(void) 15 | { 16 | // Install the IRQ trampoline 17 | mmap_trampoline(); 18 | 19 | // Initialize the display bitmap and a brush 20 | bm_init(&Screen, ScreenMem, 40, 25); 21 | bm_alloc(&Brush, 2, 2); 22 | 23 | // Clear the color memory with ROM and IO disabled 24 | mmap_set(MMAP_RAM); 25 | memset(ScreenMem, 0, 8000); 26 | memset(ColorMem, 0x70, 1000); 27 | mmap_set(MMAP_NO_ROM); 28 | 29 | // Switch VIC to hires mode 30 | vic_setmode(VICM_HIRES, ColorMem, ScreenMem); 31 | 32 | // Draw the brush 33 | ClipRect crb = {0, 0, 16, 16}; 34 | bm_fill(&Brush, 0); 35 | bm_circle_fill(&Brush, &crb, 7, 7, 6, NineShadesOfGrey[8]); 36 | 37 | // Draw the main image 38 | ClipRect crr = {0, 0, 320, 200}; 39 | bm_circle_fill(&Screen, &crr, 160, 100, 90, NineShadesOfGrey[8]); 40 | bm_circle_fill(&Screen, &crr, 120, 80, 20, NineShadesOfGrey[0]); 41 | bm_circle_fill(&Screen, &crr, 200, 80, 20, NineShadesOfGrey[0]); 42 | 43 | // And a smile 44 | for(int x=-40; x<=40; x+=4) 45 | { 46 | int y = bm_usqrt(50 * 50 - x * x); 47 | bm_bitblit(&Screen, &crr, 160 - 7 + x, 100 + y, &Brush, 0, 0, 15, 15, nullptr, BLTOP_AND_NOT); 48 | } 49 | 50 | 51 | // Reenable the kernal rom 52 | mmap_set(MMAP_ROM); 53 | 54 | // Set name for file and open it with replace on drive 9 55 | krnio_setnam("@0:TESTIMAGE,P,W"); 56 | if (krnio_open(2, 9, 2)) 57 | { 58 | // Loop in chunks of 200 bytes 59 | for(int i=0; i<8000; i+=200) 60 | { 61 | // Disable ROM 62 | mmap_set(MMAP_NO_ROM); 63 | // Copy chunk into buffer 64 | memcpy(Buffer, ScreenMem + i, 200); 65 | // Reeable the ROM 66 | mmap_set(MMAP_ROM); 67 | 68 | // Write the chunk to disk 69 | krnio_write(2, Buffer, 200); 70 | } 71 | 72 | // Close the file 73 | krnio_close(2); 74 | } 75 | 76 | // Restore the VIC 77 | vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /samples/rasterirq/movingbars.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Five raster IRQs for top and bottom of the two chasing bars, and the bottom 8 | // of the screen 9 | RIRQCode ftop, fbottom, btop, bbottom, final ; 10 | 11 | char sintab[256]; 12 | 13 | int main(void) 14 | { 15 | rirq_init(true); 16 | 17 | rirq_build(&ftop, 3); 18 | rirq_delay(&ftop, 10); 19 | rirq_write(&ftop, 1, &vic.color_back, 2); 20 | rirq_write(&ftop, 2, &vic.color_border, 2); 21 | 22 | rirq_build(&fbottom, 3); 23 | rirq_delay(&fbottom, 10); 24 | rirq_write(&fbottom, 1, &vic.color_back, 6); 25 | rirq_write(&fbottom, 2, &vic.color_border, 14); 26 | 27 | rirq_build(&btop, 3); 28 | rirq_delay(&btop, 10); 29 | rirq_write(&btop, 1, &vic.color_back, 7); 30 | rirq_write(&btop, 2, &vic.color_border, 7); 31 | 32 | rirq_build(&bbottom, 3); 33 | rirq_delay(&bbottom, 10); 34 | rirq_write(&bbottom, 1, &vic.color_back, 6); 35 | rirq_write(&bbottom, 2, &vic.color_border, 14); 36 | 37 | rirq_build(&final, 0); 38 | 39 | char yfront = 100, yback = 200; 40 | 41 | rirq_set(0, yfront, &ftop); 42 | rirq_set(1, yfront + 16, &fbottom); 43 | rirq_set(2, yback, &btop); 44 | rirq_set(3, yback + 16, &bbottom); 45 | rirq_set(4, 250, &final); 46 | rirq_sort(); 47 | 48 | 49 | rirq_start(); 50 | 51 | for(int i=0; i<32; i++) 52 | sintab[i] = (int)(120 + 60 * sin(i * PI / 16)) | 1; 53 | 54 | char fi = 3, bi = 0; 55 | for(;;) 56 | { 57 | yfront = sintab[fi & 31]; 58 | yback = sintab[bi & 31]; 59 | 60 | rirq_move(0, yfront); 61 | if (yback == yfront) 62 | { 63 | rirq_move(1, yfront + 16); 64 | rirq_clear(2); 65 | rirq_clear(3); 66 | } 67 | else 68 | { 69 | if (yback < yfront || yback > yfront + 16) 70 | { 71 | rirq_move(1, yfront + 16); 72 | rirq_move(2, yback); 73 | } 74 | else 75 | { 76 | rirq_clear(1); 77 | rirq_move(2, yfront + 16); 78 | } 79 | if (yback < yfront - 16 || yback > yfront) 80 | rirq_move(3, yback + 16); 81 | else 82 | rirq_clear(3); 83 | } 84 | 85 | rirq_sort(); 86 | rirq_wait(); 87 | 88 | fi ++; 89 | bi ++; 90 | } 91 | 92 | return 0; 93 | } 94 | 95 | --------------------------------------------------------------------------------