mirror of
https://github.com/fadden/6502bench.git
synced 2025-01-27 01:29:48 +00:00
External symbol I/O direction and address mask, part 3 (of 3)
Added regression tests. Improved error messages. Updated documentation.
This commit is contained in:
parent
4d8ee3fd07
commit
bd11aea4a4
@ -144,9 +144,9 @@ namespace SourceGen {
|
||||
if (line.StartsWith(TAG_CMD)) {
|
||||
tag = ParseTag(line);
|
||||
} else if (line.StartsWith(MULTI_MASK_CMD)) {
|
||||
if (!ParseMask(line, out multiMask)) {
|
||||
if (!ParseMask(line, out multiMask, out string badMaskMsg)) {
|
||||
report.Add(lineNum, FileLoadItem.NO_COLUMN, FileLoadItem.Type.Warning,
|
||||
Res.Strings.ERR_INVALID_MASK);
|
||||
badMaskMsg);
|
||||
}
|
||||
//Debug.WriteLine("Mask is now " + mask.ToString("x6"));
|
||||
} else {
|
||||
@ -268,12 +268,15 @@ namespace SourceGen {
|
||||
/// <param name="line">Line to parse.</param>
|
||||
/// <param name="multiMask">Parsed mask value, or null if the line was empty.</param>
|
||||
/// <returns>True if the mask was parsed successfully.</returns>
|
||||
private bool ParseMask(string line, out DefSymbol.MultiAddressMask multiMask) {
|
||||
private bool ParseMask(string line, out DefSymbol.MultiAddressMask multiMask,
|
||||
out string badMaskMsg) {
|
||||
Debug.Assert(line.StartsWith(MULTI_MASK_CMD));
|
||||
const int MIN = 0;
|
||||
const int MAX = 0x00ffff;
|
||||
|
||||
badMaskMsg = Res.Strings.ERR_INVALID_MULTI_MASK;
|
||||
multiMask = null;
|
||||
|
||||
string maskStr = line.Substring(MULTI_MASK_CMD.Length).Trim();
|
||||
if (string.IsNullOrEmpty(maskStr)) {
|
||||
// empty line, disable mask
|
||||
@ -293,16 +296,34 @@ namespace SourceGen {
|
||||
if (!Asm65.Number.TryParseInt(cmpMaskStr, out cmpMask, out ignoredBase) ||
|
||||
cmpMask < MIN || cmpMask > MAX) {
|
||||
Debug.WriteLine("Bad cmpMask: " + cmpMaskStr);
|
||||
badMaskMsg = Res.Strings.ERR_INVALID_COMPARE_MASK;
|
||||
return false;
|
||||
}
|
||||
if (!Asm65.Number.TryParseInt(cmpValueStr, out cmpValue, out ignoredBase) ||
|
||||
cmpValue < MIN || cmpValue > MAX) {
|
||||
Debug.WriteLine("Bad cmpValue: " + cmpValueStr);
|
||||
badMaskMsg = Res.Strings.ERR_INVALID_COMPARE_VALUE;
|
||||
return false;
|
||||
}
|
||||
if (!Asm65.Number.TryParseInt(addrMaskStr, out addrMask, out ignoredBase) ||
|
||||
addrMask < MIN || addrMask > MAX) {
|
||||
Debug.WriteLine("Bad addrMask: " + addrMaskStr);
|
||||
badMaskMsg = Res.Strings.ERR_INVALID_ADDRESS_MASK;
|
||||
return false;
|
||||
}
|
||||
|
||||
// The two masks should not overlap: one represents bits that must be in a
|
||||
// specific state for a match to exist, the other indicates which bits are used
|
||||
// to select a specific register. This should be a warning.
|
||||
if ((cmpMask & ~addrMask) != cmpMask) {
|
||||
Debug.WriteLine("Warning: cmpMask/addrMask overlap");
|
||||
badMaskMsg = Res.Strings.ERR_INVALID_CMP_ADDR_OVERLAP;
|
||||
return false;
|
||||
}
|
||||
// If cmpValue has bits set that aren't in cmpMask, we will never find a match.
|
||||
if ((cmpValue & ~cmpMask) != 0) {
|
||||
Debug.WriteLine("cmpValue has unexpected bits set");
|
||||
badMaskMsg = Res.Strings.ERR_INVALID_CMP_EXTRA_BITS;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -61,9 +61,14 @@ limitations under the License.
|
||||
<system:String x:Key="str_ErrFileNotFoundFmt">File not found: {0}</system:String>
|
||||
<system:String x:Key="str_ErrFileReadFailedFmt">Failed reading {0}: {1}.</system:String>
|
||||
<system:String x:Key="str_ErrFileReadOnlyFmt">Cannot write to read-only file {0}.</system:String>
|
||||
<system:String x:Key="str_ErrInvalidAddressMask">Invalid MULTI_MASK AddressMask</system:String>
|
||||
<system:String x:Key="str_ErrInvalidCmpAddrOverlap">MULTI_MASK CompareMask and AddressMask overlap</system:String>
|
||||
<system:String x:Key="str_ErrInvalidCmpExtraBits">MULTI_MASK CompareValue has bits not in CompareMask</system:String>
|
||||
<system:String x:Key="str_ErrInvalidCompareMask">Invalid MULTI_MASK CompareMask</system:String>
|
||||
<system:String x:Key="str_ErrInvalidCompareValue">Invalid MULTI_MASK CompareValue</system:String>
|
||||
<system:String x:Key="str_ErrInvalidIntValue">Could not convert value to integer</system:String>
|
||||
<system:String x:Key="str_ErrInvalidKeyValue">Key value is out of range</system:String>
|
||||
<system:String x:Key="str_ErrInvalidMask">Invalid mask value</system:String>
|
||||
<system:String x:Key="str_ErrInvalidMultiMask">Invalid MULTI_MASK line</system:String>
|
||||
<system:String x:Key="str_ErrInvalidWidth">Invalid width value</system:String>
|
||||
<system:String x:Key="str_ErrInvalidSysdef" xml:space="preserve"> - INVALID DEFINITION</system:String>
|
||||
<system:String x:Key="str_ErrLoadConfigFile">Unable to load config file</system:String>
|
||||
@ -72,7 +77,7 @@ limitations under the License.
|
||||
<system:String x:Key="str_ErrProjectLoadFail">Unable to load project file</system:String>
|
||||
<system:String x:Key="str_ErrProjectSaveFail">Unable to save project file</system:String>
|
||||
<system:String x:Key="str_ErrTooLargeForPreview">[File was too large for preview window]</system:String>
|
||||
<system:String x:Key="str_ErrValueIncompatibleWithMask">Symbol value is incompatible with multi-mask</system:String>
|
||||
<system:String x:Key="str_ErrValueIncompatibleWithMask">Symbol value is incompatible with current multi-mask</system:String>
|
||||
<system:String x:Key="str_ExternalFileBadDirFmt" xml:space="preserve">Symbol files and extension scripts must live in the application runtime directory ({0}) or project directory ({1}).

File {2} lives elsewhere.</system:String>
|
||||
<system:String x:Key="str_ExternalFileBadDirCaption">File Not In Runtime Directory</system:String>
|
||||
<system:String x:Key="str_FileFilterAll">All files (*.*)|*.*</system:String>
|
||||
|
@ -103,12 +103,22 @@ namespace SourceGen.Res {
|
||||
(string)Application.Current.FindResource("str_ErrFileReadFailedFmt");
|
||||
public static string ERR_FILE_READ_ONLY_FMT =
|
||||
(string)Application.Current.FindResource("str_ErrFileReadOnlyFmt");
|
||||
public static string ERR_INVALID_ADDRESS_MASK =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidAddressMask");
|
||||
public static string ERR_INVALID_CMP_ADDR_OVERLAP =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidCmpAddrOverlap");
|
||||
public static string ERR_INVALID_CMP_EXTRA_BITS =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidCmpExtraBits");
|
||||
public static string ERR_INVALID_COMPARE_MASK =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidCompareMask");
|
||||
public static string ERR_INVALID_COMPARE_VALUE =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidCompareValue");
|
||||
public static string ERR_INVALID_INT_VALUE =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidIntValue");
|
||||
public static string ERR_INVALID_KEY_VALUE =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidKeyValue");
|
||||
public static string ERR_INVALID_MASK =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidMask");
|
||||
public static string ERR_INVALID_MULTI_MASK =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidMultiMask");
|
||||
public static string ERR_INVALID_WIDTH =
|
||||
(string)Application.Current.FindResource("str_ErrInvalidWidth");
|
||||
public static string ERR_INVALID_SYSDEF =
|
||||
|
@ -27,12 +27,14 @@ matters.</p>
|
||||
|
||||
<p>Platform symbol files consist of comments, commands, and symbols.
|
||||
Blank lines, and lines that begin with a semicolon (';'), are ignored. Lines
|
||||
that begin with an asterisk ('*') are commands. Two are currently
|
||||
that begin with an asterisk ('*') are commands. Three are currently
|
||||
defined:</p>
|
||||
<ul>
|
||||
<li><code>*SYNOPSIS</code> - a short summary of the file contents.</li>
|
||||
<li><code>*TAG</code> - a tag string to apply to all symbols that follow
|
||||
in this file.</li>
|
||||
<li><code>*MULTI_MASK</code> - specify a mask for symbols that appear
|
||||
at multiple addresses.</li>
|
||||
</ul>
|
||||
|
||||
<p>Tags can be used by extension scripts to identify a subset of symbols.
|
||||
@ -44,30 +46,70 @@ are treated as untagged.</p>
|
||||
|
||||
<p>All other lines are symbols, which have the form:</p>
|
||||
<pre>
|
||||
label {=|@} value [width] [;comment]
|
||||
LABEL {=|@|<|>} VALUE [WIDTH] [;COMMENT]
|
||||
</pre>
|
||||
|
||||
<p>Labels must be at least two characters long, begin with a letter or
|
||||
<p>The LABEL must be at least two characters long, begin with a letter or
|
||||
underscore, and consist entirely of alphanumeric ASCII characters
|
||||
(A-Z, a-z, 0-9) and the underscore ('_'). (This is the same format
|
||||
required for line labels in SourceGen.)</p>
|
||||
<p>Use '@' for address values, and '=' for constants. The only important
|
||||
difference between them is that address values will be applied automatically
|
||||
to operands that reference addresses outside the scope of the file.
|
||||
Constants are never applied automatically.</p>
|
||||
<p>The next token can be one of:</p>
|
||||
<ul>
|
||||
<li>@: general addresses</li>
|
||||
<li><: read-only addresses</li>
|
||||
<li>>: write-only addresses</li>
|
||||
<li>=: constants</li>
|
||||
</ul>
|
||||
<p>If an instruction references an address, and that address is outside
|
||||
the bounds of the file, the list of address symbols (i.e. everything
|
||||
that's not a constant) will be scanned for a match.
|
||||
If found, the symbol is applied automatically. You normally want to
|
||||
use '@', but can use '<' and '>' for memory-mapped I/O locations
|
||||
that have different behavior depending on whether they are read or
|
||||
written.</p>
|
||||
|
||||
<p>The value is a number in decimal, hexadecimal (with a leading '$'), or
|
||||
<p>The VALUE is a number in decimal, hexadecimal (with a leading '$'), or
|
||||
binary (with a leading '%'). The numeric base will be recorded and used when
|
||||
formatting the symbol in generated output, so use whichever form is most
|
||||
appropriate. Values are unsigned 24-bit numbers.</p>
|
||||
|
||||
<p>The width is optional, and ignored for constants. It must be a
|
||||
<p>The WIDTH is optional, and ignored for constants. It must be a
|
||||
decimal or hexadecimal value between 1 and 65536, inclusive. If omitted,
|
||||
the default width is 1.</p>
|
||||
|
||||
<p>The comment is optional. If present, it will be saved and used as the
|
||||
<p>The COMMENT is optional. If present, it will be saved and used as the
|
||||
end-of-line comment on the .EQ directive if the symbol is used.</p>
|
||||
|
||||
<h4>Using MULTI_MASK</h4>
|
||||
|
||||
<p>The multi-address mask is used for systems like the Atari 2600, where
|
||||
RAM, ROM, and I/O registers appear at multiple addresses. The hardware
|
||||
looks for certain address lines to be set or clear, and if the pattern
|
||||
matches, another set of bits is examined to determine which register or
|
||||
RAM address is being accessed.</p>
|
||||
|
||||
<p>For example, suppose the access pattern for a set of registers is
|
||||
<code>???0 ??1? 1??x xxxx</code> (where '?' can be any value, 0/1 must
|
||||
be that value, and 'x' means the bit is used to determine the register).
|
||||
So any value between $0280-029f matches, as does $23c0-23df, but
|
||||
$0480 and $1280 don't. The register number is found in the low five bits.</p>
|
||||
<p>The corresponding MULTI_MASK line, with values specifed in binary,
|
||||
would be:</p>
|
||||
<pre>*MULTI_MASK %0001001010000000 %0000001010000000 %0000000000011111</pre>
|
||||
<p>The values are CompareMask, CompareValue, and AddressMask. To
|
||||
determine if an address is in the register set, we check to see if
|
||||
<code>(address & CompareMask) == CompareValue</code>. If so, we can
|
||||
extract the register number with <code>(address & AddressMask)</code>.</p>
|
||||
|
||||
<p>We don't want to have a huge collection of equates at the top of the
|
||||
file, so whatever value is used in the symbol declaration is considered
|
||||
the "canonical" value. All other matching values are expressed as an
|
||||
offset.</p>
|
||||
<p>All values must fall between 0 and $00FFFFFF. The set bits in
|
||||
CompareMask and AddressMask must not overlap, and CompareValue must not
|
||||
have any bits set that aren't also set in CompareMask.</p>
|
||||
|
||||
|
||||
<h3>Creating a Project-Specific Symbol File</h3>
|
||||
|
||||
<p>To create a platform symbol file for your project, just create a new
|
||||
|
@ -295,6 +295,11 @@ to the note in the code list and in the "Notes" window.</p>
|
||||
|
||||
<h2><a name="project-symbol">Edit Project Symbol</a></h2>
|
||||
<p>This is used to edit the properties of a project symbol.</p>
|
||||
<p>Symbols marked as "address" will be applied automatically when an
|
||||
operand references an address outside the scope of the data file. They
|
||||
will not be applied to addresses inside the data file. Symbols
|
||||
marked as "constant" are not applied automatically, and must be
|
||||
explicitly specified as an operand.</p>
|
||||
<p>The label must meet the criteria for symbols (see
|
||||
<a href="intro.html#about-symbols">All About Symbols</a>), and must
|
||||
not have the same name as another project symbol. It can overlap
|
||||
@ -302,19 +307,17 @@ with platform symbols and user labels.</p>
|
||||
<p>The value may be entered in decimal, hexadecimal, or binary. The numeric
|
||||
base you choose will be remembered, so that the value will be displayed
|
||||
the same way when used in a .EQ directive.</p>
|
||||
<p>You can optionally provide a width. For example, if the address is
|
||||
of a two-byte pointer or a 64-byte buffer, you would set the width field
|
||||
to cause all references to any location in that range to be set to the
|
||||
symbol. Widths may be entered in hex or decimal. If the field
|
||||
is left blank, a width of 1 is assumed. Overlapping symbols are allowed.
|
||||
The width is ignored for constants.</p>
|
||||
<p>You can optionally provide a width for address symbols. For example,
|
||||
if the address is of a two-byte pointer or a 64-byte buffer, you would
|
||||
set the width field to cause all references to any location in that range
|
||||
to be set to the symbol. Widths may be entered in hex or decimal. If
|
||||
the field is left blank, a width of 1 is assumed. Overlapping symbols
|
||||
are allowed. The width is ignored for constants.</p>
|
||||
<p>If you enter a comment, it will be placed at the end of the line of
|
||||
the .EQ directive.</p>
|
||||
<p>Symbols marked as "address" will be applied automatically when an
|
||||
operand references an address outside the scope of the data file. They
|
||||
will not be applied to addresses inside the data file. Symbols
|
||||
marked as "constant" are not applied automatically, and must be
|
||||
explicitly specified as an operand.</p>
|
||||
<p>For address symbols that represent a memory-mapped I/O location, it
|
||||
can be useful to have different symbols for reads and writes. Use
|
||||
the Read/Write checkboxes to specify the desired behavior.</p>
|
||||
|
||||
|
||||
<h2><a name="lvtable">Create/Edit Local Variable Table</a></h2>
|
||||
|
@ -144,6 +144,15 @@ instructions. If you don't know what state the flags are in, you can't
|
||||
know whether <code>LDA #value</code> is two bytes or three, and the
|
||||
disassembly of the instruction stream will come out wrong.</p>
|
||||
|
||||
<p>Some addresses correspond to memory-mapped I/O, rather than RAM or ROM.
|
||||
Accessing the address can have side effects, like changing between text
|
||||
and graphics modes. Sometimes reading and writing have different effects.
|
||||
For example, on later models of the Apple II, reading from
|
||||
$C000 returns the most recently hit key, while writing to $C000 disables
|
||||
80 columns.</p>
|
||||
<p>On a few systems, such as the Atari 2600, RAM, ROM, and registers can
|
||||
appear at multiple locations, "mirrored" across the address space.</p>
|
||||
|
||||
<h3><a name="charenc">Character Encoding</a></h3>
|
||||
|
||||
<p>The American Standard Code for Information Interchange (ASCII) was
|
||||
@ -459,6 +468,12 @@ a 4-byte symbol in the middle of a 256-byte symbol, the 4-byte symbol will
|
||||
be visible because the start point is closer to the addresses it covers
|
||||
than the start of the 256-byte range.</p>
|
||||
|
||||
<p>Platform symbols can be designated for reading, writing, or both.
|
||||
Normally you'd want both, but if an address is a memory-mapped I/O
|
||||
location that has different behavior for reads and writes, you'd want
|
||||
to define two different symbols, and have the correct one applied
|
||||
based on the access type.</p>
|
||||
|
||||
<p><b>Project symbols</b> behave like platform symbols, but they are
|
||||
defined in the project file itself. The editor will prevent you from
|
||||
creating two symbols with the same name. If two symbols have the same
|
||||
|
Binary file not shown.
@ -53,3 +53,53 @@ BankWrap @ $fff0 $20
|
||||
|
||||
; Width specifiers on constants should be ignored.
|
||||
FatConst = $4000 8
|
||||
|
||||
; I/O direction test
|
||||
ReadOnly < $5000 2 ;R
|
||||
WriteOnly > $5001 2 ;W
|
||||
|
||||
|
||||
;
|
||||
; MULTI_MASK tests.
|
||||
;
|
||||
; The behavior of overlapping masks is not currently defined, so we don't test
|
||||
; that scenario.
|
||||
;
|
||||
|
||||
; overlaps with multi range in second symbol file
|
||||
AlsoMoreMultiZero @ $c110 ;winner
|
||||
|
||||
*MULTI_MASK $ff00 $c000 $000f ;$c000-c00f, repeats $c010-c01f, etc. to $c0ff
|
||||
MultiZero @ $c000
|
||||
AlsoMultiZero @ $c010 ;wins (alphabetically)
|
||||
MultiOne @ $c021
|
||||
; Test: C000, C010, C020, C0F0
|
||||
; Test: C001, C011, C021
|
||||
; Test: C002, C012, C022
|
||||
|
||||
MultiRead < $c004 3 ;$c004/5/6, read-only
|
||||
MultiWrite > $c005 3 ;$c005/6/7, write-only
|
||||
; Test: read C003 C004 C005 C006 C007
|
||||
; Test: write C004 C005 C006 C007 C008
|
||||
|
||||
|
||||
;
|
||||
; Invalid values. These cause a warning at load time, and the symbol will
|
||||
; be ignored.
|
||||
;
|
||||
|
||||
; Not in range.
|
||||
MultiInvalid @ $1234
|
||||
|
||||
; Not all covered addresses are inside the masked range.
|
||||
TooLong @ $c0f8 $a
|
||||
|
||||
;
|
||||
; Badly-formed MULTI_MASK entries. These cause a warning at load time, and
|
||||
; the directive will be ignored.
|
||||
;
|
||||
*MULTI_MASK $fffff $ffff $ffff ;range
|
||||
*MULTI_MASK $ffff $fffff $ffff ;range
|
||||
*MULTI_MASK $ffff $ffff $fffff ;range
|
||||
|
||||
*MULTI_MASK
|
||||
|
@ -11,3 +11,31 @@ SameValB_A @ $2110
|
||||
SameValC_B @ $2120
|
||||
|
||||
SepOver1 @ $3100 4 ;$3100-3103, inclusive
|
||||
|
||||
; I/O direction test -- replace part of the write-only range
|
||||
WriteOnly2 > $5002
|
||||
|
||||
;
|
||||
; MULTI_MASK tests.
|
||||
;
|
||||
|
||||
; This overlaps with an earlier declaration, but *only* for address $c010,
|
||||
; not for all occurrences.
|
||||
NonMultiOver @ $c010 ;winner
|
||||
|
||||
|
||||
*MULTI_MASK $ff00 $c100 $000f ;$c100-c10f, repeats $c110-c11f, etc. to $c1ff
|
||||
|
||||
; Symbol in previous file overlaps with this.
|
||||
; Test: C100, C110, C120
|
||||
MoreMultiZero @ $c100
|
||||
|
||||
|
||||
;
|
||||
; More erroneous masks. These are in a separate file mostly to test how
|
||||
; errors in multiple files are reported.
|
||||
;
|
||||
*MULTI_MASK $fff0 $000f $000f ;CompareValue has bits not in CompareMask
|
||||
*MULTI_MASK $fff0 $fff0 $00ff ;AddressMask and CompareMask overlap
|
||||
|
||||
*MULTI_MASK
|
||||
|
@ -1,6 +1,6 @@
|
||||
### 6502bench SourceGen dis65 v1.0 ###
|
||||
{
|
||||
"_ContentVersion":2,"FileDataLength":222,"FileDataCrc32":-233099313,"ProjectProps":{
|
||||
"_ContentVersion":2,"FileDataLength":329,"FileDataCrc32":-573118187,"ProjectProps":{
|
||||
"CpuName":"6502","IncludeUndocumentedInstr":false,"EntryFlags":32702671,"AutoLabelStyle":"Simple","AnalysisParams":{
|
||||
"AnalyzeUncategorizedData":true,"DefaultTextScanMode":"LowHighAscii","MinCharsForString":4,"SeekNearbyTargets":true,"SmartPlpHandling":true},
|
||||
"PlatformSymbolFileIdentifiers":["PROJ:2021-external-symbols-1.sym65","PROJ:2021-external-symbols-2.sym65","PROJ:2021-external-symbols-3.sym65"],"ExtensionScriptFileIdentifiers":[],"ProjectSyms":{
|
||||
|
@ -18,15 +18,25 @@ Over2a = $3006 ;$3006
|
||||
Over3 = $3006 ;$3006-300c
|
||||
SepOver1 = $3100 ;$3100-3103, inclusive
|
||||
SepOver2 = $3102 ;$3102-3105, inclusive
|
||||
ReadOnly = $5000 ;R
|
||||
WriteOnly = $5001 ;W
|
||||
WriteOnly2 = $5002
|
||||
MultiRead = $c004 ;$c004/5/6, read-only
|
||||
MultiWrite = $c005 ;$c005/6/7, write-only
|
||||
AlsoMultiZero = $c010 ;wins (alphabetically)
|
||||
NonMultiOver = $c010 ;winner
|
||||
MultiOne = $c021
|
||||
MoreMultiZero = $c100
|
||||
AlsoMoreMultiZero = $c110 ;winner
|
||||
BankWrap = $fff0
|
||||
|
||||
* = $1000
|
||||
L1000 lda CodeWrap+255
|
||||
ldx L1000
|
||||
ldy L1000+1
|
||||
lda L10DD
|
||||
lda CodeWrap+478
|
||||
lda CodeWrap+485
|
||||
lda L1148
|
||||
lda CodeWrap+585
|
||||
lda CodeWrap+592
|
||||
nop
|
||||
lda $1ffe
|
||||
lda SameName1-1
|
||||
@ -103,5 +113,46 @@ LocalVar .var $41
|
||||
lda $4001
|
||||
lda BankWrap+8
|
||||
lda <BankWrap-232
|
||||
L10DD rts
|
||||
nop
|
||||
lda ReadOnly
|
||||
lda ReadOnly+1
|
||||
ldx $5002
|
||||
ldy $5003
|
||||
sta WriteOnly-1
|
||||
sta WriteOnly
|
||||
stx WriteOnly2
|
||||
sty $5003
|
||||
nop
|
||||
bit AlsoMultiZero-16
|
||||
bit NonMultiOver
|
||||
bit AlsoMultiZero+16
|
||||
bit AlsoMultiZero+224
|
||||
nop
|
||||
bit MultiOne-32
|
||||
bit MultiOne-16
|
||||
bit MultiOne
|
||||
nop
|
||||
bit $c002
|
||||
bit $c012
|
||||
bit $c022
|
||||
nop
|
||||
lda MultiRead-1
|
||||
lda MultiRead
|
||||
lda MultiRead+1
|
||||
lda MultiRead+2
|
||||
lda $c007
|
||||
sta MultiWrite-1
|
||||
sta MultiWrite
|
||||
sta MultiWrite+1
|
||||
sta MultiWrite+2
|
||||
sta $c008
|
||||
nop
|
||||
jsr MultiRead+1
|
||||
nop
|
||||
bit MoreMultiZero
|
||||
bit AlsoMoreMultiZero
|
||||
bit MoreMultiZero+32
|
||||
bit MoreMultiZero+240
|
||||
nop
|
||||
L1148 rts
|
||||
|
||||
|
@ -17,15 +17,25 @@ Over2a equ $3006 ;$3006
|
||||
Over3 equ $3006 ;$3006-300c
|
||||
SepOver1 equ $3100 ;$3100-3103, inclusive
|
||||
SepOver2 equ $3102 ;$3102-3105, inclusive
|
||||
ReadOnly equ $5000 ;R
|
||||
WriteOnly equ $5001 ;W
|
||||
WriteOnly2 equ $5002
|
||||
MultiRead equ $c004 ;$c004/5/6, read-only
|
||||
MultiWrite equ $c005 ;$c005/6/7, write-only
|
||||
AlsoMultiZero equ $c010 ;wins (alphabetically)
|
||||
NonMultiOver equ $c010 ;winner
|
||||
MultiOne equ $c021
|
||||
MoreMultiZero equ $c100
|
||||
AlsoMoreMultiZero equ $c110 ;winner
|
||||
BankWrap equ $fff0
|
||||
|
||||
org $1000
|
||||
L1000 lda CodeWrap+255
|
||||
ldx L1000
|
||||
ldy L1000+1
|
||||
lda L10DD
|
||||
lda CodeWrap+478
|
||||
lda CodeWrap+485
|
||||
lda L1148
|
||||
lda CodeWrap+585
|
||||
lda CodeWrap+592
|
||||
nop
|
||||
lda $1ffe
|
||||
lda SameName1-1
|
||||
@ -102,5 +112,46 @@ L1000 lda CodeWrap+255
|
||||
lda $4001
|
||||
lda BankWrap+8
|
||||
lda <BankWrap-65512
|
||||
L10DD rts
|
||||
nop
|
||||
lda ReadOnly
|
||||
lda ReadOnly+1
|
||||
ldx $5002
|
||||
ldy $5003
|
||||
sta WriteOnly-1
|
||||
sta WriteOnly
|
||||
stx WriteOnly2
|
||||
sty $5003
|
||||
nop
|
||||
bit AlsoMultiZero-16
|
||||
bit NonMultiOver
|
||||
bit AlsoMultiZero+16
|
||||
bit AlsoMultiZero+224
|
||||
nop
|
||||
bit MultiOne-32
|
||||
bit MultiOne-16
|
||||
bit MultiOne
|
||||
nop
|
||||
bit $c002
|
||||
bit $c012
|
||||
bit $c022
|
||||
nop
|
||||
lda MultiRead-1
|
||||
lda MultiRead
|
||||
lda MultiRead+1
|
||||
lda MultiRead+2
|
||||
lda $c007
|
||||
sta MultiWrite-1
|
||||
sta MultiWrite
|
||||
sta MultiWrite+1
|
||||
sta MultiWrite+2
|
||||
sta $c008
|
||||
nop
|
||||
jsr MultiRead+1
|
||||
nop
|
||||
bit MoreMultiZero
|
||||
bit AlsoMoreMultiZero
|
||||
bit MoreMultiZero+32
|
||||
bit MoreMultiZero+240
|
||||
nop
|
||||
L1148 rts
|
||||
|
||||
|
@ -18,15 +18,25 @@ Over2a = $3006 ;$3006
|
||||
Over3 = $3006 ;$3006-300c
|
||||
SepOver1 = $3100 ;$3100-3103, inclusive
|
||||
SepOver2 = $3102 ;$3102-3105, inclusive
|
||||
ReadOnly = $5000 ;R
|
||||
WriteOnly = $5001 ;W
|
||||
WriteOnly2 = $5002
|
||||
MultiRead = $c004 ;$c004/5/6, read-only
|
||||
MultiWrite = $c005 ;$c005/6/7, write-only
|
||||
AlsoMultiZero = $c010 ;wins (alphabetically)
|
||||
NonMultiOver = $c010 ;winner
|
||||
MultiOne = $c021
|
||||
MoreMultiZero = $c100
|
||||
AlsoMoreMultiZero = $c110 ;winner
|
||||
BankWrap = $fff0
|
||||
|
||||
* = $1000
|
||||
L1000 lda CodeWrap+255
|
||||
ldx L1000
|
||||
ldy L1000+1
|
||||
lda L10DD
|
||||
lda CodeWrap+478
|
||||
lda CodeWrap+485
|
||||
lda L1148
|
||||
lda CodeWrap+585
|
||||
lda CodeWrap+592
|
||||
nop
|
||||
lda $1ffe
|
||||
lda SameName1-1
|
||||
@ -104,5 +114,46 @@ L1000 lda CodeWrap+255
|
||||
lda $4001
|
||||
lda BankWrap+8
|
||||
lda <BankWrap-232
|
||||
L10DD rts
|
||||
nop
|
||||
lda ReadOnly
|
||||
lda ReadOnly+1
|
||||
ldx $5002
|
||||
ldy $5003
|
||||
sta WriteOnly-1
|
||||
sta WriteOnly
|
||||
stx WriteOnly2
|
||||
sty $5003
|
||||
nop
|
||||
bit AlsoMultiZero-16
|
||||
bit NonMultiOver
|
||||
bit AlsoMultiZero+16
|
||||
bit AlsoMultiZero+224
|
||||
nop
|
||||
bit MultiOne-32
|
||||
bit MultiOne-16
|
||||
bit MultiOne
|
||||
nop
|
||||
bit $c002
|
||||
bit $c012
|
||||
bit $c022
|
||||
nop
|
||||
lda MultiRead-1
|
||||
lda MultiRead
|
||||
lda MultiRead+1
|
||||
lda MultiRead+2
|
||||
lda $c007
|
||||
sta MultiWrite-1
|
||||
sta MultiWrite
|
||||
sta MultiWrite+1
|
||||
sta MultiWrite+2
|
||||
sta $c008
|
||||
nop
|
||||
jsr MultiRead+1
|
||||
nop
|
||||
bit MoreMultiZero
|
||||
bit AlsoMoreMultiZero
|
||||
bit MoreMultiZero+32
|
||||
bit MoreMultiZero+240
|
||||
nop
|
||||
L1148 rts
|
||||
|
||||
|
@ -18,6 +18,16 @@ Over2a = $3006 ;$3006
|
||||
Over3 = $3006 ;$3006-300c
|
||||
SepOver1 = $3100 ;$3100-3103, inclusive
|
||||
SepOver2 = $3102 ;$3102-3105, inclusive
|
||||
ReadOnly = $5000 ;R
|
||||
WriteOnly = $5001 ;W
|
||||
WriteOnly2 = $5002
|
||||
MultiRead = $c004 ;$c004/5/6, read-only
|
||||
MultiWrite = $c005 ;$c005/6/7, write-only
|
||||
AlsoMultiZero = $c010 ;wins (alphabetically)
|
||||
NonMultiOver = $c010 ;winner
|
||||
MultiOne = $c021
|
||||
MoreMultiZero = $c100
|
||||
AlsoMoreMultiZero = $c110 ;winner
|
||||
BankWrap = $fff0
|
||||
|
||||
; .segment "SEG000"
|
||||
@ -25,9 +35,9 @@ BankWrap = $fff0
|
||||
L1000: lda CodeWrap+255
|
||||
ldx L1000
|
||||
ldy L1000+1
|
||||
lda L10DD
|
||||
lda CodeWrap+478
|
||||
lda CodeWrap+485
|
||||
lda L1148
|
||||
lda CodeWrap+585
|
||||
lda CodeWrap+592
|
||||
nop
|
||||
lda $1ffe
|
||||
lda SameName1-1
|
||||
@ -104,5 +114,46 @@ LocalVar .set $41
|
||||
lda $4001
|
||||
lda BankWrap+8
|
||||
lda <BankWrap-232
|
||||
L10DD: rts
|
||||
nop
|
||||
lda ReadOnly
|
||||
lda ReadOnly+1
|
||||
ldx $5002
|
||||
ldy $5003
|
||||
sta WriteOnly-1
|
||||
sta WriteOnly
|
||||
stx WriteOnly2
|
||||
sty $5003
|
||||
nop
|
||||
bit AlsoMultiZero-16
|
||||
bit NonMultiOver
|
||||
bit AlsoMultiZero+16
|
||||
bit AlsoMultiZero+224
|
||||
nop
|
||||
bit MultiOne-32
|
||||
bit MultiOne-16
|
||||
bit MultiOne
|
||||
nop
|
||||
bit $c002
|
||||
bit $c012
|
||||
bit $c022
|
||||
nop
|
||||
lda MultiRead-1
|
||||
lda MultiRead
|
||||
lda MultiRead+1
|
||||
lda MultiRead+2
|
||||
lda $c007
|
||||
sta MultiWrite-1
|
||||
sta MultiWrite
|
||||
sta MultiWrite+1
|
||||
sta MultiWrite+2
|
||||
sta $c008
|
||||
nop
|
||||
jsr MultiRead+1
|
||||
nop
|
||||
bit MoreMultiZero
|
||||
bit AlsoMoreMultiZero
|
||||
bit MoreMultiZero+32
|
||||
bit MoreMultiZero+240
|
||||
nop
|
||||
L1148: rts
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# 6502bench SourceGen generated linker script for 2021-external-symbols
|
||||
MEMORY {
|
||||
MAIN: file=%O, start=%S, size=65536;
|
||||
# MEM000: file=%O, start=$1000, size=222;
|
||||
# MEM000: file=%O, start=$1000, size=329;
|
||||
}
|
||||
SEGMENTS {
|
||||
CODE: load=MAIN, type=rw;
|
||||
|
@ -117,4 +117,53 @@ Start lda Start-1 ;CodeWrap+255
|
||||
lda $fff8 ;should be BankWrap+8
|
||||
lda $08 ;should be BankWrap+24 or <BankWrap-232
|
||||
|
||||
nop
|
||||
|
||||
; test I/O direction
|
||||
Dir equ $5000
|
||||
lda Dir
|
||||
lda Dir+1
|
||||
ldx Dir+2
|
||||
ldy Dir+3
|
||||
sta Dir
|
||||
sta Dir+1
|
||||
stx Dir+2
|
||||
sty Dir+3
|
||||
|
||||
nop
|
||||
|
||||
; test MULTI_MASK stuff
|
||||
bit $c000 ;should all be AlsoMultiZero
|
||||
bit $c010 ;<-- except this NonMultiOver
|
||||
bit $c020
|
||||
bit $c0f0
|
||||
nop
|
||||
bit $c001 ;should all be MultiOne
|
||||
bit $c011
|
||||
bit $c021
|
||||
nop
|
||||
bit $c002 ;should all be hex
|
||||
bit $c012
|
||||
bit $c022
|
||||
nop
|
||||
lda $c003
|
||||
lda $c004 ;MultiRead
|
||||
lda $c005 ;MultiRead+1
|
||||
lda $c006 ;MultiRead+2
|
||||
lda $c007
|
||||
sta $c004
|
||||
sta $c005 ;MultiWrite
|
||||
sta $c006 ;MultiWrite+1
|
||||
sta $c007 ;MultiWrite+2
|
||||
sta $c008
|
||||
nop
|
||||
jsr $c005 ;MultiRead+1
|
||||
nop
|
||||
bit $c100 ;should all be MoreMultiZero
|
||||
bit $c110 ;<-- except this AlsoMoreMultiZero
|
||||
bit $c120
|
||||
bit $c1f0
|
||||
|
||||
nop
|
||||
|
||||
END rts
|
||||
|
Loading…
x
Reference in New Issue
Block a user