6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun May 19, 2024 5:06 am

All times are UTC




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: 6502 Assembly Language
PostPosted: Tue Nov 18, 2003 10:37 am 
Offline

Joined: Tue Nov 18, 2003 10:31 am
Posts: 7
Can anyone help me by finishing off this bit of Language? I'm stuck.... :?

Yours Thankfully
Mark

org $500

DATA = $400 ; Start of source of numbers to sort.
TEMP = $410 ; Temporary location.
LPCTR = $411 ; Loop counter.
NNUMS = $412 ; The number of numbers to sort.

MAIN ;SEI ; Interrupts off. Uncomment this if
; getting unpredictable results.
JSR INIT ; Call init sub-routine.
OUTER LDA LPCTR ; If we have sorted
CMP NNUMS ; all the numbers,
BEQ HALT ; branch to HALT,
JSR INNER ; else call INNER sort routine,
INC LPCTR ; increment loop counter and
JMP OUTER ; go back to start of loop.


; initialises data and loop counter
INIT LDA #1 ; Initialises loop
STA LPCTR ; counter to 1.
LDA #$10 ; Initialises NNUMS
STA NNUMS ; to 16.
LDX #00 ; Stores numbers
L1 STA DATA, x ; 16 down to 1
INX ; in increasingly
SEC ; higher
SBC #1 ; locations
BNE L1 ; from DATA,
RTS ; indexed by x.

; exchange sort loop
; smallest number in lowest memory location
INNER ; To
; Be
; Completed
;
RTS ;

; swaps locations indexed by x and y
SWAP LDA DATA, x ;
STA TEMP ;
LDA DATA, y ;
STA DATA, x ;
LDA TEMP ;
STA DATA, y ;
RTS ;

HALT BRK ;

end


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 18, 2003 4:42 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1687
Location: Sacramento, CA
Mark,

From your code, its looks as if you are doing an exchange sort. The outer loop will cycle 16 times. You need a method of comparing two locations and swapping them if they are not ordered correctly in such a way as to ensure all locations are ordered within those 16 outer loops.

I dug back on my old Quick basic files a found this exchange sort routine.
If you understand BASIC, then you should have no trouble converting to assembly.

Code:
; Your Outer Loop
MaxCnt = 16
FOR X = 1 TO MaxCnt

     ; Your inner loop
     Smallest = X
     FOR J = X + 1 TO MaxCnt
        IF Array(J) < Array(Smallest) THEN Smallest = J
     NEXT J
     IF Smallest > X THEN SWAP Array(X), Array(Smallest)

NEXT X                                                                           


Give that a try and post us your solution!

Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 18, 2003 7:57 pm 
Offline

Joined: Tue Nov 18, 2003 10:31 am
Posts: 7
Thanks for your help. This is what i've come up with so far but is still doesn't want 2 work for some reason. Ahhhhhhhhhhhh.

; exchange sort loop
; smallest number in lowest memory location
INNER
L3 LDA LPCTR
CMP NNUMS
BEQ HALT
BNE L4
L4 LDA DATA, x
CMP DATA, y
BEQ L2
BMI L2
BPL SWAP
BCS SWAP
INX
INY
RTS

L2 INC LPCTR
JMP L3
RTS[/list]


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 18, 2003 8:53 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1687
Location: Sacramento, CA
Mark,

Quote:
L3 LDA LPCTR
CMP NNUMS
BEQ HALT

This code is redundant. Its already being performed in your outer loop.

Quote:
BNE L4

This code can be deleted

Quote:
L4 LDA DATA, x
CMP DATA, y

You need to initialize the x & y pointers before you begin your loop.

Quote:
BEQ L2
BMI L2
BPL SWAP
BCS SWAP

You are using too many branching commands. One is enough.
Try BCS or BCC. BCS with jump if DATA,y is < DATA,x - BCC will jump if DATA,y >= DATA,x
Quote:
INX
INY
RTS

You are not properly recreating the FOR NEXT loops here. Take a second look.

Quote:
L2 INC LPCTR
JMP L3
RTS

Again, this is part of your outer loop.

I can see you are making progress. Hang in and give it another try. Remember, your inner loop is a subroutine, being JSR's into from the outer loop. There should be an RTS at the end of the inner loop with no JMP's or BRx's outside of the inner loop. However, your swap function is also a subroutine so at one point inside your inner loop, you'll need to JSR SWAP.

