From 86f7d4bc7c840d36eaa8dc7046eb70d6b82c7756 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Sat, 30 Dec 2023 17:05:38 -0600 Subject: [PATCH] Initial commit --- .gitattributes | 6 + .gitignore | 37 +++ build-aseprite.sh | 41 ++++ build-header-tool.sh | 5 + build-llvm-mos.sh | 38 +++ build-merlin.sh | 22 ++ f256k.patch | 82 +++++++ get-foenixmgr.sh | 9 + header/header.c | 216 ++++++++++++++++++ header/stddclmr.h | 95 ++++++++ hexbuild.asm | 24 ++ .../mos-platform/CMakeLists.txt | 81 +++++++ .../mos-platform/f256k/CMakeLists.txt | 16 ++ .../mos-platform/f256k/clang.cfg | 3 + .../mos-platform/f256k/link.ld | 49 ++++ .../mos-platform/f256k/settings.ld | 1 + pgz-thunk.py | 50 ++++ start-quartus.sh | 6 + update-defines.sh | 24 ++ update-ide-firmware.sh | 16 ++ 20 files changed, 821 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100755 build-aseprite.sh create mode 100755 build-header-tool.sh create mode 100755 build-llvm-mos.sh create mode 100755 build-merlin.sh create mode 100644 f256k.patch create mode 100755 get-foenixmgr.sh create mode 100644 header/header.c create mode 100644 header/stddclmr.h create mode 100644 hexbuild.asm create mode 100644 llvm-mos-sdk-patches/mos-platform/CMakeLists.txt create mode 100644 llvm-mos-sdk-patches/mos-platform/f256k/CMakeLists.txt create mode 100644 llvm-mos-sdk-patches/mos-platform/f256k/clang.cfg create mode 100644 llvm-mos-sdk-patches/mos-platform/f256k/link.ld create mode 100644 llvm-mos-sdk-patches/mos-platform/f256k/settings.ld create mode 100644 pgz-thunk.py create mode 100755 start-quartus.sh create mode 100755 update-defines.sh create mode 100755 update-ide-firmware.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..696333b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.gif filter=lfs diff=lfs merge=lfs -text +*.bmp filter=lfs diff=lfs merge=lfs -text +*.skp filter=lfs diff=lfs merge=lfs -text +*.pmp filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa62f57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Backup files +*~ + +# Stuff I've downloaded for the F256 +software/ + +# Binary output +*.kup +*.pgz +*.pgx +*.bin +*.elf + +# Crap for CrossOver +.windows-serial +.windows-label + +# Stuff that gets created by scripts +merlin-code/ +merlin32/ +merlin32-source/ +f256-firmware/ +ide/ +llvm-mos/ +llvm-mos-source/ +llvm-mos-sdk-source/ +FoenixMgr/ +depot_tools/ +skia/ +aseprite/ +aseprite-source/ +intelFPGA_lite/ +header/header + +# Dumb QtCreator junk +build-*/ +*.user diff --git a/build-aseprite.sh b/build-aseprite.sh new file mode 100755 index 0000000..4004bb4 --- /dev/null +++ b/build-aseprite.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +if [[ ! -d depot_tools ]]; then + sudo apt-get install -y libgnutls28-dev libbz2-dev libharfbuzz-dev g++ cmake ninja-build libx11-dev libxcursor-dev libgl1-mesa-dev libfontconfig1-dev + git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git + git clone -b aseprite-m102 https://github.com/aseprite/skia.git + export PATH="${PWD}/depot_tools:${PATH}" + cd skia + python tools/git-sync-deps +# gn gen out/Release-x64 --args='is_debug=false is_official_build=true skia_use_system_expat=false skia_use_system_icu=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_sfntly=false skia_use_freetype=true skia_use_harfbuzz=true skia_pdf_subset_harfbuzz=true skia_use_system_freetype2=false skia_use_system_harfbuzz=false cc="clang" cxx="clang++" extra_cflags_cc=["-stdlib=libc++"] extra_ldflags=["-stdlib=libc++"]' + gn gen out/Release-x64 --args="is_debug=false is_official_build=true skia_use_system_expat=false skia_use_system_icu=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_sfntly=false skia_use_freetype=true skia_use_harfbuzz=true skia_pdf_subset_harfbuzz=true skia_use_system_freetype2=false skia_use_system_harfbuzz=false" + ninja -C out/Release-x64 skia modules +fi + +if [[ ! -d aseprite ]]; then + git clone https://github.com/aseprite/aseprite.git aseprite-source + pushd aseprite-source + git submodule update --init --recursive + popd +fi + +SKIA=$(pwd)/skia + +pushd aseprite-source + if [[ -d .builddir ]]; then + rm -rf .builddir + fi + + mkdir -p .builddir + + cd .builddir + cmake \ + -G Ninja \ + -DLAF_BACKEND=skia \ + -DSKIA_DIR=${SKIA} \ + .. + ninja aseprite +popd + +mkdir -p aseprite +mv -f aseprite-source/.builddir/bin/* aseprite/. diff --git a/build-header-tool.sh b/build-header-tool.sh new file mode 100755 index 0000000..d84adab --- /dev/null +++ b/build-header-tool.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +pushd header + cc header.c -o header -lm +popd diff --git a/build-llvm-mos.sh b/build-llvm-mos.sh new file mode 100755 index 0000000..0365465 --- /dev/null +++ b/build-llvm-mos.sh @@ -0,0 +1,38 @@ +#!/bin/bash -e + +INSTALL=$(pwd)/llvm-mos + +if [[ "${1,,}" == "all" ]]; then + if [[ ! -d llvm-mos-source ]]; then + git clone https://github.com/llvm-mos/llvm-mos.git llvm-mos-source + fi + + pushd llvm-mos-source + cmake \ + -C clang/cmake/caches/MOS.cmake \ + -G Ninja \ + -S llvm \ + -B build \ + -DCMAKE_INSTALL_PREFIX=${INSTALL} + cmake --build build + cmake --install build + popd +fi + +if [[ ! -d llvm-mos-sdk-source ]]; then + git clone https://github.com/llvm-mos/llvm-mos-sdk.git llvm-mos-sdk-source +fi + +cp -Rf llvm-mos-sdk-patches/* llvm-mos-sdk-source/. + +pushd llvm-mos-sdk-source + mkdir -p build + pushd build + cmake \ + -G Ninja \ + -DCMAKE_INSTALL_PREFIX=${INSTALL} \ + .. + ninja install + popd +popd + diff --git a/build-merlin.sh b/build-merlin.sh new file mode 100755 index 0000000..97f71a0 --- /dev/null +++ b/build-merlin.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +PREFIX=$(pwd)/merlin32 + +if [[ ! -d merlin32-source ]]; then + git clone https://github.com/dwsJason/merlin32.git merlin32-source + pushd merlin32-source/Source + if [[ -f ../Scripts/config.sh ]]; then + rm -f ../Scripts/config.sh + fi + if [[ ! -f ../Scripts/install.original ]]; then + mv -f ../Scripts/install ../Scripts/install.original + sed 's/echo/#echo/' ../Scripts/install.original | + sed 's/sudo/#sudo/' | + sed 's/exit/true #exit/' > ../Scripts/install + chmod +x ../Scripts/install + fi + mkdir -p ${PREFIX}/lib + PREFIX=${PREFIX} make + PREFIX=${PREFIX} make install + popd +fi diff --git a/f256k.patch b/f256k.patch new file mode 100644 index 0000000..77f9944 --- /dev/null +++ b/f256k.patch @@ -0,0 +1,82 @@ +diff --git a/mos-platform/CMakeLists.txt b/mos-platform/CMakeLists.txt +index d5558c97..38de869c 100644 +--- a/mos-platform/CMakeLists.txt ++++ b/mos-platform/CMakeLists.txt +@@ -59,6 +59,7 @@ add_subdirectory(c128) + add_subdirectory(cpm65) + add_subdirectory(cx16) + add_subdirectory(eater) ++add_subdirectory(f256k) + add_subdirectory(mega65) + add_subdirectory(sim) + add_subdirectory(nes) +diff --git a/mos-platform/f256k/CMakeLists.txt b/mos-platform/f256k/CMakeLists.txt +new file mode 100644 +index 00000000..d6c8af82 +--- /dev/null ++++ b/mos-platform/f256k/CMakeLists.txt +@@ -0,0 +1,18 @@ ++platform(f256k COMPLETE PARENT common) ++ ++if(NOT CMAKE_CROSSCOMPILING) ++ return() ++endif() ++ ++add_platform_library(f256k-crt0) ++merge_libraries(f256k-crt0 ++ common-crt0 ++ common-init-stack ++ common-copy-zp-data ++ common-zero-bss ++ common-exit-return ++) ++ ++target_compile_options(f256k-crt0 PUBLIC -mcpu=mosw65c02) ++#target_include_directories(dodo-c SYSTEM BEFORE PUBLIC .) ++#target_compile_options(f256k-c PUBLIC -mcpu=mos65c02) +diff --git a/mos-platform/f256k/link.ld b/mos-platform/f256k/link.ld +new file mode 100644 +index 00000000..5f357eeb +--- /dev/null ++++ b/mos-platform/f256k/link.ld +@@ -0,0 +1,40 @@ ++/* f256k uses first 16 bytes of ZP for mmu control? */ ++__rc0 = 0x10; ++INCLUDE imag-regs.ld ++ASSERT(__rc0 == 0x10, "Inconsistent zero page map.") ++ASSERT(__rc31 == 0x2f, "Inconsistent zero page map.") ++ ++ ++MEMORY { ++ /* kernel uses 0xf0-0xff for parameter passing */ ++ zp : ORIGIN = __rc31 + 1, LENGTH = 0xF0 - (__rc31 + 1) ++ ram (rw) : ORIGIN = 0x200, LENGTH = 0x800-0x200 ++ rom (rw) : ORIGIN = 0x800, LENGTH = 0xC000-0x800 ++} ++ ++ ++REGION_ALIAS("c_readonly", rom) ++REGION_ALIAS("c_writeable", ram) ++ ++SECTIONS { INCLUDE c.ld } ++ ++/* Set initial soft stack address to just above last ram address. (It grows down.) */ ++__stack = ORIGIN(ram) + LENGTH(ram); ++ ++ ++/* bare binary, _start at 0x2000 */ ++OUTPUT_FORMAT { ++ TRIM(rom) ++} ++ ++/* PGX */ ++/* ++OUTPUT_FORMAT { ++ BYTE(0x50) ++ BYTE(0x47) ++ BYTE(0x58) ++ BYTE(0x03) ++ LONG(_start) ++ TRIM(rom) ++} ++*/ diff --git a/get-foenixmgr.sh b/get-foenixmgr.sh new file mode 100755 index 0000000..ba2e8ff --- /dev/null +++ b/get-foenixmgr.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [[ ! -d FoenixMgr ]]; then + sudo apt-get install -y pip + git clone https://github.com/pweingar/FoenixMgr.git + pushd FoenixMgr + pip install -r requirements.txt + popd +fi diff --git a/header/header.c b/header/header.c new file mode 100644 index 0000000..1654796 --- /dev/null +++ b/header/header.c @@ -0,0 +1,216 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "stddclmr.h" + + +/* + * This program assumes it is being run on a little endian machine. + */ + + +int utilStricmp(char *a, char *b) { + for (;; a++, b++) { + int d = tolower((unsigned char)*a) - tolower((unsigned char)*b); + if (d != 0 || !*a) { + return d; + } + } +} + + +int main(int argc, char *argv[]) { + FILE *in = NULL; + FILE *out = NULL; + int32_t reserved = 0; + int32_t start; + int32_t length; + int32_t count; + int c; + int8_t addr; + + if (argc < 2) { + printf("Usage: %s [mode] {opts}\n\n", argv[0]); + printf(" Where [mode] is: KUP, PGX, or PGZ\n"); + return 1; + } + + // Add MicroKernel header. + if (utilStricmp((char *)"kup", argv[1]) == 0) { + /* + * MicroKernel Application + * + * Byte 0 signature: $F2 + * Byte 1 signature: $56 + * Byte 2 the size of program in 8k blocks + * Byte 3 the starting slot of the program (cannot be zero) + * Bytes 4-5 the start address of the program + * Byte 6 header structure version (0 or 1) + * Bytes 7-9 reserved + * Bytes 10- the zero-terminated name of the program + * Bytes ?- the zero-terminated arguments for the program (version >= 1) + * Bytes ?- the zero-terminated description of the program (version >= 1) + */ + if (argc != 9) { + printf("Usage: %s KUP INPUT.BIN OUTPUT.KUP SLOT START \"NAME\" \"ARG LIST\" \"DESC\"\n", argv[0]); + return 1; + } + in = fopen(argv[2], "rb"); + if (!in) { + printf("Unable to open input file.\n"); + return 1; + } + out = fopen(argv[3], "wb"); + if (!out) { + fclose(in); + printf("Unable to open output file.\n"); + return 1; + } + // Get binary size in blocks. + fseek(in, 0, SEEK_END); + length = ceil((float)ftell(in) / 8192.0); + fseek(in, 0, SEEK_SET); + // Write header. + fputc(0xf2, out); + fputc(0x56, out); + fputc((int8_t)length, out); + fputc((int8_t)atoi(argv[4]), out); + start = (int16_t)strtol(argv[5], NULL, 0); + fwrite(&start, sizeof(int16_t), 1, out); + fputc(0x01, out); // version + fwrite(&reserved, sizeof(char), 3, out); + fputs(argv[6], out); + fputc(0x00, out); + if (strlen(argv[7]) > 0) fputs(argv[7], out); + fputc(0x00, out); + fputs(argv[8], out); + fputc(0x00, out); + // Copy binary into output. + while ((c = fgetc(in)) != EOF) fputc(c, out); + fclose(out); + fclose(in); + } + + // Add PGX header. + if (utilStricmp((char *)"pgx", argv[1]) == 0) { + /* + * PGX Program + * + * Byte 0-2 signature: PGX + * Byte 3 CPU Type (1=65816, 2=M680x0, 3=6502) + * Byte 4-7 load address - big endian! + * Byte 8- data + */ + if (argc != 5) { + printf("Usage: %s PGX INPUT.BIN OUTPUT.PGX START\n", argv[0]); + return 1; + } + in = fopen(argv[2], "rb"); + if (!in) { + printf("Unable to open input file.\n"); + return 1; + } + out = fopen(argv[3], "wb"); + if (!out) { + fclose(in); + printf("Unable to open output file.\n"); + return 1; + } + // Write header. + fputc('P', out); + fputc('G', out); + fputc('X', out); + fputc(0x03, out); + start = htonl((int32_t)strtol(argv[4], NULL, 0)); + fwrite(&start, sizeof(int32_t), 1, out); + // Copy binary into output. + while ((c = fgetc(in)) != EOF) fputc(c, out); + fclose(out); + fclose(in); + } + + // Create PGZ package. + if (utilStricmp((char *)"pgz", argv[1]) == 0) { + /* + * PGZ Program + * + * Byte 0 signature ("Z" = 24 bit addresses, "z" = 32 bit) + * Byte 1-3 address of segment #1 (24 bit example) + * Byte 4-6 size of segment #1 + * Byte 7- data + * ... repeat address/size/data for more segments + * Byte ? start address + * Byte ? zeros to indicate this is the start address + */ + if (argc < 7) { + printf("Usage: %s PGZ [32|24] OUTPUT.PGZ START SEG1.BIN ADDR1 ... SEGx.BIN ADDRx\n", argv[0]); + return 1; + } + // Must specify 32 or 24 bit addressing. + addr = atoi(argv[2]); + if (addr != 24 && addr != 32) { + printf("Addressing bits must be 24 or 32.\n"); + return 1; + } + // Must have argument pairs. + if ((argc - 5) % 2 != 0) { + printf("Must provide an even number of segment arguments.\n"); + return 1; + } + // Start of segment arguments. + count = 5; + // Open file to write. + out = fopen(argv[3], "wb"); + if (!out) { + printf("Unable to open output file.\n"); + return 1; + } + // Header. + if (addr == 24) fputc('Z', out); else fputc('z', out); + // Assemble segments. + while (count < argc) { + // Open segment to read. + in = fopen(argv[count], "rb"); + if (!in) { + fclose(out); + printf("Unable to open segment %s.\n", argv[count]); + return 1; + } + count++; + // Get segment size. + fseek(in, 0, SEEK_END); + length = ftell(in); + fseek(in, 0, SEEK_SET); + // Write segment info. + start = (int32_t)strtol(argv[count], NULL, 0); + count++; + if (addr == 24) { + fwrite(&start, sizeof(char), 3, out); + fwrite(&length, sizeof(char), 3, out); + } else { + fwrite(&start, sizeof(int32_t), 1, out); + fwrite(&length, sizeof(int32_t), 1, out); + } + // Copy binary into output. + while ((c = fgetc(in)) != EOF) fputc(c, out); + fclose(in); + } + // Write start address. + start = (int32_t)strtol(argv[4], NULL, 0); + if (addr == 24) { + fwrite(&start, 3, 1, out); + fwrite(&reserved, 3, 1, out); + } else { + fwrite(&start, sizeof(int32_t), 1, out); + fwrite(&reserved, sizeof(int32_t), 1, out); + } + fclose(out); + } + + return 0; +} diff --git a/header/stddclmr.h b/header/stddclmr.h new file mode 100644 index 0000000..8e6b3d9 --- /dev/null +++ b/header/stddclmr.h @@ -0,0 +1,95 @@ +#ifndef STDDCLMR_H +#define STDDCLMR_H + +/* +Action figures sold separately. Add toner. All models over 18 years of age. +All rights reserved. Allow four to six weeks for delivery. An equal +opportunity employer. Any resemblance to actual persons, living or dead, is +unintentional and purely coincidental. Apply only to affected area. Approved +for veterans. As seen on TV. At participating locations only. Avoid contact +with mucous membranes. Avoid contact with skin. Avoid extreme temperatures +and store in a cool dry place. Batteries not included. Be sure each item is +properly endorsed. Beware of dog. Booths for two or more. Breaking seal +constitutes acceptance of agreement. Call toll free number before digging. +Caveat emptor. Check here if tax deductible. Close cover before striking +Colors may fade. Contains a substantial amount of non-tobacco ingredients. +Contents may settle during shipment. Contestants have been briefed on some +questions before the show. Copyright 1995 Joker's Wild. Disclaimer does +not cover hurricane, lightning, tornado, tsunami, volcanic eruption, +earthquake, flood, and other Acts of God, misuse, neglect, unauthorized +repair, damage from improper installation, broken antenna or marred cabinet, +incorrect line voltage, missing or altered serial numbers, sonic boom +vibrations, electromagnetic radiation from nuclear blasts, customer +adjustments that are not covered in the joke list, and incidents owing to +airplane crash, ship sinking, motor vehicle accidents, leaky roof, broken +glass, falling rocks, mud slides, forest fire, flying projectiles, or +dropping the item. Do not bend, fold, mutilate, or spindle. Do not place +near flammable or magnetic source. Do not puncture, incinerate, or store +above 120 degrees Fahrenheit. Do not stamp. Use other side for additional +listings. Do not use while operating a motor vehicle or heavy equipment. Do +not write below this line. Documents are provided "as is" without any +warranties expressed or implied. Don't quote me on anything. Don't quote me +on that. Driver does not carry cash. Drop in any mailbox. Edited for +television. Employees and their families are not eligible. Falling rock. +First pull up, then pull down. Flames redirected to /dev/null. For a +limited time only. For external use only. For off-road use only. For office +use only. For recreational use only. Do not disturb. Freshest if eaten +before date on carton. Hand wash only, tumble dry on low heat. If a rash, +redness, irritation, or swelling develops, discontinue use. If condition +persists, consult your physician. If defects are discovered, do not attempt +to fix them yourself, but return to an authorized service center. If +ingested, do not induce vomiting, if symptoms persist, consult a doctor. +Keep away from open flames and avoid inhaling fumes. Keep away from +sunlight, pets, and small children. Keep cool; process promptly. Limit +one-per-family please. Limited time offer, call now to ensure prompt +delivery. List at least two alternate dates. List each check separately by +bank number. List was current at time of printing. Lost ticket pays maximum +rate. May be too intense for some viewers. Must be 18 to enter. No Canadian +coins. No alcohol, dogs or horses. No anchovies unless otherwise specified. +No animals were harmed in the production of these documents. No money down. +No other warranty expressed or implied. No passes accepted for this +engagement. No postage necessary if mailed in the United States. No +preservatives added. No purchase necessary. No salt, MSG, artificial color +or flavor added. No shoes, no shirt, no service, no kidding. No solicitors. +No substitutions allowed. No transfers issued until the bus comes to a +complete stop. No user-serviceable parts inside. Not affiliated with the +American Red Cross. Not liable for damages due to use or misuse. Not +recommended for children. Not responsible for direct, indirect, incidental +or consequential damages resulting from any defect, error or failure to +perform. Not the Beatles. Objects in mirror may be closer than they appear. +One size fits all. Many suitcases look alike. Other copyright laws for +specific entries apply wherever noted. Other restrictions may apply. Package +sold by weight, not volume. Parental advisory - explicit lyrics. Penalty for +private use. Place stamp here. Please remain seated until the ride has come +to a complete stop. Possible penalties for early withdrawal. Post office will +not deliver without postage. Postage will be paid by addressee. Prerecorded +for this time zone. Price does not include taxes. Processed at location +stamped in code at top of carton. Quantities are limited while supplies last. +Read at your own risk. Record additional transactions on back of previous +stub. Replace with same type. Reproduction strictly prohibited. Restaurant +package, not for resale. Return to sender, no forwarding order on file, +unable to forward. Safety goggles may be required during use. Sanitized for +your protection. Sealed for your protection, do not use if the safety seal is +broken. See label for sequence. Shading within a garment may occur. Sign here +without admitting guilt. Simulated picture. Slightly enlarged to show detail. +Slightly higher west of the Rockies. Slippery when wet. Smoking these may be +hazardous to your health. Some assembly required. Some equipment shown is +optional. Some of the trademarks mentioned in this product appear for +identification purposes only. Subject to FCC approval. Subject to change +without notice. Substantial penalty for early withdrawal. Text may contain +material some readers may find objectionable, parental guidance is advised. +Text used in these documents is made from 100% recycled electrons and magnetic +particles. These documents do not reflect the thoughts or opinions of either +myself, my company, my friends, or my rabbit. This is not an offer to sell +securities. This offer is void where prohibited, taxed, or otherwise +restricted. This product is meant for educational purposes only. Times +approximate. Unix is a registered trademark of AT&T. Use only as directed. Use +only in a well-ventilated are. User assumes full liabilities. Void where +prohibited. We have sent the forms which seem right for you. You must be +present to win. You need not be present to win. Your canceled check is your +receipt. Your mileage may vary. I didn't do it. You can't prove anything. + +This supersedes all previous notices. +*/ + +#endif // STDDCLMR_H diff --git a/hexbuild.asm b/hexbuild.asm new file mode 100644 index 0000000..3f2af92 --- /dev/null +++ b/hexbuild.asm @@ -0,0 +1,24 @@ +* = $2000 * $41 +.binary "xdev.bin" +.binary "dos.bin" +.binary "sb01.bin" +.binary "sb02.bin" +.binary "sb03.bin" +.binary "sb04.bin" +.binary "pexec.bin" +* = $2000 * $50 +.binary "help.bin" +.binary "docs_superbasic1.bin" +.binary "docs_superbasic2.bin" +.binary "docs_superbasic3.bin" +.binary "docs_superbasic4.bin" +* = $2000 * $7b +.binary "3b.bin" +* = $2000 * $7c +.binary "3c.bin" +* = $2000 * $7d +.binary "3d.bin" +* = $2000 * $7e +.binary "3e.bin" +* = $2000 * $7f +.binary "3f.bin" \ No newline at end of file diff --git a/llvm-mos-sdk-patches/mos-platform/CMakeLists.txt b/llvm-mos-sdk-patches/mos-platform/CMakeLists.txt new file mode 100644 index 0000000..cc2d103 --- /dev/null +++ b/llvm-mos-sdk-patches/mos-platform/CMakeLists.txt @@ -0,0 +1,81 @@ +include(platform) + +if (CMAKE_CROSSCOMPILING) + add_compile_options(-flto) +else() + # Make nested build directory cross-compiling to MOS, but using this + # CMakeLists.txt. + ExternalProject_Add(mos-platform + SOURCE_DIR ${CMAKE_SOURCE_DIR} + BINARY_DIR build + INSTALL_DIR build/install + STAMP_DIR build/stamp + TMP_DIR build/tmp + DOWNLOAD_DIR build + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX= + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/llvm-mos-toolchain.cmake + -DCMAKE_C_COMPILER=${LLVM_MOS_C_COMPILER} + -DCMAKE_CXX_COMPILER=${LLVM_MOS_CXX_COMPILER} + -DCMAKE_ASM_COMPILER=${LLVM_MOS_ASM_COMPILER} + -DCMAKE_C_FLAGS=${LLVM_MOS_ARCH_FLAGS} + -DCMAKE_CXX_FLAGS=${LLVM_MOS_ARCH_FLAGS} + -DCMAKE_ASM_FLAGS=${LLVM_MOS_ARCH_FLAGS} + -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} + USES_TERMINAL_CONFIGURE On + USES_TERMINAL_BUILD On + USES_TERMINAL_INSTALL On + BUILD_ALWAYS On) + ExternalProject_Get_Property(mos-platform INSTALL_DIR) + install(DIRECTORY ${INSTALL_DIR}/ DESTINATION .) + + # Clean the build directories with the host project. + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY + ADDITIONAL_CLEAN_FILES build ../examples) + + find_package(Doxygen OPTIONAL_COMPONENTS dot) + if (Doxygen_FOUND) + set(DOXYGEN_FILE_PATTERNS *) + set(DOXYGEN_EXTENSION_MAPPING no_extension=C++) + set(DOXYGEN_EXTRACT_ALL YES) + set(DOXYGEN_EXCLUDE_SYMBOLS __*) + set(DOXYGEN_EXCLUDE_PATTERNS *.c *.cc *.s *.S *.cfg *.ld *.awk __*) + doxygen_add_docs(doxygen .) + endif() +endif() + +add_subdirectory(common) +add_subdirectory(atari2600-common) +add_subdirectory(atari2600-4k) +add_subdirectory(atari2600-3e) +add_subdirectory(atari8-common) +add_subdirectory(atari8-dos) +add_subdirectory(atari8-stdcart) +add_subdirectory(atari8-xegs) +add_subdirectory(commodore) +add_subdirectory(c64) +add_subdirectory(c128) +add_subdirectory(cpm65) +add_subdirectory(cx16) +add_subdirectory(eater) +add_subdirectory(f256k) +add_subdirectory(mega65) +add_subdirectory(sim) +add_subdirectory(nes) +add_subdirectory(nes-action53) +add_subdirectory(nes-cnrom) +add_subdirectory(nes-gtrom) +add_subdirectory(nes-nrom) +add_subdirectory(nes-mmc1) +add_subdirectory(nes-mmc3) +add_subdirectory(nes-unrom) +add_subdirectory(nes-unrom-512) +add_subdirectory(osi-c1p) +add_subdirectory(dodo) +add_subdirectory(pet) +add_subdirectory(rpc8e) +add_subdirectory(pce-common) +add_subdirectory(pce) +add_subdirectory(pce-cd) +add_subdirectory(vic20) diff --git a/llvm-mos-sdk-patches/mos-platform/f256k/CMakeLists.txt b/llvm-mos-sdk-patches/mos-platform/f256k/CMakeLists.txt new file mode 100644 index 0000000..30d5495 --- /dev/null +++ b/llvm-mos-sdk-patches/mos-platform/f256k/CMakeLists.txt @@ -0,0 +1,16 @@ +platform(f256k COMPLETE PARENT common) + +if(NOT CMAKE_CROSSCOMPILING) + return() +endif() + +add_platform_library(f256k-crt0) +merge_libraries(f256k-crt0 + common-crt0 + common-init-stack + common-copy-zp-data + common-zero-bss + common-exit-loop +) + +target_compile_options(f256k-crt0 PUBLIC -mcpu=mosw65c02) diff --git a/llvm-mos-sdk-patches/mos-platform/f256k/clang.cfg b/llvm-mos-sdk-patches/mos-platform/f256k/clang.cfg new file mode 100644 index 0000000..96e3500 --- /dev/null +++ b/llvm-mos-sdk-patches/mos-platform/f256k/clang.cfg @@ -0,0 +1,3 @@ +-mlto-zp=192 +-D__F256K__ +-mcpu=mosw65c02 diff --git a/llvm-mos-sdk-patches/mos-platform/f256k/link.ld b/llvm-mos-sdk-patches/mos-platform/f256k/link.ld new file mode 100644 index 0000000..2cbc0f8 --- /dev/null +++ b/llvm-mos-sdk-patches/mos-platform/f256k/link.ld @@ -0,0 +1,49 @@ +INCLUDE settings.ld + +/* f256k uses first 16 bytes of ZP for mmu control? */ +__rc0 = 0x10; +INCLUDE imag-regs.ld +ASSERT(__rc0 == 0x10, "Inconsistent zero page map.") +ASSERT(__rc31 == 0x2f, "Inconsistent zero page map.") + + +MEMORY { + /* kernel uses 0xf0-0xff for parameter passing */ + zp : ORIGIN = __rc31 + 1, LENGTH = 0xF0 - (__rc31 + 1) + ram (rw) : ORIGIN = __f256_start, LENGTH = 0xC000-__f256_start +} + + +REGION_ALIAS("c_readonly", ram) +REGION_ALIAS("c_writeable", ram) + + +/* NOTE: c.ld has zp.ld before text.ld. + * If the compiler decides to put data into the zeropage (.zp.data), + * then it would appear in our output binary before the .text section. + * And because the text section is our starting point, the zeropage + * data pushes our _start address up by some indeterminate amount, which + * is a pain. + * So, here I've just done the same as c.ld, but reordered things so the + * .zp data appears _after_ our .text section. + * (the zeropage data copied into the zeropage at startup by the crt + * copy-zp-data, I think) + */ +SECTIONS { + INCLUDE text.ld + INCLUDE zp.ld + INCLUDE rodata.ld + INCLUDE data.ld + INCLUDE bss.ld + INCLUDE noinit.ld +} + + +/* Set initial soft stack address to just above last ram address. (It grows down.) */ +__stack = ORIGIN(ram) + LENGTH(ram); + + +/* Bare Binary */ +OUTPUT_FORMAT { + TRIM(ram) +} diff --git a/llvm-mos-sdk-patches/mos-platform/f256k/settings.ld b/llvm-mos-sdk-patches/mos-platform/f256k/settings.ld new file mode 100644 index 0000000..beb97f1 --- /dev/null +++ b/llvm-mos-sdk-patches/mos-platform/f256k/settings.ld @@ -0,0 +1 @@ +__f256_start = 0x2000; diff --git a/pgz-thunk.py b/pgz-thunk.py new file mode 100644 index 0000000..4fb3827 --- /dev/null +++ b/pgz-thunk.py @@ -0,0 +1,50 @@ +import struct, sys + +def unpack_bytes(len, bytes): + if len == 3: + bytes.extend(b'\x00') + return struct.unpack(' ${HEADER} + echo "#define ${BLOCK}" >> ${HEADER} + echo >> ${HEADER} + sed 's/;/\/\//' ${FILE} | \ + sed 's/;;//' | \ + sed 's/ = \$/ 0x/' | \ + sed 's/\(^[[:alpha:]].*$\)/#define \1/' >> ${HEADER} + echo >> ${HEADER} + echo "#endif // ${BLOCK}" >> ${HEADER} + done +popd diff --git a/update-ide-firmware.sh b/update-ide-firmware.sh new file mode 100755 index 0000000..9d3eca8 --- /dev/null +++ b/update-ide-firmware.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +if [[ ! -d f256-firmware ]]; then + git clone https://github.com/FoenixRetro/f256-firmware.git +else + pushd f256-firmware + git pull + popd +fi + +pushd f256-firmware/shipping/firmware + cp -f ../../../hexbuild.asm . + 64tass --intel-hex -o kernel_F256jr.hex hexbuild.asm + #cp -f kernel_F256jr.hex "~/.cxoffice/FoenixIDE/drive_c/Program Files/C256 Foenix Project/FoenixIDE Setup/roms/." + mv -f kernel_F256jr.hex ../../../ide/roms/. +popd