MaxCoderz

for your 1 bit pleasure!

All times are UTC




Post new topic Reply to topic  [ 27 posts ]  Go to page Previous  1, 2
Author Message
 Post subject:
PostPosted: Fri 17 Nov, 2006 4:56 am 
Offline
New Member
User avatar

Joined: Tue 28 Mar, 2006 10:50 pm
Posts: 73
Location: Wouldn't you like to know?
Where do I put the 0104 key?

_________________
Please "encourage" me to work more on Image any way you deem necessary


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri 17 Nov, 2006 7:55 am 
Offline
Calc King

Joined: Sat 05 Aug, 2006 7:22 am
Posts: 1513
you dont, it defaults to 0104
or if you mean the file.. I put it in the map "compile", not sure whether it should be there though


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri 17 Nov, 2006 12:03 pm 
Offline
Maxcoderz Staff
User avatar

Joined: Thu 16 Dec, 2004 10:06 pm
Posts: 3064
Location: Croydon, England
Brass Website wrote:
Setting up the SDK

Brass does not sign applications itself - it delegates the job to the Wappsign utility supplied as part of the TI-83 Plus SDK. You must have the SDK installed, therefore, to sign applications.

You need to run Wappsign. It should be listed somewhere in the TI-83 Plus Flash Debugger start menu entry, or in the \Utils subdirectory of the Flash Debugger's installation folder. For signing to work, the Wappsign application needs to know where your key file resides. Click the [...] button next to the 'Key File' box, then browse for the 0104.key file. Click 'Yes' on the 'This directory is not in your search path. Add it now?' dialog box. Tick the 'Save Settings on Exit' box, then click 'Close'.


Emphasis mine. Brass doesn't need to know about the 0104.key file - Wappsign does.

As Brass 2 can load custom output plugins, somebody clever might be able to write a self-signing application output plugin. For the moment, using Wappsign's COM interface is the way it's done.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri 17 Nov, 2006 10:28 pm 
Offline
New Member
User avatar

Joined: Tue 28 Mar, 2006 10:50 pm
Posts: 73
Location: Wouldn't you like to know?
Code:
.binarymode ti8xapp                 ; TI-83+ Application

When I try this, it keeps giving me 'error: can't locate 0104 key'. I not sure, but is this an unfinished feature of Brass1? If so, would this work:
Code:
.binarymode intelhex                 ; hex file
(and then use Wappsign)?

_________________
Please "encourage" me to work more on Image any way you deem necessary


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu 01 Feb, 2007 11:00 am 
Offline
Maxcoderz Staff
User avatar

Joined: Thu 16 Dec, 2004 10:06 pm
Posts: 3064
Location: Croydon, England
Sorry, I didn't see this post until now... did you ever get it working? :|

Good grief. I can see what Spencer was getting at when he went to write his own assembler. This is really rather embarrassing.

Code:
.rept 9000
   ld a,1
.unsquish
   ld a,2
.squish
   ret
.loop


Pretty simple stuff. Rather meaningless, but there you go. Here's the result of oldschool Brass:

Code:
Brass Z80 Assembler 1.0.4.9 - Ben Ryves 2005-2006
-------------------------------------------------
Assembling...
Pass 1 complete. (2093ms).
Pass 2 complete. (22062ms).
Writing output file...
Errors: 0, Warnings: 0.
Done!


You're not reading that wrong. Nearly half a minute to assemble that code. Keep that in mind. ;) Also keep in mind that that's a simple, single-assembly project built in the optimised release mode.

I've had a look back into Brass again. I've written quite a lot of code for it, and it's not doing an awful lot thus far. However, it can build the above code and produce identical output -
Code:
Brass Assembler - Copyright © Bee Development 2005-2007
-------------------------------------------------------
ZiLOG Z80 - Copyright © Bee Development 2005-2006
TI Program Files - Copyright © Bee Development 2005-2006
Core Plugins - Copyright © Bee Development 2005-2006

Parsing source...
Building...
Writing output...
Time taken: 484.38ms.
Done!
That's almost 50 times faster; running in Debug mode, within the VS IDE, loading three other (also Debug) DLLs as plugins. I'm so, so, sorry. :(

Anyhow. So far, I have these directives in the 'Core Plugins' collection -

  • .if/.elseif/.else/.endif - conditional compilation.
  • .org/.porg - set the origin (.org) or pad up to the origin (.porg).
  • .align - align to a particular boundary (pads).
  • .rept/.loop - usual loop-unrolling stuff.
  • .push/.pop - pushing and popping a value onto a stack.
  • .db/.dw - the usual byte definition stuff.


Core Plugins also provides a 'Raw' output and an 'IntelHex' output plugin.

'TI Program Files' contains a series of .8?p output plugins, an 'Unsquish' byte transformer plugin and two directive plugins (.unsquish and .squish) that switch the byte transformer plugin on and off. (A byte transformer plugin takes a byte input and returns an array of bytes).

Do people have any particular favourite directives they use that I haven't listed above? (I know it's a rather incomplete list).


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu 01 Feb, 2007 3:23 pm 
Offline
Maxcoderz Staff
User avatar

Joined: Wed 15 Dec, 2004 7:26 pm
Posts: 2735
Location: The Hague, Netherlands
to be honest, that's all I ever used :P

_________________
Image


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu 01 Feb, 2007 4:03 pm 
Offline
Maxcoderz Staff
User avatar

Joined: Thu 16 Dec, 2004 10:06 pm
Posts: 3064
Location: Croydon, England
kv83 wrote:
to be honest, that's all I ever used :P
Well, include files usually have a ".equ". I might put .equ into a 'TASM' plugin collection, as for most people using the '=' operator should be good enough.

There's also TASM-style #define. I'm puzzling over how best to do this. Do I build function support into the emulator (so calling a function can output code and return a value?) or use a TASM-style text-replacement?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri 02 Feb, 2007 11:36 am 
Offline
Maxcoderz Staff
User avatar

Joined: Thu 16 Dec, 2004 10:06 pm
Posts: 3064
Location: Croydon, England
(This post is partially to indicate progress, and partially to post some sample code from the plugin system).

I decided to add functions. They're not that tricky, really... if a constant token is found (a constant being something like 'abcd' or '"fish"' or 763) with an opening parenthesis directly after it, all the stuff between that parenthesis and the matching closing one is removed from the expression and dumped 'inside' the constant token, which is turned into a new 'function' token. When the token is executed, rather than return the label or numeric value associated with it, it's name is looked up from the loaded plugins, and if one matches the arguments that were extracted are sent to the plugin.

I've wrapped up the majority of .NET's Math class as plugins. The Core Plugins package comes with a few classes of its own that can be use to aid plugin development (such as ways to hook in to its conditional compilation system, and in this case a specialised template that accepts a fixed number of comma-delimited arguments, called CommaDelimitedFunction where the third argument added to the constructor is the number of arguments required).

Code:
using System;
using System.Reflection;

using Brass2;
using Brass2.Plugins;
using Brass2.Compiler;

namespace MixedCore {

    public class Min : FunctionHelper.CommaDelimitedFunction {
        public Min(Assembly containingAssembly, Builder compiler)
            : base(containingAssembly, compiler, 2) {
        }
        public override string Identifier {
            get { return "min"; }
        }
        protected override double EasyExecute(Builder.ExpressionGroup[] arguments) {
            return Math.Min(arguments[0].ValueDouble, arguments[1].ValueDouble);
        }
    }

    public class Max : FunctionHelper.CommaDelimitedFunction {
        public Max(Assembly containingAssembly, Builder compiler)
            : base(containingAssembly, compiler, 2) {
        }
        public override string Identifier {
            get { return "max"; }
        }
        protected override double EasyExecute(Builder.ExpressionGroup[] arguments) {
            return Math.Max(arguments[0].ValueDouble, arguments[1].ValueDouble);
        }
    }

}
All plugins need the Identifier, so Brass knows when to use it. EasyExecute in this case takes over from the primitive 'Execute' that's exposed by Brass to automatically handle incorrect numbers of arguments and to strip out the commas.

Why do I feel it worth supporting functions? Well, there's the old mess of the trig table generation functions (and remembering argument orders), so you have finer control over them with the above...

Code:
theta = -1
.rept 256
    .db floor(127 * sin(++theta * pi() / 128))
