Assembler with structured conditionals

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Assembler with structured conditionals

Post by Dr Jefyll »

Dr Jefyll wrote:
[...] Self Modifying Code (perhaps too broad a title
JimBoyd wrote:
Sorry about that, I kinda got sidetracked on that one. The disscussion digressed to a discussion on fixing that ugly hand calculated offset in my example SMC.
Oops. And the digression was caused by me. :oops: FWIW, my excuse is that Self Modifying Code has gotten a lot of bad PR, and I feel the best way to overcome that is to show SMC being used in a clean and tidy way. When your example of SMC also happened to include hand calculated offsets I felt compelled to speak up, because the two do NOT go hand in hand.
Dr Jefyll wrote:
[...] I daresay there's no perfect solution, but perhaps it'd be best if the error-check codes (but not the addresses) got pushed & popped from their own separate stack.
JimBoyd wrote:
That's why I've got CS-DUP CS-DROP CS-SWAP and CS-ROT which also work with high level Forth conditionals. I just treat the address and security number as a single unit.
Yes, you have a solution of sorts but it's not one I like much, and I thought perhaps I could do a little better.

Unfortunately, after refreshing myself on the subject (it's been years since I involved myself with this) I have no dramatic improvement to offer. In my notes I did find the following...

Code: Select all

: IF[WITHIN], ( like IF, but used within an assembler structured conditional )
    >R >R [COMPILE] IF,
    R> R> ; IMMEDIATE
... but this is less flexible than what you're doing, and certainly no prettier. :|

cheers,
Jeff

ps: returning to the subject of clean and tidy coding, don't you think you should used a named constant in cases like this? :P :wink:

Code: Select all

98 LDY,
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Assembler with structured conditionals

Post by GARTHWILSON »

If I implement the structured conditionals, I might do something like:

Code: Select all

HEX

CODE ACLOSE  ( -- )         \ Close all open files.
   STX_ZP  XSAVE  C,
   BEGIN,
      LDY_ZP  98  C,        \ (but give a name, as Jeff suggests)
      0<>
   WHILE,
      LDA_ABS   258  C,     \ LAST OPENED
      JSR      FFC3   ,     \ CLOSE
   REPEAT,
   LDX_ZP  XSAVE  C,
   JMP     NEXT    ,

(My Forth assembler requires comma'ing in the operands.)  One thing I would definitely do is put the test condition on the line before the WHILE, so the first character of WHILE, can be vertically aligned with that of BEGIN, and REPEAT,.  Same thing with an IF, for example.  It's just (very strong) personal preference.  That's a nice thing about Forth though, and maybe one reason that managers sometimes aren't too fond of Forth.  It allows us free thinkers to do things our own way, independently of how others do it.  It's also one reason Forth will never die.  Since we can get under the hood and modify or extend even the very compiler and assembler, it won't affect us much if commercial support were ever to disappear.

Edit:  In my assembler macros for the normal (non-Forth) assembler, I put the condition with the IF, WHILE, etc., like IF_EQ, WHILE_NEG, etc..
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?
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

whartung wrote:
and, yes, you should include a copy of the license in the ZIP file.
You are correct, I should have. I wasn't thinking about it but, those who downloaded the first ZIP file are limited to 'fair use' of copyright law. The first one has been replaced with a ZIP file containing the assembler and a copy of the LGPL version 2.1.
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

Dr Jefyll wrote:
ps: returning to the subject of clean and tidy coding, don't you think you should used a named constant in cases like this? :P :wink:

Code: Select all

98 LDY,
Well, it's one of those locations used by the C64 kernel and I didn't want to add a constant to my Forth kernel that would only be used once.
I suppose I could add a constant that exists on the host but not the target. Since it's only used once in the entire Forth kernel, would a comment do?
The Commodore 64 Programmers Reference Guide calls location $98 LDTND number of open files/index to file table, and locations $259-$262 LAT Kernel table: active logical file numbers.
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

GARTHWILSON wrote:
One thing I would definitely do is put the test condition on the line before the WHILE, so the first character of WHILE, can be vertically aligned with that of BEGIN, and REPEAT,. Same thing with an IF, for example. It's just (very strong) personal preference.
Since the conditional has to be there to determine which branch opcode is compiled by WHILE, , and IF, , I tend to see the conditional as part of the WHILE,. That's why I put it on the same line.

If I understand your assembly notation, shouldn't this:

Code: Select all

      LDA_ABS   258  C,     \ LAST OPENED
be this:

Code: Select all

      LDA_ABS,Y   258  C,     \ LAST OPENED
or something similar?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Assembler with structured conditionals

Post by GARTHWILSON »

JimBoyd wrote:
GARTHWILSON wrote:
One thing I would definitely do is put the test condition on the line before the WHILE, so the first character of WHILE, can be vertically aligned with that of BEGIN, and REPEAT,. Same thing with an IF, for example. It's just (very strong) personal preference.
Since the conditional has to be there to determine which branch opcode is compiled by WHILE, , and IF, , I tend to see the conditional as part of the WHILE,. That's why I put it on the same line.
I always have the test condition before the conditional word.  So instead of something like

Code: Select all

    FOOBAR @  0= IF
        <do stuff>
        <do stuff>
    THEN

I always do

Code: Select all

    FOOBAR @  0=       \ Is it zero?
    IF  <do stuff>     \ If so, do this stuff.
        <do stuff>
    THEN

An exception would be when it works well to have all the structure words at the end of the line, something like

Code: Select all

    <bla>  <bla>  <bla>   <condition?>     IF
    <do_this>  <do_that>  <do_the_other>   ELSE
    <otherwise_do_this_other_stuff>        THEN

Also for looping controls:

Code: Select all

    <limit>  <index>
    DO  <do_stuff>
        <do_stuff>
    LOOP

In any case, I don't ever want the structure words to be at a diagonal from each other.  Always either vertical or horizontal for visual factoring.  Always.  (Again, personal preference.)

Quote:
If I understand your assembly notation, shouldn't this:

Code: Select all

      LDA_ABS   258  C,     \ LAST OPENED
be this:

Code: Select all

      LDA_ABS,Y   258  C,     \ LAST OPENED
or something similar?

Yes, you're right.  LDA,Y.  (For ZP, there's LDA_ZP,Y.)
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?
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

GARTHWILSON wrote:
In any case, I don't ever want the structure words to be at a diagonal from each other. Always either vertical or horizontal for visual factoring. Always. (Again, personal preference.)
That doesn't really bother me, as long as the indentation correctly shows the control flow nesting.
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

JimBoyd wrote:
When I was developing my metacompiler, I added a feature that I never actually needed ( it was easy to add ). The metacompiler has a word SUB which is used to write subroutines a code word might need.
I really shouldn't post when I'm tired. I do use SUB in my kernel source. Before that, I used LABEL ( makes a metacompiler label ) and invoked the assembler directly. SUB was so much easier.
whartung wrote:
If it were just a stand alone program that takes a text file and spits out an assembled binary, then it's simply a different syntax rather than an entirely different tool chain.
I made some improvements to my metacompiler. With INCLUDE , it can take this sequential file from a C64 disk and compile it with no Forth, no headers, just the assembly code. It then prompts for a filename and spits out a binary to the disk. The demo does what some programs meant to be called from BASIC does, SYS 49152 does one thing and SYS 49155 does another.

Code: Select all

HEX  START
C000 ORIGIN
SUB TWIN.DEMOS
   AHEAD,
      0 # LDA,  TAX,
      10 # LDY,
      BEGIN,
         D020 STA,  CLC,  1 # ADC,
      CS-DUP 0= UNTIL,  // CONTINUE
         INX,
      CS-DUP 0= UNTIL,  // CONTINUE
         DEY,
      0= UNTIL,
      RTS,
   THEN,
   0 # LDY,  FC STY,
   7 # LDA,  FD STA,
   4 # LDA,  FE STA,
   E8 # LDY,
   BEGIN,
      DEY,
      FC )Y LDA,  80 # EOR,
      FC )Y STA,
      0 # CPY,
   CS-DUP 0= UNTIL, // CONTINUE
      FD DEC,  FE DEC,
   0= UNTIL,
   RTS,
