The only thing I've ever encountered that did something like this was the
A86 assembler from Eric Isaacson.
However, the feature there is that errors from assembling your code would be injected directly into your source file so that you could see them in the place where you needed to fix them ("normal" practice at the time being to write a separate listing file with hex data, source lines, and errors).
Re-assembling the file would automatically remove these errors before (possibly) adding new errors (or the same error if you forgot to fix something).
What you're discussing still happens nowadays, with (for example) a single file running as a
cmd script which then runs Python using that exact same script as the source. The trick is to make the Python bits invisible to
cmd and the
cmd bits invisible to Python, something like:
rem = """
rem cmd stuff goes here, runs python with this file.
rem Python sees this as setting var rem to a multi-line string.
# Python stuff goes here, cmd will have already left.
Or, in your case, "hiding" the executable code from the editor and assembler while still allowing it to run.
A COM file that placed the executable code after the source (in your actual source file) presents a couple of problems, as per below.
First, since COM files get loaded at a specific location and run from there (
0x0100), there would have to be at a minimum some binary jump instruction before the source to go the the executable portion of your code.
A general purpose text editor is likely to complain bitterly about this. I suppose you could have a purpose-built editor which only allowed you to edit the source section (between jump and executable code) but it seems strange to need a special editor for what is really a dubious feature.
Alternatively, you may find a way to encode binary data in such a way that it looks like something good to the editor but acts as code when loaded to execute.
; were used as a comment marker, you could place that at the very start of your file, followed by some executable code and a new-line marker.
For example, ASCII
; is code point
0x3b which, on the 8080, was the
DCX SP instruction for decrementing the starck pointer. Yo could follow that immediately by an equivalent
INX SP then a jump to your code, something like:
0100 3b DCX SP ; First byte of file, but loaded at 0x0100.
0101 33 INX SP
0102 c3 xx xx JMP xxxx
0105 0d 0a DB 0d, 0a
That would show up in your source as
;3<c3><xx><xx><cr><lf> and your actual source code would follow after that.
On the chance that editors would not be keen on characters above code point
0x7f (such as the
JMP) or even the non-printable characters under
0x80, I have no doubt that some smart person could construct a byte sequence that did the same job using only printable values (for both opcodes and data).
For example you could load printable-char values into registers and
not them to get non-printable-char values, or push things on the stack and return rather than jump (unfortunately
RET is also above
0x7f but you get the idea).
Second, and this is probably more important given the 64K-ish limit to COM files, it's probably not a good idea to waste in-memory space on storing the source during runtime. It unnecessarily limits the size of your program.
If you have 30K of source, that's 30K less space that you have available for your executable code.
Again, you could have a special loader which only pulled out the executable code from the file but then it's not really a COM file at that point.