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
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!

Re: 16-bit Subtraction
Posted: Wed Nov 03, 2021 7:50 pm
by drogon
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!

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
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?