How do I branch the loop when the accumulator value is -1?
The LMC defines mailboxes with values between 0 and 999. They cannot be negative. Even though you can subtract a bigger value from a smaller value, the accumulator's value is then undefined. According to Wikipedia:
SUBTRACT
[...] the actions of the accumulator are not defined for subtract instructions that cause negative results - however, a negative flag will be set so that 7xx (BRZ) and 8xx (BRP) can be used properly.
So the only way to reliably detect a negative value is by using BRP
: that branch instruction will jump to the provided target address unless a recent subtraction had set the negative flag.
Code review
There are the following issues in your code:
Par DAT -1
: as stated above, you cannot store -1 in an LMC mailbox. Mailboxes can only store values between 000 and 999.
Par
versus PAR
: you have two labels that only differ in capitalisation. LMC implementations are usually not case sensitive, so this would make those two labels the same. Better use entirely different labels.
BRP PO
: The label PO
points to the very next instruction, so this means that code execution will always continue at that instruction, whether you branch or not. It makes this instruction useless.
O DAT 79
: this line appears right after a set of instructions that ends with OTC
. If ever that code is executed, it will run into this DAT
line. That could lead to undefined behaviour. You don't want this to happen. So make sure that DAT
mailboxes are shielded from code execution. Add a HLT
before a block of DAT
to avoid that they are ever executed as if they were code. You have a similar issue at P DAT 80
.
BRZ EXIT
: at the EXIT
address, you have a BRP
, but as you can only arrive there when the accumulator is zero, the negative flag will not be set, and so BRP
will branch always. Note that BRP
branches when the negative flag is not set.
ODDE
: this label is never referenced, and that code block is never executed. You could consider changing the BRA
-- that appears just before it -- to a BRP
. Then the execution will fall through when the last subtraction led to a negative result (virtually -1 in your case, but the accumulator is undefined).
If you correct all these issues, you'll get to an implementation that will be very close to this working version