.loop
(I haven't written a for-loop directive yet).

All plugins have a reference to 'Builder compiler'. This is the current compiler, so when called they can control the compiler in some way. In other words, if I was feeling very lazy, and didn't add macro support...
Code:
public class BCall : Function {

    public BCall(Assembly containingAssembly, Builder compiler)
        : base(containingAssembly, compiler) { }

    public override string Identifier { get { return "bcall"; } }

    public override double Execute(Builder.ExpressionGroup[] arguments) {
        if (Compiler.IsWritingOutput) {
            if (arguments.Length != 1) {
                throw new Exception("BCALL expects one argument.");
            } else {
                ushort RomCallIndex = (ushort)arguments[0].ValueLong;
                Compiler.WriteData(0xEF); // RST $28
                Compiler.WriteData(new byte[] { (byte)RomCallIndex, (byte)(RomCallIndex >> 8) });
            }
        }
        Compiler.CurrentInstructionPointer.Value += 3;
        return double.NaN;
    }
   
}
Sadly this won't work as you can't have floating expressions that don't perform an assignment. ;)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon 05 Feb, 2007 11:26 am 
Offline
Maxcoderz Staff
User avatar

Joined: Thu 16 Dec, 2004 10:06 pm
Posts: 3064
Location: Croydon, England
I've updated a fixed a number of the directives, and added a file operations plugin.

Code:
fhnd = fopen("test.txt", r)

#while !feof(fhnd)
    chr = freadbyte(fhnd)
    .if chr >= 'a' && data <= 'z'
        #db chr + 'A' - 'a'
    .else
        #db chr
    .endif
#loop

fclose(fhnd)


I've added while and for loops too.

Code:
#for theta = 0, theta < 360, ++theta
    .db min(127, round(128 * sin(deg2rad(theta))))
#loop


Alternatively, that could be written as:

Code:
#for theta is 0 to 359
    .db min(127, round(128 * sin(deg2rad(theta))))
#loop


The advantage of the Basic-styled loops is that they have a higher chance of success when detecting infinite loops, and also don't have floating-point creep when using non-integer steps.

There's also the ability to declare your own functions at runtime, though I haven't figured out a clean way to return a value. For the moment they can be used like TASM's macros;

Code:
_PutS = $450A

.function bcall(label)
    rst $28
    .dw label
.endfunction

bcall(_PutS)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue 06 Feb, 2007 2:58 am 
Offline
New Member
User avatar

Joined: Tue 28 Mar, 2006 10:50 pm
Posts: 73
Location: Wouldn't you like to know?
This looks great... When are you going to release Brass2/LateNite2 for public use?

_________________
Please "encourage" me to work more on Image any way you deem necessary


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue 06 Feb, 2007 11:42 am 
Offline
Maxcoderz Staff
User avatar

Joined: Thu 16 Dec, 2004 10:06 pm
Posts: 3064
Location: Croydon, England
There are a lot of things to sort out - least of all the Z80 assembler plugin isn't even finished - so "when it's done".

I realise it's rude to post previews but not deliver, but I wanted to demonstrate that this complete rewrite is worth it in at least it's a more robust system.

The biggest worry with releasing it is if someone decides to start writing plugins and I revise the way they're handled. :)

For starters, the current way a source file is represented (as a LinkedList<Command>) is not great as the functionality for compiling the list is built in to it - so you can't have two such lists of commands and build them into a single output, so this is where the returning values from a function problem comes in (it would be easier if I could split the function body into its own list of commands and execute that whenever the function is called) or even support include files!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed 07 Feb, 2007 11:25 am 
Offline
Maxcoderz Staff
User avatar

Joined: Thu 16 Dec, 2004 10:06 pm
Posts: 3064
Location: Croydon, England
I've broken down the compiler into an "Overseer" (which still contains all of the methods for controlling the assembly process, such as switching the assembler on/off or jumping around the source using bookmarks) and "Source Segments" (which are a series of commands).

A source segment is typically a single assembly file, but by using two new methods - StartRecording and StopRecording - you can extract a block of code from the main assembly process and run it at a later date. You can run it alongside the main body of code (in the case of an include file) or externally (in the case of a function). Now, this sort of thing is possible:

Code:
.function slow_mul(op1, op2)
    slow_mul = 0
    .rept abs(op1)
        .if sign(op1) > 0
            slow_mul += op2
        .else
            slow_mul -= op2
        .endif
    .loop
.endfunction

.echo slow_mul(log(100, 10), slow_mul(5, 4))


(I'm using the VB-style return mechanism where the return value is set by assigning to a variable with the same name of the function).

Something's not quite right with running the functions away from the main body of code, and calling another user-defined function from your own doesn't work, and so there's no recursion either. It should hopefully be a simple enough fix. A 'return' statement would also be easy enough; when encountered set the value as required and switch the assembler off for the remainder of the function. :)

I think the problem is the large number of static variables that still exist from the "one source segment only" idea. It should hopefully be easy enough to fix.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


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:  
cron
Powered by phpBB ® Forum Software © phpBB Group | DVGFX2 by: Matt