It is included with PPMCK: http://zzo38computer.org/nes_program/ppmck.zip
Document of new features is file EXTENSION.TXT which is also copied here:
Code: Select all
This is document to describe unofficial extensions of MagicKit assembler.
Status ask expression:
?A bank base index
?B current bank
?C current section
?D data location counter
?E error counter
?L location counter
?M map data at current location
?P page
?Q pseudopage
?R RS counter
?S source line number
?X pass counter (0=first pass, 1=last pass)
?Z max bank used
Emulator I/O ($2000..$3FFF):
$2000 RW Bank number
$2001 R Error counter
$2002 RW Location counter low byte
$2003 RW Location counter high byte
$2004 RW Section (0=ZP, 1=BSS, 2=CODE, 3=DATA, 4=EMU)
$2005 W Send byte to output file
$2006 RW Bank output length low byte
$2007 RW Bank output length high byte
$2008 W Send contents of ROM bank to output file
$2009 R Maximum bank used
$200A RW Standard I/O
$200B RW Read next byte of data file (write anything for next file)
$200C RW Read to test EOF of data file, write to rewind file
$200D RW Address increment amount
$200E RW Low byte of address
$200F RW High byte of address
$2010 RW Data at address
$2011 RW Map data at address
$2012 RW Data at address, postincrement address
$2013 RW Map at address, postincrement address
$2014 W Write location counter in decimal to output file
$2015 W Compile a line of input in FIRST PASS mode
$2016 W Compile a line of input in LAST PASS mode
Instructions (NES/Famicom):
ANC AND accumulator by immediate and carry bit7
ALR AND accumulator by immediate and shift right
ARR AND accumulator by immediate and rotate right
AXS AND X register by accumulator and subtract immediate
DCP Decrement memory and compare with accumulator
HLT Jam the computer (until resets)
ISC Increment memory and subtract from accumulator
JAM Jam the computer (until resets)
KIL Jam the computer (until resets)
LAX Load into accumulator and into X register
RLA Left rotate memory and AND accumulator by memory
RRA Right rotate memory and add memory to accumulator
SAX Store value of accumulator AND X register
SLO Left shift memory and OR accumulator by memory
SRE Right shift memory and XOR accumulator by memory
Pseudos:
.ASSIGN Update value of reserved symbols
.DATAFILE Load extra data file
.EMU Select emulator memory section
.MACGOTO Tail call to another macro keeping same parameters
.MACSET Modify macro arguments
Pseudos (NES 2.0):
.NES2CHRRAM Set amount of CHR RAM (non-battery, battery)
.NES2PRGRAM Set amount of PRG RAM (non-battery, battery)
.NES2SUB Submapper number
.NES2TV TV mode (0=NTSC, 1=PAL, 2=both)
.NES2VS Vs. Unisystem mode
Macro special parameters:
\\ backslash
\@ unique five-digit number for each call of a macro
\# number of arguments
\1 read argument
\?1 read type of argument
\<1 first character of argument only
\>1 argument except first character
\$1 length of argument
Command-line switch:
-.nes Select NES/Famicom machine type
-.pce Select PC-Engine machine type
-o # Override output filename
-M Create map file
== Use of .MACGOTO and .MACSET ==
You can use .MACGOTO command followed by a name of a macro (no quotation
marks) to call that macro with the same parameters as the current macro,
and is tail call so it will not continue with the current macro after that
one is finished. If you use it with conditions it could make a loop. You
can also adjust the parameter of .MACGOTO by .MACSET as well. Note: \@ is
not incremented if .MACGOTO is used.
The command .MACSET is followed by three numbers (or expressions)
delimited by commas. The first is the parameter number 1 to 9. Second is a
mode. Third parameter depend on the mode. The selected parameter value
will be changed for the current macro and affects subsequent commands and
.MACGOTO calls.
Mode 1: Copy argument inside of called macro. The third parameter is a
parameter number (1 to 9) and whatever macro has been called from inside
of this one, a parameter given to it, will be copied to this macro.
Mode 2: Copy argument of current macro. Third parameter is the parameter
number and it copy to another slot of the same macro.
Mode 3: Single character. The parameter will become a single character,
with the third parameter specifying the ASCII code of the character.
Mode 4: Numeric. Third parameter is evaluated and converted to a decimal
number which is placed in the macro arguments.
Mode 5: Cut off string. Third parameter is maximum number of characters to
keep from beginning of parameter string.
Mode 6: ASCII code at position. Third parameter is position. The parameter
is use as string, character at specified position, is converted to number
of ASCII. If the string is shorter than that, the result is zero.
Mode 7: Set and increment mcounter (the \@ counter). Third parameter is
the amount to increase by.
Mode 8: Read one byte of data from the current ROM bank.
Mode 9: Get a bank name, using third parameter as the bank number.
Mode 10: Read one byte of data from the map area for current ROM bank.
Mode 11: Read the macro argument from standard input.
Mode 12: Change the current nesting level for IF blocks. Second parameter
is amount of adjustment, and third parameter is nonzero to skip lines. The
resulting value will be the old nesting level.
Other modes currently have no use.
== Use of .ASSIGN ==
Syntax: .ASSIGN "name" value
The name is a name in quotation marks and the value can be any expression.
Do not include a comma between the name and value.
This makes a reserved symbol and assign a value. You can assign different
values in different parts of the input file more than once, unlike the
ordinary labels.
It runs in both passes, in the order specified in input file, and you can
use the old value of the symbol to calculate the next value, too.
== Use of emulator ==
Unofficial MagicKit includes an emulator for use as a postprocessor. Note
that unofficial opcodes cannot be used, except for HLT.
If you put .EMU to assemble emulator codes and data in the emulator memory
map, which is 64K bytes, except for $2000..$3FFF for I/O, $4000..$5FFF for
data of active ROM bank (can be written as well), and $6000..$7FFF for map
data of ROM bank.
Inside of .EMU section use .ORG to specify where in the emulator RAM to
enter data (bank/page is not used in emulator RAM).
If the reset vector of the emulator is nonzero, it will run the emulator
after both passes of assembler, before writing output binary file. If you
write .EMU X at the start of .EMU block then it will use the emulator code
to write the binary file instead of using the normal way. (If .EMU X is
used but does not write to $2005 and $2008 then you will get empty output
file.)
Use HLT command to stop the emulator.
Emulation is done by lib6502, with a modification to suppress the error
message for illegal opcodes.
== Counted labels ==
Counted labels are given by making a label starting with / and optionally
followed by the name.
It is allowed to define these labels more than once, and it can keep track
of all of their addresses (similar to the anonymous labels found in some
other assemblers).
In an expression, you can use / and the name (if applicable) followed by
? to access the current counter, # to access the total counter, or any
number of + or - to access the label occuring that many spaces forward or
backward from the use.
== Bank chaining ==
If you give a bank the same name as a previous bank, then it will chain
them together; once one 8K bank runs out it will advance to the next bank
and set the page number correctly.
To set a bank name, put a comma and quoted string after the bank number.
== Pseudopages ==
Pseudopage numbers are simply added to the value to write to the map data.
They are set by specifying a number after a CODE or DATA command.
Note: The low two bits and high three bits are used by the assembler; the
other three bits can be used for your own use.
== Filenames from standard input ==
Where a quoted filename is expected, you may use an ampersand to instead
read the filename from standard input.
Note, that it will read it twice; once for each pass. You can avoid this
by using a condition involving ?X in order to do it only once.