END-CODE
TSAVE
meta assembler demo 2.png
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

Changes to the Fleet Forth kernel necessitated changes to the definitions of CODE , ;CODE , and END-CODE .
Here is the new source

Code: Select all

SCR# F 
// SUBR CODE ;CODE END-CODE
HEX  FORTH DEFINITIONS
: SUBR  ( -- ADR TRUE )
   CREATE  LATEST TRUE
   OVER TSB
   [ ASSEMBLER ] ASSEMBLER MEM ;
: CODE  ( -- ADR TRUE )
   SUBR  HERE DUP 2- ! ;
: ;CODE  ( TRUE -- TRUE )
   DUP TRUE ?PAIRS
   COMPILE DOES  [COMPILE] [
   [ ASSEMBLER ] ASSEMBLER
   MEM ; IMMEDIATE
: END-CODE  ( ADR TRUE -- )
   CURRENT @ CONTEXT !
   TRUE ?PAIRS TSB ;
As for SUBR , well, some Forth's have code like this:

Code: Select all

CREATE SOMENAME  <setup assembler>
   <assembly code>
to create subroutines. SOMENAME returns its address and is used like this:

Code: Select all

   SOMENAME JSR,
or, depending on the assembler, like this:

Code: Select all

   JSR SOMENAME ,
SUBR creates a subroutine without the need to explicitly setup the assembler.
All such subroutines are concluded with END-CODE .
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

Dr Jefyll wrote:
returning to the subject of clean and tidy coding, don't you think you should used a named constant in cases like this? :P :wink:

Code: Select all

98 LDY,
Since defining a constant in the target source builds that constant in the target, I added DEFINE to my metacompiler. It builds a constant on the host so no memory is used for it on the target.

Code: Select all

SCR# 2 
// META CONSTANTS
HEX
  98 DEFINE #FILES
 259 DEFINE LF.TABLE
FFC3 DEFINE FCLOSE

// CLOSE ALL OPEN FILES
CODE ACLOSE  ( -- )
   XSAVE STX,
   BEGIN,
      #FILES LDY,
   0= NOT WHILE,
      LF.TABLE 1- ,Y LDA, // LAST OPENED
      FCLOSE JSR,    // CLOSE
   REPEAT,
   XSAVE LDX,
   NEXT JMP,  END-CODE
P.S. It may take a while to cleanup all of Fleet Forth's source code, but the improved readability will be worth it.

Cheers,
Jim
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

JimBoyd wrote:

Code: Select all

HEX  START
C000 ORIGIN
SUB TWIN.DEMOS
     .
     .
     .
I renamed the metacompiler's SUB to SUBR for consistency with the host assembler. Why SUBR over SUB ? To avoid confusion if this Forth assembler macro is ever defined:

Code: Select all

: SUB,  ( OPERAND -- )
   SEC,  SBC, ;
The metacompiler's SUBR creates a label on the host ( in the shadow vocabulary ) that returns the virtual address of the subroutine on the target, but no header or CFA is compiled on the target, only the subroutine.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Assembler with structured conditionals

Post by barrym95838 »

GARTHWILSON wrote:
(For ZP, there's LDA_ZP,Y.)
And what op-code do you comma in for that one? :wink:
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)
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Assembler with structured conditionals

Post by GARTHWILSON »

barrym95838 wrote:
GARTHWILSON wrote:
(For ZP, there's LDA_ZP,Y.)
And what op-code do you comma in for that one? :wink:
Yeah, messed up again.  It happens too much.  Thanks for straightening me out.  Too much hurrying, and it's counterproductive.  I'd get more done if I would just make better use of time (which is sort of a New Year's resolution for 2019) instead of trying to hurry through things.

In any case, the op codes are never comma'ed in, but are laid down by the words like LDA,Y.  (Since there's no LDA ZP,Y, there's no need to put the "ABS" in. I had to check.)  The word LDA,Y just has the header, plus the CFA pointing to comp_op ("compile op code," a runtime routine), and the parameter field of only one byte (not two), that of the op code.  The assembly-language source code has two macro invocations and looks like this:

Code: Select all

        HEADER "LDA,Y", NOT_IMMEDIATE
        OP_CODE $B9

The operand (but not the op code) must be comma'ed in.

Now I'm in a hurry to get to bed.  :lol:   Important meeting later today.
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?
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Assembler with structured conditionals

Post by barrym95838 »

GARTHWILSON wrote:
I'd get more done if I would just make better use of time ...
[OT] Amen. I have a gigantic pile of "stuff" that needs my attention. I often get a feeling of being lost under the weight of it all, and I don't even have the fortitude to at least nibble away at it, which would be better than trying to pretend that it's not there ... [sigh]
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)
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Assembler with structured conditionals

Post by JimBoyd »

I didn't mention it ( although it's in the source code ) but my assembler has the word BRAN, which takes an address and a condition code from the stack. As an example of how it works, here is the source for Fleet Forth's S>D

Code: Select all

CODE S>D  ( N -- D )
   1 ,X LDA,
   PUSH.TRUE 0< BRAN,       // COMPILES BMI
   PUSH.FALSE 0< NOT BRAN,  // COMPILES BPL
END-CODE
PUSH.TRUE and PUSH.FALSE are metacompiler labels for the locations where a true and a false respectively are pushed onto the data stack.
TRUE and FALSE have no bodies. Their code field's point to these locations so S>D could have been written as

Code: Select all

CODE S>D  ( N -- D )
   1 ,X LDA,
   ' TRUE @ 0< BRAN,       // COMPILES BMI
   ' FALSE @ 0< NOT BRAN,  // COMPILES BPL
END-CODE
BRAN, and all the words that compile or resolve a branch perform distance checking and abort if the distance is too far. I was motivated to add this when I was working on that word that takes a 64 bit unsigned number and returns the square root as a 32 bit result.
Post Reply