I am trying to create an LMC assemble code that will allow a user to put two inputs: a decimal number and a base that the number should be converted to. The code should be able
I'll assume that the output should be a series of single-digit numbers representing the given decimal number in the given base notation.
You could use a data-based approach: store all relevant powers of 2, 3, 4, ... and 9 in memory (mailboxes). We only need powers that are not greater than 999, so this list is limited:
This also has the advantage that you don't have to perform that many subtractions. Imagine the difference when the input is 999 and base 2. If you have the powers of 2 already available (up to 512), you'll only do about 9 subtractions, while if you try to do it with only 2, you'll do hundreds of subtractions...
So, given these powers, use a "pointer" in that list (through self modifying code) that will first find the range of powers that belong to the given base, and then will take it from there to perform repeated subtractions of a power (greatest first) from the original number to determine each output digit.
With some care you can avoid that zeroes are output as long as no one has been output.
Here is how that could be coded:
#input: 12 2
INP // number
STA DECIMAL
INP // base
SUB ONE
STA BASE
LOOPBASE LDA BASE // count down to find powers of base
SUB ONE
STA BASE
BRZ DIVIDE
LOOPPOW LDA CODE1 // take next power
ADD ONE
STA CODE1 // self-modifying
LDA ONE // is it 1?
CODE1 SUB POWER
BRZ LOOPBASE // yes...
BRA LOOPPOW // no...
DIVIDE LDA CODE1
ADD ONE
STA CODE2
BRA ENTRY
LOOP STA DECIMAL
LDA DIGIT
ADD ONE
STA DIGIT
ENTRY LDA DECIMAL
CODE2 SUB POWER
BRP LOOP
LDA FIRST // do not output prepadded 0
BRZ OUTPUT // not the first digit
LDA DIGIT
BRZ SKIP
OUTPUT LDA DIGIT
OUT
SUB DIGIT
STA FIRST // no longer first digit
SKIP STA DIGIT
LDA CODE2
ADD ONE
STA CODE2 // self-modifying
STA CODE3 // self-modifying
LDA ONE // is power 1?
CODE3 SUB POWER
BRP FINISH // yes
BRA ENTRY
FINISH LDA DECIMAL
OUT
HLT
DECIMAL DAT
BASE DAT
DIGIT DAT
FIRST DAT 1
POWER DAT
DAT 512 // powers of 2
DAT 256
DAT 128
DAT 64
DAT 32
DAT 16
DAT 8
DAT 4
TWO DAT 2
ONE DAT 1
DAT 729 // powers of 3
DAT 243
DAT 81
DAT 27
DAT 9
DAT 3
DAT 1
DAT 256 // powers of 4
DAT 64
DAT 16
DAT 4
DAT 1
DAT 625 // powers of 5
DAT 125
DAT 25
DAT 5
DAT 1
DAT 216 // powers of 6
DAT 36
DAT 6
DAT 1
DAT 343 // powers of 7
DAT 49
DAT 7
DAT 1
DAT 512 // powers of 8
DAT 64
DAT 8
DAT 1
DAT 729 // powers of 9
DAT 81
DAT 9
DAT 1
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.7/lmc.js"></script>
This uses almost all available mailboxes. Probably some optimisation in space use is still possible.