Last update:
2 II 2022

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


ELSA change log


  • 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