A block diagram would look something like this:
Code:
Init data locations with scrambled data
init pointers to the data area

Outer Loop
  count from first element to the last element
  JSR to Inner Loop
  inc count
  count = last element?
  no - do outer loop again
done

Inner Loop Sub
  init pointers
  count from outerloop's value to last element
    compare the two data bytes
    out of order?
       yes - set new smallest pointer
    inc innner loop counter
    equal to last element?
  no - loop back to inner count
  JSR SWAP
RTS

Swap Sub
  swap two values
RTS


Post back your entire program once you've looked at it again and I'll be glad to help more.

Daryl


Top
 Profile  
Reply with quote  
 Post subject: a quibble
PostPosted: Tue Nov 18, 2003 10:30 pm 
Offline

Joined: Tue Nov 18, 2003 8:41 pm
Posts: 250
I suppose you're trying to keep it simple, but you don't
need to start by comparing the current element to itself.
You can start by assuming it's the smallest and then
skipping the swap if that turns out to be the case.


something like:

Inner Loop Sub
SmallestPointer=LPCTR
InnerLoopCounter=LPCTR

inc InnerLoopCounter
compare the two data bytes
out of order?
yes - set new SmallestPointer
InnerLoopCounter pointing to last element?
no - loop back

LPCTR=SmallestPointer?
yes - branch to RTS and skip the swap
JSR SWAP
RTS


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 19, 2003 2:20 pm 
Offline

