Jump to content
IGNORED

Six Forks Assembler Upgrades


Recommended Posts

Tonight I checked the DataQue X816 assembler, and it treats BRK as a one byte instruction like MAC/65 does.

 

    1 005000                    .CSEG  $5000           ; new origin
    2                  ;
    3 005000 EA                 NOP
    4                  ;
    5 005001 00                 BRK
    6 005002 0244               COP $44
    7 005004 00                 BRK $33
    8                  ;        COP
    9                  ;
   10 005005 EA                 NOP
   11                  ;

End of assembly, 0 error(s) 0 warning(s)

 

Its interesting feature is that it suppresses the optional second byte without generating either a warning or an error. It also does not allow COP to be specified without an operand, which is a bit of a surprise. The second byte is optional according to WDC, so it should permit a blank operand and just substitute $00 for the operand like the WDC assemblers do. Oh well, not like Chuck will fix it now.

 

The ICD cross-assembler XASM65 also treats BRK as a 1-byte instruction. Interestingly enough, it does not permit you to specify an optional second byte; BRK $44 is flagged as a "bad addressing mode" error.

 

Finally, I've discovered a bug in the older version of the SFAxxx assemblers. Any version which supports .CBYTE/.SBYTE has a bug in the .CFE processor which results in all labels after any .CFE being off by 1 in value. So don't use .CFE in those versions (sigh).

 

 

Link to comment
Share on other sites

  • 3 weeks later...

Minor status update: The assembler once again supports all 65816 instructions and addressing modes, properly this time. BRK and COP are treated as two byte instructions which take an optional second byte, which is $00 if it is not specified. JSR and JMP are treated as JSL and JML if they have a known 24 bit address or the ">" forced long operator is used. BRL and PER can take a virtual operand unlike the normal short branches.

 

Still undecided on a mechanism to handle virtual external 24 bit references, although I have to say I dislike the WDC approach with hardcoding the bank, so I will probably just add a .VIRT24 and/or an .XTRN24 directive. I'll probably wait until I'm writing 24 bit code and see how bad the external reference cases are.

 

Once the linker is updated to handle the new relocatable op codes as well as generate the new binary file header for code >$FFFF I'll release a new disk with the updates.

  • Like 2
Link to comment
Share on other sites

Sample output from SFAX816. The MVN/MVP object bytes are in reverse order because the way Six Forks handles outputting expressions makes it difficult to reverse operands. Instead, the linker will just swap them when it builds the final binary. I'll also see if I can widen the listing display so not quite so much gets cut off.

 

Made some good progress with the linker today, almost half done I think.

ax816.jpg

  • Like 1
Link to comment
Share on other sites

when this is complete, as you are now nearing the finish line...

perhaps a contest where one must use six forks to make some goodies across the line...

I think I would donate one of my Perle I/O LAN serial to lan devices as a prize (in fact I will). Maybe other would offer up some goodies and we could bang out some sort of contest parameters. All in good fun and taking it as retro as most are willing to go :)

Edited by _The Doctor__
Link to comment
Share on other sites

Well that's a nice offer but not needed really. I'm not invested in getting people to use SF. Let's face it, the little development that is still happening is being done on the PC, and that's not likely to change. Now that I'm close to having a full 65816 native assembler, I've already started working on my 65816 DOS. I'll use it to work out the bugs in SFAX816/SFL816 like I did SFAXE8 and the Bruce Lee code. That way I'm not just wasting time debugging, I'm also getting something done. I was going to produce a 6502 version for the 800 with an Axlon board, but today I decided to do the 816 version first because that's the one I really want. I can do an 800 and an XL version later.

 

I was trying to think today what, if anything was made with the OSS products and which might be worth updating to run under an 816 DOS. BASIC XE afaik was only used for FOREM XE. Basic XL, nothing. Action! was used for BBS EXPRESS, HardBack and Homepak, and maybe the first Express Terminal. So I might only do Action! and maybe PL65, although I haven't finished disassembling PL65 yet.

  • Like 1
Link to comment
Share on other sites

  • 6 months later...

