Updated: 11/5/2005; 6:10:29 PM.
Chris Double's Radio Weblog
        

Thursday, September 08, 2005

For the Space Invaders emulator in Factor I wanted to automate the creation of the 8080 instruction emulation words. To do this I used a format for describing the 8080 instructions based on the Z80 equivalents and coded a Factor parsing word that parsed this format and produced some of the code. For example, some instructions are:

INSTRUCTION: DEC DE ; opcode 1B cycles 06
INSTRUCTION: INC E ; opcode 1C cycles 05
INSTRUCTION: DEC E ; opcode 1D cycles 05
INSTRUCTION: LD E,n ; opcode 1E cycles 07
INSTRUCTION: RRA ; opcode 1F cycles 04
INSTRUCTION: LD HL,nn ; opcode 21 cycles 10
INSTRUCTION: LD L,(HL) ; opcode 6E cycles 07
INSTRUCTION: LD L,A ; opcode 6F cycles 05
INSTRUCTION: LD (HL),B ; opcode 70 cycles 07

Using the parser combinators library I write parsers that processed the instructions and seperated them into families of instructions. For example, LD R,(RR) was the family for loading an indirect register into a direct register. The parser combinator word for this is:

: LD-R,(RR)-instruction
"LD-R,(RR)" "LD" complex-instruction
8-bit-registers sp <&>
"," token <&
16-bit-registers indirect <&>
just [ unswons unswons >r swap append r> cons ] <@ ;

For LD R,R it is:

: LD-R,R-instruction
"LD-R,R" "LD" complex-instruction
8-bit-registers sp <&>
"," token <&
8-bit-registers <&>
just [ unswons unswons >r swap append r> cons ] <@ ;

Notice the change in the word is just whether it is for 8-bit or 16-bit registers and whether it is an indirect access. The combinator produced a list of words for retrieving and setting the relevant registers from the CPU tuple and a pattern matcher replaced these words in a pattern for that instruction family:

[[ "LD-R,(RR)" [ [ $3 ] keep [ read-byte ] keep $2 ] ]]
[[ "INC-R" [ [ $1 ] keep [ inc-byte ] keep $2 ] ]]

In this way I could write code for just the groups of instructions and at parse time Factor would generate code for the specific instructions. This cut down on the amount of code to write. In the near future I plan to extend this so that it will not only generate the emulation words, but the assembler and disassembler words as well. It could even go further and on seeing a '(RR)' on the right hand side, could generate the '[ $3 ] keep' and reduce the instructions families that need to be coded by hand even more. The code for this is in cpu.factor. This ability to do things at parse time is very similar to Lisp macros.

4:11:15 PM      

I've been working on a Space Invaders emulator written in Factor. I plan to make a generic 8080 emulator, assembler and disassembler. Currently the emulator works for a lot of the instructions and can run some parts of the Space Invaders arcade machine ROM. A screenshot of it running is here.

There's lots to be done but the current code is in Factor CVS and from my Factor Darcs repository. You will need to have your own invaders.rom file to test it though. There is a brief readme.txt file.

I'll post more on the design and implementation when I've got the main part of the game running. And then work on the assembler and disassembler.

As an example of the speedups obtained from optimisations in Factor 0.78, running 1,000,000 instructions in 0.77 took 3,174 milliseconds. In 0.78 it took 2,293 milliseconds.

Even in 'interpreted' mode the emulator runs faster than normal speed. When compiled it is very fast.

1:57:40 PM      

Factor 0.78 has been released by Slava. It contains fixes to the PPC back end and some optimisations.


12:07:12 PM      

Joel Reymont compares Java vs Erlang implementations of his poker server's protocols.

12:06:14 PM      

© Copyright 2005 Chris Double.
 
September 2005
Sun Mon Tue Wed Thu Fri Sat
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
Aug   Oct



Click here to visit the Radio UserLand website.

Listed on BlogShares

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.