Last update:
12 VI 2024

== ELSA ==
* Information
* Change log
* Downloads
== 65C816 XL OS ==
* Information
* Change log
* Compatibility list
* Download
== Fixes ==
* Downloads
== IDE Plus ==
* Information
* Download
== Other stuff ==
* Downloads
== CPU boards ==
* Information
* Downloads
== SysInfo ==
* Information
* Download
== Let's Emu! ==
* Information
* Downloads
== U-BASIC ==
* Information
* Downloads
== CP/Emu ==
* Information
* Downloads
== MultiBASIC ==
* Information
* Change log
* Download


ELSA change log


  • new: block count in SDX relocatable binaries increased to 128
  • new: added preliminary code to run under DataQue Turbo-816 OS - disabled for now (Rapidus OS is still the recommended choice)
  • new: added DOS XL compatibility code to the command line parser
  • bugfix: blocked execution of the E: control codes in the line being displayed as a part of an error message
  • new: /L now accepts a file name as a parameter, try /
  • bugfix: blocked opening the listing file twice (or more) within .include
  • bugfix: more intelligent detection if there was /L in the command line, and if with a file name
  • bugfix: when an I/O operation cannot be completed due to an I/O error, do not attempt to flush output buffers, just close everything and exit
  • new: command line parsing reworked so that /O and /L now accept device names, like /OD5:FOO.BAR or /OPCL:FOO.BAR etc.
  • new: the .ls directive now accepts an optional name of a file where the listing will be written to, try .ls foo.lst
  • bugfix: fixed a visual glitch (wrong PC value displayed) while listing the contents of the .byte directive
  • new: overall listing formatting improvements (headers, data directives)
  • bugfix: the .ll directive works again
  • new: BRK (without an argument) now generates $00,$00
  • other: minor corrections in warning messsages
  • new: throw an error when two addresses from different program blocks are used in one arithmetic expression
  • bugfix: INW/DEW/DWA threw errors or were assembled incorrectly when syntax like INW <VAR or INW !VAR was used.


  • bugfix: fixed regression which caused an uninitialized pointer reference when INW was used in a .rel block
  • bugfix: .xrefs were ignoring the "standard" status imposed by .stdinc
  • added: .xrefw keyword to define a weak symbol (as of SpartaDOS X 4.50)
  • bugfix: sorted out the mess with expression and argument prefixes !,+,-,<,>,^ and \, thus 1000+<1000 not only assembles now but also gives the correct result ($04d0)
  • bugfix: mark local namespace label as used, when a label in that namespace is referenced externally
  • bugfix: when .xref was executed after its label's reference, the label was not recognized as referenced
  • bugfix: fixed bogus warnings about zp,Y->abs,Y promotion which appeared when a symbol was used in the address field
  • more compact listing of label declarations
  • bugfix: fixed a possible line buffer overrun in the ' operator
  • bugfix: INW/DEW/DWA abs or abs,x was sometimes recognized as zp or zp,x
  • disallow JSR/JMP/Jxx from the high RAM to the low RAM (other inter-segment calls get caught by the fixup generator)
  • disallow JMP (abs) and JMP [abs] with argument outside the first 64k
  • disallow JMP (abs,x) and JSR (abs,x) with argument outside the current code segment
  • the 6502 stack given up (too small), now allocated 1k stack under the memtop
  • bugfix: .rel $03 / .ds 100 generated wrong block type ($FFF9/$03 instead of $FFFE/$83)
  • bugfix: if the program consisted of segment .rel, then segment .abs, an incorrect header for the latter was produced.


  • added .stdinc
  • bugfix: if the program consisted of segment .abs, then segment .rel, then .abs again, incorrect headers were produced
  • bugfix: .run can now be used with a forward-declared argument
  • bugfix: .run now works in SpartaDOS relocatable programs
  • addresses are now cut down to 24 bits on 65C816 and to 16 bits on everything else
  • bugfix: bogus warnings were generated about addressing mode promotion to abs,y, when the instruction in question was referencing a .rel block (so a zp addressing mode was not allowed anyways)
  • experimentally added more logic to the "NUMBER TOO BIG" warning
  • XDEF labels, even not explicitly referenced, will be now marked used while being exported
  • .rsset now accepts negative offsets
  • added .used
  • bugfix: various fixes related to the .bss section
  • bugfix: spurious warnings were generated about "SUSPICIOUS ARG SIZE"
  • bugfix: numeric ASCII to decimal integer conversion was limited to 16777215
  • bugfix: a regression that made .dbyte, .tbyte and .qbyte generate values in little endian order of bytes, instead of big endian
  • bugfix: SCS was assembled as TCS - a symptom of a major mess in one of the internal lookup tables, hopefully sorted out for good now
  • the BRK instruction will now by default generate a warning, use .opt b- to suppress them
  • bugfix: unused XREFs were not reported on /V
  • the .cache keyword removed: caching will now be enabled automatically unless /A was specified in the command line.


  • .org $xxxx, where $xxxx < 256, will now NOT automatically switch to the zero-page segment
  • .byte will not warn, if bytes 1-3 of the value being non-zero are just the sign-extension of its first byte
  • the first .zp directive in your program must now get explicit zp base address.


  • added __RELCNT__ and __RELNUM__
  • .org did not have any effect when used to reset the PC to the last address before .ds
  • restored code which was uncommented for debugging purposes and mistakenly left so in the release binary; this resulted in very bad behaviour of accepting forward-declared labels as being of value 0 in the first pass, which in turn caused the expressions containing them to be miscalculated.


  • /S command line switch removed (it is only useful in debugging ELSA itself)
  • fixed a bug which caused forward .xref declarations to be undefined in the second pass
  • fixup records for .abs blocks now use relative offsets whenever possible
  • .rs did not work correctly when it was typed in uppercase
  • fixed a bug in the ! binary negation (one's complement) operator, which was not cleared after use and thus was propagated to subsequent arguments of an expression
  • fixed a crash when an option was given (e.g. /C) without input filename
  • cleanups in the code generating SDX relocation information
  • the force-zero-page operator < when used after the ( or [ token (signifying the indirect addressing mode) was intepreted by the parser as the extract-low-byte operation, which in turn caused warnings to be thrown on such instructions as lda (<adr),y; fixed now
  • fixed a bug causing bogus phase errors when the .include directive was used in the last line of a source file, with .cache being active
  • fixed a bug in .cache causing bogus out of memory errors
  • .cache will not get enabled if there is no memory past the first 64k
  • fixed a (probably harmless) bug in .local
  • setup new name for include file after opening it, not before. This makes error mesages make much more sense when error occurs during .include
  • implemented .incdir
  • computations which give XREF as result will also return 16-bit values (with high word zeroed)
  • fixed a regression, the example program HELLOO.MAE did not assemble
  • SDX relocatable binary headers will now appear in the listing (I forgot about this)
  • fixed regression in .align
  • fixed typos (the same typo, in fact) in opcode tables for ASR, RRA, RLA
  • .org and .abs will not generate new headers, when new PC is greater than the old one by less than 5 bytes, the gap will be filled with zeros instead
  • in immediate addressing mode cast the argument automatically to the required size, if the remaining bytes are just its sign-extension - this gets rid of the notorious "NUMBER TOO BIG" warning when you use LDA #-1 or sim.
  • the zp,Y addressing mode for instructions which do not have it gets promoted automatically to abs,Y and generates a warning
  • .opt f- gets enabled automatically if the underlying DOS has NOTE/POINT functions instead of TELL/SEEK
  • few cosmetic changes all around


  • /R command line switch removed (by internal assembler's design the statistics could not be 100% reliable).
  • changing addresses with .set now explicitly forbidden.
  • cleanups in the code handling namespace markers.
  • cleanups in the code handling the ":" character at the end of a label.
  • .rs 0 will not generate a warning anymore: .rs 0 may be intentionally used to create unions inside structures.
  • implemented .abs.
  • implemented declarators .xref and % (xdef).
  • implemented .rel and SDX relocatable file format.
  • fixed a bug, where ZP addresses were considered internal to the program (and thus subject to relocation)
  • added files containing equates: sysequ.i, sdxkern.i, sdxsymb.i.


  • merged redundant parts of the code generating INW/DEW/DWA.
  • also cleaned up some (unnecessary) kludge in the same code.
  • make .set (with the dot) official.
  • fixed the bug when .set label=value (no spaces around the equal sign) caused syntax error.
  • fixed the bug when an address label changed by .set in the first pass, instead of being redeclared in the second pass, was skipped, causing the "undefined" error at the neares reference.
  • the parser was accepting .[, .ASR and such, should do this no more.
  • fixed uninitialized variable in .cache which might have resulted in bogus "out of ram" errors.
  • fixed .include against bogus file names and line numbers in error messages in second pass, when .cache was active.
  • implemented .opt p+.


  • further speed optimizations in the routines searching through the symbol table.
  • fixed the regression which made the program unable to find labels inside local namespace when referenced from the outside of that namespace.
  • some keywords (notably .else and .endif) were ignored when preceded with a comma instead of a dot, though a syntax error should be thrown in such circumstances.
  • .zp may be now used within a [] block.
  • added the directives .bss and .data, plus pseudolabels __BSS__ and __DATA__.
  • the sizes of the sections (CODE, ZP, DATA, BSS) in the final resume will also be displayed in decimal besides hex.
  • the listing, when enabled, was corrupting the data produced by the directives .word, .long etc., fixed (this is what re-using static variables does to programs).
  • fixed a bug in phase error detection at the end of the second pass.
  • fixed silly typo in the listing code displaying values assigned to labels with the equal sign (decimal values were bogus).
  • implemented .run and .init.
  • reworked preparing filenames for .include, .bin and .out, it should now accept devices like PCL: and such.
  • gave up reporting base and length of the code section at the end, it was useless and confusing sometimes.
  • add size of headers to the length of object file being reported after pass 2.
  • show "human" interpretation of the DOS 2 headers in the listing.
  • implemented .mc.
  • implemented .cache.


  • added directive .cpu to tell the assembler what the current CPU mode is.
  • added pseudolabel __CPU__ indicating the currently selected CPU mode: 8 for 8-bit mode (aka emulation mode), 16 for 8/16-bit mode (aka native mode).
  • added a warning when the MX bits are about to be cleared and the CPU mode currently selected is 8-bit.
  • fixed a bug that caused the program to throw bogus errors in certain circumstances when a reference was being made to the inside of a .local namespace.
  • removed JSR from the list of instructions which trigger the "NULL JUMP" warning.
  • jfsymbol (SDX function) was called in the native mode, fixed now.
  • added a warning on .rs used without previous .rsset (which is a potential mistake for the intended .ds).
  • added pseudo-label __RS__ containing the current offset inside the structure being defined with .rs.
  • .rs, .ds and .dc with the byte count of 0 will generate a warning.
  • listings now show the contents of the binary headers being generated.
  • at the end, besides the amount of free memory remaining, also report how many bytes were used for the symbol table and such.
  • added missing check for the error condition when the first pass ends with an open [ block without the closing ].
  • accept (and skip) : at the end of a label being declared.
  • fixes against bogus line numbers appearing when an error occurs during execution of .rept
  • added /S to command line switches = dump symbol table.
  • the ! operator (bitwise negation) can now be applied to individual expression components instead of inverting the result of the entire evaluation. This fixes its behaviour which was incoherent with the behaviour of the minus sign operator (arithmetic negation).
  • fixes made in the code which internally handles data types.
  • also implemented cast operators: ($) and (&) - for value and address types, respectively.
  • switched from 24-bit to 32-bit arithmetics.
  • also program counters are now 32-bit for arithmetic operations, but internally the low word only is taken into account (most of the time); 24-bit PC values will appear on the listings, though.
  • .print and .error will now display numeric values in both hexadecimal and decimal form; also insert spaces between the consecutive ASCII strings being printed.
  • implemented binary operators >> and << for logical shift right and logical shift left, respectively.
  • implemented directives generating 32-bit words: .quad (aka .dword) and .qbyte, for little and big endian byte order, respectively.
  • implemented unary operator \ which extracts bits 24-32 of computation result (analogically as <, > and ^ do).
  • directives .lsb, .msb and .usb removed (more hassle than it is worth).
  • in the listing print the values assigned to labels with =.
  • sorted out some old and provisional (and forgotten) code which effectively prevented the symbol table from being larger than 64k.
  • also, the symbol table was only capable of holding up to 32 KB of MAE-style local labels ("?label", this stuff) in the scope of a single global label due to 16-bit signed offsets used instead of pointers. This limitation is lifted now, but the symbol table will occupy somewhat more memory (which may be important on machines only equipped with 6502-compatible RAM).
  • the routine(s) searching through the symbol table somewhat speeded up at the occasion.
  • added pseudolabel __ZP__ (current zero page counter).


  • in SpartaDOS X the assembler will, while exiting to DOS, write a value to the system variable ERRNO: 0 on success or a non-zero value on error. An I/O error will result in writing the corresponding system error code, an assembly error will cause a positive value greater than 1 to be written there. This will allow to catch assembly errors in batch scripts using the IF ERROR conditional (on SDX later than 4.49-release, that is, because up to 4.49 IF ERROR only reacts to error codes greater than 127).
  • added implied pseudo-addressing-mode to the following instructions: BCC, BCS, BEQ, BNE, BPL, BMI, BVC, BVS, so that they can easily be used to mask the following one-byte instruction. They are one cycle faster than BIT zp in this role and do not generate a spurious read.
  • added implied pseudo-addressing-mode to the BIT instruction so that it can easily be used to mask the following two-byte instruction.
  • the program was freaking out if there was a comment placed next to .zp directive.
  • directives without the leading dot (like org $2000) were accepted, fixed.
  • added the directive .align.
  • added pseudo-instructions JSR (abs) and JSL [abs].


  • forgot to add .hex to the list of directives which should stuff data to the listing.
  • forgot to zero the delta which is to be added/subtracted to/from the data bytes generated by the .byte/.cbyte/.sbyte directives, which in turn caused it to be propagated to subsequent .byte directives (& co.)
  • if one of these directives contain nothing but this delta value, an error will be thrown.
  • removed a duplicated error message from the error list.
  • output of multiplication or division must always be of type "value", not "address" regardless of the input types.
  • fixed a bug that sometimes caused the label type to be clobbered (symptom: "UNDEFINED" error for a label which has been perfectly defined).


  • the procedure looking up the symbol table slightly (5-10%) speeded up.
  • contrary to what was stated in the docs, .lc was able to switch off the listing enabled with the /L command line switch.
  • changed the ELSA.EXE-building procedure to something faster (gave up the old linking script running in MultiBASIC) and more robust (fixes in the relocator).
  • most I/O functions will now handle errors automatically, which allowed to get rid of many status checks all across the code.
  • suggest shortening Jxx on 6502 too.
  • suggest shortening JMP on everything but 6502.
  • warn on JMP/JSR/Jxx instructions which jump to the address located immediately after themselves.
  • fixed typos and other cosmetic changes in messages.
  • deleting now the line buffer contents after returning from .include
  • adjustments made to make the listing more compact and more readable at the same time.
  • .byte, .cbyte, .sbyte, .word, .dbyte, .long, .tbyte, .float now generate actual information to the listing.
  • so does .dc, but this one just displays up to 11 first data bytes of the block being generated.
  • also, .dc's arguments may be now separated with comma (besides space).
  • fixed the phase error bug occurring when DEW/DWA was used with forward declaration.
  • fixed a silly typo in RRA expansion, which resulted in putting $09 (ORA #) into the output buffer instead of $c9 (CMP #).
  • reworked the code expanding ASR, B2H, PHR, PLR, RLA, RRA at the occasion.
  • the arguments to .opt were only recognized when typed in lowercase.
  • added .opt f- to be used before including a binary file (with .bin) from a filesystem which does not provide a reliable information about file's length (such as the AtariDOS FS). Use .opt f+ afterwards.
  • added .opt w- to disable warnings during assembling. w+ is the default, /Q in the command line has a priority over this.
  • changed the operation of .float so that it now accepts both floating point constants and integer expressions.
  • added pseudo-labels __M65C802__ and __M65C816__ as aliases to the existing __M65802__ and __M65816__ (which were misdocumented previously).
  • added the /R command line switch.

0.9 (first public release)

  • implemented pseudo-instructions RCC, RCS, REQ, RGE, RLT, RNE, RMI, RPL, RVC, RVS (Repeat last instruction if Carry clear... and so on), SCC, SCS, SEQ, SGE, SLT, SNE, SMI, SPL, SVC, SVS (Skip next instruction if Carry Clear etc.), INW, DEW, DWA, B2H, ADD, SUB, PHR, PLR, ECC, ECS, EEQ, EGE, ELT, ENE, EMI, EPL, EVC, EVS (Exit subroutine if Carry Clear etc.), ASR, RRA, RLA.
  • changed the syntax of PEA to what some other assemblers :) use, i.e. PEA #$xxxx, PEA ($xx), PEA $xxxx, last two being PEI and PER in MAE.
  • implemented directives .zp, .code, .ifdef, .ifndef, .ll (list just the following line), .el, *** (.else and .endif, respectively, for backward compatibility with MAE), [ and ], .rept, .endr, related pseudo-label __REPT__ and (likewise related) operator #.
  • .ifs can finally be nested.
  • implemented logical AND (&&), logical OR (||) and unary negation (!).
  • cleaned up the implementation of the directive set.
  • implemented pseudo-labels __ASIZE__, __ISIZE__ (size of the A and XY in bits, respectively), __M65C02__, __M65SC02__, __M65802__ indicating 65C02, W65SC02 and 65C802 as targets; and .65c02 (or .c02), .65sc02, .65c802 to enable these targets in source.
  • code identifying a pseudo-label cleaned up.
  • directive .error made better, it is now the same as .print, except that it also aborts the assembling with the "USER-DEFINED" error message.
  • warnings will be produced in second pass only.
  • no more checking CPU hardware: init will now rely solely on the information returned by the OS.
  • when there is no kmalloc() in the OS, or the High RAM is occupied, use base 64k (this leaves about 20k for symbol table).
  • command line options may be now marked also with the slash character, e.g. /D instead of -D.
  • implemented command line option -M to specify the default target CPU (it can be overridden in the source).
  • the object file name may be now specified in the command line.
  • the PRINTF library replaced with a new version, which does not use OS mathpack (thus releasing large portion of zero page) and is able to convert integer values up to 32-bit into decimal or hexadecimal ASCII strings.
  • fixed a bunch of minor bugs here and there.


  • implemented pseudo-labels __M6502__, __M65816__, __RSSIZE__ and entire mechanism to predefine new ones
  • added a warning when a value is truncated by one or two bytes down
  • implemented directives .if/.else/.endif (not nestable for now)
  • fixed bug in .end directive
  • implemented directives: .rsset and .rs
  • fixed bug in expression calculation for .word directive in 1st pass
  • fixed bug in .cbyte: in .cbyte 0,0,0,0,0 and the like it used to set bit 7 on every byte instead of on the last one only
  • implemented directives .rb and .rw © KMK
free counters