Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 55

Thread: SCAR Assembler/Emulator

  1. #26
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default Looking into an Emulator Redesign

    I am thinking about re-designing the emulator. I have managed to code the actual processor well enough, and there is little more to add while staying within the bounds of a processor. Thus, I need to add some sort of peripheral support.

    The new emulator will incorporate the old one, but will allow for additional bus-based hardware to be 'added' to the system. Each program will inform the emulator what hardware it uses inside its header.

    Each component will have the ability to designate graphics. I have not decided exactly how this part will work, but I hope to be able to draw wires from the processor IO to each peripheral.

    Would be cool to be able to have multiple processors / other ICs, but that, for now, is just wishful thinking.

    Thoughts...
    Code:
    Component
    -CPU
    -Memory
    -Peripheral
    
    consts
    -PROGRAM_BUS //Protected RAM (internal CPU)
    -MEMORY_BUS //Only one memory bus supported
    -IO_BUS //GetNextByte will fetch you IO from the correct processor port
    
    
    
    LoadHeader(programbinary);
    
    AddComponent(CPU);
    AddComponent(Memory_64K);
    AddComponent(LED_ARRAY);
    AddComponent(LED_ARRAY);
    AddComponent(LED_ARRAY);
    AddComponent(LED_ARRAY);
    
    LoadProgram(programbinary);on
    
    TurnProcessorOn();
    
    
    
    TurnProcessorOn:
    
    for i := 0 to high(Components) do
      begin
        Param[0] := GetNextByte(Components[i].Bus);
        Call("Component_" + Components[i].Name, Param);
      end;
    
    Component_CPU(opcode: byte);
    
    Component_Memory(val: byte);
    
    Component_LED_ARRAY(state: byte);
    Interested in C# and Electrical Engineering? This might interest you.

  2. #27
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Ability to write new devices for this would be interesting. If you provided well documented stable interface, it would be quite easy to write 'devices' for this. That would let you e.g. write a ATA controller for this.

    EDIT: Imagine, an operating system running on this. Howeber, it wouldn't be easy to write a multi tasking system for this because there isn't memory protection or any kind of timer. Timer and some kind of MMU should be written like devices.
    Last edited by fronty; 10-27-2009 at 03:02 PM.

  3. #28
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    Coming update:
    -RAM dynamically sized as suggested by fronty, this is more efficient
    -Fixed some bugs

    Won't be until monday; I left my flash drive at work

    Still figuring out the peripheral & bus implementation.
    Interested in C# and Electrical Engineering? This might interest you.

  4. #29
    Join Date
    Apr 2007
    Posts
    3,152
    Mentioned
    3 Post(s)
    Quoted
    1 Post(s)

    Default

    ive been following this, as it is sort of interesting, yet im not sure what one would do with it. Enlighten me please?
    SCAR Tutorials: The Form Tutorial | Types, Arrays, and Classes
    Programming Projects: NotePad | Tetris | Chess


  5. #30
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    You can use it to write and run programs. There isn't compiler for any high level language targeting this, so you are stuck with Assembly, but it wouldn't be hard to write a compiler for this. It's sort of like JVM or CLR without any HLL (and JIT ad linking and other fancy stuff ).

  6. #31
    Join Date
    Apr 2006
    Location
    I live in NH
    Posts
    611
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    How about EQU and ORG directives?
    DFM Form Parser - SCAR Obfuscator - Master Keylogger - RuneScape Stats Grabber - Index Cards

  7. #32
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    EDIT: What kind of ORG directive do you mean? If you mean ORG that could specify address where loader is expected to place program, it wouldn't make any sense. ORG which would advance location counter could possibly be useful sometimes.
    Last edited by fronty; 11-05-2009 at 06:53 PM.

  8. #33
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    I understand EQU, but is ORG really necessary?

    Sorry I haven't been doing any work on this recently, I got the flu so I've been sleeping
    Plus I keep forgetting my flash drive at work >,<
    Interested in C# and Electrical Engineering? This might interest you.

  9. #34
    Join Date
    Apr 2006
    Location
    I live in NH
    Posts
    611
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    @Smartzkid, We use a Motorola microprocessor and I think our usable memory range is $2000 to $3FFF, if you were ever to expand your assembler/emulator, you may want to have certain programs stored in certain memory locations using ORG. Plus I feel that ORG is a vital part of any assembler. It shows how easily, you can include an asm file that stores in say $2000 and your program that includes it, stores its own code in $2100, causing an overlap which completely fucks up the instructions cause half the code is correct and the other half is missing. Point being, it would be a more accurate emulation with an ORG directive.

    Hope you get better! My uni is filled with flu and swine flu cases. So we have something bad and something worse, rawr, i hate flu season. Hopefully sledding and snowboarding will make it better.

    @fronty, why wouldn't it work?
    DFM Form Parser - SCAR Obfuscator - Master Keylogger - RuneScape Stats Grabber - Index Cards

  10. #35
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    ORG which would just tell assembler where it should assume loader to load the program wouldn't make sense, because the loads programs to fixed location, at address 0x0. Do you In my opinion org like this would make sense:
    Code:
    jmp label/* address: 0x0 */
    /* address 0x2 */
    org 10 /* jump 0xA forward */
    label: mov ax bx /* address 0xC */
    /* address 0xF */
    What kind of 'including' some other code do you mean? Including source code like #include <code.S>, executing other files with exec\{1,2} or linking other object files like ld main.o code.o? I don't think in first case code.S shouldn't care about it's location on memory, and for the last case there is linking and relocation. I think emulator should create a new address space when executing other programs or do some relocation.

    <offtopic evenslightlyrelated="not at all">Finally got my operating system of choice on this computer. _o/ make buildworld and make buildkernel waits!</offtopic>
    Last edited by fronty; 11-08-2009 at 09:23 AM.

  11. #36
    Join Date
    Apr 2006
    Location
    I live in NH
    Posts
    611
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    An ORG directive like that would be perfect. Make sure there is a /tab needed before it to compile properly. At least, that's what my assembler requires us to do.

    Including just as you said. Include files with
    #include code.asm

    It would be cool if we could have a gui for this too so we could see exactly what line of code the assembler is executing by showing us the lines of code and which line the PC is at.

    ~Ron
    DFM Form Parser - SCAR Obfuscator - Master Keylogger - RuneScape Stats Grabber - Index Cards

  12. #37
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    I think (GUI) debugger would be quite nice. Simple machine level debugger wouldn't be hard to implement and right now there isn't source leven debugger needed or even possible to implement.

  13. #38
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    I was sick and bored today so I wrote simple debugger for this in C# with WPF. It's far away from perfect (partly because this was first time I touched WPF). If someone is interested, I can send it.

    Waiting for Smartzkid to post the updated version. ;o

  14. #39
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    Aah. I broke it ~_~

    I'm currently working to implement a peripheral system.. I'll see what I can do about getting the bugfix release out. Atm it's.. lost in a couple files
    Interested in C# and Electrical Engineering? This might interest you.

  15. #40
    Join Date
    Nov 2009
    Posts
    52
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    bumped: learn to use function pointers :-) apart from that, nice work i suppose. also, nice code you have there fronty, although i would've personally done it a bit differently :-p

  16. #41
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Yeah, that program by me was initially just a quick hack. Then Smartzkid came and released a new version so I had to hack together more hackish version. Maybe I should rewrite it.

  17. #42
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    Delays, delays.

    I'm still procrastinating about adding peripherals.

    I need to look over some embedded-microprocessor assembly (ie microchip asm) to see how they handle IO. I'll probably hardcode some LEDs into it for now; later on I'll add some support for peripherals.

    I was thinking about a pin-based setup. Every peripheral has a name ('CPU', 'Some_Bus', 'RAM') and a certain amount of pins (40, 3, 20). During initialization, the various peripherals would connect their pins to another peripheral (CPU - RAM, etc.), and would only be able to communicate to the hardware to which they were connected.

    But that's crazy talk. I also want to have -one- script for assembly and -one- script for emulation, so I would need to come up with a way to pack peripherals into the executables. This is possible, especially now that SCAR has a Call function, but challenging, nonetheless.

    Yep, so that's the state of things. I haven't forgotten this project, I just can't figure out how to continue. I'll leave the crazy stuff for V3 and 4. Right now, it's all going to be hardcoded. Should give me a good chance to learn and improve before taking huge leaps like that. Wish me luck
    Interested in C# and Electrical Engineering? This might interest you.

  18. #43
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default Sanity at last! (rev 4)

    I've been reading up on the implementation of other emulators and decided I was heading the entirely wrong direction with this. So ignore my last post entirely, here's the new version (rev 4).

    Changes:
    • Magic number incremented to 54
    • Changed how STOR works (flipped order of parameters)
    • Implemented a memory controller (much like what is in a true computer)
    • Note that the memory controller has a memory security feature that allows you to block writing to the program/stack memory. This feature is chosen at assemblytime.
    • Mapped PORTA-PORTD to addresses (see below for details)
    • No longer dynamically positions the stack; however this may change in the future.
    • 'Actual' memory extends from address 0 (start of program memory) to address 255 (end of general memory). This will be increased in the near future; 64 bytes of program memory is starting to become constrictive.


    Code:
    //Memory mapping scheme:
    //0-63 ---| Program
    //64-80 --| Stack
    //81-255 -| General Memory
    
    [Edit] I have just realized that the below addresses are inaccessible because of the currently in place 8 bit addressing scheme. This will be resolved when I switch over to 16 bit addresses.
    //256 ----| PORTA
    //257 ----| PORTB
    //258 ----| PORTC
    //259 ----| PORTD
    Things to know:
    • To assemble a file (.asm) into an executable (.bxe), use AssemblerV2.2.scar.
    • To run a file, use Emulator_advanced.scar.
    • There is a 50 second delay at the end of execution to allow pausing and peeking at the RAM.
    • The supplied program demonstrates the memory protection feature.
    • PORTA - PORTD currently serve no use other than extra general memory. In a future release, though, they will allow for communication to the 'outside' world.


    EDIT:
    The program stack is stored from bytes 64 to 80, not 64 to 79 as previously stated.

    --
    I wrote the code that would have added a display, but I discovered a bit of a problem. Under the currently used 8 bit addressing system, you cannot access anything mapped to a memory location above 255 (obviously). This blocks the use of PORTA-D in this release and stopped the display code from being released today. Before I can take this any further, I am going to need to implement 16 bit addresses. Wish me luck
    Last edited by Smartzkid; 02-20-2010 at 09:45 PM. Reason: 8 bit addresses
    Interested in C# and Electrical Engineering? This might interest you.

  19. #44
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Do you have plans for your memory map when you have 16-bit memory? Are you going to stick with mmio and put devices' address ranges to upper part of memory like right now (but to accessible addresses ) or are planning to switch to pmio?

    Will you add some kind of traps for error handling? If you add some supervisor and user modes, system calls could be implemented also that way.

  20. #45
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    Zomg fronty you're alive! Yay

    I am going to keep it mmio unless I find any distinct advantages to going to pmio (running out of 16 bit space?)

    Once 16 bit addresses are done, I would like to work on the assembler. There needs to be a way to use hardcoded numbers/addresses without having to first store them in a register - the current kluge is a beast to code.

    My current idea is something along these lines:

    [1 byte]
    [Instruction][number format (00 => 8 bit address, 01=> 16 bit address, 02=> 8 bit number, 03 => 16 bit number)][first byte of 16 bit number - OR - 8 bit number][second byte of 16 bit number - OR - nothing, if it was an 8 bit number or address]

    Do you have any idea how they do it in real computers?

    I'm not quite sure about error handling, I'll have to look into it. Good idea though, that would be a good step in the right direction.
    Interested in C# and Electrical Engineering? This might interest you.

  21. #46
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Mmio with 16-bit addressing will be fine unless you add a video controller which keeps everything about 1440x900 display in RAM.

    There is two types of instruction formats used by processor architectures. RISCs use fixed length instructions, CISCs have variable instruction length. For examble SPARC has 32-bit instructions. IIRC, instructions like ld st (load and store values from and to memory, eg. ld [%r2+%r3] %r1) are formatted like this:
    Code:
    op = opcode
    rd = destination register
    rs = source register
    asi = address space indicator
    immed = immediate
    
    31   30 29   25 24      19 18     14   13 12       5 4        0
    |   10   |   rd     |     op     |    rs1    |  0  |    asi    |    rs2   |
    
    31   30 29   25 24      19 18     14   13 12                    0
    |   10   |   rd     |     op     |    rs1    |  1  |     immed         |
    10 (or what ever it is) is a fixed value for load and store instructions. Registers are encoded as 5-bit values. Bit 13 tells us is another register or immediate value used. This doesn't force compiler or programer use two values in different places, register %r0 which is harwired zero can be used (in fact even mov in SPARC is actually "or %r0 source dest"). Arithmetic, logic and shift instructions use very similar format, they only have different bits 30-31 and in case of two registers, bits 5-12 are unused.

    x86 OTOH has very complex instruction format. There are prefixes which modify meaning of instruction and extension bytes and secondary instruction bytes and bits telling which operands are registers or immediate values or memory addresses and operands. Five different addressing modes don't make it any simpler.
    Last edited by fronty; 03-02-2010 at 08:43 AM.

  22. #47
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    I did some looking into various instruction formats, and here is what I came up with:

    Instructions are variable width, composed of an opcode followed by one or more 'parameters'

    Instruction format
    [opcode (byte)] + [id (byte)][data (varies)] x n

    id byte:
    [0][0][0][0][0][0][a][b]

    Currently, only two bits in the id byte are used.

    A: Register bit. If this bit is set, data is interpreted as a 1 byte register; if not, data is interpreted as an immediate number

    B: Immediate Length bit. If this bit is set, data is interpreted as a 2 byte number. Else, data is interpreted as a 1 byte number. This bit is ignored if the register bit is set.

    Data is big endian.


    Advantages:
    • Easily expandable, for example, to allow for the manipulation of 32 bit numbers
    • Every chunk of the instruction is byte aligned
    • Easy to understand (as opposed to the ARM instruction format...)


    Disadvantages
    • Could be more dense. ID byte and opcode could both be shrunk and shoved into a single byte
    • Variable width
    • Very open ended



    What do you think?
    Last edited by Smartzkid; 03-05-2010 at 06:39 PM.
    Interested in C# and Electrical Engineering? This might interest you.

  23. #48
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Big-endian, good choice. 8)

    Does the R bit mean that you are going to remove VAL and possibly allow immediate values for branch, arithmetic, logic and shift instructions? If you'll allow immediates for arithmetic, will they take reg reg val if R bit isn't set?

    I was thinking about that IL bit. Is it just to save some space, or are you going to allow instructions that touch only lower byte of register (:s) ? If it is just to save space, I'm not sure if I think it is necessary, but I am sure I find instructions like that unnecessary even if they save one instruction.

  24. #49
    Join Date
    Sep 2006
    Location
    New Jersey, USA
    Posts
    5,347
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    Quote Originally Posted by fronty View Post
    Does the R bit mean that you are going to remove VAL and possibly allow immediate values for branch, arithmetic, logic and shift instructions? If you'll allow immediates for arithmetic, will they take reg reg val if R bit isn't set?
    Yes, this will allow opcodes to operate on any combination of numbers and registers.

    IE, jie could accept a register, followed by an immediate, and then a label (would would be converted into an immediate by the assembler), or three registers, or anything in between.


    I was thinking about that IL bit. Is it just to save some space, or are you going to allow instructions that touch only lower byte of register (:s) ? If it is just to save space, I'm not sure if I think it is necessary, but I am sure I find instructions like that unnecessary even if they save one instruction.
    I was thinking along the lines of short jump for that one. Additionally, it would save space on small immediates. Practicality with a thought towards code density. If I was going for max code density, I would get rid of the ID byte and shove the R bit into the opcode byte. Maybe I should...
    Interested in C# and Electrical Engineering? This might interest you.

  25. #50
    Join Date
    Sep 2009
    Posts
    66
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by Smartzkid View Post
    IE, jie could accept a register, followed by an immediate, and then a label (would would be converted into an immediate by the assembler), or three registers, or anything in between.
    How is that possible with one bit? You have these combinations:
    Code:
    reg - reg - reg             reg - reg - immed
    reg - immed - reg       reg - immed - immed
    immed - reg - reg       immed - immed  - reg
    immed - reg -immed  immed - immed - immed
    It's not possibly to tell JIE with one bit which combination it has this time.

Page 2 of 3 FirstFirst 123 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •