Search code examples
assemblypep9-assembly

PEP9 assembly application interpreting characters


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                  


Solution

  • 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.