-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added initial Atari 2600 support (4K and 3E mappers) (#237)
* Added initial Atari 2600 support (4K and 3E mappers) * Atari 2600: * Updated section origins to include bank index. * Fixed mapper weak symbols. * Fix for set_horiz_pos() register ordering. * Pass -mcpu=mos6502x flag. * Added license notices. * Atari 2600: - Refactored into atari2600-common as parent. - Changed to MAPPER_* defines. - Better XRAM support with DECLARE_XRAM_VARIABLE macro. * [Atari 2600] Refactored headers for future mappers. Added 3E signature for Stella. * [Atari 2600] Minor updates. - Removed weak attributes and redundant declarations. - 16 more bytes of zeropage, leaving 16 bytes of stack. - 3E mapper selects ROM0 on startup. - MAPPER_CART_ROM_KB macro. * [Atari 2600] Removed (leaf) attribute from C functions.
Showing
33 changed files
with
1,205 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ | |
.vscode/** | ||
build/** | ||
build* | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
add_executable(demo_vcslib.a26 demo_vcslib.c) | ||
target_compile_options(demo_vcslib.a26 PRIVATE "-Os") | ||
install_example(demo_vcslib.a26) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
|
||
#include <atari2600.h> | ||
#include <vcslib.h> | ||
#include <peekpoke.h> | ||
#include <mapper.h> | ||
|
||
#ifdef __ATARI2600_MAPPER_3E__ | ||
MAPPER_CART_ROM_KB(8); // 8K ROM (3 * 2 KB + 2 KB) | ||
#endif | ||
#ifdef __ATARI2600_MAPPER_4K__ | ||
MAPPER_CART_ROM_KB(4); // 4K ROM | ||
#endif | ||
|
||
#if !defined(__ATARI2600__) | ||
#error "This example is for Atari 2600 only" | ||
#endif | ||
|
||
unsigned char color; // a frame counter | ||
|
||
#ifdef MAPPER_BANKED_ROM | ||
#define ROM_BANK(index) __attribute__((noinline, section(".rom"#index))) | ||
#else | ||
#define ROM_BANK(index) | ||
#endif | ||
|
||
#define KERNEL_BANK 1 | ||
|
||
ROM_BANK(KERNEL_BANK) void my_preframe(void) { | ||
// Doing frame computation during blank | ||
// Update color | ||
TIA.colubk = color++; | ||
// Set player 1 horizontal position | ||
set_horiz_pos(0, color >= 0x80 ? -color : color); | ||
apply_hmove(); | ||
} | ||
|
||
ROM_BANK(KERNEL_BANK) void my_doframe(void) { | ||
int i; | ||
char c = color; | ||
// Set player sprite color | ||
TIA.colup0 = COLOR_CONV(color); | ||
// Draw each scanline | ||
for (i=0; i<192; i++) { | ||
TIA.wsync = 0; // sync to scanline | ||
TIA.colubk = COLOR_CONV(c); // set background | ||
TIA.pf1 = i; // set playfield | ||
TIA.grp0 = i; // set sprite bitmap | ||
c++; | ||
} | ||
TIA.grp0 = 0; // clear sprite | ||
} | ||
|
||
ROM_BANK(KERNEL_BANK) void my_postframe(void) { | ||
// additional post-frame processing goes here | ||
} | ||
|
||
// Display kernel loop | ||
ROM_BANK(KERNEL_BANK) void do_kernel_loop() { | ||
// loop until reset released | ||
while (SW_RESET()) { } | ||
// loop forever | ||
while (1) { | ||
kernel_1(); | ||
my_preframe(); | ||
kernel_2(); | ||
my_doframe(); | ||
kernel_3(); | ||
my_postframe(); | ||
kernel_4(); | ||
} | ||
} | ||
|
||
#ifdef MAPPER_XRAM | ||
|
||
// XRAM on the VCS has different areas for read vs. write | ||
|
||
typedef struct { | ||
char buf[256]; | ||
} XRAMStruct; | ||
|
||
// XRAM on the VCS has different areas for read vs. write | ||
// declare xram_data_read and xram_data_write as XRAM variables | ||
DECLARE_XRAM_VARIABLE(0, XRAMStruct xram_data); | ||
|
||
void test_ram(void) { | ||
char x; | ||
POKE(MAPPER_XRAM_WRITE | 0x7f0, 0xaa); | ||
x = PEEK(MAPPER_XRAM_READ | 0x3f0); | ||
if (x != 0xaa) asm("brk"); | ||
xram_write(0x3f1, 0x55); | ||
x = xram_read(0x3f1); | ||
if (x != 0x55) asm("brk"); | ||
xram_write(0x3f2, 0xaa); | ||
x = xram_read(0x3f2); | ||
if (x != 0xaa) asm("brk"); | ||
xram_data_write.buf[0] = 1; | ||
x = xram_data_read.buf[0]; | ||
if (x != 1) asm("brk"); | ||
} | ||
|
||
#endif | ||
|
||
int main() { | ||
|
||
// test extra RAM, if available | ||
#ifdef MAPPER_XRAM | ||
ram_select(0); | ||
test_ram(); | ||
#endif | ||
|
||
// test banked rom call, if available | ||
#ifdef MAPPER_BANKED_ROM | ||
bank_select(KERNEL_BANK ^ 1); | ||
banked_call_rom(KERNEL_BANK, do_kernel_loop); | ||
#else | ||
do_kernel_loop(); | ||
#endif | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
platform(atari2600-3e COMPLETE PARENT atari2600-common) | ||
|
||
if(NOT CMAKE_CROSSCOMPILING) | ||
return() | ||
endif() | ||
|
||
file(READ clang.cfg CONFIG) | ||
|
||
install(FILES | ||
mapper.h | ||
TYPE INCLUDE) | ||
|
||
install(FILES | ||
link.ld | ||
TYPE LIB) | ||
|
||
add_platform_object_file(atari2600-3e-init-mapper-o | ||
init_mapper_3e.o | ||
init_mapper_3e.S | ||
) | ||
|
||
add_platform_library(atari2600-3e-c | ||
mapper_3e.c | ||
) | ||
target_include_directories(atari2600-3e-c SYSTEM BEFORE PUBLIC .) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-D__ATARI2600_MAPPER_3E__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
; ensure that ROM0 is selected on startup | ||
; so that it matches the __current_bank variable | ||
; which is zero-initialized | ||
|
||
.section .init.055,"axR",@progbits | ||
sta $3F ; A = 0 from init.050 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* TigerVision 3E ROM mapper */ | ||
|
||
INCLUDE vcs.ld | ||
|
||
INPUT(init_mapper_3e.o) | ||
|
||
PROVIDE(__cart_rom_size = 32); | ||
PROVIDE(__cart_ram_size = 32); | ||
|
||
ASSERT(__cart_rom_size >= 6, | ||
"ATARI 2600 3E: ROM must be at least 6 KiB") | ||
ASSERT(__cart_rom_size <= 32, | ||
"ATARI 2600 3E: ROM must be no larger than 32 KiB") | ||
ASSERT(__cart_rom_size % 2 == 0, | ||
"ATARI 2600 3E: ROM must be multiple of 2 KiB") | ||
ASSERT(__cart_ram_size <= 255, | ||
"ATARI 2600 3E: RAM must be no larger than 255 KiB") | ||
ASSERT(__cart_ram_size % 2 == 0, | ||
"ATARI 2600 3E: RAM must be multiple of 2 KiB") | ||
|
||
/* | ||
High word of origin address: | ||
0x00 0x00 = fixed ROM | ||
0x01 [bank#] = bank-switched ROM | ||
0x02 [bank#] = bank-switched RAM | ||
*/ | ||
|
||
MEMORY { | ||
rom0 : ORIGIN = 0x01001000, LENGTH = 0x800 | ||
rom1 : ORIGIN = 0x01013000, LENGTH = 0x800 | ||
rom2 : ORIGIN = 0x01025000, LENGTH = __cart_rom_size >= 8 ? 0x800 : 0 | ||
rom3 : ORIGIN = 0x01037000, LENGTH = __cart_rom_size >= 10 ? 0x800 : 0 | ||
rom4 : ORIGIN = 0x01049000, LENGTH = __cart_rom_size >= 12 ? 0x800 : 0 | ||
rom5 : ORIGIN = 0x0105b000, LENGTH = __cart_rom_size >= 14 ? 0x800 : 0 | ||
rom6 : ORIGIN = 0x0106d000, LENGTH = __cart_rom_size >= 16 ? 0x800 : 0 | ||
rom7 : ORIGIN = 0x0107f000, LENGTH = __cart_rom_size >= 18 ? 0x800 : 0 | ||
rom8 : ORIGIN = 0x01081000, LENGTH = __cart_rom_size >= 20 ? 0x800 : 0 | ||
rom9 : ORIGIN = 0x01093000, LENGTH = __cart_rom_size >= 22 ? 0x800 : 0 | ||
rom10 : ORIGIN = 0x010a5000, LENGTH = __cart_rom_size >= 24 ? 0x800 : 0 | ||
rom11 : ORIGIN = 0x010b7000, LENGTH = __cart_rom_size >= 26 ? 0x800 : 0 | ||
rom12 : ORIGIN = 0x010c9000, LENGTH = __cart_rom_size >= 28 ? 0x800 : 0 | ||
rom13 : ORIGIN = 0x010db000, LENGTH = __cart_rom_size >= 30 ? 0x800 : 0 | ||
rom14 : ORIGIN = 0x010ed000, LENGTH = __cart_rom_size >= 32 ? 0x800 : 0 | ||
|
||
perm : ORIGIN = 0x0000f800, LENGTH = 0x800 | ||
} | ||
|
||
REGION_ALIAS("c_readonly", perm) | ||
|
||
MEMORY { | ||
xram0_read : ORIGIN = 0x02001000, LENGTH = __cart_ram_size >= 4 ? 0x400 : 0 | ||
xram0_write : ORIGIN = 0x02001400, LENGTH = __cart_ram_size >= 4 ? 0x400 : 0 | ||
xram1_read : ORIGIN = 0x02013000, LENGTH = __cart_ram_size >= 8 ? 0x400 : 0 | ||
xram1_write : ORIGIN = 0x02013400, LENGTH = __cart_ram_size >= 8 ? 0x400 : 0 | ||
xram2_read : ORIGIN = 0x02025000, LENGTH = __cart_ram_size >= 12 ? 0x400 : 0 | ||
xram2_write : ORIGIN = 0x02025400, LENGTH = __cart_ram_size >= 12 ? 0x400 : 0 | ||
xram3_read : ORIGIN = 0x02037000, LENGTH = __cart_ram_size >= 16 ? 0x400 : 0 | ||
xram3_write : ORIGIN = 0x02037400, LENGTH = __cart_ram_size >= 16 ? 0x400 : 0 | ||
xram4_read : ORIGIN = 0x02049000, LENGTH = __cart_ram_size >= 20 ? 0x400 : 0 | ||
xram4_write : ORIGIN = 0x02049400, LENGTH = __cart_ram_size >= 20 ? 0x400 : 0 | ||
xram5_read : ORIGIN = 0x0205b000, LENGTH = __cart_ram_size >= 24 ? 0x400 : 0 | ||
xram5_write : ORIGIN = 0x0205b400, LENGTH = __cart_ram_size >= 24 ? 0x400 : 0 | ||
xram6_read : ORIGIN = 0x0206d000, LENGTH = __cart_ram_size >= 28 ? 0x400 : 0 | ||
xram6_write : ORIGIN = 0x0206d400, LENGTH = __cart_ram_size >= 28 ? 0x400 : 0 | ||
xram7_read : ORIGIN = 0x0207f000, LENGTH = __cart_ram_size >= 32 ? 0x400 : 0 | ||
xram7_write : ORIGIN = 0x0207f400, LENGTH = __cart_ram_size >= 32 ? 0x400 : 0 | ||
} | ||
|
||
|
||
SECTIONS { | ||
INCLUDE c.ld | ||
|
||
.rom0 : { *(.rom0 .rom0.*) } >rom0 | ||
.rom1 : { *(.rom1 .rom1.*) } >rom1 | ||
.rom2 : { *(.rom2 .rom2.*) } >rom2 | ||
.rom3 : { *(.rom3 .rom3.*) } >rom3 | ||
.rom4 : { *(.rom4 .rom4.*) } >rom4 | ||
.rom5 : { *(.rom5 .rom5.*) } >rom5 | ||
.rom6 : { *(.rom6 .rom6.*) } >rom6 | ||
.rom7 : { *(.rom7 .rom7.*) } >rom7 | ||
.rom8 : { *(.rom8 .rom8.*) } >rom8 | ||
.rom9 : { *(.rom9 .rom9.*) } >rom9 | ||
.rom10 : { *(.rom10 .rom10.*) } >rom10 | ||
.rom11 : { *(.rom11 .rom11.*) } >rom11 | ||
.rom12 : { *(.rom12 .rom12.*) } >rom12 | ||
.rom13 : { *(.rom13 .rom13.*) } >rom13 | ||
.rom14 : { *(.rom14 .rom14.*) } >rom14 | ||
|
||
.perm : { *(.perm .perm.*) } >perm | ||
|
||
.xram0_read (NOLOAD) : { *(.xram0_read .xram0_read.*) } >xram0_read | ||
.xram0_write (NOLOAD) : { *(.xram0_write .xram0_write.*) } >xram0_write | ||
.xram1_read (NOLOAD) : { *(.xram1_read .xram1_read.*) } >xram1_read | ||
.xram1_write (NOLOAD) : { *(.xram1_write .xram1_write.*) } >xram1_write | ||
.xram2_read (NOLOAD) : { *(.xram2_read .xram2_read.*) } >xram2_read | ||
.xram2_write (NOLOAD) : { *(.xram2_write .xram2_write.*) } >xram2_write | ||
.xram3_read (NOLOAD) : { *(.xram3_read .xram3_read.*) } >xram3_read | ||
.xram3_write (NOLOAD) : { *(.xram3_write .xram3_write.*) } >xram3_write | ||
.xram4_read (NOLOAD) : { *(.xram4_read .xram4_read.*) } >xram4_read | ||
.xram4_write (NOLOAD) : { *(.xram4_write .xram4_write.*) } >xram4_write | ||
.xram5_read (NOLOAD) : { *(.xram5_read .xram5_read.*) } >xram5_read | ||
.xram5_write (NOLOAD) : { *(.xram5_write .xram5_write.*) } >xram5_write | ||
.xram6_read (NOLOAD) : { *(.xram6_read .xram6_read.*) } >xram6_read | ||
.xram6_write (NOLOAD) : { *(.xram6_write .xram6_write.*) } >xram6_write | ||
.xram7_read (NOLOAD) : { *(.xram7_read .xram7_read.*) } >xram7_read | ||
.xram7_write (NOLOAD) : { *(.xram7_write .xram7_write.*) } >xram7_write | ||
|
||
.vector 0x0000fffc : { | ||
/* we don't really need NMI on the 2600 */ | ||
SHORT(_start) /* START entrypoint */ | ||
SHORT(_start) /* START entrypoint */ | ||
} >perm | ||
} | ||
|
||
OUTPUT_FORMAT { | ||
FULL(rom0) | ||
FULL(rom1) | ||
FULL(rom2) | ||
FULL(rom3) | ||
FULL(rom4) | ||
FULL(rom5) | ||
FULL(rom6) | ||
FULL(rom7) | ||
FULL(rom8) | ||
FULL(rom9) | ||
FULL(rom10) | ||
FULL(rom11) | ||
FULL(rom12) | ||
FULL(rom13) | ||
FULL(rom14) | ||
FULL(perm) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* TigerVision (3E) mapper include files */ | ||
|
||
#ifndef MAPPER_H | ||
#define MAPPER_H | ||
|
||
#define MAPPER_TYPE_3E | ||
|
||
#define MAPPER_BANKED_ROM | ||
#define MAPPER_BANKED_ROM_SIZE 0x800 | ||
|
||
#define MAPPER_XRAM | ||
#define MAPPER_XRAM_SIZE 0x400 | ||
#define MAPPER_XRAM_READ 0x1000 | ||
#define MAPPER_XRAM_WRITE 0x1400 | ||
|
||
#define MAPPER_CART_ROM_KB(kb) \ | ||
asm(".globl __cart_rom_size\n__cart_rom_size = " #kb) | ||
|
||
#include <mapper_rom_single.h> | ||
#include <mapper_xram_single.h> | ||
|
||
typedef unsigned char bank_index_t; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
#include <peekpoke.h> | ||
#include <mapper.h> | ||
|
||
__attribute__((section(".zp.bss"))) bank_index_t __current_bank; | ||
|
||
void set_current_bank(bank_index_t bank_id) { | ||
if (bank_id & 0x80) { | ||
ram_select(bank_id & 0x7f); | ||
} else { | ||
bank_select(bank_id); | ||
} | ||
} | ||
|
||
bank_index_t get_current_bank(void) { | ||
return __current_bank; | ||
} | ||
|
||
void bank_select(bank_index_t bank_id) { | ||
POKE(0x3f, bank_id); | ||
__current_bank = bank_id; | ||
} | ||
|
||
void ram_select(bank_index_t bank_id) { | ||
POKE(0x3e, bank_id); | ||
__current_bank = bank_id | 0x80; | ||
} | ||
|
||
void xram_write(int offset, unsigned char value) { | ||
POKE(MAPPER_XRAM_WRITE | offset, value); | ||
} | ||
|
||
unsigned char xram_read(int offset) { | ||
return PEEK(MAPPER_XRAM_READ | offset); | ||
} | ||
|
||
__attribute__((callback(2))) void banked_call_rom(bank_index_t bankId, | ||
void (*method)(void)) { | ||
bank_index_t previous_bank_id = get_current_bank(); | ||
bank_select(bankId); | ||
method(); | ||
set_current_bank(previous_bank_id); | ||
} | ||
|
||
__attribute__((callback(2))) void banked_call_ram(bank_index_t bankId, | ||
void (*method)(void)) { | ||
bank_index_t previous_bank_id = get_current_bank(); | ||
ram_select(bankId); | ||
method(); | ||
set_current_bank(previous_bank_id); | ||
} | ||
|
||
// From Stella (cartridge auto-detection): | ||
// 3E cart RAM bankswitching is triggered by storing the bank number | ||
// in address 3E using 'STA $3E', ROM bankswitching is triggered by | ||
// storing the bank number in address 3F using 'STA $3F'. | ||
// We expect the latter will be present at least 2 times, since there | ||
// are at least two banks | ||
// https://github.com/stella-emu/stella/blob/d6224a8a6e30b4b323cde86ade2f05f75dcdfbec/src/emucore/CartDetector.cxx#L4 | ||
// It also only calls the 3E detection routine on powers-of-two, | ||
// and if it hasn't detected Superchip via repeating bytes. | ||
__attribute__((used, retain, section(".rom0"))) static void _stella_signature_3e() { | ||
asm("sta $3f"); | ||
asm("sta $3e"); | ||
asm("sta $3f"); | ||
} | ||
// Javatari.js detects 3E as a fallback for weird ROM sizes... | ||
// 6 KB, 14 KB, 18 KB, etc. | ||
// or if you have [3E] in the filename. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
platform(atari2600-4k COMPLETE PARENT atari2600-common) | ||
|
||
if(NOT CMAKE_CROSSCOMPILING) | ||
return() | ||
endif() | ||
|
||
install(FILES | ||
mapper.h | ||
TYPE INCLUDE) | ||
|
||
install(FILES | ||
link.ld | ||
TYPE LIB) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-D__ATARI2600_MAPPER_4K__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* 4K ROM */ | ||
|
||
INCLUDE vcs.ld | ||
|
||
PROVIDE(__cart_rom_size = 4); | ||
ASSERT(__cart_rom_size == 4 || __cart_rom_size == 2, | ||
"ROM size must be 4 KiB or 2 KiB"); | ||
|
||
MEMORY { | ||
perm : ORIGIN = 0xF000, LENGTH = __cart_rom_size * 1024 | ||
} | ||
|
||
REGION_ALIAS("c_readonly", perm) | ||
|
||
SECTIONS { | ||
INCLUDE c.ld | ||
|
||
.perm : { *(.perm .perm.*) } >perm | ||
|
||
.vector (0xf000 + __cart_rom_size * 1024 - 4) : { | ||
/* we don't really need NMI on the 2600 */ | ||
SHORT(_start) /* START entrypoint */ | ||
SHORT(_start) /* START entrypoint */ | ||
} >perm | ||
} | ||
|
||
OUTPUT_FORMAT { | ||
FULL(perm) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* 4K ROM */ | ||
|
||
#ifndef MAPPER_H | ||
#define MAPPER_H | ||
|
||
#define MAPPER_TYPE_4K | ||
|
||
#define MAPPER_CART_ROM_KB(kb) \ | ||
asm(".globl __cart_rom_size\n__cart_rom_size = " #kb) | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
platform(atari2600-common PARENT common) | ||
|
||
if(NOT CMAKE_CROSSCOMPILING) | ||
return() | ||
endif() | ||
|
||
install(FILES | ||
vcs.ld | ||
TYPE LIB) | ||
|
||
install(FILES | ||
_riot.h | ||
_tia.h | ||
atari2600.h | ||
atari2600_constants.h | ||
vcslib.h | ||
mapper_rom_single.h | ||
mapper_rom_multi.h | ||
mapper_xram_single.h | ||
TYPE INCLUDE) | ||
|
||
install(FILES | ||
atari2600.inc | ||
atari2600_riot.inc | ||
atari2600_tia.inc | ||
DESTINATION ${ASMINCDIR}) | ||
|
||
add_platform_object_file(atari2600-common-crt0-o | ||
crt0.o | ||
crt0.S | ||
) | ||
target_link_libraries(atari2600-common-crt0-o PRIVATE common-asminc) | ||
|
||
add_platform_library(atari2600-common-crt0) | ||
merge_libraries(atari2600-common-crt0 | ||
common-copy-zp-data | ||
common-copy-data | ||
common-exit-loop | ||
) | ||
target_link_libraries(atari2600-common-crt0 PRIVATE common-asminc) | ||
|
||
add_platform_library(atari2600-common-c | ||
frameloop.c | ||
vcslib.S | ||
) | ||
target_include_directories(atari2600-common-c BEFORE PUBLIC .) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
// Originally from cc65. | ||
|
||
/*****************************************************************************/ | ||
/* */ | ||
/* Atari VCS 2600 RIOT registers addresses */ | ||
/* */ | ||
/* Source: DASM - vcs.h */ | ||
/* */ | ||
/* Florent Flament (contact@florentflament.com), 2017 */ | ||
/* */ | ||
/*****************************************************************************/ | ||
|
||
/* RIOT registers */ | ||
struct __riot { | ||
unsigned char swcha; | ||
unsigned char swacnt; | ||
unsigned char swchb; | ||
unsigned char swbcnt; | ||
unsigned char intim; | ||
unsigned char timint; | ||
|
||
unsigned char unused[14]; | ||
|
||
unsigned char tim1t; | ||
unsigned char tim8t; | ||
unsigned char tim64t; | ||
unsigned char t1024t; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
// Originally from cc65. | ||
|
||
/*****************************************************************************/ | ||
/* */ | ||
/* Atari VCS 2600 TIA registers addresses */ | ||
/* */ | ||
/* Source: DASM - vcs.h */ | ||
/* */ | ||
/* Florent Flament (contact@florentflament.com), 2017 */ | ||
/* */ | ||
/*****************************************************************************/ | ||
|
||
/* TIA write / read registers */ | ||
struct __tia { | ||
union { | ||
unsigned char vsync; | ||
unsigned char cxm0p; | ||
}; | ||
union { | ||
unsigned char vblank; | ||
unsigned char cxm1p; | ||
}; | ||
union { | ||
unsigned char wsync; | ||
unsigned char cxp0fb; | ||
}; | ||
union { | ||
unsigned char rsync; | ||
unsigned char cxp1fb; | ||
}; | ||
union { | ||
unsigned char nusiz0; | ||
unsigned char cxm0fb; | ||
}; | ||
union { | ||
unsigned char nusiz1; | ||
unsigned char cxm1fb; | ||
}; | ||
union { | ||
unsigned char colup0; | ||
unsigned char cxblpf; | ||
}; | ||
union { | ||
unsigned char colup1; | ||
unsigned char cxppmm; | ||
}; | ||
union { | ||
unsigned char colupf; | ||
unsigned char inpt0; | ||
}; | ||
union { | ||
unsigned char colubk; | ||
unsigned char inpt1; | ||
}; | ||
union { | ||
unsigned char ctrlpf; | ||
unsigned char inpt2; | ||
}; | ||
union { | ||
unsigned char refp0; | ||
unsigned char inpt3; | ||
}; | ||
union { | ||
unsigned char refp1; | ||
unsigned char inpt4; | ||
}; | ||
union { | ||
unsigned char pf0; | ||
unsigned char inpt5; | ||
}; | ||
unsigned char pf1; | ||
unsigned char pf2; | ||
unsigned char resp0; | ||
unsigned char resp1; | ||
unsigned char resm0; | ||
unsigned char resm1; | ||
unsigned char resbl; | ||
unsigned char audc0; | ||
unsigned char audc1; | ||
unsigned char audf0; | ||
unsigned char audf1; | ||
unsigned char audv0; | ||
unsigned char audv1; | ||
unsigned char grp0; | ||
unsigned char grp1; | ||
unsigned char enam0; | ||
unsigned char enam1; | ||
unsigned char enabl; | ||
unsigned char hmp0; | ||
unsigned char hmp1; | ||
unsigned char hmm0; | ||
unsigned char hmm1; | ||
unsigned char hmbl; | ||
unsigned char vdelp0; | ||
unsigned char vdelp1; | ||
unsigned char vdelbl; | ||
unsigned char resmp0; | ||
unsigned char resmp1; | ||
unsigned char hmove; | ||
unsigned char hmclr; | ||
unsigned char cxclr; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
// Originally from cc65. Modified from original version (added volatile). | ||
|
||
/*****************************************************************************/ | ||
/* */ | ||
/* Atari VCS 2600 TIA & RIOT registers addresses */ | ||
/* */ | ||
/* Source: DASM Version 1.05 - vcs.h */ | ||
/* */ | ||
/* Florent Flament (contact@florentflament.com), 2017 */ | ||
/* */ | ||
/*****************************************************************************/ | ||
|
||
|
||
#ifndef _ATARI2600_H | ||
#define _ATARI2600_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include <_tia.h> | ||
#define TIA (*(volatile struct __tia*)0x0000) | ||
|
||
#include <_riot.h> | ||
#define RIOT (*(volatile struct __riot*)0x0280) | ||
|
||
#include <atari2600_constants.h> | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
/* End of atari2600.h */ | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
; Copyright 2023 LLVM-MOS Project | ||
; Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
; See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
; information. | ||
; Originally from cc65. | ||
|
||
; Atari 2600 TIA & RIOT read / write registers | ||
; | ||
; Florent Flament (contact@florentflament.com), 2017 | ||
|
||
; TIA & RIOT registers mapping | ||
.include "atari2600_tia.inc" | ||
.include "atari2600_riot.inc" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
// Originally from cc65. | ||
|
||
#ifndef _ATARI2600_CONSTANTS_H | ||
#define _ATARI2600_CONSTANTS_H | ||
|
||
// TIA - CONSTANTS | ||
|
||
#define HMOVE_L7 (0x70) | ||
#define HMOVE_L6 (0x60) | ||
#define HMOVE_L5 (0x50) | ||
#define HMOVE_L4 (0x40) | ||
#define HMOVE_L3 (0x30) | ||
#define HMOVE_L2 (0x20) | ||
#define HMOVE_L1 (0x10) | ||
#define HMOVE_0 (0x00) | ||
#define HMOVE_R1 (0xF0) | ||
#define HMOVE_R2 (0xE0) | ||
#define HMOVE_R3 (0xD0) | ||
#define HMOVE_R4 (0xC0) | ||
#define HMOVE_R5 (0xB0) | ||
#define HMOVE_R6 (0xA0) | ||
#define HMOVE_R7 (0x90) | ||
#define HMOVE_R8 (0x80) | ||
|
||
// Values for ENAMx and ENABL | ||
#define DISABLE_BM (0b00) | ||
#define ENABLE_BM (0b10) | ||
|
||
// Values for RESMPx | ||
#define LOCK_MISSILE (0b10) | ||
#define UNLOCK_MISSILE (0b00) | ||
|
||
// Values for REFPx | ||
#define NO_REFLECT (0b0000) | ||
#define REFLECT (0b1000) | ||
|
||
// Values for NUSIZx | ||
#define ONE_COPY (0b000) | ||
#define TWO_COPIES (0b001) | ||
#define TWO_MED_COPIES (0b010) | ||
#define THREE_COPIES (0b011) | ||
#define TWO_WIDE_COPIES (0b100) | ||
#define DOUBLE_SIZE (0b101) | ||
#define THREE_MED_COPIES (0b110) | ||
#define QUAD_SIZE (0b111) | ||
#define MSBL_SIZE1 (0b000000) | ||
#define MSBL_SIZE2 (0b010000) | ||
#define MSBL_SIZE4 (0b100000) | ||
#define MSBL_SIZE8 (0b110000) | ||
|
||
// Values for CTRLPF | ||
#define PF_PRIORITY (0b100) | ||
#define PF_SCORE (0b10) | ||
#define PF_REFLECT (0b01) | ||
#define PF_NO_REFLECT (0b00) | ||
|
||
// Values for SWCHB | ||
#define P1_DIFF_MASK (0b10000000) | ||
#define P0_DIFF_MASK (0b01000000) | ||
#define BW_MASK (0b00001000) | ||
#define SELECT_MASK (0b00000010) | ||
#define RESET_MASK (0b00000001) | ||
|
||
#define VERTICAL_DELAY (1) | ||
|
||
// SWCHA joystick bits | ||
#define MOVE_RIGHT (0b01111111) | ||
#define MOVE_LEFT (0b10111111) | ||
#define MOVE_DOWN (0b11011111) | ||
#define MOVE_UP (0b11101111) | ||
#define P0_JOYSTICK_MASK (0b11110000) | ||
#define P1_JOYSTICK_MASK (0b00001111) | ||
|
||
// SWCHA paddle bits | ||
#define P0_TRIGGER_PRESSED (0b01111111) | ||
#define P1_TRIGGER_PRESSED (0b10111111) | ||
#define P2_TRIGGER_PRESSED (0b11110111) | ||
#define P3_TRIGGER_PRESSED (0b11111011) | ||
|
||
// Values for VBLANK | ||
#define DUMP_PORTS (0b10000000) | ||
#define ENABLE_LATCHES (0b01000000) | ||
#define DISABLE_TIA (0b00000010) | ||
#define ENABLE_TIA (0b00000000) | ||
|
||
// Values for VSYNC | ||
#define START_VERT_SYNC (0b10) | ||
#define STOP_VERT_SYNC (0b00) | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
; Copyright 2023 LLVM-MOS Project | ||
; Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
; See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
; information. | ||
; Originally from cc65. | ||
|
||
; Atari 2600 RIOT read / write registers | ||
; | ||
; Source: DASM - vcs.h | ||
; Details available in: Stella Programmer's Guide by Steve Wright | ||
; | ||
; Florent Flament (contact@florentflament.com), 2017 | ||
|
||
; Read registers | ||
SWCHA = $0280 | ||
SWACNT = $0281 | ||
SWCHB = $0282 | ||
SWBCNT = $0283 | ||
INTIM = $0284 | ||
TIMINT = $0285 | ||
|
||
; Write registers | ||
TIM1T = $0294 | ||
TIM8T = $0295 | ||
TIM64T = $0296 | ||
T1024T = $0297 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
; Copyright 2023 LLVM-MOS Project | ||
; Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
; See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
; information. | ||
; Originally from cc65. | ||
|
||
; Atari 2600 TIA read / write registers | ||
; | ||
; Source: DASM - vcs.h | ||
; Details available in: Stella Programmer's Guide by Steve Wright | ||
; | ||
; Florent Flament (contact@florentflament.com), 2017 | ||
|
||
; Read registers | ||
VSYNC = $00 | ||
VBLANK = $01 | ||
WSYNC = $02 | ||
RSYNC = $03 | ||
NUSIZ0 = $04 | ||
NUSIZ1 = $05 | ||
COLUP0 = $06 | ||
COLUP1 = $07 | ||
COLUPF = $08 | ||
COLUBK = $09 | ||
CTRLPF = $0A | ||
REFP0 = $0B | ||
REFP1 = $0C | ||
PF0 = $0D | ||
PF1 = $0E | ||
PF2 = $0F | ||
RESP0 = $10 | ||
RESP1 = $11 | ||
RESM0 = $12 | ||
RESM1 = $13 | ||
RESBL = $14 | ||
AUDC0 = $15 | ||
AUDC1 = $16 | ||
AUDF0 = $17 | ||
AUDF1 = $18 | ||
AUDV0 = $19 | ||
AUDV1 = $1A | ||
GRP0 = $1B | ||
GRP1 = $1C | ||
ENAM0 = $1D | ||
ENAM1 = $1E | ||
ENABL = $1F | ||
HMP0 = $20 | ||
HMP1 = $21 | ||
HMM0 = $22 | ||
HMM1 = $23 | ||
HMBL = $24 | ||
VDELP0 = $25 | ||
VDELP1 = $26 | ||
VDELBL = $27 | ||
RESMP0 = $28 | ||
RESMP1 = $29 | ||
HMOVE = $2A | ||
HMCLR = $2B | ||
CXCLR = $2C | ||
|
||
; Write registers | ||
CXM0P = $00 | ||
CXM1P = $01 | ||
CXP0FB = $02 | ||
CXP1FB = $03 | ||
CXM0FB = $04 | ||
CXM1FB = $05 | ||
CXBLPF = $06 | ||
CXPPMM = $07 | ||
INPT0 = $08 | ||
INPT1 = $09 | ||
INPT2 = $0A | ||
INPT3 = $0B | ||
INPT4 = $0C | ||
INPT5 = $0D |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
-mcpu=mos6502x | ||
-mlto-zp=112 | ||
-D__ATARI2600__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
; Copyright 2023 LLVM-MOS Project | ||
; Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
; See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
; information. | ||
; Originally from cc65. Modified from original version. | ||
|
||
.section .init.010,"axR",@progbits | ||
; Clear decimal mode | ||
cld | ||
|
||
.section .init.050,"axR",@progbits | ||
; Initialization Loop: | ||
; * Clears Atari 2600 whole memory (128 bytes) including BSS segment | ||
; * Clears TIA registers | ||
; * Sets system stack pointer to $ff (i.e top of zero-page) | ||
ldx #0 | ||
txa | ||
clearLoop: | ||
dex | ||
txs | ||
pha | ||
bne clearLoop | ||
|
||
; we jump to main directly here to save 2 bytes of stack | ||
; TODO: how do we get rid of "jsr main" in crt0? | ||
.section .init.400,"axR",@progbits | ||
jmp main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
#include "vcslib.h" | ||
|
||
void kernel_1(void) { | ||
// Vertical Sync signal | ||
TIA.vsync = START_VERT_SYNC; | ||
TIA.wsync = 0x00; | ||
// Test reset switch | ||
if (SW_RESET()) { | ||
asm("brk"); | ||
} | ||
TIA.wsync = 0x00; | ||
TIA.wsync = 0x00; | ||
TIA.vsync = STOP_VERT_SYNC; | ||
|
||
// Vertical Blank (preframe) | ||
RIOT.tim64t = VBLANK_TIM64; | ||
} | ||
|
||
void kernel_2(void) { | ||
while (RIOT.intim != 0) {} | ||
|
||
// Turn on beam | ||
TIA.wsync = 0x00; | ||
TIA.vblank = ENABLE_TIA; | ||
|
||
// Display frame (doframe) | ||
#ifdef PAL | ||
RIOT.t1024t = KERNAL_T1024; | ||
#else | ||
RIOT.tim64t = KERNAL_TIM64; | ||
#endif | ||
} | ||
|
||
void kernel_3(void) { | ||
while (RIOT.intim != 0) {} | ||
|
||
// Turn off beam | ||
TIA.wsync = 0x00; | ||
TIA.vblank = DISABLE_TIA; | ||
|
||
// Overscan (postframe) | ||
RIOT.tim64t = OVERSCAN_TIM64; | ||
} | ||
|
||
void kernel_4(void) { | ||
while (RIOT.intim != 0) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
// Mapper functions for multiple-area bank switching schemes. | ||
// (E0, EC) | ||
|
||
#ifndef _MAPPER_ROM_MULTI_H_ | ||
#define _MAPPER_ROM_MULTI_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// ROM bank index type. | ||
typedef unsigned char rom_bank_t; | ||
typedef unsigned char banked_area_t; | ||
|
||
// Switch in a ROM bank into a given area. | ||
void bank_select(banked_area_t area, rom_bank_t bank_id); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
// Mapper functions for single-area bank switching schemes. | ||
// (F8, F6, F4, 3E, FA, E7, F0, UA, 0840) | ||
|
||
#ifndef _MAPPER_ROM_SINGLE_H_ | ||
#define _MAPPER_ROM_SINGLE_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// ROM bank index type. | ||
typedef unsigned char rom_bank_t; | ||
|
||
// Switch in a ROM bank. | ||
void bank_select(rom_bank_t bank_id); | ||
|
||
// Switch in a ROM or RAM bank, depending on the high bit (if set, it's RAM) | ||
void set_current_bank(rom_bank_t bank_id); | ||
|
||
// Get the currently switched bank index. | ||
// If the high bit is set, it's a RAM bank, otherwise it's a ROM bank. | ||
rom_bank_t get_current_bank(void); | ||
|
||
// Switch to another ROM bank and call this function. Note: Using banked_call to | ||
// call a second function from within another banked_call is safe. This function | ||
// works no matter which switchable bank the function is in. | ||
__attribute__((callback(2))) void banked_call_rom(rom_bank_t bank_id, | ||
void (*method)(void)); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright 2022 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
// Functions for single-area RAM bank switching schemes. | ||
// (3E, E7) | ||
|
||
#ifndef _MAPPER_XRAM_H_ | ||
#define _MAPPER_XRAM_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// RAM bank index type. | ||
typedef unsigned char ram_bank_t; | ||
|
||
// Macro to declare a variable in XRAM. | ||
// - index = XRAM bank index | ||
// - declaration = variable declaration | ||
// This will declare two variables, one read-only and one write-only. | ||
// For example, DECLARE_XRAM_VARIABLE(0, int my_var) | ||
// creates two variables: my_var_read and my_var_write. | ||
// NOTE: These variables are not initialized by default. | ||
#define DECLARE_XRAM_VARIABLE(index, declaration) \ | ||
__attribute__((section(".xram" #index "_read"))) volatile const declaration##_read; \ | ||
__attribute__((section(".xram" #index "_write"))) volatile declaration##_write; | ||
|
||
// Switch in a RAM bank. | ||
void ram_select(ram_bank_t bank_id); | ||
|
||
// Switch to another RAM bank and call this function. | ||
__attribute__((callback(2))) void banked_call_ram(ram_bank_t bank_id, | ||
void (*method)(void)); | ||
|
||
// Write a byte to extended RAM at set offset | ||
// RAM must be selected first, or use banked_call_ram | ||
void xram_write(int offset, unsigned char value); | ||
|
||
// Read a byte from extended RAM at set offset | ||
// RAM must be selected first, or use banked_call_ram | ||
unsigned char xram_read(int offset); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif // _MAPPER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
|
||
MEMORY { | ||
zp : ORIGIN = __rc31 + 1, LENGTH = 0x100 - (__rc31 + 1) | ||
|
||
pia_ram (w) : ORIGIN = 0x80, LENGTH = 0x80 | ||
} | ||
|
||
/* Provide imaginary (zero page) registers. */ | ||
__rc0 = 0x80; | ||
INCLUDE imag-regs.ld | ||
ASSERT(__rc31 == 0x9f, "Inconsistent zero page map.") | ||
|
||
REGION_ALIAS("c_writeable", pia_ram) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
; Copyright 2023 LLVM-MOS Project | ||
; Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
; See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
; information. | ||
|
||
.include "atari2600.inc" | ||
|
||
.align $10 | ||
.global _set_horiz_pos | ||
_set_horiz_pos: | ||
sec ; set carry flag | ||
sta WSYNC ; start a new line | ||
div15: | ||
sbc #15 ; subtract 15 | ||
bcs div15 ; branch until negative | ||
eor #7 ; calculate fine offset | ||
asl | ||
asl | ||
asl | ||
asl | ||
sta HMP0,x ; set fine offset | ||
sta RESP0,x ; fix coarse position | ||
rts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Copyright 2023 LLVM-MOS Project | ||
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions. | ||
// See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license | ||
// information. | ||
|
||
#ifndef _VCSLIB_H | ||
#define _VCSLIB_H | ||
|
||
#include <atari2600.h> | ||
#include <stdint.h> | ||
|
||
#if defined(__ATARI2600_MAPPER__) | ||
#include <mapper.h> | ||
#endif | ||
|
||
// Define data types for different data sizes and signedness | ||
|
||
typedef unsigned char byte; // 8-bit unsigned data type | ||
typedef signed char sbyte; // 8-bit signed data type | ||
typedef unsigned short word; // 16-bit unsigned data type | ||
|
||
// Atari 2600 kernel helpers, called in a sequence every frame | ||
|
||
void kernel_1(void); // before preframe | ||
void kernel_2(void); // before kernel | ||
void kernel_3(void); // after kernel | ||
void kernel_4(void); // after postframe | ||
|
||
// Function to set horizontal position of a game object. | ||
|
||
typedef enum { PLAYER_0=0, PLAYER_1, MISSILE_0, MISSILE_1, BALL } TIAObject; | ||
|
||
// A = X coordinate | ||
// X = object index | ||
__attribute__((leaf)) void _set_horiz_pos(byte xpos, byte objindex); | ||
|
||
// swap order of call | ||
#define set_horiz_pos(objindex,xpos) _set_horiz_pos(xpos,objindex) | ||
|
||
// Waits for next scanline start | ||
#define do_wsync() \ | ||
__attribute__((leaf)) asm volatile("sta $42 /* WSYNC */"); | ||
|
||
// Applies horizontal motion to sprite(s) after set_horiz_pos() | ||
#define apply_hmove() \ | ||
__attribute__((leaf)) asm volatile("sta $42 /* WSYNC */" "\n" "sta $6a /* HMOVE */"); | ||
|
||
// Macros | ||
|
||
#define P0 0 | ||
#define P1 1 | ||
#define M0 2 | ||
#define M1 3 | ||
#define BALL 4 | ||
|
||
#define SW_RESET() ((RIOT.swchb & RESET_MASK) == 0) | ||
#define SW_SELECT() ((RIOT.swchb & SELECT_MASK) == 0) | ||
#define SW_COLOR() ((RIOT.swchb & BW_MASK) != 0) | ||
#define SW_P0_PRO() ((RIOT.swchb & P0_DIFF_MASK) != 0) | ||
#define SW_P1_PRO() ((RIOT.swchb & P1_DIFF_MASK) != 0) | ||
|
||
#define JOY_UP(plyr) (!(RIOT.swcha & ((plyr) ? 0x1 : ~MOVE_UP))) | ||
#define JOY_DOWN(plyr) (!(RIOT.swcha & ((plyr) ? 0x2 : ~MOVE_DOWN))) | ||
#define JOY_LEFT(plyr) (!(RIOT.swcha & ((plyr) ? 0x4 : ~MOVE_LEFT))) | ||
#define JOY_RIGHT(plyr) (!(RIOT.swcha & ((plyr) ? 0x8 : ~MOVE_RIGHT))) | ||
#define JOY_FIRE(plyr) !(((plyr) ? TIA.inpt5 : TIA.inpt4) & 0x80) | ||
|
||
// make color greyscale if black and white switch is set | ||
#define COLOR_CONV(color) (SW_COLOR() ? color : color & 0x0f) | ||
|
||
// macros for setting PIA timers | ||
#define _CYCLES(lines) (((lines) * 76) - 13) | ||
#define _TIM64(cycles) (((cycles) >> 6) - (((cycles) & 63) < 12)) | ||
#define _T1024(cycles) ((cycles) >> 10) | ||
|
||
#ifdef PAL | ||
#define VBLANK_TIM64 _TIM64(_CYCLES(45)) | ||
#define KERNAL_T1024 _T1024(_CYCLES(250)) | ||
#define OVERSCAN_TIM64 _TIM64(_CYCLES(36)) | ||
#else | ||
#define VBLANK_TIM64 _TIM64(_CYCLES(37)) | ||
#define KERNAL_TIM64 _TIM64(_CYCLES(194)) | ||
#define OVERSCAN_TIM64 _TIM64(_CYCLES(32)) | ||
#endif | ||
|
||
#endif |