The intended purpose of this application is to take a single character from user input, and output its 4 bit binary equivalent. For example, 'E' should output 1110. 5 Should output 0101
When I input 'E', this program outputs 0101. When I input 5, however I get 0101 too. I am wondering if I am somehow reading the 8-bit binary of the character input rather than the 4-bit? Here is my program so far (attached). Please let me know if you have any suggestions. I'm not sure how to tell the program to give me it's 4-bit binary value (if that is even the issue)
CALL start
start: LDBA 0xFC15,d ; load user input
CPBA 0x0058,i ; compare user input to 'X'
BREQ end ; if user input is 'X', branch to end
STBA 0x0001,d ; store user input at 0x0001
LDBA 0x0031,i ; load 1 for counter
STBA 0x0000,d ; store counter at 0000
next_let:LDBA 0x0001,d ; load user input back
ANDA 0x0008,i ; check if character has a bit at 1000
CPBA 0x0000,i ; check if ANDA is zero
BREQ zero ; branch to zero: if it is zero
one: LDBA 0x0031,i
BR print
zero: LDBA 0x0030,i
print: STBA 0xFC16,d
LDBA 0x0001,d ; load user input back
ASLA ; shift character binary left
STBA 0x0001,d ; store shifted user input at 0x0001
LDBA 0x0000,d ; load counter back
ADDA 0x0001,i ; increment counter by 1
STBA 0x0000,d ; store updated counter value at 0000
CPBA 0x0035,i ; compare counter to 0005
BRNE next_let ; branch if counter not equal to 0035
LDBA 0xFC15,d ; load user input
LDBA 0x000D,i ;load return
STBA 0xFC16,d ;print return
CALL start ; loop back to start
end: STOP
.END
Your program is mostly ok for what it is programmed:
E
is an ascii character, whose hex value is 0x45.e
is an ascii character, whose hex value ix 0x65.5
is an ascii character, whose hex value is 0x35.So, we would expect all of these, if you simply take the last 4 bits, to print 0101
, which is 5 or 0x5.
The ascii characters for the digits 0
through 9
line up nicely with their numeric values of 0x30-0x39. This is effectively biased by 0x30, meaning you can subtract 0x30 from any such decimal digit character and get the decimal numeric value. You can also simply remove the upper 4 bits, taking only the lower 4 bits and get that same decimal numeric value of 0-9.
However, if you study an ascii chart closely, you'll notice that the character values for letters A
through F
— which are sometimes used for conveying larger hex digits — do not line up properly with 0-9 — they are in their own set of numberings. They do line up nicely with a
through f
, though, but that doesn't help here.
So, what your program could do is determine the bias and apply it in reverse. A
has the value 0x41, and you want to get the value 1010, aka 10102 from that, B
the value 0x42, and you want to get the value 1110 from that, aka 10112. So, instead of ignoring the upper 4 bits, you have to subtract 0x37 aka 55 from A
, to get 10, from B
to get 11, from C to get 12, etc..
So, you'll have to apply conditional logic — one logic for 0-9 and another for A-F.
On other notes: don't use CALL
if you're not also using RET
, as the stack will become unbalanced. Running your program long enough will result in a stack overflow. Use BR
instead where you're currently using CALL
.
Your choice of using ascii digit characters for the loop counter is very unusual, but will work. Most programmers would use a counter started at 0 and stop after 3, or even started at 1 and stopping after 4. But you're using a counter starting 0x31 and stopping at 0x35 — like I said, very unusual, but not incorrect.