Still tinkering with the assembler. Added in some CLI options tonight, turn the screen off, etc. Allows for a future MAKE type program to invoke the assembler and pass it a list of files to be assembled, without having to press all the keys you normally need to press. 65816 support still being worked on, trying to cover all the cases. New option .AUTOSW that when you use the register width options like .ACCB if auto-switch is on the assembler will emit the necessary SEP or REP instruction to change modes for you. Also working on adding macro support, which will be modelled on Assembler H although much simplified.

Link to comment
Share on other sites

  • 5 weeks later...

Still tinkering with Six Forks, but SFAX816 has reached the point where I think it's good enough to start using it on other projects. I've decided that cloning the WDC assembler can wait, that I can build the projects I want with what I have, it just means they need to be structured differently. All 65816 opcodes are supported in all modes. BRL/PER allow the target to be a virtual, the linker will catch if the target is too far away. If 24 bit code is used, the binary file header is $FBFA as I used in AlfAsm and Chuck used in his XASM for the Turbo-816. Mostly I've been running 65816 code through the assembler to verify it's correct but a few things have popped up that I hadn't thought of in advance.

 

In the WDC assembler, any external reference to a label is treated as a long reference, unless you use a forced address mode operator. So something like:

 

LDA MEMLO  becomes LDA $00:02E7. This strikes me as wasteful of space, and means a lot of extra typing to keep putting ! in front as in LDA !MEMLO . I had forgotten about this issue until I was testing the PER instruction. Early tests showed it working but when I moved the binary origin to $01:3000 it failed. The assembler balked and said target out of range. PER of course only takes a 16 bit offset and the $01 bank address was causing the opcode processor to fail the expression because of that $01. This wasn't an issue in other tests where the target of PER was a virtual, because, based on its 6502 origin, Six Forks treats all external references as 16 bit addresses, unless you use an address operator or have specifically declared the external via .VIRT24 or .VIRT8. So, the same code works if the target is virtual but fails if the target is an absolute reference above bank 0. What to do ? I want to keep the short addressing because using longs everywhere just slows things down, and I'm not typing in all those ! characters. So I'm going to add a .IGN24O (Ignore 24 On) directive and what it will do is: If the operand is 24 bit and the desired result is 16 bit and there is no forced address operator, then ignore the bank address and treat the result as 16 bit. So LDA $01:02E7 still works because we can handle a 24 bit operand, but PER $01:3030 will also work. This way the same code should work in both cases. It might cause issues with other code, so I'll have to try it and see.

 

Link to comment
Share on other sites

I'm lost, isn't PER always 16 bit... it pushes 16 bit, from whatever comes next. are you saying it wouldn't just truncate it to 16 bit if 24 bits were fed to it?

-snip-

PER is an unusual case. It can be considered 16-bit immediate data, like PEA. Unlike PEA (which pushes the immediate data onto the stack), PER adds the immediate data to the address of the next instruction. This is the same formula that relative16 addressing uses for the destination address, and thus PER is often documented as relative16 addressing rather than immediate addressing. See the section on the PER instruction for further details.

-snip-

62 3 6 imm ........ . PER LABEL

PEA, PEI, and PER all push a 16-bit value onto the stack. In fact, they could be thought of as the different addressing modes of the same instruction, since the operation is otherwise the same. This is analogous to there being different instruction names for JMP absolute and BRL, which are really the same operation, it's just that there is no assembler syntax to differentiate absolute from relative addressing, hence the different names.

Note, however, that the names of these instructions are a bit misleading. The 16-bit value that is pushed onto the stack need not be an address; it could be a constant. Because of the names, the operand syntax permitted (or required) can vary from assembler to assembler.

PEA #$1234 is the syntax that is most consistent with the operation of the instruction, since it simply pushes the value $1234, but does not access memory location $1234 (in any bank). This is analogous to LDA #$1234 vs. LDA $1234; the former does not access memory location $1234 (in any bank), but the latter does (in some bank). Nonetheless, some assemblers permit (or require) the syntax PEA $1234.

Likewise, PEI $12 is the syntax that is most consistent with the operation of the instruction. It pushes the same 16-bit value that (assuming the m flag is 0) LDA $12 loads into the accumulator, rather that the value that LDA ($12) loads into the accumulator. Nonetheless, some assemblers permit (or require) the syntax PEI ($12). Note, however, that PEI always pushes a 16-bit value no matter what the value of the m flag (or, for that matter the x flag) is.

