6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 01, 2024 8:26 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Sun Oct 03, 2021 2:41 am 
Offline

Joined: Sun Oct 03, 2021 2:17 am
Posts: 114
Hi, I am curious why the MVN instruction decrements C until it rolls under to $FFFF instead of stopping at zero. I know many programming languages increment loop counters until they are one past the last valid value in a for loop, so maybe it's something like that.

Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 03, 2021 7:42 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1482
Location: Scotland
jeffythedragonslayer wrote:
Hi, I am curious why the MVN instruction decrements C until it rolls under to $FFFF instead of stopping at zero. I know many programming languages increment loop counters until they are one past the last valid value in a for loop, so maybe it's something like that.

Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.


I don't know exactly, but I suspect 2 reasons - one is that it might take less logic to detect bit 15 of the counter going from 0 to 1 than to test for bits 0:15 = 0, also if it were the exact number of bytes then you would not be able to move 65536 bytes without needing a 17-bit register.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 03, 2021 7:58 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8468
Location: Midwestern USA
jeffythedragonslayer wrote:
Hi, I am curious why the MVN instruction decrements C until it rolls under to $FFFF instead of stopping at zero. I know many programming languages increment loop counters until they are one past the last valid value in a for loop, so maybe it's something like that.

Is there a hardware reason for this? The way it works, according to Eyes & Lichty, seems to be that you need to put the # of bytes to move minus 1 into C, not simply the # of bytes.

I see Gordon replied and echoed my thoughts. It's likely the internal logic needed to determine when terminal count has been reached was simpler by having all bits in .C flipped to 1 at the end. So, yes, .C has to be loaded with the COUNT - 1, which means COUNT = 0 will copy one byte.

Note that MVN and MVP, unlike all other instructions, can be interrupted. That being the case, it is essential that your interrupt service routine (ISR) exactly preserve the microprocessor's state and exactly restore it when interrupt servicing has completed. Otherwise the copy operation will likely go off the rails when the ISR returns control to the foreground.

The front end I use in my ISR is:

Code:
         rep #%00110000        ;16-bit everything
         phy                   ;preserve MPU state
         phx
         pha
         phb
         phd
         ...program continues...

The return is:

Code:
         rep #%00110000        ;16-bit everything
         pld                   ;restore MPU state
         plb
         pla
         plx
         ply
         rti

The above methods work because when RTI is executed the status register (SR) will be pulled, putting all the flags back the way they were when the interrupt was serviced. Since the m and x flags in SR determine register sizes, the pulling of SR when RTI is executed will automatically set the registers to whatever size they were before the interrupt.

Another "quirk" of MVN and MVP is they tinker with DB, setting it to the destination data bank. Therefore is wise to push DB before the copy and then pull it afterwards to put things back in order:

Code:
         rep #%00110000        ;16-bit everything
         lda #count-1          ;bytes to copy -1
         ldx #source & $FFFF   ;source address LSW
         ldy #dest & $FFFF     ;destination address LSW
         phb                   ;protect current data bank
         mvn #source,dest      ;execute copy
         plb                   ;back to current data bank
         ...program continues...

The official WDC assembly language syntax for MVN and MVP has the full 24-bit source and destination addresses as the operands. The WDC assembler performs <address> >> 16 to extract the banks. In the Kowalski assembler, only the banks are used as the operands. The WDC syntax is more logical in terms of how the programmer would think about the source and destination, but the Kowalski syntax is easier for the assembler to parse. In a 65C816 machine language monitor, only the banks would be assembled with the instruction.

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


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 03, 2021 8:05 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8468
Location: Midwestern USA
drogon wrote:
...one is that it might take less logic to detect bit 15 of the counter going from 0 to 1 than to test for bits 0:15 = 0...

That seems likely.

Quote:
...also if it were the exact number of bytes then you would not be able to move 65536 bytes without needing a 17-bit register.

If MVN/MVP had been designed to use the exact count I supposed setting the initial count to $0000 would give you the full 64 KB copy when .C returned to $0000. However, bit 15 flipping from 0 to 1 is an easy test.

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


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 03, 2021 2:32 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Welcome, jeffythedragonslayer!

As for your question, I think WDC simply provided what the programmer would want. As Gordon noted, C is a register with only 16 bits, and that means a choice had to be made. So, just ask yourself which seems more useful. Would you rather have...
    a minimum move of 0 bytes and a maximum move of $FFFF bytes, or
    a minimum move of 1 bytes and a maximum move of $10000 bytes ?


As for the screen name you've chosen for yourself, jeffythedragonslayer seems intended to resonate with Buffy the Vampire Slayer -- is that right?

For me, that's somewhat interesting and amusing, given that my own handle -- a nickname I acquired as a teenager -- is intended to resonate with Dr Jekyll from Robert Louis Stevenson's Strange Case of Dr Jekyll and Mr Hyde. :P

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 25, 2021 2:47 am 
Offline

Joined: Sun Oct 03, 2021 2:17 am
Posts: 114
Thank you for your enlightening replies. It's a nickname a friend game me in high school - I've never asked him if it had anything to do with Buffy.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


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: