Page 1 of 1

help understanding data transfer

Posted: Fri Aug 30, 2019 5:10 pm
by andrew
In Programming the 6502 there is a chapter on IO techniques. Zak's shows a piece of code like this:

Code: Select all

        LDX     COUNT
WATCH   LDA     STATUS
        BPL     WATCH
        LDA     INPUT
        PHA
        DEX
        BNE     WATCH          
I feel I understand this, it "watches" STATUS, then when bit 7 is one, it transfers INPUT to the stack, decreases X, then goes back to watching STATUS.

He then discusses what would happen if the data you wanted to transfer was > 256 words and to large for the stack. To deal with this, he proposes to modify the code to this:

Code: Select all

        LDY     #0
WATCH   LDA     STATUS
        BPL     WATCH
        STA    (POINTER), Y
        INC    (POINTER)
        DEC    COUNT
        BNE     WATCH          
This I am not sure on. He is still watching the status. But then he wants to transfer the status from the accumulator to (POINTER), Y. This feels like a mistake to me. It also seems strange that he is incrementing POINTER, rather than Y.

I have been thinking about this for a while and cannot figure out his motivation here. Does anyone have any thoughts? Thanks

Re: help understanding data transfer

Posted: Fri Aug 30, 2019 11:23 pm
by BigDumbDinosaur
andrew wrote:
In Programming the 6502 there is a chapter on IO techniques. Zak's shows a piece of code like this:

Code: Select all

        LDX     COUNT
WATCH   LDA     STATUS
        BPL     WATCH
        LDA     INPUT
        PHA
        DEX
        BNE     WATCH          
I feel I understand this, it "watches" STATUS, then when bit 7 is one, it transfers INPUT to the stack, decreases X, then goes back to watching STATUS.

That's a stack smash just waiting to happen. If that code starts out with $FF in .X and an IRQ hits just after .X has reached $00, the stack pointer will wrap and there will be no telling what might happen. The orthodox procedure would be to store the incoming byte into a circular queue, which can be any size you want.
Quote:

Code: Select all

        LDY     #0
WATCH   LDA     STATUS
        BPL     WATCH
        STA    (POINTER), Y
        INC    (POINTER)
        DEC    COUNT
        BNE     WATCH          
INC (POINTER) is not a valid 6502 instruction. Could that be a typo perchance?

Re: help understanding data transfer

Posted: Sat Aug 31, 2019 12:01 am
by Chromatix
The second routine fails to read INPUT, uses the wrong syntax for incrementing the data pointer, and doesn't seem to actually handle the more than 256 words that are advertised. A better alternative, starting with PTR and LEN as 2-byte values in zero page:

Code: Select all

readBlock:
 LDY #0
 LDX LEN+1
 BEQ readTail
bigLoop: ; whole blocks of 256 bytes first
 BIT STATUS
 BPL bigLoop
 LDA INPUT
 STA (PTR),Y
 INY
 BNE bigLoop
 INC PTR+1 ; block finished, move to next one
 DEX
 BNE bigLoop
readTail: ; small block of less than 256 bytes at end
 LDX LEN
 BEQ done
smallLoop:
 BIT STATUS
 BPL smallLoop
 LDA INPUT
 STA (PTR),Y
 INY
 DEX
 BNE smallLoop
done: ; fixup the high byte of PTR that we've been advancing
 SEC
 LDA PTR+1
 SBC LEN+1
 STA PTR+1
 RTS
You may also notice I use BIT instead of LDA. This is a good way to set the N and V flags to bits 7 and 6 of a status byte without clobbering the accumulator.

The above code is an example of a "peeled" loop, which has to repeat the implementation of the loop body in both halves of the loop. It's also common to write routines like this as nested loops, but since you then run out of registers to count and index with, you must keep at least one of them in RAM - preferably one that you only need to use in the outer loop, which is executed less often. Or you could do it as a single loop with conditional decrement of the high half of the counter (kept in RAM) and increment of the pointer. So your exercise might be to try implementing those styles yourself, using my "peeled" example for reference.

Re: help understanding data transfer

Posted: Sat Aug 31, 2019 8:51 am
by andrew
BigDumbDinosaur wrote:
INC (POINTER) is not a valid 6502 instruction. Could that be a typo perchance?
Sorry, that was my fault. It is written as INC POINTER. I've double checked though, the rest is as it is in the book. I hadn't realised what you pointed out about the stack pointer wrapping, its something I'll keep in mind now though, thanks.
Chromatix wrote:
The above code is an example of a "peeled" loop..
Thank you for a working solution, I'll try play around with changing it to different types of loops.

Its a little worrying that his answers appear to be wrong sometimes (failing to read input, not handling >256 words, stack-smashing..) but I suppose making sure you understand his answers and why they might not work is a good way to make sure you're learning.

Re: help understanding data transfer

Posted: Sat Aug 31, 2019 3:19 pm
by barrym95838
I found it online:
watchfail.JPG
The single-word comment appears to be appropriate in more ways than one.

Re: help understanding data transfer

Posted: Sun Sep 01, 2019 7:42 pm
by BigEd
Zaks also has his name on a book for programming the 6800 - I suspect that book came first, there was some copy-pasting, and that leads to errors. The two machines have some broad similarities but many differences. But as he owned the company which published the 6502 book, he wasn't perhaps going to be held to task by an editor.

Re: help understanding data transfer

Posted: Mon Sep 02, 2019 2:06 am
by floobydust
Having some typos seems all too common, even today with modern spell checkers and such. One would think that published source code examples would at least be correct, as in they were compiled or assembled to verify they're correct. Using one's position to publish error-prone material is poor at best and very sloppy indeed.

Back in those early days, I generally bought many of the books published by OSBORNE/McGraw-Hill. Computing books in general, the CRT controller handbook and some of the books from Lance Leventhal (6502 and Z80). One of my favorites is the 6502 Assembly Language Subroutines co-authored by Winthrop Saville. I would likely recommend this one for many decent code examples that were coded and assembled to run on an Apple II, that is, they actually work.

Re: help understanding data transfer

Posted: Thu Sep 05, 2019 5:55 pm
by andrew
floobydust wrote:
Back in those early days, I generally bought many of the books published by OSBORNE/McGraw-Hill. Computing books in general, the CRT controller handbook and some of the books from Lance Leventhal (6502 and Z80). One of my favorites is the 6502 Assembly Language Subroutines co-authored by Winthrop Saville. I would likely recommend this one for many decent code examples that were coded and assembled to run on an Apple II, that is, they actually work.

I think when I finish Zaks I'll move onto one of the ones you have mentioned, thanks. In the long run I'd like to make a small NES game, but I'm enjoying working through textbooks at the moment, so I'm in no rush