6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 11:56 pm

All times are UTC




Post new topic Reply to topic  [ 36 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Thu Dec 06, 2018 1:41 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3346
Location: Ontario, Canada
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:
: 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:
98 LDY,

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 06, 2018 1:45 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
If I implement the structured conditionals, I might do something like:
Code:
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?


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 07, 2018 9:10 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 07, 2018 9:17 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
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:
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 07, 2018 9:29 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
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:
      LDA_ABS   258  C,     \ LAST OPENED

be this:
Code:
      LDA_ABS,Y   258  C,     \ LAST OPENED

or something similar?


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 07, 2018 10:45 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
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:
    FOOBAR @  0= IF
        <do stuff>
        <do stuff>
    THEN

I always do
Code:
    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:
    <bla>  <bla>  <bla>   <condition?>     IF
    <do_this>  <do_that>  <do_the_other>   ELSE
    <otherwise_do_this_other_stuff>        THEN

Also for looping controls:
Code:
    <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:
      LDA_ABS   258  C,     \ LAST OPENED

be this:
Code:
      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?


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 08, 2018 9:19 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
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.


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 16, 2018 7:40 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
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:
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

Attachment:
meta assembler demo 2.png
meta assembler demo 2.png [ 23.67 KiB | Viewed 6000 times ]


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 04, 2019 12:21 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
Changes to the Fleet Forth kernel necessitated changes to the definitions of CODE , ;CODE , and END-CODE .
Here is the new source
Code:
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:
CREATE SOMENAME  <setup assembler>
   <assembly code>

to create subroutines. SOMENAME returns its address and is used like this:
Code:
   SOMENAME JSR,

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

SUBR creates a subroutine without the need to explicitly setup the assembler.
All such subroutines are concluded with END-CODE .


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 09, 2019 9:48 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
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:
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:
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


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 09, 2019 9:59 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
JimBoyd wrote:
Code:
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:
: 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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 10, 2019 7:59 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1927
Location: Sacramento, CA, USA
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)


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 10, 2019 10:35 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
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:
        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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 10, 2019 6:18 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1927
Location: Sacramento, CA, USA
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)


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 29, 2019 9:34 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
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:
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:
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.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 36 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC


Who is online

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