Page 1 of 1

16-bit Subtraction

Posted: Wed Nov 03, 2021 7:15 pm
by ty9000
Hello all! I am working on expanding the Ben Eater 6502 project and I started looking at implementing a serial function, with data coming from an Arduino and being loaded into RAM. I managed to get the code to work properly, but only for an 8-bit amount of instructions. If the number of instructions is > 255, my code breaks down. I'm not sure exactly what the issue is, though. I've tried the "standard" 16-bit subtraction code snippit from https://dwheeler.com/6502/oneelkruns/asm1step.html to completely replace what I have, but it didn't work, even for an 8-bit number. Here is the code I'm using:

Code: Select all

(BYTECOUNT and BYTECOUNT+1 are used to keep track of how many instructions are to be sent from the Arduino)
(These numbers are 1 based, i.e. when the BYTECOUNT (and BYTECOUNT+1) are 0, there are no more instructions left and the code should branch out to the end)

.byteToRam:
  ; Receive 8 individual bits and construct them into a byte
  jsr .receiveBits
  ; Builds up IECDATA as the byte
  
  ; Save byte to RAM
  ; USRMEM is the location in RAM the code can start writing to = $0400
  ; X starts at 0
  lda IECDATA
  sta USRMEM,X
  INX
  
  dec BYTECOUNT
  beq .highByte
  jmp .byteToRam

.highByte:
  lda BYTECOUNT+1
  bne .decBC1
  jmp .end
  
.decBC1:
  dec BYTECOUNT+1
  lda #%11111111
  sta BYTECOUNT
  jmp .byteToRam

.end:
  cli ; enable interrupts
  jmp USRMEM
I have one thought that the above code is missing the 0th byte when there is more than 255 instructions to pass in, i.e. byte 256 or 512, etc. I tried coding for that, but it still didn't work as I expected. Does anyone have any ideas and/or simplifications? I really appreciate it! Please let me know if more detail is required and I shall add it.

Thanks!

Re: 16-bit Subtraction

Posted: Wed Nov 03, 2021 7:33 pm
by drogon

Code: Select all

  ; Save byte to RAM
  ; USRMEM is the location in RAM the code can start writing to = $0400
  ; X starts at 0
  lda IECDATA
  sta USRMEM,X
  INX
Before going any further, you know that the X register is only 8-bits wide and will wrap to zero after 255 ...

-Gordon

Re: 16-bit Subtraction

Posted: Wed Nov 03, 2021 7:43 pm
by ty9000
drogon wrote:
Before going any further, you know that the X register is only 8-bits wide and will wrap to zero after 255 ...
-Gordon
Doh! That's what my issue is! I even thought about that a few days ago before I started to code anything and I must have just forgotten about it in all the excitement of getting the code to initially work. Thanks for the second set of eyes - I couldn't see the forest for the trees. Haha! :lol:

Re: 16-bit Subtraction

Posted: Wed Nov 03, 2021 7:50 pm
by drogon
ty9000 wrote:
drogon wrote:
Before going any further, you know that the X register is only 8-bits wide and will wrap to zero after 255 ...
-Gordon
Doh! That's what my issue is! I even thought about that a few days ago before I started to code anything and I must have just forgotten about it in all the excitement of getting the code to initially work. Thanks for the second set of eyes - I couldn't see the forest for the trees. Haha! :lol:
If using a 65C02 (which I think you will be with the Ben Eater setup), then

Code: Select all


; Initialisation

dataStore = $0400

    lda    #<dataStore
    sta    usrmem+0
    lda    #>dataStore
    sta    usrmem+1

....

; Store value

    sta    (usrmem)
    inc    usrmem+0
    bne    foo
     inc    usrmem+1
foo:

; do the length subtraction here, etc. 

    jmp    dataStore
-Gordon

Re: 16-bit Subtraction

Posted: Wed Nov 03, 2021 9:28 pm
by ty9000
Yes, that was it - thank you so very much! That has been kicking my butt for way too long. Adding in that code even made the program shorter, overall. Still trying to get the hang of this all. Thanks again!!

Re: 16-bit Subtraction

Posted: Wed Nov 03, 2021 9:33 pm
by Dr Jefyll
Welcome to the land of 65xx, ty9000, and welcome to this forum! :)

-- Jeff

Re: 16-bit Subtraction

Posted: Thu Nov 04, 2021 2:23 pm
by teamtempest
For your subtraction set, another idea is:

Code: Select all


    sec
    lda bytecnt
    sbc #<1              ; ie., 1
    sta bytecnt
    lda bytecnt+1
    sbc #>1              ; ie., 0
    sta bytecnt+1
    ora bytecnt
    bne bytetoram         ; b: both not zero yet...
or something like this:

Code: Select all


    lda bytecnt
    bne notzero
    lda bytecnt+1
    beq finished
    dec bytecnt+1

notzero
   
    dec bytecnt
    bra bytetoram

finished


Re: 16-bit Subtraction

Posted: Thu Nov 04, 2021 2:50 pm
by barrym95838
That second example is properly optimized ... neat!

[Be careful about using it though, because it checks for zero before the decrement instead of after ...]

Re: 16-bit Subtraction

Posted: Mon Nov 08, 2021 5:34 pm
by Meterman58761
I'm curious as to how your .receieveBits routine works.

I have some code I'm working on that also involves converting a serial stream into bytes:

Code: Select all

lda piaPortA
ror A
rol presentSIByte
; piaPortA is port A on a MC6821 PIA
; roll bit 0 to carry, then into current byte being received

(test status of transmitter flag)

dec bitcount
; bitcount is continuously decremented - only last 3 bits are important
lda bitcount
and #$07
beq itsmathtime
; if we have counted off 8 bits, continue into math section, else exit interrupt
rti

.itsmathtime
lda presentSIByte
sta lastSIByte
(continue with the math)

Re: 16-bit Subtraction

Posted: Sun Nov 21, 2021 5:56 pm
by ty9000
Meterman58761 wrote:
I'm curious as to how your .receieveBits routine works.
So, I did move away from bit-banging the code into RAM one bit at a time and instead moved over to "byte-banging" the code using a '595 shift register. It's much more stable this way. But, I do still have the .receiveBits code around:

Code: Select all

BITCOUNT is reset to 8 before getting to .receiveBits

.receiveBits:  
  lda PORTA ; the bit coming in needs to be shifted left 4 times (for my hardware setup) in order to get it into the carry bit
  asl a
  asl a
  asl a
  asl a
  ror presentSIByte
  
  dec BITCOUNT
  bne .receiveBits
  jsr .byteSetup
Does this help some?