Skip to content

Commit 1a9438d

Browse files
committed
Allows setting the segment for the DATA statements.
This allows placing DATA in ROM in the Atari Cartridge and Atari 5200 targets, minimizing RAM usage.
1 parent 5897a18 commit 1a9438d

9 files changed

Lines changed: 101 additions & 5 deletions

File tree

manual.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,22 @@ General Statements
16441644
the same folder than the current
16451645
basic source.
16461646

1647+
*Storing data into ROM*
1648+
1649+
In addition to the above, the cross
1650+
compiler allows to specify that the
1651+
data should be stored in ROM, instead
1652+
of the default in RAM. This means
1653+
that the data can't be modified in
1654+
targets that use ROM (cartridges),
1655+
but will lower RAM usage.
1656+
1657+
To specify this, simply add the `ROM`
1658+
word after the type:
1659+
1660+
DATA img() ROM 1234,5678
1661+
DATA pos() BYTE ROM 1,2,3,4
1662+
16471663

16481664
**Decrements variable by 1**
16491665
**DEC _var_ / DE.**

src/compiler/compile.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,11 @@ int compiler::compile_file(std::string iname, std::string output_filename,
299299
std::cerr << "internal error: unknown label type '" << name << "'\n";
300300
else
301301
{
302-
if(it->second.is_proc())
302+
auto lbl = it->second;
303+
auto seg = lbl.get_segment();
304+
if(seg.size())
305+
ofile << "\t.segment \"" << seg << "\"\n";
306+
else if(lbl.is_proc())
303307
ofile << "\t.segment \"" << segname << "\"\n";
304308
else
305309
ofile << "\t.segment \"DATA\"\n";

src/compiler/parser-actions.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,32 @@ static bool SMB_E_LABEL_SET_TYPE(parse &s)
675675
return true;
676676
}
677677

678+
static bool SMB_E_DATA_SET_ROM_SEG(parse &s)
679+
{
680+
s.debug("E_DATA_SET_ROM_SEG");
681+
s.skipws();
682+
s.labels[s.last_label].set_segment("CODE");
683+
return true;
684+
}
685+
686+
static bool SMB_E_DATA_SET_SEGMENT(parse &s)
687+
{
688+
s.debug("E_DATA_SET_SEGMENT");
689+
s.skipws();
690+
// Get segment name
691+
std::string seg;
692+
if(s.get_ident(seg))
693+
{
694+
s.labels[s.last_label].set_segment(seg);
695+
return true;
696+
}
697+
else
698+
{
699+
s.error("segment name");
700+
return false;
701+
}
702+
}
703+
678704
// Reads a DATA array from a file
679705
static bool SMB_E_DATA_FILE(parse &s)
680706
{
@@ -714,6 +740,8 @@ static std::map<std::string, bool (*)(parse &s)> actions = {
714740
{"E_LABEL_CREATE", SMB_E_LABEL_CREATE},
715741
{"E_LABEL_DEF", SMB_E_LABEL_DEF},
716742
{"E_LABEL_SET_TYPE", SMB_E_LABEL_SET_TYPE},
743+
{"E_DATA_SET_ROM_SEG", SMB_E_DATA_SET_ROM_SEG},
744+
{"E_DATA_SET_SEGMENT", SMB_E_DATA_SET_SEGMENT},
717745
{"E_NUMBER_BYTE", SMB_E_NUMBER_BYTE},
718746
{"E_NUMBER_FP", SMB_E_NUMBER_FP},
719747
{"E_NUMBER_WORD", SMB_E_NUMBER_WORD},

src/compiler/vartype.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ void labelType::set_type(std::string str)
121121
throw std::runtime_error("invalid label type " + str);
122122
}
123123

124+
void labelType::set_segment(std::string str)
125+
{
126+
segment = str;
127+
}
128+
129+
std::string labelType::get_segment()
130+
{
131+
return segment;
132+
}
133+
124134
bool labelType::is_defined()
125135
{
126136
return type >= 64;

src/compiler/vartype.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ class labelType
5656
int num_params();
5757
void define();
5858
void set_type(std::string);
59+
void set_segment(std::string);
60+
std::string get_segment();
5961
bool operator!=(const labelType &l) const { return type != l.type; }
6062

6163
private:
64+
std::string segment;
6265
int type;
6366
};

src/syntax/basic.syn

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,13 @@ DATA_BYTES: data byte
445445
DATA_BYTE "," DATA_BYTES
446446
DATA_BYTE
447447

448+
# Used in the extended compiler, set's the segment of the label
449+
DATA_EXT_TYPE: extended data type
450+
pass
451+
448452
DATA_TYPE: data type
449-
TYPE_BYTE EQUAL E_LABEL_SET_TYPE DATA_BYTES
450-
TYPE_WORD EQUAL E_LABEL_SET_TYPE E_NUMBER_WORD DATA_WORDS
453+
TYPE_BYTE DATA_EXT_TYPE EQUAL E_LABEL_SET_TYPE DATA_BYTES
454+
TYPE_WORD DATA_EXT_TYPE EQUAL E_LABEL_SET_TYPE E_NUMBER_WORD DATA_WORDS
451455

452456
DATA_END:
453457
","

src/syntax/extended.syn

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,25 @@
2020

2121
EXTERN {
2222
E_DATA_FILE
23+
E_DATA_SET_ROM_SEG
24+
E_DATA_SET_SEGMENT
2325
E_COUNT_PARAM
2426
E_PROC_CHECK
2527
}
2628

2729
# Reda DATA statements from a file:
30+
DATA_FILE:
31+
"File" DATA_EXT_TYPE E_LABEL_SET_TYPE "\"" E_DATA_FILE
32+
33+
# Expands data types with "file" data
2834
DATA_TYPE:
29-
TYPE_BYTE "File" E_LABEL_SET_TYPE "\"" E_DATA_FILE
30-
TYPE_WORD "File" E_LABEL_SET_TYPE "\"" E_DATA_FILE
35+
TYPE_BYTE DATA_FILE
36+
TYPE_WORD DATA_FILE
37+
38+
# Reda DATA statements location (ROM or RAM):
39+
DATA_EXT_TYPE:
40+
"ROM" E_DATA_SET_ROM_SEG
41+
"[" E_DATA_SET_SEGMENT "]"
3142

3243
# In the cross-compiler, we count parameters to detect program errors:
3344
# Count parameters before EXEC

testsuite/tests/data-rom.bas

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
' Test DATA in ROM segments
2+
? "Start"
3+
4+
DATA rfb() ROM = 1,2,3,4,5
5+
DATA rfw() BYTE ROM = 1,2,3,4,5,6
6+
DATA dfw() BYTE = 7, 8, 9
7+
DATA other() [RUNTIME] = 128, 129, 130, 131
8+
9+
? rfb(0), rfb(1)
10+
? rfw(0), other(1)
11+
' Check that the DATA addresses are in different segments
12+
? ABS(ADR(dfw) - ADR(rfw)) > 10
13+

testsuite/tests/data-rom.chk

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Name: Test DATA ROM
2+
Test: run-int
3+
Output:
4+
Start
5+
1 2
6+
1 129
7+
1

0 commit comments

Comments
 (0)