0

I'm writing a program (in PEP9 assembly) which is supposed to output -1 at the beginning, then take a lowercase ASCII character as input, convert it to uppercase, and output it.

So far, I have:

LDWA 0xFFFF, i 
DECO 0xFFFF, i
LDBA 0xFC15, d
STWA 0x001D, d
STBA 0xFC16, d
LDWA 0x001D, d
SUBA 0x001F, d
ORA 0x0021, d
STBA 0xFC16, d
STOP 

.BLOCK 2
.WORD 20
.WORD 0x0020
.END

Whenever I run it with my input, it instead adds 20h instead of subtracting 20h to make the ASCII character uppercase. Any pointers?

zx485
  • 28,498
  • 28
  • 50
  • 59
asavyy
  • 31
  • 1
  • 9
  • 1
    Any pointers? Here's one: `0xdeadbeef` :-) On a more serious note, that's about as helpful as just dropping a question with the raw machine language hex bytes. Perhaps you may want to consider giving us at least the assembly language. That would go a long way towards helping us helping you. – paxdiablo Sep 30 '19 at 00:50
  • Thats all I'm allowed to use. We havent gone over assembly language in class yet. I dont know how to convert it all. If you put that into pep9 itll run. – asavyy Sep 30 '19 at 01:36
  • 2
    asavyy, I'm assuming here you didn't just create those hex numbers off the top of your head. Instead, you almost certainly wrote a human-readable program first, then converted it into machine language, yes? If so, that human-readable one should be what you give us. – paxdiablo Sep 30 '19 at 05:55
  • 1
    I converted it and i hope that helps? Now im not getting the uppercase portion correct. – asavyy Sep 30 '19 at 16:44
  • 1
    asavvy, that's much better, retracted close vote and upvoted, since it's now a much better question. You also identified the problem much better (that being the addition rather than subtraction). Now I'll have a look :-) – paxdiablo Oct 01 '19 at 01:02
  • I almost finished this entire program. What it's supposed to do is take a lowercase ascii character and convert it to upper, display the deci value of the lowercase letter, the deci value of the uppercase character, and the value of the lowercase letter in hex. All of it should have linefeeds inbetween (which ive done) but for some reason, im getting 00 and then my hex conversion when it should only be the hex. I'll edit the question real quick. – asavyy Oct 01 '19 at 01:34
  • 1
    asavyy, you should keep in mind that this is *not* a conversational board. Your lateswt edit has basicallyremoved all context regarding what the question is, rendering it rather useless. I am reverting to the earlier version since, without that context, your question will almost certainly be deleted as incomplete. – paxdiablo Oct 01 '19 at 01:42
  • I was unaware, I was just updating you with my latest issue since that question is basically solved. – asavyy Oct 01 '19 at 01:46
  • No probs, a better approach would be to just ask another question, referencing this one. The problem would be a lot worse if someone had already answered your original question :-) – paxdiablo Oct 01 '19 at 02:38

1 Answers1

1

Re-jigging your code with addresses (and some comments) makes it a little easier to figure out potential problems:

0000  LDWA 0xFFFF, i    ; set A to -1, why?
0003  DECO 0xFFFF, i    ; decimal output -1
0006  LDBA 0xFC15, d    ; get input character
0009  STWA 0x001D, d    ; store to variable
000c  STBA 0xFC16, d    ; output character
000f  LDWA 0x001D, d    ; get character back
0012  SUBA 0x001F, d    ; presumably subtract 0x20
0015  ORA  0x0021, d    ; not sure what this intends
0018  STBA 0xFC16, d
001b  STOP              ; 1-byte operation

001c  .BLOCK 2          ; two arbitrary bytes.
001e  .WORD 20          ; takes two bytes 0x0014
0020  .WORD 0x0020      ; 0x0020
.END

Based on that, you appear to have used the wrong addresses for direct storage and retrieval, possibly because you think STOP is a two-byte operation but I can't be sure.

Going forward, you should be able to get rid of superfluous code and ensure you only uppercase lowercase letters by only acting on the range (inclusive) a..z. Something like this would be a good start:

asc_a:    .equate  0x0061      ; Lower case A.
asc_z:    .equate  0x007a      ; Lower case Z.
sub_val:  .equate  0x0020      ; Difference from upper to lower.
in_char:  .equate  0xfc15      ; Address to get char from user.
out_char: .equate  0xfc16      ; Address to put char to user.

main:     deco     0xffff,i    ; Decimal output -1.

          ldba     in_char,d   ; Get input character.

          cpwa     asc_a,i     ; If outside a..z, do not translate.
          brlt     no_xlat
          cpwa     asc_z,i
          brgt     no_xlat

          suba     sub_val,i   ; Convert to upper (61..7a -> 41..5a).

no_xlat:  stba    out_char,d   ; Output character.
          stop

You'll see there that we don't actually need data storage since we can just use immediate operands for constants and the accumulator for the character itself.


If you do need data storage, I would tend to place it at a fixed location so that code changes do not affect it, something like:

0000   start:       br       main

0003   some_data:   .block   0x20
0023   more_data:   .word    0xdead
0026   more_data:   .word    0xbeef

0029   main:        <<Code goes here>>

That way, no changes to the code affect your variables, something that will be quite handy if you have to hand-code your stuff rather than relying on a decent assembler that can work out the symbols automatically.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953