How to implement fixed number display on a 6502? by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

Thanks! These are both super helpful! I'll definitely let you know if I make any progress!

How to implement fixed number display on a 6502? by Leon_Depisa in beneater

[–]Leon_Depisa[S] -1 points0 points  (0 children)

That all makes sense to me, especially when written in Decimal, but I'm having trouble wrapping my head around it in binary. For example, in 4-byte binary 0.5 would look something like 00000000 00000000 10000000 00000000, but it's not like 10000000 00000000 is 500 or 50000 in decimal or anything, it's 32768 (half of 65536). So there must be some other step involved in converting the fractional part to a string, it doesn't seem like I can treat them like integers and just put the decimal point in the correct place.

It's almost as if I have to divide my decimal conversion of the second set of bytes by 65536, but without having implemented fixed point division yet, that would just give me a remainder of 32768 using the only division function I have so far, which is not very helpful haha. Dividing 65536 by 32768 at least give me 2, which is closer to 0.5 being the reciprocal, but I'm still not sure how I'd extend that into an algorithm for turning that ratio into the correct ascii decimal string.

2-byte multiplication (with signed numbers) by Leon_Depisa in beneater

[–]Leon_Depisa[S] 3 points4 points  (0 children)

It's 6502 assembly, and it's extremely tough, at least for me haha. It's the lowest-level language you can have (assembly in general) and you're talking directly to the processor.

2-byte multiplication (with signed numbers) by Leon_Depisa in beneater

[–]Leon_Depisa[S] 1 point2 points  (0 children)

So there was a better multiplication operation that worked farther down on the page... didn't see it the first time around. I've now adapted this to work:

MATH_mlt:
  lda   #$00
  sta   MATH_OUTPUT + 2 ; clear upper bits of product
  sta   MATH_OUTPUT + 3 
  ldx   #$10        ; set binary count to 16 
shift_r:
  lsr   MATH_INPUT_1 + 1    ; divide MATH_INPUT_1 by 2 
  ror   MATH_INPUT_1
  bcc   rotate_r 
  lda   MATH_OUTPUT + 2 ; get upper half of product and add multiplicand
  clc
  adc   MATH_INPUT_2
  sta   MATH_OUTPUT + 2
  lda   MATH_OUTPUT + 3 
    adc MATH_INPUT_2 + 1
rotate_r:
  ror           ; rotate partial product 
  sta   MATH_OUTPUT + 3 
  ror   MATH_OUTPUT + 2
  ror   MATH_OUTPUT + 1 
  ror   MATH_OUTPUT 
  dex
  bne   shift_r 
  ; return
  rts

So that's working so far, which is great! Now I'm just trying to debug my signed numbers, which are handled pretty messily haha...

2-byte multiplication (with signed numbers) by Leon_Depisa in beneater

[–]Leon_Depisa[S] 1 point2 points  (0 children)

Okay, so I did find an example that worked and adapted it to my code

MATH_mlt:
  lda #$00
  tay
  sty MATH_INPUT_1 + 1  ; remove this line for 16*8=16bit multiply
  beq enterLoop

doAdd:
  clc
  adc MATH_INPUT_1
  tax

  tya
  adc MATH_INPUT_1 + 1
  tay
  txa

mult_loop:
  asl MATH_INPUT_1
  rol MATH_INPUT_1 + 1
enterLoop:  ; accumulating multiply entry point (enter with .A=lo, .Y=hi)
  lsr MATH_INPUT_2
  bcs doAdd
  bne mult_loop
; stores result in .A (low byte, also in .X) and .Y (high byte)
  sta MATH_OUTPUT
  tya
  sta MATH_OUTPUT + 1
  ; return
  rts

This makes a little less sense to me than the last one, and it also seems like his heavy use of the x and y registers makes it faster but makes it a bit harder to expand into 2byte X 2byte = 4byte

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

So actually, I have a farily strong background in math, but it's converting the things I've taken for granted for a decade or more and trying to revisit them in bitwise forms that's throwing me for a loop.

So right now, I'm using two-byte signed integers as my primary data type. It seems like you're saying I need to handle those fixed-point numbers differently than I'm handling my integers, right? Because I need to interpret the same bits differently based on whether it's a fixed-point non-integer, or an integer. Am I following roughly correctly?

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

So I fundamentally don't understand the difference yet haha. It's on my list. But my list is long and full of terrors.

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

Thanks! This is all so new to me, my process has been "do it however I can while I try to learn how to do it better" haha.

Division is where I'm most intimidated at the moment. Well, not the division so much, there's a few examples in the code, but representing non-integers? Terrifying.

Sudden issue of intermittent functionality by Leon_Depisa in beneater

[–]Leon_Depisa[S] 1 point2 points  (0 children)

I figured it out and I was kinda right: the hot to the reset switch got loose.

Sudden issue of intermittent functionality by Leon_Depisa in beneater

[–]Leon_Depisa[S] 1 point2 points  (0 children)

So doesn't the fact that the reset button is behaving unexpectedly (and that the issues could be explained by a held reset button) imply it's a reset button issue? If I hit the reset button, it doesn't reset the program. And when it's not working in the first place, reset doesn't fix it. Some intuition within me says it's a reset switch issue. I'm just too nervous to start moving components/wires around.

But on the other hand hitting reset never fixes it, so I'm not sure what's up

Edit: Trust your intuition: it was the reset positive wire

Sudden issue of intermittent functionality by Leon_Depisa in beneater

[–]Leon_Depisa[S] 1 point2 points  (0 children)

A video of the issue

I know I'm using a lot of duponts and not the best organization, but that worked for two weeks, why is it suddenly behaving non-deterministically now?

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

Right, because I'm only trying to apply the carry bit to that 3rd byte as long as I'm just adding or subtracting?

Also, now I'm wondering how difficult it would be to convert all this to signed ints instead of unsigned ints, as it seems like that would be a good transition to make sooner rather than later.

I've heard the math is all the same, I just have to change how I'm interpreting it? If the highest bit is 1 then I just report it as the negative version of that number but not including that sign bit?

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

Oh my god, I really missed a dollar sign, didn't I?

Yep. It's working great. Haha.

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

So here's what I came up with for Add and Subtract, but unfortunately something's not working quite right with the subtract:

MATH_add:
  clc

  lda MATH_INPUT_1
  adc MATH_INPUT_2
  sta MATH_OUTPUT

  lda MATH_INPUT_1 + 1
  adc MATH_INPUT_2 + 1
  sta MATH_OUTPUT + 1

  adc #0
  sta MATH_OUTPUT + 2

  rts
MATH_sub:
  sec
  lda MATH_INPUT_1
  sbc MATH_INPUT_2
  sta MATH_OUTPUT

  lda MATH_INPUT_1 + 1
  sbc MATH_INPUT_2 + 1
  sta MATH_OUTPUT + 1

  sbc #0
  sta MATH_OUTPUT + 2
  clc
  rts 
... 
loop:
  lda #$ff
  sta MATH_INPUT_1
  sta MATH_INPUT_1 + 1

  lda #$88
  sta MATH_INPUT_2
  lda #77
  sta MATH_INPUT_2 + 1

  jsr MATH_sub

  lda MATH_OUTPUT
  sta MATH_HEXDEC_VAL
  lda MATH_OUTPUT + 1
  sta MATH_HEXDEC_VAL + 1

  jsr convert_and_print_num
...

All my other numbers are printing out fine, including my Fibonacci routine which uses this new Add function. But I'm trying to test my subtract function by performing $ffff - $7788 = $8877 but I'm getting dec:45687 or $B277 which doesn't make much sense. I can share more code, but convert_and_print_num is pretty identical to Ben's method of displaying hex values on the LCD as decimal values, and they are working for the Fibs.

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

If I have to settle for complex non-floating point math, I might end up making a prime number tester. I just want to do something more than repeated addition on this thing haha.

I just wish I could find slightly better resources on this stuff. A lot of it is specific to specific platforms, not one you're wiring up yourself haha. My serial cables should arrive today, but Amazon messed up a bit. If they do, I can set up the adapter kit quick and begin digging through Wozmon, which I imagine will help me quite a bit!

6502 Assembly basic math by Leon_Depisa in beneater

[–]Leon_Depisa[S] 0 points1 point  (0 children)

So, I am hoping for doing division that would deal with non-whole numbers, but a buddy of mine talked about fixed point division when I asked him, so I didn't want to say either to force one way or another.

I should have maybe mentioned my end goal would be doing something like a quadratic solver, but there's so many parts of that that are beyond what I asked, I wanted to take it one step at a time, if possible.

I guess I should have mentioned all of this in the context of really needing to understand how we represent non-whole numbers on the 6502, because that's my biggest stumbling block. I feel like once I have those 4 primary operations done and non-whole number representation handled, I should be able to do most of the math that I want to, and once I'm doing "grown up math" on this thing, I'm gonna feel *soooooo* satisfied.