Joined: Tue Nov 18, 2003 10:31 am
Posts: 7
I tried this and it still wont work...... :(

; exchange sort loop
; smallest number in lowest memory location
INNER LDA LPCTR
CMP NNUMS
BEQ HALT
JSR OUTER
INC LPCTR
JMP INNER
LDA DATA, x
CMP DATA, y
INC LPCTR
BEQ L2

JSR SWAP
L2 RTS


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 19, 2003 4:23 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1687
Location: Sacramento, CA
Mark,

I suggest you take a step back from your code for a moment and make sure you understand what you are trying to do. Get out some paper and perform an exchange sort by hand. Get to know the steps involved such as initializing counters and pointer, doing the loops, making the comparisions and understanding what the swap is doing and why. Try sorting just 4 objects this way.

Then, you should have a better grasp of what your code should be doing. If you need help with the explanation of how the exchange sort works, then you can email me privately and I'll help you in more detail.

Give it a try!

Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Nov 19, 2003 5:29 pm 
Offline

Joined: Tue Nov 18, 2003 8:41 pm
Posts: 250
It seems to me that you must be missing some
really fundamental stuff about what's going
on but it's hard to know how to correct you,
since (to me any way) your code makes no sense.

To that end, I'd suggest you comment each line
and tell exactly what you think it's doing and
exactly why you think it should be doing that.

But I'll elaborate on a previously made
observation.

Your inner loop shouldn't be futzing with
LPCTR

(I think it would be generally agreed) that
it's good form to break your code into seperate
easy to understand and easy to impliment functions
or actions that interfere with each other
as little as possible.

You've got a good start.

In this case, the outer loop deals with LPCTR
the inner loop scans for the smallest remaining
value and swap puts it in place

The task is to scan through the locations in
order picking the lowest value from the remaining
locations and putting it in the place that
LPCTR is pointing to.

The outer loop does that scanning. It manages LPCTR
It starts LPCTR at the beginning increments it and
tests LPCTR to see if it's done and exits if it is.
And it calls the inner loop for each value (except
maybe the last location)


The inner loop looks through the remaining locations
picks the location of the smallest remaining value
and passes that to the swap routine if necessary.
The inner loop needs to know what LPCTR is since
LPCTR points to the location that the inner loop
is going to sort/fix/change
and any location below where the LPCTR points is
already done and so can and should be skipped by the
inner loop
and anything above where the LPCTR points needs to
be scanned for the next smallest value.
But the inner loop only needs to know the value of
the LPCTR it shouldn't be messing with it.
it doesn't need to, and it shouldn't, test or change
LPCTR, that's the resonsibility of the outer loop.


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 20, 2003 3:55 pm 
Offline

Joined: Tue Nov 18, 2003 8:41 pm
Posts: 250
I said your code makes no sense.

I didn't mean that the way it sounds.

first, I was refering to the latest rendition of the inner loop
and second, I should have said you're doing things in it that don't seem to make much sense.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Nov 20, 2003 4:28 pm 
Offline

Joined: Tue Nov 18, 2003 10:31 am
Posts: 7
I am trying to change the numbers which i have in the memery location from being unordered to being ordered.....

from this:
L0400,2
400 10 0F 0E 0D 0C 0B 0A 09
408 08 07 06 05 04 03 02 01

to this:
L0400,2
400 01 02 03 04 05 06 07 08
408 09 0A 0B 0C 0D 0E 0F 10


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Nov 20, 2003 5:02 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1687
Location: Sacramento, CA
tiplam00 wrote:
I am trying to change the numbers which i have in the memery location from being unordered to being ordered.....

from this:
L0400,2
400 10 0F 0E 0D 0C 0B 0A 09
408 08 07 06 05 04 03 02 01

to this:
L0400,2
400 01 02 03 04 05 06 07 08
408 09 0A 0B 0C 0D 0E 0F 10


Right. Now, can you manually go through the steps it takes to sort these?

Try this:
Code:
Set a pointer (LPCTR) to $00
set a pointer to the first value (SMALL this pointer will hold the lowest value found)
Do a loop from LPCTR+1 to the end of the lost
  within the loop, compare the value pointed to by the loop variable with the one pointed to by SMALL
  If the loop variable is smaller, then point SMALL to the new value
  inc the loop and repeat until you reach the last value

At this point, you have two pointers.  LPCTR and SMALL.  SMALL points to the smallest value in the entire list.  You want to move it to the first position, so do a swap using these two pointers.

Now, increment LPCTR and do the whole thing over until you reach the last value.  As you inc LPCTR, you'll be comparing only the remaining, unsorted items and building them in ascending order.


Do this process on paper. It works. Now, try to find your outer and inner loops from my description above. Lastly, convert it to code.

Your first post in 100% correct. All you need to do is fill in the inner loop steps.

Give it a try and post your entire program back here. And as Bogax stated, USE comments on every line (as you did on the first post) to help you keep your logic flowing correctly.

We'll be waiting for your solution!

Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Nov 20, 2003 8:50 pm 
Offline

Joined: Tue Nov 18, 2003 10:31 am
Posts: 7
I know this is still wrong but am i getting any closer?

org $500

DATA = $400 ; Start of source of numbers to sort.
TEMP = $410 ; Temporary location.
LPCTR = $411 ; Loop counter.
NNUMS = $412 ; The number of numbers to sort.

MAIN ;SEI ; Interrupts off. Uncomment this if
; getting unpredictable results.
JSR INIT ; Call init sub-routine.
OUTER LDA LPCTR ; If we have sorted
CMP NNUMS ; all the numbers,
BEQ HALT ; branch to HALT,
JSR INNER ; else call INNER sort routine,
INC LPCTR ; increment loop counter and
JMP OUTER ; go back to start of loop.


; initialises data and loop counter
INIT LDA #1 ; Initialises loop
STA LPCTR ; counter to 1.
LDA #$10 ; Initialises NNUMS
STA NNUMS ; to 16.
LDX #00 ; Stores numbers
L1 STA DATA, x ; 16 down to 1
INX ; in increasingly
SEC ; higher
SBC #1 ; locations
BNE L1 ; from DATA,
RTS ; indexed by x.

; exchange sort loop
; smallest number in lowest memory location
INNER LDA #$00 ; Start of source of numbers to sort.
LDX #1 ; Initiate pointers
LDX #2 ; Initiate pointers
LDA LPCTR+1 ; Count elements
CMP DATA ; Compare 2 data types
STA #1 ; Set new smallest pointer
L2 JSR INNER ; Increment INNER loop counter
BCS L2 ; Loop back to INNER counter
JSR SWAP ; Swap locations
RTS ; End

; swaps locations indexed by x and y
SWAP LDA DATA, x ;
STA TEMP ;
LDA DATA, y ;
STA DATA, x ;
LDA TEMP ;
STA DATA, y ;
RTS ;

HALT BRK ;

end


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Nov 21, 2003 6:32 am 
Offline

Joined: Tue Nov 18, 2003 8:41 pm
Posts: 250
Looks to me like every thing except the inner loop
routine will work (but I don't guarantee anything,
I may have missed something, I often do :)

except..

Looking at the inner loop, I'm wondering
if you're confused about how an assembler works.

; exchange sort loop
; smallest number in lowest memory location
INNER LDA #$00 ; Start of source of numbers to sort.
label INNER the name of the location of this
LDA instruction and this instruction loads the
accumulator immediate with 0
ie takes the value of the byte (which in this case
will be zero) following the LDA instruction in
the object code (that the assembler puts out) and
puts it in the accumulator

LDX #1 ; Initiate pointers
load the X register immediate with 1

LDX #2 ; Initiate pointers
load the X register immediate with 2, but you didn't
do anything with the 1 and now it's gone, what was
it for?

LDA LPCTR+1 ; Count elements
now this is what makes me think you may be confused
about how an assembler works.
When you told the assembler:

LPCTR = $411

you were naming a constant for you and/or the
assembler to use, not creating a program variable.
sort of like immediate mode in basic.
(I should say here, I don't know what assembler
you're using and not all assemblers are the same
so I can't really be sure, but I think this is the
way it usually works)
so now the assembler looks at this instruction and
probably assumes LPCTR+1 is meant as an address so it
sees that as a load accumulator from address LPCTR+1,
$411+1 in other words this instruction comes out the same
as LDA $412 and loads the accumulator from the location
in memory that's right after the the LPCTR location,
which is the location in memory corresponding to NNUMS
in other words this instrustion is also the same as
LDA NNUMS, and every time you do that instruction in
your loop it's going to load the accumulator from
location $412
ie it doesn't change LPCTR, memory location $411

CMP DATA ; Compare 2 data types
DATA is $400 so you're comparing the the first element
of your list, the contents of memory location $400
(which you intialised to $10) to the value you just
loaded into the accumulator, the value from
location NNUMS (which you initialised to $10)

STA #1 ; Set new smallest pointer
unless your assembler is rather odd, this is a
'store accumulator immediate' instruction
(or something) and there is no such instruction

L2 JSR INNER ; Increment INNER loop counter
label L2 the name of the location of this JSR
now we jump subroutine back to location INNER
you push the current value of the program
counter on to the stack and jump to INNER
so you never get past this point and every
time you get here you increase the number of
bytes on the stack by two
(pretty soon you're going to run out of stack)

BCS L2 ; Loop back to INNER counter
you won't get here, but if by some dark miracle
you should get past the previous instruction :),
you'll branch right back to it 'cause you
just compared $10 to $10 and that should set the
carry and BCS L2 looks at the carry and branches
to L2 if the carry is set

JSR SWAP ; Swap locations
RTS ; End


Maybe I'm misinterpreting your intent in this code
but it looks like you're making mistakes in the
inner loop that you didn't make elsewhere.

And I'm still wondering what an assembler could
make of STA #1
I'm guessing you haven't tryed to assemble it,
but maybe your assembler uses a syntax I'm not
familiar with, and if that's so, a lot of what
I just said about what your code does maybe
rubbish

Did you write the rest of it?
Or is this, like, homework?
"your assignment: right an inner loop for this
sort routine"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Nov 21, 2003 8:28 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8440
Location: Southern California
I was going to stay out of this one, but here goes. I hope this wasn't homework because I just did it for you. But maybe to leave some challenge, I should leave it mostly uncommented. Then if the teacher requires you to understand it, at least you have something working to "reverse-engineer". I initially had the swap to be only three instructions, but the assembler reminded me there's no STY abs,X like there's an LDY abs,X. so I used TYA and lengthened it to four instructions. Then it ran on the first try. I didn't use your TEMP variable or any subroutines.

Code:
        DEC NNUMS    ; There are n-1 pairs.

        LDX NNUMS
        STX LPCNT

loop2:  LDX NNUMS
loop1:  LDA DATA,X
        CMP DATA-1,X
        BCS no_swap

        LDY DATA-1,X
        STA DATA-1,X
        TYA
        STA DATA,X

no_swap:DEX
        BNE loop1

        DEC LPCNT
        BNE loop2

        INC NNUMS    ; Restore NNUMS' original value.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Nov 21, 2003 12:24 pm 
Offline

Joined: Tue Nov 18, 2003 10:31 am
Posts: 7
I tried this code but my memory locations just ended up being like this:

L0400,2
400 10 10 10 10 10 10 10 10
408 10 10 10 10 10 10 10 10

What did i do wrong??????????????


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 6 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: