Kowalski Simulator Updates
Re: Kowalski Simulator Updates
Yuri wrote:
Quote:
I won’t even mention how intrusive Windows has become...
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Kowalski Simulator Updates
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!
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Kowalski Simulator Updates
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. 
x86? We ain't got no x86. We don't NEED no stinking x86!
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Kowalski Simulator Updates: Bank Pains
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.
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.
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!
Re: Kowalski Simulator Updates
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?
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/
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Kowalski Simulator Updates
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 PB. PB 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!
Re: Kowalski Simulator Updates
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
I'll get to work on this.
thanks!
Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Kowalski Simulator Updates
Version 1.3.4.9 is posted on my website with corrections to the 24/16 bit addressing in upper banks.
Enjoy!
Daryl
Enjoy!
Daryl
Please visit my website -> https://sbc.rictor.org/
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Kowalski Simulator Updates
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!
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Kowalski Simulator Updates
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.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Kowalski Simulator Updates
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:
here is the Intel HEX output:
I'll be working on these as time allows.
thanks!
Daryl
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"Code: Select all
:0D12340054657374696E67203120322033D9
:020000040001F9
:08987600546573742074776FD0
:020000040002F8
:0AAABB0054657374207468726565B9
:00123401B9thanks!
Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Kowalski Simulator Updates
8BIT wrote:
...However, I do need to add the Record Type 05 for the start address above bank 0.
Daryl
Please visit my website -> https://sbc.rictor.org/
Re: Kowalski Simulator Updates
BigDumbDinosaur wrote:
- 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.
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.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"
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/
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Kowalski Simulator Updates
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!