Most assemblers use the syntax PER LABEL, rather than PER #LABEL; in fact, assemblers that even permit the latter syntax (much less require it) are rare. Even though PER $1234 itself does not access memory location $1234, subsequent instructions in any program that uses PER are likely to use the value pushed to access that memory location shortly thereafter. For example

PER LABEL2-1 BRL LABEL1 LABEL2

is like a JSR LABEL1 but with relative (instead of absolute) addressing. PER doesn't access address LABEL2, but address LABEL2 gets accessed when the subroutine returns and the opcode at LABEL2 is fetched. A (somewhat) comparable situation is JMP $1234; the JMP itself does not access $1234, but $1234 is accessed when the opcode at $1234 (i.e. the next instruction) is fetched.

-snip-

if it's rare to have to use something to identify what comes as a label are those assemblers looking for PER and making an adjustment based on whether a label exists because it's not any instruction and also detects $ in order to know how to handle it?

even in this document it's sometimes hard to follow because parenthesis and brackets make determinations and sometimes in the course of typing (as is the case right now)  it becomes an issue when you reading as the writer put parenthesis around some examples...

Edited by _The Doctor__
Link to comment
Share on other sites

Yes, that’s true. However the expression processor returns $013030 as the value of the label. The PER processor balks because it’s expecting a 16 bit value, which isn’t. Now it’s occurred to me that it’s a bug, since what I should be doing is subtracting the target address from the current location counter to get the offset that is pushed on the stack. I’ve tried to be clever so that BRL, PER and PEA are all handled by the same subroutine, so the PER subtraction function should be yielding a 16 bit offset. My guess is the subroutine is catching the bank as $01 because that’s an error for PEA before the code gets around to doing the actual PER math. PER processing should split from PEA before the range check, do its range math and rejoin PEA to check if the final result is >64K. This is why I’m trying to run so many edge cases because everything the original codebase “knows is true” like all addresses are 16 bit or all immediate operates are 8 bit isn’t true in 65816 mode. I’ve had to fix a lot of things in Six Forks to get past the restrictions of the original codebase. I’d only rate the assembler as a good beta atm. 

  • Like 1
Link to comment
Share on other sites

  • 5 months later...

Well now that summer is over it's time to do some coding. Since cross-assembly seems to be all the rage, as an exercise in futility I thought I'd knock off a version of Six Forks that will run under z/OS for those who use the Hercules emulator or have access to real iron. I was going to do it in PLI since that's a reasonably close language to Action!, and it might prove useful in developing an Action! port. Sadly, my PLI skills appear to have rusted almost solid: There seems to be a great many changes from the PLI Optimizing R2.3.0 compiler of my youf that last was available under OS/390 2.10 and the Enterprise PLI 4.2 that came with z/OS 1.13. It might turn out that it would be faster to just do it in Action! from the start. Or S/390 assembly language.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

So still been tinkering with Six Forks, it's good enough for me to use to start working on other 65816 projects, but using it requires some knowledge of how it works internally, so not really any point in releasing it publicly. Once I get it cleaned up, I'll maybe put out a disk. Other than that I'll quit posting because as the prescient FJC said "Wow. Your Six Forks assembler thread deserves the amount of interest it generated.".

  • Thanks 1
Link to comment
Share on other sites

  • 1 year later...
  • 2 years later...

Updated disk. SFA8 and SFL8 may just be copies of SFAXE8 and SFLXE8. I ran into bugs with my copy, so made new ones, but it's not clear if these old diskette ones are still good.

 

SFAX816 is the current 65816 version, only requires a machine with XE-style ram banks, not an actual 65816. Allows for eight character labels, 384 labels per assembly. If any segment is assigned an address above the 64K boundary, the linker will produce a binary that has a non-standard header, starting with $FCFC. See the pdf for more details, I updated some things, new directives etc. Alternating my time between this and my 65816 DOS.

CURRENTSIXF.ATR NewSixf.pdf

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...