6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 15, 2024 5:36 pm

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Fri Aug 30, 2019 5:10 pm 
Offline

Joined: Mon Aug 26, 2019 2:06 pm
Posts: 12
In Programming the 6502 there is a chapter on IO techniques. Zak's shows a piece of code like this:

Code:
        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:
        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


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 30, 2019 11:23 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8490
Location: Midwestern USA
andrew wrote:
In Programming the 6502 there is a chapter on IO techniques. Zak's shows a piece of code like this:

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

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 31, 2019 12:01 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
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:
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.


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 31, 2019 8:51 am 
Offline

Joined: Mon Aug 26, 2019 2:06 pm
Posts: 12
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.


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 31, 2019 3:19 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
I found it online:
Attachment:
watchfail.JPG
watchfail.JPG [ 18.26 KiB | Viewed 763 times ]

The single-word comment appears to be appropriate in more ways than one.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 01, 2019 7:42 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10980
Location: England
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 02, 2019 2:06 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
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.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Thu Sep 05, 2019 5:55 pm 
Offline

Joined: Mon Aug 26, 2019 2:06 pm
Posts: 12
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


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: