Kowalski Simulator Updates

Topics pertaining to the emulation or simulation of the 65xx microprocessors and their peripheral chips.
User avatar
Yuri
Posts: 371
Joined: 28 Feb 2023
Location: Texas

Re: Kowalski Simulator Updates

Post by Yuri »

Yuri wrote:
Quote:
I won’t even mention how intrusive Windows has become...
Preaching to the choir here; if I could I'd jump from Windoze to OS X or Linux (actually I prefer FreeBSD myself, but Linux seems better supported these days)
I was trolling through the source code to look at the raw HTML files myself and I was noticing that this application seems to have been written with the venerable MFC framework. I'm not even sure Mircosloth is updating that any longer, but I was wondering about a more cross platform version. It does look like almost all the code is pretty heavily tied to the MFC implementation though, so I susspect that it would be a huge pain to port.
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Kowalski Simulator Updates

Post by BigDumbDinosaur »

Yuri wrote:
I was trolling through the source code to look at the raw HTML files myself and I was noticing that this application seems to have been written with the venerable MFC framework.

The Kowalski simulator has been around for at least 20 years, as I started using it in 2004.  I’m sure the Microsoft programming paradigm has changed in many ways since then.

I’ve concluded Microsoft has the attention span of a canary when it comes to developing solid standards and supporting them over the long haul.  Good software development should be based upon the principle of “evolution, not revolution.”  Evidently, that principle is unknown in Redmond, as things we knew about Windows 10 years ago are all but useless now.  In contrast, things I knew about UNIX 40 years ago are still relevant.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Kowalski Simulator Updates

Post by BigDumbDinosaur »

I've been testing version 1.3.4.8 of the assembler, which has corrections and improvements to handle JML, JMP, JSL and JSR instructions.  Attached is test source code and the assembly listing.  So far, so good.  :D

jump_usage.asm
Test Source Code
(6.2 KiB) Downloaded 287 times
aout.txt
Test Code Assembly Listing
(7.43 KiB) Downloaded 315 times
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Kowalski Simulator Updates: Bank Pains

Post by BigDumbDinosaur »

My efforts to assemble a 65C816 program to a non-zero bank continue to trip over things.  The attached source files will illustrate the problem.

vectors_bank0.asm
Bank $00 Target, Will Assemble
(900 Bytes) Downloaded 284 times
vectors_bank1.asm
Bank $01 Target, Won’t Assemble
(900 Bytes) Downloaded 318 times


If I assemble the vectors_bank1 program into bank $00, load it into bank $00 on POC V1.3 and then use the M/L monitor to copy it to bank $01, it can be run in bank $01.  Or, I can assemble to bank $00, tell V1.3’s S-record loader to load into bank $01, after which I can also run it.  The problem is purely with assembly.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Kowalski Simulator Updates

Post by 8BIT »

It looks like the first pass is assigning an absolute value to the addresses and on the second pass, it sees an abolute long value and is trying to change the size, resulting in the phase error.

I can either truncate absolute long addresses unless they have /3 modifier or i can require the programmer to add a /2 modifier if they want addresses above bank 0 addressed as 2 bytes. /2 does not work that way right now... still tries to use 3 bytes. Either way can result in logical errors in assembly.

The first option would not warn the programmer and could result in more logic errors, but would be less cluttered to read. The second option gives a phase error and gives the programmer visibility of the choice, but could make reading the source more difficult.

If a label is defined before the line in question gets assembled, then an absolute long operand will be used without user notification, unless there is not a valid absolute long opcode. The programmer could override with /2 if they want an absolute operand.

What do you think?
Please visit my website -> https://sbc.rictor.org/
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Kowalski Simulator Updates

Post by BigDumbDinosaur »

8BIT wrote:
It looks like the first pass is assigning an absolute value to the addresses and on the second pass, it sees an abolute long value and is trying to change the size, resulting in the phase error.

That was what I was thinking as well.

Quote:
I can either truncate absolute long addresses unless they have /3 modifier or i can require the programmer to add a /2 modifier if they want addresses above bank 0 addressed as 2 bytes.  /2 does not work that way right now... still tries to use 3 bytes.  Either way can result in logical errors in assembly.

I think what we need to do is take a metaphorical step back and think in terms of the 65C816’s behavior as it runs a program.  I’m hoping what I’m going to say makes sense.  The picture of how the 816 behaves is crystal-clear in my mind, but I often have trouble articulating my thoughts.

PB’s function is to set bits 16-23 of the effective address during opcode and operand fetches, that is, when the VPA signal is true.  Code execution is always confined to a single bank, disregarding long jumps and subroutine calls—even there, execution is confined to a single bank, just a different one.  The key point is: opcodes and operands (but not data) are always fetched from an address that is PB << 16 | PC (<< means left-shift and | is bitwise OR).  PB will never change as code runs, disregarding a long jump or a JSL, and does not figure into the calculation of relative offsets or any other program flow control.  Incrementing PC (program counter) past $FFFF will not affect PBPB never figures into the generation of an effective address for data fetches and stores, something an assembler wouldn’t know about anyhow, since data access is a run time thing.

Where I think the trouble is arising is in that the assembler’s behavior isn’t reflecting the 816’s behavior.  Right now, the assembler is using bits 16-23 of the * = <addr> declaration to internally generate addresses as it parses the source code.  Those bits do not matter during assembly—they only matter when it comes time to save the object code so the target system knows where to load it.  Hence all internal address computations should be 16-bit operations, unless addressing is overridden by the program with a \n modifier, and the assembler should continue to cause a forward reference to default to 16 bits.

Using the test code I had posted as an example, the initial entry of vectab into the symbol table during the first pass should assume that it is a 16-bit address reference.  Since the running value of the assembler’s “program counter” will be 16 bits, not 24, the second pass will assign a 16-bit address to vectab to the data table structure.  The result will be a program that will run in any bank.

As you know, the usual practice in defining dynamic storage is with * = *+ <size>.  Such a declaration usually defines storage to be in the same bank in which the program that uses it is running.  However, it should be possible to use something such as:

Code: Select all

         * = $FE2000           ;start of dynamic storage

diskbufr =*                    ;disk buffer at $FE2000
         * = * + s_dskbuf      ;advance program counter by s_dskbuf bytes
tapebufr =*
         * = * + s_tapbuf

          ...etc...

The above should, I think, assemble without generating a forward reference or phase error, provided that in-program references to diskbufr and tapebufr use the \3 modifier, e.g., LDA \3diskbufr.

When the assembled program is save as Motorola S-record, S2 and S8 records should be used if the code space was defined as something other than bank $00, e.g., * =   $AB1234, with ‘AB’ as the first character pair in the load address field.  If code space was defined in bank $00, e.g., * = $001234, then S0 and S9 records would be used.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Kowalski Simulator Updates

Post by 8BIT »

Good description BDD. While the assembler does have to track the bank address for cases of long addressing modes being used, it should ignore them for all other cases. The programmer can either use explicit long address opcodes (JML, JSL) or use the \3 modifier to force long addresses for data access. Otherwise, use absolute or zero page (direct page) address modes.

I'll get to work on this.

thanks!
Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Kowalski Simulator Updates

Post by 8BIT »

Version 1.3.4.9 is posted on my website with corrections to the 24/16 bit addressing in upper banks.

Enjoy!
Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Kowalski Simulator Updates

Post by BigDumbDinosaur »

8BIT wrote:
Version 1.3.4.9 is posted on my website with corrections to the 24/16 bit addressing in upper banks.

I’ll give it a spin and report back.

Thanks for your hard work on this.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Kowalski Simulator Updates

Post by BigDumbDinosaur »

BigDumbDinosaur wrote:
8BIT wrote:
Version 1.3.4.9 is posted on my website with corrections to the 24/16 bit addressing in upper banks.

I’ll give it a spin and report back.

Thanks for your hard work on this.
I gave it a spin and it appears that assembly is now working as it should.  Attached are the source code, Motorola S-record object code and the assembly listing.  Sending the object code to POC V1.3 results in a runable program in bank $01.

vectors_bank1.asm
Source File
(900 Bytes) Downloaded 285 times
srecord.txt
Object File
(180 Bytes) Downloaded 301 times
aout.txt
Listing File
(1.53 KiB) Downloaded 300 times
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Kowalski Simulator Updates

Post by 8BIT »

Good news! :D
Please visit my website -> https://sbc.rictor.org/
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Kowalski Simulator Updates

Post by 8BIT »

I've been evaluating BigDumbDinosaur's list of feature enhancements and what I might be able to address. his list is here -> viewtopic.php?f=8&t=5011&start=270#p107024

The Goto Line Number is a useful addition and I have it 90% done. Still working on two bugs - can open multiple goto boxes and if a box is open and you close the Simulator, it orphans the box and it must be killed through the Windows Task Manager.

Find Pattern match and Find & Replace crashes - these are Microsoft AFX functions that I do not want to dig into, so most likely will not get addressed anytime soon.

.PARAMTYPE bug - going to work on that next

File handling
Change default source file extension to .ASM , retain support for .65S - will work after bugs
Set default binary file to .BIN vs .65P - will work after bugs
Remove default file name 'Binary Code' - changed to 'Binary_Code' for now - I would like to grab the source file name as the default, but have not looked into that yet

File types
Change default saved object to S-record - Everyone has there own preferences (I only use binary files, never use Hex or S records) so I will not change this.

Intel-hex does not work with 65816 addresses beyond bank 0 - Yes, it does. According to this document and others ( https://developer.arm.com/documentation ... 92/latest/ ), the address field is only 16 bits wide. The use of extended address records allows for addresses above bank 0. I used Record type 04 to identify a change in Bank addresses. However, I do need to add the Record Type 05 for the start address above bank 0. Currently, the End of File record type 01 is used to pass the start address for Bank 0.

Here's a sample source:

Code: Select all

	*= $1234
	.ASCII "Testing 1 2 3"
	
	*= $19876
	.ASCII "Test two"
	
	*= $2aabb
	.ASCII "Test three"
here is the Intel HEX output:

Code: Select all

:0D12340054657374696E67203120322033D9
:020000040001F9
:08987600546573742074776FD0
:020000040002F8
:0AAABB0054657374207468726565B9
:00123401B9
I'll be working on these as time allows.

thanks!
Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Kowalski Simulator Updates

Post by 8BIT »

8BIT wrote:
...However, I do need to add the Record Type 05 for the start address above bank 0.
After testing a few things, I apparently did write the Record Type 05 so saving Intel Hex files should work. Having said that, I'll need to verify that loading one of those saved files works correctly. I also cannot vouch for other system's ability to use the other record types. YMMV

Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
8BIT
Posts: 1787
Joined: 30 Aug 2002
Location: Sacramento, CA
Contact:

Re: Kowalski Simulator Updates

Post by 8BIT »

BigDumbDinosaur wrote:
  1. The .PARAMTYPE (parameter type) internal macro variable that is supposed to differentiate between a macro argument passed as numeric and an argument passed as a character string, causes an error if used.  The below short program illustrates this.

    Code: Select all

            .opt caseinsensitive,swapbin
    
    string   .macro ...                         ;accepts variable number of parameters
             .if @0                             ;if at least 1 parameter is passed...
    .p           .=1                            ;.P is a variable, not a symbol
                 .rept @0                       ;repeat for number of parameters
                     .if .paramtype(@.p) == 2   ;if parameter is a string...
                         .byte @.p$             ;assemble it
                     .endif
    .p               .=.p+1                     ;next parameter
                 .endr
                 .byte 0                        ;terminate string
             .endif
             .endm
    
             *=$400
    
             string "this is",$12," a test"
    If the above were to correctly assemble, the $12 argument would be skipped during macro expansion due it not being a string.  Instead, assembly will stop with the text pointer at the STRING macro invocation, with the actual error occurring on the line with the .PARAMTYPE test.


My research into the .PARAMTYPE code suggests that only labeled parameter names work with this feature. This in turn would not work on a macro defined with the ellipsis '...' as its parameter list. This goes directly against the example Michael K. gave in his help documents.

This macro works and returns 7 ASCII characters at location $1000: 31 32 33 34 68 65 6C 6C 6F

Code: Select all

test .MACRO one, two, three
  .IF .paramtype(one) == 2   ; number = 1, string = 2
     .db one$
  .ENDIF
  .IF .paramtype(two) == 2
     .db two$
  .ENDIF
  .IF .paramtype(three) == 2
     .db three$
  .ENDIF
 .endm  
 
 
 	*= $1000
 	test "1234", $1234, "hello"


This code also works, noting the use of numbered parameters for the .db statements

Code: Select all

	.opt    ; use @ for numbered parameters

test .MACRO one, two, three
  .IF .paramtype(one) == 2
     .db @1$
  .ENDIF
  .IF .paramtype(two) == 2
     .db @2$
  .ENDIF
  .IF .paramtype(three) == 2
     .db @3$
  .ENDIF
 .endm  
 
 
 	*= $1000
 	test "1234", $1234, "hello"


This example fails with a "Missing label on line 5" (first paramtype statement):

Code: Select all

	.opt swapbin   ; use @ for numbered parameters

test .MACRO one, two, three
  .IF .paramtype(@1) == 2
     .db @1$
  .ENDIF
  .IF .paramtype(@2) == 2
     .db @2$
  .ENDIF
  .IF .paramtype(@3) == 2
     .db @3$
  .ENDIF
 .endm  
 
 
 	*= $1000
 	test "1234", $1234, "hello"


Finally, I tried a work around by defining local fixed labels. That failed with "Local labels not allowed. Global label expected". Its clear Michael K. limited the parameters to fixed labels.

Code: Select all

	.opt swapbin   ; use @ for numbered parameters

test .MACRO ...
.one .= @1
.two .= @2
.three .= @3

  .IF .paramtype(.one) == 2
     .db @1$
  .ENDIF
  .IF .paramtype(.two) == 2
     .db @2$
  .ENDIF
  .IF .paramtype(.three)== 2
     .db @3$
  .ENDIF
 .endm  
 
 
 	*= $1000
 	test "1234", $1234, "hello"


I will look into allowing numbered variables, but its likely Michael K. intended to allow them but never got it to work. I may not be able to either.

thanks!
Daryl
Please visit my website -> https://sbc.rictor.org/
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Kowalski Simulator Updates

Post by BigDumbDinosaur »

If .PARAMATYPE could be made to work as documented, it would greatly augment the macro features, and make it relatively easy to write a “universal” string-printing macro. You could do SPRINT STRING or SPRINT "This is a test." and have the macro figure out how to correctly assemble the string-printing function call.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
Post Reply