Holy Guacamole! I'm glad that I'm learning 8085 assembly at the right
moment so I can, with some work, perceive the beauty of this. Even after
reading Ken's lucid description I didn't quite get what the code was doing.
The lightbulb went on for me when I saw the machine language values next to
the assembly listing, with the sequence "3E01", "3E02", "3E03".

6F52  3E 01                     MVI     A,01H           ; A = 1
6F54  01 3E02                   LXI     B,023EH         ; BC = 023Eh
6F57  01 3E03                   LXI     B,033EH         ; BC = 033Eh
6F5A  E5                        PUSH    H

But even understanding how it functioned, I thought maybe it was
needlessly obfuscated. Couldn't one have something like three `INCREMENT A`
instructions in a row and jump to the right one? The answer of course is
No, but I had to try my hand at writing something better and being proven
wrong before I got how insanely brilliant this technique is.

In fact, I now realize I had actually been puzzling over exactly this for
some time in a different context. There’s some code buried in the middle of
the Tandy 200 FOR statement implementation which Virtual T’s disassembly
renders like so:

077EH  (F9H) SPHL
077FH  (22H) SHLD F650H     ; SP used by BASIC to reinitialize the stack
0782H  (0EH) MVI C,D1H       ; ??? b9 asks, "What is this for since C
gets overwritten?"
0784H  (EBH) XCHG
0785H  (0EH) MVI C,0CH
0787H  (CDH) CALL 4C1AH

In trying to understand, I had found online a hand-commented disassembly
for the T102 which had said,

0782H MVI   C,D1H     ; Make POP D (D1H) below look like MVI C,D1H

but that made no sense to me because there was no “POP D” below.
Now I think I get that it must have been allowing another entry point that
started with POP D:

0782H DB  0Eh     ; Make POP D (D1H) below look like MVI C,D1H
0783H POP D

I wonder who invented this technique and what it is called. When I google
for “Multi-Entry Point Function”, I get only results for a much more
mundane method that doesn’t use the specific values of the opcodes. (For
example, the cosine routine being just a single instruction, A=A+π/2
<http://jklp.org/profession/books/mix/c06.html#:~:text=6.5%20OTHER%20TOPICS%20ABOUT%20SUBROUTINES>,
before the sine routine.)

—b9

P.S. I now have a glimmering of why in that epic ballad of hackerdom I
shared before, Real Programmers
<https://users.cs.utah.edu/~elb/folklore/mel.html> had the numerical value
of every operation code memorized!

On Fri, Apr 10, 2026 at 2:15 PM Kenneth Pettit <[email protected]> wrote:

> A better disassembly would look like:
>
> ; ======================================================
> ; Initialize RS232 or modem
> ; ======================================================
> 6F52H  (3EH) MVI A,01H
> 6F54H DB 01H    ; Make next opcocde look like LXI B,023Eh
> 6F55H  (3EH) MVI A,02H
> 6F57H DB 01H    ; Make next opcode look like LXI B,033Eh
> 6F58H  (3EH) MVI A,03H
> 6F5AH  (E5H) PUSH H
>
> Ken
>
>
> On 4/10/26 1:59 PM, Kenneth Pettit wrote:
>
> Hi Kurt,
>
> Oh, I okay, I see.  Yeah, this took me a minute to figure out back in my
> days of disassembling lots of M100 ROM code.
>
> Good old Mr. Gates found a way to really squeeze instructions into the
> ROM.  This is an example of a multi-entry point function.  If you write
> code to JMP 6F52H, then you get
>
> MVI A,01H
> LXI B,023EH
> LXI B,033EH
> PUSH H
>
> This results in A being loaded with 1
>
> But entering at 6F55H looks like:
>
> MVI A,02H
> LXI B,033EH
> PUSH H
>
> (i.e. A is loaded with 2)
>
> And entering at 6F58H looks like:
>
> MVI A,03H
> PUSH H
>
> So this routine can be entered from 3 different locations to perform 3
> different functions (loaded into A as 01H, 02H or 03H) and it only costs a
> couple of extra bytes.  It uses dummy LXI B,#### opcodes (which only cost 1
> byte for the 01H) to "hide" the "MVI A,02" (3EH,02H) and "MVI A,03"
> (3EH,03H) opcodes and make them look like the LXI B opcodes, loading B with
> dummy values of 023EH and 033Eh).
>
> Ken
>
> On 4/10/26 1:35 PM, Kurt McCullum wrote:
>
> Thanks Ken,
>
> I do have an example.
>
> 1. Put a breakpoint at 6F58
> 2. Go to TELCOM and type TERM
> 3. Look at the Instruction Trace. It will say 6F58s MVI A, 03H
>
> 4. Go to the ROM source listing.
> You will notice there is no command at 6F58H. Instead it says
> ; ======================================================
> ; Initialize RS232 or modem
> ; ======================================================
> 6F52H  (3EH) MVI A,01H
> 6F54H  (01H) LXI B,023EH
> 6F57H  (01H) LXI B,033EH
> 6F5AH  (E5H) PUSH H
>
> To me it looks like the debugger got off track at the bottom of the ROM.
>
> Kurt
>
>
> On Fri, Apr 10, 2026, at 3:06 PM, Kenneth Pettit wrote:
>
> Hi Kurt,
>
> Umm, I believe the disassembler *should* be looking at the ROM if I
> remember correctly.  Could just be a latent bug.  Do you have examples of
> discrepancies?
>
> Ken
> On 4/10/26 12:35 PM, Kurt McCullum wrote:
>
> I am running into a problem with the disassembler for the main ROM in
> Virtual-T for the NEC 8201a.
>
> In particular, the RS232 initialize routines don't match what the ROM and
> debugger show as far as code.
>
> For the main ROM, is the disassembler actually looking at the ROM, or
> something else?
>
> Kurt
>
>
>
>
>

Reply via email to