6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon May 06, 2024 2:45 pm

All times are UTC




Post new topic Reply to topic  [ 203 posts ]  Go to page Previous  1 ... 10, 11, 12, 13, 14  Next
Author Message
PostPosted: Thu Dec 03, 2020 10:36 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10799
Location: England
Well done!


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 03, 2020 1:18 pm 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
There is a call to the success macro just ahead of the jmp start. The macro actually injects the jmp *. In case you assemble the test with flag report = 1 the injected instruction changes to jsr report_success (part of report.i65). After the message "All tests completed, press R to repeat" pressing R simply executes an rts and continues with jmp start.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 04, 2020 9:20 pm 
Offline

Joined: Tue Apr 19, 2005 7:25 pm
Posts: 15
Thanks Klaus, and thanks so much again.

So, now that I measured the time it took for me to run the test, I have been working on optimizing my emulation code and I have switched on optimization with -O2 flag. Furthermore, I have inlined the opcode functions as well as my get_address function (which basically returns the opcodes addresses depending on addressing mode).

Here are the results in microseconds in case it's of interest.

Using standard flags (no optimization)
Number of cycles spent = 100369613
Test completed successfully in 832092 us Estimated CPU speed in this computer = 120 Mhz
Test completed successfully in 970133 us Estimated CPU speed in this computer = 103 Mhz
Test completed successfully in 831020 us Estimated CPU speed in this computer = 120 Mhz
Test completed successfully in 819964 us Estimated CPU speed in this computer = 122 Mhz
Test completed successfully in 836025 us Estimated CPU speed in this computer = 120 Mhz

Using -O2 flags
Number of cycles spent = 100369613
Test completed successfully in 469384 us Estimated CPU speed in this computer = 213 Mhz
Test completed successfully in 503100 us Estimated CPU speed in this computer = 199 Mhz
Test completed successfully in 463132 us Estimated CPU speed in this computer = 216 Mhz
Test completed successfully in 495520 us Estimated CPU speed in this computer = 202 Mhz
Test completed successfully in 453542 us Estimated CPU speed in this computer = 221 Mhz

Using inline functions
Number of cycles spent = 100369613
Test completed successfully in 368536 us Estimated CPU speed in this computer = 272 Mhz
Test completed successfully in 375406 us Estimated CPU speed in this computer = 267 Mhz
Test completed successfully in 368005 us Estimated CPU speed in this computer = 272 Mhz
Test completed successfully in 371324 us Estimated CPU speed in this computer = 270 Mhz
Test completed successfully in 386403 us Estimated CPU speed in this computer = 259 Mhz

This is actually so much fun :-)

Note: My cycle counting is not perfect, as I don't detect yet the extra cycle on some opcodes addressing modes when a page boundary is crossed.


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 14, 2020 6:40 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 679
Location: Potsdam, DE
Morning all,

First - many thanks to Klaus for the test suite, which I successfully pass with my C emulator/debugger in both a linux terminal version and a GTK graphical debugger.

It runs around 60,000,000 6502 instructions to completion (I halt on an instruction which jumps to itself i.e. the finish trap) on this old laptop in about 1.2 seconds for the emulator alone, about five minutes with the debug trace running in a terminal, and about three hours for the GTK trace... there's a lot going on there :)

But on attempting to run Grant Searle's version of MS Basic, modified to compile with Frank Kingswood's assembler (and probably introducing all sorts of exciting new bugs) I did discover one issue with my emulator:

Code:
stx 0x88


was actually writing to 0xff88 (a casting error in my emulator). Slightly confusing because this was not picked up by the test suite. Does this count as a genuine, for real, bug? Do I get a lollipop? From the way my emulator is written, the same fault would have applied to any zero page read or write instruction (though not the indexed ZPs) if the target address was 0x80 or higher; it's just that I noticed it when the first STX instruction in the basic code didn't write where I expected it to.

Neil

p.s. my emulator has fixed that addressing mode, but the basic still doesn't quite run!


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 15, 2020 10:41 pm 
Offline

Joined: Tue Apr 19, 2005 7:25 pm
Posts: 15
Weird, on my emulator I only counted 30646176 opcodes on the test. :?

Well, actually if your bug applies to all zero page addressing, it is possible that the test can't figure out the issue, right ? When it reads from $88 it will get the value of $FF88, and not notice the issue.

I had a similar issue when I first implemented JSR. I used the wrong order to push bytes on the stack, and then used the wrong order to pull the bytes from the stack. So, JSR and RTS would work, but my Apple 2 boot was failing because of that. It turns out the ROM reads the address from the stack and was getting the wrong results. Gladly the test suite detected it and led me to solving this issue (among so many others).

EDIT: Well, actually, sorry for providing incomplete information above. I believe Klaus test may detect the issue if you enable the check_ram test, which would check that no memory has changed beyond the expected test addresses. However, this test, if I understood correctly, is disabled by default. From the code here:

;RAM integrity test option. Checks for undesired RAM writes.
;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k)
;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM
ram_top = -1


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 23, 2020 12:52 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 679
Location: Potsdam, DE
30,000,000 vs 60,000,000 - it's quite possible that my code is counting cycles both on the emulation *and* on the debug report. It's still early days... I need to look further into whether the memory bounds test will detect out-of-area read/writes in the case that a broken addressing mode is causing the issue.

I need to drop this for other projects for a while, but it'll bubble back up to the top pretty soon I guess.

For what it's worth, a linux GTK debugging system with full debugging written to a pane and with the listing leaping around as the program counter changes runs to a touch under 3,000 instructions per second on this old laptop :)

Neil


Attachments:
Screenshot from 2020-12-05 08-23-38.png
Screenshot from 2020-12-05 08-23-38.png [ 148.62 KiB | Viewed 2349 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 27, 2020 9:16 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
Sorry for the late response, I had to ramp up anti-spam measures and forgot to put 6502.org notifications on my whitelist.

Unfortunately the default page zero test area is just a few bytes at $a well below $80 and therefore errors that start to occur at addresses above that test area go undetected. I will look into what can be done as a remedy in january.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 03, 2021 9:57 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 679
Location: Potsdam, DE
Thanks Klaus, I'll wait until you update before I change my broken code :)

Perhaps simply moving the test area to either side of 0x80? Though I think in this case you'd also need to test with an absolute read from the expected target address, which could get a bit clumsy?

Neil


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 04, 2021 9:39 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
Hi Neil,

the test always uses absolute addressing to verify zero page addresses. I am certain, that had the zero page test area been at or above $80 the test would have reported the address generation fault. So the fix may just be as simple as moving the test area to $8A. I currently can't think of any other reason for the generated absolute address not beeing uniform other than the sign extension of an 8 bit value.

cheers, Klaus

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Tue May 18, 2021 11:15 am 
Offline

Joined: Tue Apr 19, 2005 7:25 pm
Posts: 15
Hello Klaus and fellow forum readers.

As I work on my Apple II+ emulator, I have found a bug on my 6502 emulation library (probably one of too many). Nothing unexpected, but the reason I post it here is that this bug was not detected by Klaus suite (assuming of course I didn't do anything wrong on the configuration of the test). I have only run the general tests, so please excuse me if the bug is checked somewhere else. It is related to the setting of the negative flag on the CMP, CPX and CPY instructions.

Just to be clear, the error is on my own code, I am just suggesting maybe we can add a test to detect it on Klaus' suite.

On my original code I had the following:
Code:
    if (cpu.a<operand) setflag(NEGATIVE); else clearflag(NEGATIVE);

Please note that in my code, cpu.a and operand are not signed.

So, my guess without going into too much of an investigation, is that this logic does not work for signed negative numbers. By changing the code to the following, it seems that I fixed the issue:
Code:
    if ((cpu.a-operand)&(1UL << 7)) setflag(NEGATIVE); else clearflag(NEGATIVE);

Probably the compiler is treating the inputs to the substraction as signed integers, so it is doing an implicit cast to signed variables, and then the results are correct since bit 7 will be the resulting sign of the substraction.

It was difficult to identify, given my assumption that my 6502 emulation was correct, and I found the issue by looking into the ROM disassembly. The Apple II+ ROM has an HGR applesoft BASIC routine that does a cmp followed by a bpl that was failing, and as a result, my high resolution screen was becoming white even when the page was filled with black.

Code:
f47e: 0a           COLOR_SHIFT asl     A               ;rotate low-order 7 bits
f47f: c9 c0                    cmp     #$c0            ; of HGR_BITS one bit posn
f481: 10 06                    bpl     LF489
f483: a5 1c                    lda     HGR_BITS
f485: 49 7f                    eor     #$7f
f487: 85 1c                    sta     HGR_BITS
f489: 60           LF489       rts


Anyways, problem solved on my side, here is just a suggestion to include this case on the testing suite.

Cheers,
Nelson


Top
 Profile  
Reply with quote  
PostPosted: Tue May 18, 2021 7:52 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
I think your problem arises when you compare certain positive values with negative ones.

As you know a negative number is represented with values $80...$ff.
Now let's assume that you have in .A the value +8 and the operand has a signed value -7 ($F9). Doing (cpu.a<operand) consists in asking if $08 is less than $F9. Of course it is, and by your statement the negative flag is going to be set.
But CMP performs a subtraction, and in a two's complement 8 bit subtraction (limited to 8 bits) $08-$F9=$0F (%00001111), so that CMP will produce a clear Negative flag because bit 7 is clear.

With your new statement you're going to check the value of the 7th bit, thus assigning the correct value.


Top
 Profile  
Reply with quote  
PostPosted: Thu May 20, 2021 2:59 pm 
Offline

Joined: Tue Apr 19, 2005 7:25 pm
Posts: 15
Quote:
Now let's assume that you have in .A the value +8 and the operand has a signed value -7 ($F9). Doing (cpu.a<operand) consists in asking if $08 is less than $F9. Of course it is, and by your statement the negative flag is going to be set.
But CMP performs a subtraction, and in a two's complement 8 bit subtraction (limited to 8 bits) $08-$F9=$0F (%00001111), so that CMP will produce a clear Negative flag because bit 7 is clear.


Yes, great explanation. That's exactly what I think was happening.

Looking into the Apple II ROM disassembly, I can see cmp is done against $C0, which exactly meets your description. So, I looked into Klaus' assembly code, and on the cmp test, I realized his test is comparing $0 to $0 (should result in clear negative flag) and then $0 to $1 (should result in negative flag). These tests would of course have worked on my original code. When I have a chance, I will try to change the first test to be $0 against $C0 instead (or any negative number) and check whether it then detects the error (also need to check the impact on other flags). I will post the results.

Klaus can then decide if he wants to add a new test, change the existing one or do nothing :-)

Thx,
nelbr


Top
 Profile  
Reply with quote  
PostPosted: Thu May 20, 2021 4:05 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10799
Location: England
Interesting: I thought Klaus tended to use a short array of interesting values to act on: perhaps with CMP and the like that's not done the same way.


Top
 Profile  
Reply with quote  
PostPosted: Sun May 23, 2021 9:10 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
Yes, i am comparing various values in the accumulator to a single positive value as operand of the compare. I should also add a negative operand it seems or do a full run of all possible values as I did for SBC/ADC. There are 2 more "no catch" bugs open with a pending fix, but I´ve been busy with my other passion lately (electronic music) and being away from home it may still be a while before I fix the issues.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Tue May 25, 2021 5:13 pm 
Offline

Joined: Tue Apr 19, 2005 7:25 pm
Posts: 15
Hi,

So I reverted my code to the previous buggy implementation, and went into the functional test source code to check if I could change it to trap the error. I have been bold and changed the assembly code on the following section to include a new test using a negative operand C0:

Code:
;partial test BNE & CMP, CPX, CPY immediate
        cpy #1          ;testing BNE true
        bne test_bne
        trap
test_bne
        lda #0
        cmp #0          ;test compare immediate
        trap_ne
        trap_cc
        trap_mi
        cmp #1
        trap_eq
        trap_cs
        trap_pl


I added the following code immediately after trap_pl:

Code:
        cmp #$C0
        trap_eq
        trap_cs
        trap_mi


I have tested this with cmp only, but it should work with cpx and cpy as well.

The test now failed with my original code (good) and then I re-fixed my code and the test worked again. So, I added the same code to CPX and CPY tests that follow (using the correct instruction) and now the test suite will detect any misbehaviour of the negative flag when running a cmp to negative numbers.

Cheers,
nelbr


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

All times are UTC


Who is online

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