6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 4:42 am

All times are UTC




Post new topic Reply to topic  [ 48 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Wed Apr 29, 2020 2:01 am 
Offline

Joined: Fri Nov 16, 2018 8:55 pm
Posts: 71
BitWise wrote:
It can even be structured...
...
which removes the need for labels.


Wow, this feedback is great all the way around.

Damn, BitWise, you rather neatly cleaned that up that code with assembler directives. Sorry for the delay in my reply. I don't always get email notifications when someone post a response.


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 29, 2020 2:27 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
load81 wrote:
BitWise wrote:
It can even be structured...
...
which removes the need for labels.

Wow, this feedback is great all the way around.

Damn, BitWise, you rather neatly cleaned that up that code with assembler directives. Sorry for the delay in my reply. I don't always get email notifications when someone post a response.

It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.

That said, an experienced assembly language programmer can see "structure" in what appears to be alien mumbo-jumbo to programmers who don't know assembly language. The use of macros can help in this regard, as they can be used to substitute English-like statements for complex sequences of assembly language instructions, especially ones that manipulate complicated data structures. I constantly use macros to reduce the tedium of writing large programs, and also as a defensive mechanism against insidious bugs that come from typos or simple character transposition errors, e.g., TXA when what was meant was TAX.

As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen. A very useful tool for that purpose is the Kowalski 6502 simulator, which is a complete development environment, plus a simulator in which to try out your programs. You ought to take a look at it.

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


Last edited by BigDumbDinosaur on Wed Apr 29, 2020 7:48 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 29, 2020 7:41 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 29, 2020 9:05 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
cjs wrote:
The negative and carry flags will be set as appropriate as well, but the result will be thrown away, rather than being stored somewhere.

Each flag is preserved until an instruction is executed which affects that particular flag. For example, if there is an instruction which sets the carry flag followed by several instructions which don't affect the carry flag, the carry flag will still be set and available for a branch on carry set ( BCS ).


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 29, 2020 9:49 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
BigEd wrote:
> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!

That's assuming, of course, the programmer commented his code. I've seen a lot of assembly language source in which a comment would die from loneliness. :D It can be tough going for a novice to try to decipher what such code does.

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


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 7:09 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
BigDumbDinosaur wrote:
BigEd wrote:
> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!

That's assuming, of course, the programmer commented his code. I've seen a lot of assembly language source in which a comment would die from loneliness. :D It can be tough going for a novice to try to decipher what such code does.


Even so, even so: code that's written to do something useful can be worth trying to puzzle out. Not every puzzle comes with hints, and not every puzzle would be better if it did.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 4:44 pm 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 730
Location: Tokyo, Japan
JimBoyd wrote:
cjs wrote:
The negative and carry flags will be set as appropriate as well, but the result will be thrown away, rather than being stored somewhere.

Each flag is preserved until an instruction is executed which affects that particular flag.

Right. But the (numerical) result of the subtraction done by CMP is thrown away; only the flags are kept.

_________________
Curt J. Sampson - github.com/0cjs


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 7:32 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
cjs wrote:
JimBoyd wrote:
cjs wrote:
The negative and carry flags will be set as appropriate as well, but the result will be thrown away, rather than being stored somewhere.

Each flag is preserved until an instruction is executed which affects that particular flag.

Right. But the (numerical) result of the subtraction done by CMP is thrown away; only the flags are kept.

Oops. For some reason I wasn't thinking about the numerical result, just the resulting flags.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 7:50 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
BigEd wrote:
BigDumbDinosaur wrote:
BigEd wrote:
> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!

That's assuming, of course, the programmer commented his code. I've seen a lot of assembly language source in which a comment would die from loneliness. :D It can be tough going for a novice to try to decipher what such code does.


Even so, even so: code that's written to do something useful can be worth trying to puzzle out. Not every puzzle comes with hints, and not every puzzle would be better if it did.


Reverse engineering usually involves disassembling code, then figuring out what it does. It is not uncommon to hear of working with poorly commented code described as "reverse engineering." A good programmer will document things as they are understood instead of leaving the code unchanged.

A comment such as

Code:
    dex    ; Decrement X register


adds no useful information and may as well not be there.

A comment like

Code:
    dex    ; Decrement loop counter


is generally not much better as the structure of a loop is usually obvious.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 8:38 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
My current reverse engineering obsession is WOZ BASIC. I found a few very-lightly commented sources on the 'net, and I am now wading in neck-deep with the goal of figuring out exactly what WOZ was doing throughout that originally hand-assembled ~6K ball of twine. If it somehow magically becomes one of my few projects that reaches a satisfactory conclusion, I'll post my commented source on 6502.org and open a discussion for a strategy involving the addition of a few features notably absent, like DATA, READ, RESTORE, CHR$ ... and the feature that WOZ had wanted to add if he hadn't been so busy at the time ... WOZ floats!

_________________
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: Thu Apr 30, 2020 10:55 pm 
Offline

Joined: Fri Nov 16, 2018 8:55 pm
Posts: 71
BigDumbDinosaur wrote:
It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.


Hmmm.... So, what is your take on projects like High Level Assembly (HLA)?


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 11:07 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
My current reverse engineering obsession is WOZ BASIC. I found a few very-lightly commented sources on the 'net, and I am now wading in neck-deep with the goal of figuring out exactly what WOZ was doing throughout that originally hand-assembled ~6K ball of twine.


Me too. The source code I have for the TSC FLEX BASIC interpreter is not exactly well documented. I will have to more or less understand it in order to build a 6502 version.

Then there is their Extended BASIC. No source code for it that I can find, so building that will require extreme reverse engineering.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 11:53 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
Quote:
load81 wrote:
BigDumbDinosaur wrote:
It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.


Hmmm.... So, what is your take on projects like High Level Assembly (HLA)?

That's why he went on to say,
Quote:
The use of macros can help in this regard, as they can be used to substitute English-like statements for complex sequences of assembly language instructions, especially ones that manipulate complicated data structures

I have an article on that at http://wilsonminesco.com/StructureMacros/, with extended programming examples in the last 40% of the page at http://wilsonminesco.com/multitask/, and more on how the program flow-control macros work internally in section 17 of the 6502 stacks treatise at http://wilsonminesco.com/stacks/pgmstruc.html . On that last page's last example, you can mouse-over the underlined words to see an explanation of what what that line does. The code hardly looks like assembly language.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 30, 2020 11:55 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
load81 wrote:
BigDumbDinosaur wrote:
It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.

Hmmm.... So, what is your take on projects like High Level Assembly (HLA)?

It's nothing about which I could get excited. Randall Hyde has great credentials, has written a fine book about assembly language and all that, but I think is a bit misguided with this concept.

The very name "high level assembly" is an oxymoron. Assembly language is, by definition, the lowest level at which you can program a computer, short of manually poking bytes into RAM with a panel of switches and push buttons. As soon as you are insulated from the assembler, which is what "high level assembly" is doing, you are no longer programming in assembly language. If you want that much insulation you might as well fire up a COBOL compiler or a BASIC interpreter.

Programs are written in assembly language so as to avoid the performance issues that are present to some extent in all high level languages, compiled or interpreted. Also, sometimes assembly language is the only way to accomplish something, or to accomplish something in an efficient manner, especially on small 8- and 16-bit systems such as what we build.

To quote that Wikipedia article:

Quote:
It uses a syntax loosely based on several high-level programming languages (HLLs), such as Pascal, Ada, Modula-2, and C++, to allow creating readable assembly language programs, and to allow HLL programmers to learn HLA as fast as possible.

That doesn't sound like assembly language to me. Instead, it sounds like illustrating a landscape by connecting the dots. Just what is it someone would learn from a mish-mash of Pascal, Ada (the ultimate designed-by-a-committee programming language), etc? And don't get me started on C++, what I consider to be the ultimate bloatware language.

As for "creating readable assembly language programs," there's this little thing called a comment, which if judiciously used in assembly language source code, makes the program eminently readable. Good commenting is the heart of writing understandable programs in any language. If the programmer can't explain in his/her comments what the program is doing then he/she doesn't know what it's doing. Perhaps Mr. Hyde should hammer that home to his followers.

Both Garth and I strongly advocate for the use of macros in assembly language programs, especially large programs. Macros allow you to add some higher-level features to your programs without sacrificing the inherent speed and flexibility of assembly language. A well-chosen macro name can make for very readable code. Macros can also be invaluable for reducing errors, as a properly-structured macro will report an assembly time error that might go undetected in raw assembly language (e.g., missing parameters).

That said, nothing can beat the performance of assembly language that has been hand-optimized to produce the tightest loops and smallest code. You can't do that when the language does all sorts of hand-holding for you. The folks who developed action games for machines like the Commodore 64 understood that 37 years ago. It's still true today.

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


Top
 Profile  
Reply with quote  
PostPosted: Fri May 01, 2020 1:07 am 
Offline
User avatar

Joined: Sat Dec 01, 2018 1:53 pm
Posts: 730
Location: Tokyo, Japan
BillG wrote:
A good programmer will document things as they are understood instead of leaving the code unchanged.

Or even rewrite the code as he goes. That's a technique I often use when when trying to understand new code. Whether I keep the rewritten code or just throw it out depends on how good the test framework is, whether I actually improved it or not, and so on, but the mere act of trying to do what was already done in a different way can be very enlightening.

Quote:
A comment such as
Code:
    dex    ; Decrement X register
adds no useful information and may as well not be there.

In fact, it may have negative value: making a developer read a lot of useless (to her) verbiage can slow her down.

But on the other hand, even comments like the above may be valuable. The key is to understand your audience: who will be reading your code, and what do they likely need to understand it? If you're writing code you expect to be read mainly by people entirely unfamiliar with 6502 assembly language, a comment like the above might be exactly the right thing.

For example, here's a little routine with a fair amount of subtlety in it:

Code:
;   Convert ASCII character to binary number in bases up to 41.
;   This translates A-Z[\]^_ and a-z{|}~DEL as 10, 11...40.
;   The caller must check the returned value if the intended base was
;   less than 41.
;
;          A: (written) ASCII character to convert; binary number on return
;     N flag: (written) clear on success, set on error.
;       X, Y: (preserved)
;
convascdigit
            cmp #'9'+1
            bcs .letter         ; >'9', convert letter
            sbc #'0'-1          ; convert digit; if <'0', N flag set for error
            rts                 ; N clear, no error
.letter
            and #%11011111      ; clear bit 5 to convert to upper-case
            bmi .exit           ; high bit set, error
            sbc #'A'-$0A
            cmp #$0A            ; if <$0A, set N flag to indicate error
.exit       rts

That version is what I'd normally use in my projects, or post here if I were seeking help or comments on it. But this code is also the example I use for explaining certain aspects of assembly language to people, such as careful use and tracking of flag values. So the the actual source code is in fact a bloated 50-line monstrosity where you can hardly find the code amongst the comments. It's pretty horrible to read if you're a half-way decent 6502 programmer, but good for beginners, and doesn't really hurt the project too much since it's unlikely to be changed in the future anyway.

Code:
;   Convert ASCII character to binary number in bases up to 41.
;   This translates A-Z[\]^_ and a-z{|}~DEL as 10, 11...40.
;   The caller must check the returned value if the intended base was
;   less than 41.
;
;          A: (w) ASCII character to convert; binary number on return
;     N flag: (w) clear on success, set on error.
;       X, Y: (p)
;
convascdigit
            ;   This routine has extra explanation for 6502 beginners.
            cmp #'9'+1
            bcs .letter         ; >'9', convert letter
            ;   At this point we know that the carry is clear, better thought
            ;   of as the borrow being set. Rather than use an extra instr
            ;   to set the carry, we instead subtract 1 from the subtrahend
            ;   because the set borrow will also be subtracted from the result.
            sbc #'0'-1          ; convert digit; if <'0', N flag set for error
            ;   Normally for an unsigned comparison we'd check to see if the
            ;   carry is clear, i.e., the borrow was used, to determine
            ;   whether our result was negative. We can't do this here to see
            ;   if our char was < '0' because of the optimization above. But
            ;   it's safe to check the N flag because we know from the check at
            ;   the start that the char was ≤ $39 ('9') and so this will
            ;   always produce a result between $39-$30=$09 and $00-$30=-$30
            ;   ($D0 in two's complement), all values of which are negative.
            ;   Since the N flag is our error code, we need not even BMI;
            ;   just let the N flag pass through.
            rts                 ; N clear, no error
.letter
            and #%11011111      ; clear bit 5 to convert to upper-case
            ;   Now the char is in one of two ranges:
            ;     $3A-$40  chars between '9' and 'A'
            ;     $40-$5F  A-Z and punctuation after ([\]^_)
            ;     $80-$FF  chars above DEL
            ;   We check the N flag here to see if the high bit is set, which
            ;   means the character is invalid. We have to do the AND first
            ;   because the N bit from the CMP test is based on the result
            ;   of the CMP subtraction.
            bmi .exit           ; high bit set, error
            ;   We subtract 'A'-$0A to bring it down to the $00-$28 range,
            ;   No SEC is needed before this SBC; we branched here because the
            ;   carry was already set and AND does not affect the carry.
            sbc #'A'-$0A
            ;   Values less than $0A are invalid, so error out on those.
            cmp #$0A            ; if <$0A, set N flag to indicate error
            ;   The result of SBC is signed, so it may be, e.g., -$01 = $FF.
            ;   However, CMP does only unsigned comparisons so the carry flag
            ;   would be set (indicating ≥) rather than clear (indicating <)
            ;   for those "negative" results. But since we know our value in A
            ;   is in range $00-$28, the most negative possible result produced
            ;   by the SBC is -$28 = $D8, so we can check the N flag instead.
            ;   Since the N flag is our error code, we need not even BMI.
.exit       rts

_________________
Curt J. Sampson - github.com/0cjs


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

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 45 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: