6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 8:42 pm

All times are UTC




Post new topic Reply to topic  [ 413 posts ]  Go to page Previous  1 ... 10, 11, 12, 13, 14, 15, 16 ... 28  Next
Author Message
PostPosted: Fri Mar 19, 2021 11:56 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
I hate finding heisenbugs.

Most of the ones I have encountered have been due to uninitialized local variables.

Are you compiling with optimization turned on. Often optimization makes heisenbugs show up because the stack frame has different junk left on it.


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 20, 2021 12:02 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8506
Location: Midwestern USA
8BIT wrote:
So its even more odd now. I got home and ran the code and experienced the problem. Now, without changing anything, its working correctly on 3 versions.

This is going to be a hard one to track down.

Daryl

Yikes! An intermittent problem in software.

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 20, 2021 5:31 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
The Good news - I found the problem - .REF does not consider the case_insensitive directive. The problem could have been much harder to find.

Remove the case_insensitive directive from this example and it will assemble correctly.

The bad news - .DEF & .REF do not take the case_insensitive feature into consideration. There could be other features that were also overlooked. It will take time to root them all out and correct them.

No more work on the code until next weekend as I have other commitments to deal with.

be safe all!!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 20, 2021 5:44 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
I hate case sensitivity.

Too many years of programming in C made me learn to deal with it, but I still hate it.

Isn't it customary for assembler pseudo operations to be case insensitive?


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 20, 2021 5:49 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
I've had bugs that took a long time to find because the assembler was not case-sensitive.

_________________
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: Sat Mar 20, 2021 4:31 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8506
Location: Midwestern USA
8BIT wrote:
The Good news - I found the problem - .REF does not consider the case_insensitive directive. The problem could have been much harder to find.

Remove the case_insensitive directive from this example and it will assemble correctly.

The bad news - .DEF & .REF do not take the case_insensitive feature into consideration. There could be other features that were also overlooked. It will take time to root them all out and correct them.

No more work on the code until next weekend as I have other commitments to deal with.

be safe all!!

Daryl

Interesting! Thanks for finding this. It didn't occur to me that case might be the case. :D

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 20, 2021 4:36 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8506
Location: Midwestern USA
BillG wrote:
Isn't it customary for assembler pseudo operations to be case insensitive?

None of the assemblers I have used in the past had case-sensitivity for non-quoted strings. The first assembler I used way back in 1970 required everything to be in upper case, even quoted strings. It wasn't until I started writing code for the 6502 (c. 1976) that source code could be entered in lower case, as well as quoted strings.

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 27, 2021 5:46 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
I have reviewed the case sensitive features in the assembler and am pretty sure that only .DEF and .REF were overlooked in previous versions. I have corrected the code for these two directives and have posted updated files to my website as version 1.3.4.1. Thanks to BigDumbDinosaur for pointing out the issue and thanks to everyone using this program for helping me to continue to improve and expand its capabilities.

https://sbc.rictor.org/kowalski.html

It's going to be a busy spring/summer for me with work and family, so my responses will be slower, but rest assured I will get to them when I can.

Thanks!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 28, 2021 6:37 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8506
Location: Midwestern USA
8BIT wrote:
I have reviewed the case sensitive features in the assembler and am pretty sure that only .DEF and .REF were overlooked in previous versions. I have corrected the code for these two directives and have posted updated files to my website as version 1.3.4.1.

Excellent! I will download and install the new version sometime during the day. It's getting late here and being the old man that I am, it's well past my bedtime. :D

Quote:
Thanks to BigDumbDinosaur for pointing out the issue and thanks to everyone using this program for helping me to continue to improve and expand its capabilities.

It is you we should be thanking. You've put a ton (or tonne) of effort into extending the assembler to what it now is.

Quote:
It's going to be a busy spring/summer for me with work and family, so my responses will be slower, but rest assured I will get to them when I can.

I promise to try to not find any more bugs. :D

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


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 31, 2021 4:34 am 
Offline

Joined: Fri Apr 15, 2016 1:03 am
Posts: 140
edit: it's not a bug, it's a feature!
Reading back thru this thread...
The assembler does not attempt to model the M & X sizes at all. It just guesses depending on the value.
There are overrides ( !# \1 \2 \3 ) for the programmer to mark up each reference as needed.

-----------------------------------
Sorry for probably finding another bug...

edit: using version 1.3.4.1, 65816 mode

It seems like the assembler isn't sure what size to make an immediate value on an instruction. In the following code, the LDA # is sometimes 1 byte & sometimes 2 bytes. See line 1206, 1218, 1238.
It seems like the size changed between passes at line 1238 & caused a E022: phase error.
Is the assembler applying part of the 6502 absolute vs zero-page address optimization here? For immediate values, it should depend only on the assembler's opinion of the M or X size values.

Another question: how does the assembler come up with the current values of the M or X size bits?

Code:
01199     FHdr "B/Scr",0 ; ( -- n )
01200  .L1:   .byte .name1   ;name of word as a string
01201     .byte *-.L1+.opt1 ;flags & length of name (see ha_*)
01202     .word DictLink   ;link to previous word in dictionary chain
01203    0835              DictLink .set *
01204  ; This constant leaves the number of blocks per editing screen.  By convention,
01205  ; an editing screen is 1024 bytes organized as 16 lines of 64 chars each.
01206  000835  A9 02         BScr:   lda #1024/SSize ; blocks to make one screen
01207  000837  4C 2C 07         jmp Push
01208 
01209 
01210     FHdr "+Origin",0 ; ( n -- adr )
01211  .L1:   .byte .name1   ;name of word as a string
01212     .byte *-.L1+.opt1 ;flags & length of name (see ha_*)
01213     .word DictLink   ;link to previous word in dictionary chain
01214    083E              DictLink .set *
01215  ; Leave the memory address relative by n to the origin parameter area.
01216  ; n is the minimum address unit, either byte or word.  This definition
01217  ; is used to access or modify the boot-up parameters at the origin area.
01218  00083E  A9 00 04      POrig:   lda #ORIG
01219  000841  4C B4 06         jmp PlusA
01220 
01221 
01222     FHdr "User",0 ;
01223  .L1:   .byte .name1   ;name of word as a string
01224     .byte *-.L1+.opt1 ;flags & length of name (see ha_*)
01225     .word DictLink   ;link to previous word in dictionary chain
01226    0848              DictLink .set *
01227  ; A defining word used in the form:
01228  ;   n USER cccc
01229  ; which creates a user variable cccc.  The parameter field of cccc contains n
01230  ; as a fixed offset relative to the user pointer register UP for this user
01231  ; variable.  When cccc is later executed, it places the sum of its offset and
01232  ; the user area base address on the stack as the storage address of that
01233  ; particular variable.
01234  000848  20 39 0D      User:   jsr WordHeader
01235  Debug0:
01236  00084B  20 A1 0D         JSR LdaComma
01237  Debug1:
01238  00084E  A9 53 08         lda #DoUser
01239  Debug2:


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 31, 2021 5:06 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Hello leepivonka,

There is not a bug, but I have been considering a different approach to handling immediate values to reduce phase errors.

Short answer, place a ! in front of the # in the source file for line 1238 and try it again. Let me know how that works. This feature is documented in the help file on the "Overriding Expression Sizes" page.

Here is what going on "under the hood."

The assembler does not track status of any register bits, including those in the status register. The programmer should be aware of when the registers are 8 bits vs 16 bits, especially with respect to immediate operands.

So, as variables are assigned their values, they are also given the attribute of byte (8 bit), word (16 bit), or long (24 or 32 bit). Uninitialized variables are marked as "undefined" when first identified and changed once they are given a value. The assembler is a 2 pass assembler, so when assigning a value to an immediate operand, it defaults to 8 bits unless the variable attribute is word. The variable value has to be know before this line is assembled to be given the 16 bit size in pass 1. If it is defined AFTER the usage, you will get the phase error as it was assigned as 8 bits on pass 1 and changed to 16 bits on pass 2.

I created a method to force the immediate to 16 bits by using the '!' symbol before the '#' in the assembly source.
For instance, LDA !#$0 with result in $A9, $00, $00 being generated in the output file.

Now, I have been considering making the assignments hard coded as 8 bits only for # and 16 bits for !#. This will result in an error on the line of an immediate operand if the value is greater than 255. Corrected by use !#. This is much easier to locate and correct that having the phase errors, which do not point to the cause, only the first label after the cause.

I'm open to feedback whether to keep it as it is or hardcode the immediate sizes. If hardcoding is preferred, I'll need to verify that does not break anything else in the process.

thanks!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 31, 2021 5:46 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Quote:
I'm open to feedback whether to keep it as it is or hardcode the immediate sizes.

The way C32 does it, and I have never had any problem with it, is that LDA #0 gives a 16-bit operand, and LDA #<0 gives an 8-bit operand, the "<" meaning "give me just the low byte." This holds true even for loading constants that have not been defined yet in the first pass.

_________________
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: Wed Mar 31, 2021 11:01 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
The issue with deciding the size for the 65816 is that the mode the processor is in dictates whether the operands should be 8 or 16 bits. The programmer must understand the current mode for the code and have the operands be sized accordingly. So with C32, when not in a 16 bit register mode, you use '#<' and for 16 bit accesses, you use '#'. That is not really standard for 8 bit only code. I would rather force 16 bit mode and keep the plain '#' reserved for 8 bit use. ... just my thoughts.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 01, 2021 2:34 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
True, the programmer does have to know what mode it's in (if he doesn't, shame on him), or put it in the right mode. I think that in most cases he will arrive at that part of the code in the right mode already though, and that it's often a wasted instruction if telling the assembler to go into 16-bit-accumulator mode for example also lays down the REP instruction when you know you will only be calling that routine from that mode anyway. I have never had a bug from the way C32 does it. It seems to me like the perfect solution.

_________________
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 01, 2021 5:25 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8506
Location: Midwestern USA
leepivonka wrote:
The assembler does not attempt to model the M & X sizes at all.

Nor should it. The m and x bits' state is a run-time matter, not an assembly-time concern.

Quote:
There are overrides ( !# \1 \2 \3 ) for the programmer to mark up each reference as needed.

Concerning the overrides, either set the simulator's environment to 65C816 or use the .opt pseudo-op to tell the assembler that it is generating code for an 816. The syntax is .opt proc65816. That should be the first line in the first file that is to be assembled (it's not necessary in INCLUDE files, but will cause no harm if it is present). In my source files, I start with .opt proc65816,caseinsensitive,swapbin. This combination causes the assembler to closely follow the MOS Technology/WDC assembly language syntax.

Quote:
It seems like the assembler isn't sure what size to make an immediate value on an instruction. In the following code, the LDA # is sometimes 1 byte & sometimes 2 bytes. See line 1206, 1218, 1238.
It seems like the size changed between passes at line 1238 & caused a E022: phase error.
Is the assembler applying part of the 6502 absolute vs zero-page address optimization here? For immediate values, it should depend only on the assembler's opinion of the M or X size values.

I couldn't make head or tail of your code (I found it quite difficult to read), but I will tell you this.

  1. The assembler knows nothing about the m and x bits in SR. This is the case with every 65C816 assembler I've tried. It's your responsibility to keep track of register sizes, not the assembler's. It's also your responsibility to make sure the assembler understands what you want it to do.

  2. The assembler will try to optimize immediate mode operands to use the fewest number of bits. This is common behavior—it's not unique to the Kowalski assembler. If you must have an immediate mode instruction assemble the operand as a word, even though the operand can be resolved to a byte, you should make sure the assembler knows what you want by using !# as the addressing mode. Otherwise, if the operand can be resolved to a byte, that is what the assembler will assemble. If the operand resolves to a word, use of the exclamation point to "coerce" the operand to 16 bits is unnecessary, as long as the .opt proc65816 pseudo-op is present in the source file, or the simulator is set to 65C816 mode.

  3. The assembler will also try to optimize absolute mode operands to use the fewest number of bits. An address that can be resolved to 8 bits will be assembled as a direct (zero) page location. By default, an address that can be resolved to 16 bits will be assembled as an absolute address. Only if the address can be resolved to 24 bits will absolute long addressing be employed. If you want an address to be assembled to a specific size preface it with \1 (8-bit address), \2 (16-bit address) or \3 (24-bit address).

  4. The assembler will rebuke you if you try to assemble an invalid address for a particular instruction and addressing mode combination. For example, LDA \3$1234,Y would cause an error, as <laddr>,Y is not a supported addressing mode. On the other hand, LDA \3$00,X would be fine and would use <laddr>,X on physical address $000000.

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


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 413 posts ]  Go to page Previous  1 ... 10, 11, 12, 13, 14, 15, 16 ... 28  Next

All times are UTC


Who is online

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