Firmware 0.9.9 Progress

148 views
Skip to first unread message

Julian Skidmore

unread,
Feb 11, 2014, 12:09:23 PM2/11/14
to FIGnition
Hi folks,

As for the FIGkeys development I'm going to provide an online progress
report. A line of "*******..." separates the tasks I've accomplished
from those I haven't started yet.

1. The Flash disk driver will be rewritten in Forth which will make it
a bit slower, but should provide about 0.5Kb of space in the Firmware
:-)

The Forth version of the VFlash driver is basically written apart from
a couple of minor TODOs. The conversion from the 'C' version has been
surprisingly easy; though I will have made a number of mistakes, e.g.
getting parameters the wrong way round when calling 'C' routines;
forgetting to make sure certain constants are entered as literals.
I'll go through a checking phase; then I'll get it to compile before
testing.

Thankfully I have a test harness called PurgeTest which is already
written in Forth :-)

***************************************************************

2. The editor will be able to use all the free RAM space for editing
text, which will make editing more convenient. It will save the larger text
files in consecutive blocks. Perhaps I'll also get it to support 2
text editing regions so you can copy text from one block to another!
Finally, I'll fix the Cmd+z bug.

3. Stack checking will be added. This will be embedded into the jump
code [when doing calls/returns, loops, branches and Serial RAM
fetch/stores] therefore I should be able to support it without
incurring any performance penalty. I think this is reasonable, since
most issues to do with stack overflow will occur because of loops that
take things off the stack or add to it.

4. Break will be supported. Again this will be embedded into the jump
code. I'm not sure of the FIGgypad keypress to handle this (I think,
Shift/Release then SW1+SW2+SW3+SW4). I'll probably also need a mod in
FIGkeys for that too. Again, handling break from jump code is
reasonable since BASIC only normally supported break at the end of
each statement.

5. Forth-based Interrupts will be supported, again, this will be
embedded into the jump code. Interrupts will have pretty poor latency
on FIGnition owing to the video code taking up most of the time. In
text mode it won't be quite so bad because Forth is executed (at 8%
performance) during image generation, but in hi-res mode there will be
up to 14ms of latency. Interrupts will be supported for video refresh,
timers and other unassigned interrupts (e.g. I2C)

6. The Quit bug will be fixed.

7. The classic FIG-Forth u/ bug will be fixed (to my shame, it's in there :-( )

You might be quite surprised at how much I think I can squeeze into
the jump code. Actually though there should be plenty of space. When
FIGnition performs a jump it needs to send a command and two address
bytes before the RAM even starts to read data. This means that around
2.7us are available, or 54 cycles and almost all of this is spent
waiting for SPI to finish transmitting each byte. Stack checking,
interrupt support and break only require testing a few registers and
performing simple bit tests so it sounds pretty feasible to me. And it
will add quite a bit of usability and capability to the machine.

I hope you find this interesting!

--

The DIY 8-bit computer from nichemachines(tm)

Mark Wills

unread,
Feb 11, 2014, 2:42:22 PM2/11/14
to fign...@googlegroups.com

This sounds great! Figgy is turning into quite a sophisticated Forth machine!

Thumbs up!

Mark

--
You received this message because you are subscribed to the Google Groups "FIGnition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fignition+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

David Bambrough

unread,
Feb 11, 2014, 3:10:26 PM2/11/14
to Fignition

Hi Julz.

Will you be fixing the blitter bug in 0.9.9?

Cheers,
Dave

On 11 Feb 2014 17:09, "Julian Skidmore" <theorigi...@gmail.com> wrote:

Julian Skidmore

unread,
Feb 11, 2014, 3:12:06 PM2/11/14
to FIGnition

Hi dave,

Good point! I don't think it's hard to fix :-) then you'll find it easier to write your blitter game :-)

Cheers julz

Julian Skidmore

unread,
Feb 12, 2014, 7:06:19 AM2/12/14
to fign...@googlegroups.com
Hi Mark,

> This sounds great! Figgy is turning into quite a sophisticated Forth
> machine!
>
> Thumbs up!

Thanks for that :-)

Sometimes it requires a lot of effort to add things which don't seem
to provide much functionality, but at other times you can add
relatively little and gain significant functionality.

The Disk driver to Forth conversion is definitively in the former
case. It adds nothing to the functionality of FIGnition - it's the
same algorithms! However, it's important because at a practical level
it adds the space I need for a few other, valuable features (like
stack checking). But also, philosophically it's good because from the
beginning I envisaged FIGnition becoming more Forthy, because ideally
Forth is the system and everything should be done through the core set
of words. The 'C'/Assembler/Forth hybrid nature of FIGnition's
firmware messes with that somewhat, mostly because the Forth system
doesn't have any real access to 'C' and 'C' can't call Forth. So where
it doesn't impact, I've been shifting things to Forth. For example,
the editor was re-done in Forth (which actually does add useful
functionality) and the start-up screen was shifted to Forth too.
Ultimately most of the video initialization can be shifted to Forth,
which will help when I add a no-video mode to FIGnition : -1 vmode
(better for embedded real-time applications).

VDisk is a really good example of how FIGnition's firmware has
changed. The earliest version (which wasn't called VDisk) expected
users to supply physical Flash blocks to write to, which meant that
users had to keep allocating a new physical page every time they
wanted to edit a page. Then it was quickly enhanced to support a
simple virtual table of pages, but without purging. This meant that
users would eventually run out of flash simply by editing the same
sectors over and over. The most recent version includes purging and I
love its tiny algorithm! The Forth version could be easily converted
to support a raw Flash-chip based disk system on a retro computer;
including both parallel and serial Flash variants [ A 29F040 would
give you a similar amount of storage as with FIGnition, 512Kb-34Kb or
so]. Anyway, I digress!

On the other hand, it only requires minor changes for the editor to
support >512b of text. In fact you can already use boxed to edit any
amount of text, I did that in order to test FIGkeys 1.1.

-cheers from Julz

Julian Skidmore

unread,
Feb 13, 2014, 10:35:06 AM2/13/14
to FIGnition
Hi folks,

> 1. The Flash disk driver will be rewritten in Forth which will make it
> a bit slower, but should provide about 0.5Kb of space in the Firmware

I needed to do quite a bit more checking, but it's now ready to build
into a FIGnition ROM and begin the test process :-)

Julian Skidmore

unread,
Feb 14, 2014, 8:59:17 AM2/14/14
to FIGnition
Hi folks,

> 1. The Flash disk driver will be rewritten in Forth which will make it
> a bit slower, but should provide about 0.5Kb of space in the Firmware

I've now been able to compile a new firmware ROM with the Flash Disk
Driver in Forth. It turns out I've saved over 800bytes rather than a
mere 512! That feels good :-)

I'm now moving into testing it, but that will probably begin next week
and will take at least a few days I imagine (24 procedures to test).
As a bonus, a number of EEProm commands: ec@, ec! and emove> will now
become part of the standard firmware :-)
> 8. The blitter bitmap dimension bug will be fixed.

> 9. Michael Procter branched some changes to enable FIGnition's firmware to be built under Linux, this will be merged into 0.9.9.

-cheers from Julz

Julian Skidmore

unread,
Feb 22, 2014, 8:52:38 AM2/22/14
to FIGnition
Hi folks,

Progress update.

> 1. The Flash disk driver will be rewritten in Forth which will make it
> a bit slower, but should provide about 0.5Kb of space in the Firmware

This early afternoon I've managed to complete the driver testing. Because the reliability of the flash driver is so critical (you don't want to lose data!), it's required quite extensive testing, but I'm now happy that it works correctly.

As I mentioned before, the new driver also means there's now built-in commands to read the EEProm (and write to it). In addition, it will be possible to erase the disk using a new fdisk command.

Although the testing is complete I have discovered that the block find routine is relatively slow when translated into Forth meaning that in a worst case it may take about 0.5s to search for a block (leading to a wondrous 1Kb/s loading rate!). The original 'C' version wasn't very time efficient (though it was short). It's usable, but if I have time I'll substitute a faster search algorithm.

But as a whole I'm really pleased :-) :-)

This means I'm now on to the next stage - the editor.

> 2. The editor will be able to use all the free RAM space for editing
> text, which will make editing more convenient. It will save the larger text
> files in consecutive blocks. Perhaps I'll also get it to support 2
> text editing regions so you can copy text from one block to another!
> Finally, I'll fix the Cmd+z bug.

A key part of the editor I think is the user-interface for supporting 2 text editing areas. I think what I'll do is actually have a shell option (Cmd $). This will jump to a command window in the bottom 4 lines where you can type Forth and exit back to the editor using ;s . I'll also add a command mark to set the editor's mark address.

Then you could load in a block below the editor's text region and set the mark address to somewhere in that block.

But you could also do more than just copy from a different block, you could computationally generate strings and insert them into the edit region by setting the mark point that way.

What do you think?

Julian Skidmore

unread,
Feb 24, 2014, 1:13:05 PM2/24/14
to FIGnition
Hi folks,

Another Progress Update!

> 1. The Flash disk driver will be rewritten in Forth which will make it
> a bit slower, but should provide about 0.5Kb of space in the Firmware

The Forth version of the Flash driver is now complete. It includes commands to read the EEProm (and write to it); access raw Flash commands via Forth opcodes and format a Flash disk directly.

> 2. The editor will be able to use all the free RAM space for editing
> text, which will make editing more convenient. It will save the larger text
> files in consecutive blocks. Perhaps I'll also get it to support 2
> text editing regions so you can copy text from one block to another!
> Finally, I'll fix the Cmd+z bug.

Today I've mostly completed the editor changes:

* The editor can edit text up to nearly 32Kb of RAM now! ( on 8Kb RAM FIGnitions it will only edit up to nearly 8Kb of RAM).
* The second text edit region is achieved using a shell command (Cmd+$). You type bye to exit the shell.
* The Quit bug has been fixed.

In addition I've added the following commands:

top ( -- addr) the address of the top of ram.
n claim ( -- addr) allocates n bytes from the top of ram and returns the first available allocation byte.
reclaim deallocates the last allocation.

Thus claim and reclaim can allocate a stack of memory blocks from the end of memory and top @ tells you the top of memory. FIGnition calculates the size of memory in abort and it's startup message is now:

FIGnition
©nichemachines 2011-2014
8,061 bytes free

n mark ( n --) sets the editor's mark location. Thus if you're in the editor and you type Cmd+$ it takes you into the shell (which is the same as quit except the stacks aren't reset). So if you then type e.g:

find vlist lfa>nfa mark bye

it'll set the editor's mark location to the first character of vlist's name and then return to the editor. Or, you could do:

15 blk> top @ mark bye

Which would load in block 15 and set the mark location to the first character of the block and then return to the editor. Or you could perform a calculation:

16 bytes markVal
: markCalc 0 <# #s #> markVal swap cmove mark ;

89 23 * $450D + markCalc bye

Which would calculate the result, copy it to the markVal text area and then quit (you don't have to redefine markVal and markCalc every time, only the first time).

So the possibilities are fairly flexible, for anything that can generate text, you can set the block editor's text position to it using mark then exit the shell using bye and Cmd+C will copy the text until it gets to \0.

Editor changes aren't quite complete, I can only load and save one block at a time. I'm going to make changes to blk> to claim ram for the block buffer and >blk to reclaim it. I'll supplant them with:

n blks> ( n -- phys size )  Which will load in successive blocks until it finds a block whose last character is \0 up or until there wouldn't be enough room to store the blocks.

phys virt size >blks ( phys virt size -- ) Writes successive blocks up to size bytes to the disk from physical block phys.

I'm no longer sure that the phys parameters is needed. Originally it was needed because the editor used internal RAM for the edit buffer (because it was much easier to do that in 'C'). But the VDsk buffer also used internal RAM, so if you didn't pre-calculate the physical block to write back to then >blk would end up overwriting the edit buffer with the search blocks from Flash until it found the right buffer. These days I always use serial RAM for the edit region, so perhaps I can remove the phys parameter :-) (this will also make >blk and blk> more less error prone to use).
Finally, load and loads needs to be able to work with multiple blocks, this will require a bit of thinking as its non-trivial. For example, load can't just load in multiple blocks because there might not be enough room to compile the code if there's a lot of text there. There are other issues to consider too.

Anyway, that concludes todays changes on the editor and memory management :-)


> 3. Stack checking will be added. This will be embedded into the jump
> code [when doing calls/returns, loops, branches and Serial RAM
> fetch/stores] therefore I should be able to support it without
> incurring any performance penalty. I think this is reasonable, since
> most issues to do with stack overflow will occur because of loops that
> take things off the stack or add to it.
>
> 4. Break will be supported. Again this will be embedded into the jump
> code. I'm not sure of the FIGgypad keypress to handle this (I think,
> Shift/Release then SW1+SW2+SW3+SW4). I'll probably also need a mod in
> FIGkeys for that too. Again, handling break from jump code is
> reasonable since BASIC only normally supported break at the end of
> each statement.
>
> 5. Forth-based Interrupts will be supported, again, this will be
> embedded into the jump code. Interrupts will have pretty poor latency
> on FIGnition owing to the video code taking up most of the time. In
> text mode it won't be quite so bad because Forth is executed (at 8%
> performance) during image generation, but in hi-res mode there will be
> up to 14ms of latency. Interrupts will be supported for video refresh,
> timers and other unassigned interrupts (e.g. I2C)
>
> 6. The Quit bug will be fixed.

Fixed.

> 7. The classic FIG-Forth u/ bug will be fixed (to my shame, it's in there
> :-( )

Julian Skidmore

unread,
Feb 25, 2014, 12:21:31 PM2/25/14
to FIGnition
Hi folks,

Another Progress Update! I've implemented the loader changes so that multiple consecutive blocks can be loaded. I've fixed the editor Z command; the editor can now edit multiply loaded blocks (yesterday it could only load/save a single block to edit, but it would allow you to edit >512b of text).

I've also implemented the stack and break checking (but it's not tested yet). I've also removed the need for blk> and >blk to handle physical block addresses.

I'll be testing this stuff tomorrow and if possible, starting work on the interrupt handling code.
>blk and blk> don't need the physical block parameter any more. This means changes to Carls UDG editor.
> 2a. Loader changes.

I've implemented the loader changes I thought should be done now.

> 3. Stack checking will be added. This will be embedded into the jump
> code [when doing calls/returns, loops, branches and Serial RAM
> fetch/stores] therefore I should be able to support it without
> incurring any performance penalty. I think this is reasonable, since
> most issues to do with stack overflow will occur because of loops that
> take things off the stack or add to it.

Implemented, not yet tested.

> 4. Break will be supported. Again this will be embedded into the jump
> code. I'm not sure of the FIGgypad keypress to handle this (I think,
> Shift/Release then SW1+SW2+SW3+SW4). I'll probably also need a mod in
> FIGkeys for that too. Again, handling break from jump code is
> reasonable since BASIC only normally supported break at the end of
> each statement.

Implemented, not yet tested.

> 5. Forth-based Interrupts will be supported, again, this will be
> embedded into the jump code. Interrupts will have pretty poor latency
> on FIGnition owing to the video code taking up most of the time. In
> text mode it won't be quite so bad because Forth is executed (at 8%
> performance) during image generation, but in hi-res mode there will be
> up to 14ms of latency. Interrupts will be supported for video refresh,
> timers and other unassigned interrupts (e.g. I2C)

> 6. The Quit bug will be fixed
Fixed.

> 7. The classic FIG-Forth u/ bug will be fixed (to my shame, it's in there
> :-( )

> 8. The blitter bitmap dimension bug will be fixed.

> 9. Michael Procter branched some changes to enable FIGnition's firmware to be built under Linux, this will be merged into 0.9.9.
--
                             
                  The DIY 8-bit computer from nichemachines™

FIG - black on whiteMini.jpg
NmLogoMini.jpg

Julian Skidmore

unread,
Feb 26, 2014, 12:49:17 PM2/26/14
to FIGnition
Hi folks,

Today's Progress Update!

Today I tested multiple block loading; the new version of load and the new version of enclose (which can read in text from multiple consecutive blocks if it's loading from a block). It took quite a while to do that, so I wasn't able to test the break and stack checking features. But basically it's pretty much working. The editor also needed additional testing to work with blks> and >blks. My z bug correction had been wrong, I've fixed that and Cmd+z really does work now.

Tomorrow I'll move onto testing the break and stack checking features... I'm getting closer to the end of 0.9.9 development :-) !

> 1. The Flash disk driver will be rewritten in Forth which will make it
> a bit slower, but should provide about 0.5Kb of space in the Firmware

The Forth version of the Flash driver is now complete. It includes commands to read the EEProm (and write to it); access raw Flash commands via Forth opcodes and format a Flash disk directly.

> 2. The editor will be able to use all the free RAM space for editing
> text, which will make editing more convenient. It will save the larger text
> files in consecutive blocks. Perhaps I'll also get it to support 2
> text editing regions so you can copy text from one block to another!
> Finally, I'll fix the Cmd+z bug.

Today I've completed the editor changes:

> 2a. Loader changes.

I've tested the loader changes now.


> 3. Stack checking will be added. This will be embedded into the jump
> code [when doing calls/returns, loops, branches and Serial RAM
> fetch/stores] therefore I should be able to support it without
> incurring any performance penalty. I think this is reasonable, since
> most issues to do with stack overflow will occur because of loops that
> take things off the stack or add to it.

Implemented, not yet tested.

> 4. Break will be supported. Again this will be embedded into the jump
> code. I'm not sure of the FIGgypad keypress to handle this (I think,
> Shift/Release then SW1+SW2+SW3+SW4). I'll probably also need a mod in
> FIGkeys for that too. Again, handling break from jump code is
> reasonable since BASIC only normally supported break at the end of
> each statement.

Implemented, not yet tested.

> 5. Forth-based Interrupts will be supported, again, this will be
> embedded into the jump code. Interrupts will have pretty poor latency
> on FIGnition owing to the video code taking up most of the time. In
> text mode it won't be quite so bad because Forth is executed (at 8%
> performance) during image generation, but in hi-res mode there will be
> up to 14ms of latency. Interrupts will be supported for video refresh,
> timers and other unassigned interrupts (e.g. I2C)

> 6. The Quit bug will be fixed

Fixed.

> 7. The classic FIG-Forth u/ bug will be fixed (to my shame, it's in there
> :-( )

Julian Skidmore

unread,
Feb 27, 2014, 12:21:53 PM2/27/14
to FIGnition
Hi folks,

Thursday's Progress Update!

Today I found a few more issues with multiple block loading and saving which tied up the morning.

In the afternoon I tested the Stack checking and Break support  - and I've managed to make it work :-) I haven't redone the benchmarks yet, I expect the computer will be no slower, or at least only very marginally, as detailed in the notes below.

The next job is to implement interrupts on FIGnition :-)
> 2a. Loader changes.

I've tested the loader changes now.
> 3. Stack checking will be added. This will be embedded into the jump
> code [when doing calls/returns, loops, branches and Serial RAM
> fetch/stores] therefore I should be able to support it without
> incurring any performance penalty. I think this is reasonable, since
> most issues to do with stack overflow will occur because of loops that
> take things off the stack or add to it.
> 4. Break will be supported. Again this will be embedded into the jump
> code. I'm not sure of the FIGgypad keypress to handle this (I think,
> Shift/Release then SW1+SW2+SW3+SW4). I'll probably also need a mod in
> FIGkeys for that too. Again, handling break from jump code is
> reasonable since BASIC only normally supported break at the end of
> each statement.

Both Stack checking and Break key checking are now implemented. The break key sequence is now: SW2+SW3+SW5+SW8 which is equivalent to Up+Right+Shift+Enter on the keypad. There's no FIGkeys sequence that can yet produce that output. Break can be disabled by setting bit 7 of GPIOR0:

$80 $7F $3E >port> drop

Stack checking and Break should result in little or no performance loss. There is one scenario I can think of where it could make a difference, here's the explanation:

Normally if you need to make a jump (like a loop or if/else/then or until) or a serial RAM access, then stack checking and break access is performed. The tests are done between individual SPI bytes, because it takes 18 cycles or so to read the next SPI byte so there is time to do some extra work.

However, there's one case where reading an SPI byte will be slower and that's during video scanning if the access is taking place just as a scan line starts to be read. In the normal case the SPI fetch would be initiated and when the scan line is done the routine that waits for SPI to complete will find it's already completed. With the new firmware it will still have to spend another 11 cycles or so checking for stack access.

Let's consider a fairly worst-case scenario. In text mode about 9µs are available per scan line for executing Forth when generating video. If we had a tight loop:

: tightLoop [ 5 c, -1 c, ] ; ( which is the same as begin repeat )

Then the computer accesses 2 bytes normally and then does a jump which involves sending a command, then 2 address bytes followed by data to read. So, that's (in theory) 5 bytes or 5µs. This would give a loop speed of about 200KIPs, but we know that a little over 50% of the time is spent generating video so the resultant speed would be about 100KIPs, which is about right.

We can do 9/5 loops every scan line, so every 0.555.. loops a first byte fetch will clash and waste on average 5.5c or a second byte will clash and we'll waste on average 4c. Giving 9.5c or 0.53µs per loop wasted. This will add 0.53µs * 192 delay to the execution or: 102µs in 20ms which amounts to a performance loss of 0.5%.

On the other hand, the new code uses an rcall for the VMTrap jump instead of call, saving one cycle. This will save 1*100,000 cycles/s = 100000/(50*20) = 100µs which balances out the performance loss above.

The next part of the firmware upgrade involves supporting interrupts. As a result I'll have to modify the video scan synchronisation. That's because the current method is to sleep the cpu between each HSync and the actual scan line image generation and that won't work if we support interrupts because if an interrupt occurs between HSync and the scan line generation then the video code will get delayed. Instead we'll have to use another, more complex technique which involves synchronizing the cpu with the timer (see below***).

> 5. Forth-based Interrupts will be supported, again, this will be
> embedded into the jump code. Interrupts will have pretty poor latency
> on FIGnition owing to the video code taking up most of the time. In
> text mode it won't be quite so bad because Forth is executed (at 8%
> performance) during image generation, but in hi-res mode there will be
> up to 14ms of latency. Interrupts will be supported for video refresh,
> timers and other unassigned interrupts (e.g. I2C)

*** CPU Timer synchronization. How do you synchronize the CPU exactly on a timer clock edge without using the sleep technique? The obvious way to check when a timer changes is to put it in a tiny loop. E.g:

Wait:
lds r16,TCNT1L
Wait1:
cp r16,r17
Wait2:
brlo Wait

This loop takes 5c, so TCNT1L could change to the right value during any one of the cycles in the loop and so we could be up to 5c out (which is just over 1 pixel). In addition, TCNT1 runs at 2.5MHz, clk/8. So, what we do is execute some subsequent code which has different execution times in order to tease out which cycle TCNT1 actually changed, e.g:

Path0:
inc r17
Path0a:
lds r16,TCNT1L
Path0B:
cp r16,r17
breq Path2
Path1:

Here, if TCNT1 changed at Wait1 then 8c later the AVR will be at Path0a and the second lds r16 will see a new value so Path2 would get executed. However, if TCNT1 changed at Wait, then 5c later the AVR will be at Path0a and the second lds r16 won't see a new value so Path1 would get executed.

Using this kind of technique we can synchronize the CPU exactly. Note: the  maximum time it should take will be in the region of 5*7 (7c to check 5 cases) = 35c or 1.75µs. Ironically although it looks like quite a bit of effort to do it this way, in fact it should be more efficient than the current method, since the current method involves sleeping the CPU for 18*0.4µs = 7.2µs and executing the video state machine twice. Perhaps we'll save about 5µs per scan line; which would increase FIGnition's performance marginally :-)

> 6. The Quit bug will be fixed

Fixed.

> 7. The classic FIG-Forth u/ bug will be fixed (to my shame, it's in there
> :-( )

Julian Skidmore

unread,
Feb 28, 2014, 11:51:21 AM2/28/14
to FIGnition
Hi folks,

Friday's progress update.

1. I've managed to sync the video without needing to sleep the cpu - it's rock steady in both text and bitmapped modes and increases performance by about 2%... oooh ;-) This means Interrupts can now be supported.

2. I've written the FIGnition user interrupt handler, and it assembles, but it's not yet tested. I also need to write the code to trap interrupts in Forth. This means that 0.9.9 development will go into next week, but that should be the last week for 0.9.9 :-) However, and this is the tricky bit, I currently only have 10b free in the ROM... I'll have to save some space somewhere!

And that's it, I think for this week!

-cheers from Julz

Julian Skidmore

unread,
Mar 8, 2014, 7:13:13 AM3/8/14
to FIGnition
Hi folks,

The next progress update is a *whole*week*later* !!! This week I've been doing quite a lot of bitty work; Thanks to Carl I've had an opportunity to run a FIGnition advert for a German magazine called Lotek64; so I've been designing that and getting it translated into German courtesy of Carl's brilliant linguistic skills! I've also been doing some church music prep; so that's been taking up a bit of time too.

But finally I was able to get some development done! This morning I've been able to finally get user-interrupts on FIGnition to work :-) :-)

So, how does it work? I've added 4 bytes to the sysvars, at offset 19 there's the interrupt vector, which is the cfa of a normal FIGnition Forth routine. At offset 21 there are 3 bytes which contain activated interrupt flags. The firmware has every spare interrupt vector defined as a call to  "vector_1". vector_1 picks up the return address from the vector: an even program address between 4 and 0x34. It then sets the flag bit ((return_address/2)-2)&7 in interrupt flag byte ((return_address/2)-2). FIGnition's trap code looks for any set flag bits and if any are, it pushes the existing Forth IP and then sets it to the forth interrupt vector cfa in sysvars +19. It also pushes the flag bits as two words on the stack and clears them (so the same interrupts aren't retriggered).

So, that might sound a bit complex, but the upshot is that FIGnition's Forth user-interrupt system can support multiple interrupts simultaneously and reentrantly. The Forth interrupt routine is just another Forth word which finds the interrupt flags on the top two items of the stack and can simply return as normal.

Now let's see how it works in practice with my example code ( a simple timer0 overflow interrupt):

$35 const TIFR0
$6E const TIMSK0
$45 const TCCR0B
$46 const TCNT0

: OVF ( intFlags23to16 intFlags15to0 --)
  drop drop
  16 $26 ic!
  clock i@ vram i!
;

: setupInts
  [ find OVF lfa>cfa ] literal
  sysvars 19 + i!
  0 TCNT0 ic!
  5 TCCR0B ic! ( clk/1K)
;

: testInts
  setupInts
  1 TIMSK0 ic!
  begin
    inkey dup emit
  asc ! = until
  0 TIMSK0 ic!
;

OVF is the interrupt routine itself. Since it's the only user-interrupt routine I'm handling, I don't care about the flags on the stack, so I just drop the values. If I didn't do that, the stack would overflow and a stack error will now be generated. The interrupt routine just inverts the LED (16 $26 ic!) and then outputs the current clock value on the top left-hand part of the screen. It doesn't do anything clever with the interrupts itself, it just lets timer0 carry on and generate another overflow interrupt in 256 timer 0 ticks.

setupInts sets up the interrupt. It finds the cfa of OVF and stores it in the FIGnition interrupt vector at sysvars+19. Then it clears the timer0 counter and then starts it running at just under 20KHz (20MHz/1024). This will cause an overflow every 13ms (about 76Hz). However, it doesn't actually activate the overflow interrupt quite yet.

testInts first does setupInts to set the interrupt information up and then finally does 1 TIMSK0 ic! to activate the timer0 overflow interrupt. Then it sits in a loop emitting anything you type until you press !. At the end it disables the Timer0 interrupt.

The upshot is that when you type testInts <exe>, the clock value is poked into video memory and the LED inverts every 13ms. While this is happening, you can type and text starts to appear from the current cursor position - hey presto, interrupt, driven code.

There are things to be aware of. OVF can't be allowed to run for more than 13ms or OVF itself would get interrupted! You would have to disable the TIMSK0 interrupt at the beginning of OVF; clear any OVF and sysvar flags and then at the end re-enable the interrupt. In addition, if you handled more than one interrupt it'll all have to go through the one routine which would then need to skip to the intended user interrupt code. This will add to user-interrupt latency, which is already not great owing to an interrupt only ever being called when you do a serial RAM fetch/store or do a jump in the program code (begin/until or begin/while/repeat or do/until or call/return). Interrupt latency, I guess will be typically in the region of 20µs to 200µs.

But I think that's OK for an educational system like FIGnition - you can demonstrate interrupts in a fairly flexible way, and it's more usable than many early 80s computers. I need to do a bit of work to make sure interrupts will happen when you execute inkey or key; and in fact it means I need to convert key to Forth to make that happen (key is only used once in FIGnition's firmware, when you press the command key).

This means that the majority of the development for Revision 0.9.9 is done and only the bug-fixing for u/ and the blitter remains.

-cheers from Julz
FIG - black on whiteMini.jpg
NmLogoMini.jpg

Julian Skidmore

unread,
Mar 11, 2014, 11:36:40 AM3/11/14
to FIGnition
Hi folks,

Progress for Monday and Tuesday.

On Monday I did two jobs: I found a bug in the editor so that when returning from the shell command, editor text would be badly messed up. This was traced to an error in the locs command which didn't take into account the way the avr return stack is post-decremented (odd, but that's the way Atmel handles it!). This meant that executing >l 0 would overwrite the StackFrame restore value which meant that nested locs invocations would incorrectly restore the locs stack frame.

Secondly, I managed to get the interrupts working even when executing key. This meant recoding key in Forth and removing the 'C' version. However, I'd already essentially written a version of key for the editor so it just meant factoring that out - saving around 40 bytes.

Today I mostly did bug corrections:

1. The u/ division bug. It turned out that there was only an issue with division if the result would overflow $FFFF. However, when investigating it, I realized that my 32bit/16bit division algorithm was twice as slow as it needed to be. FIGnition's u/ command now returns a -1 modulus if overflow occurred (a -1 modulus result can't occur from a 32bit / 16-bit div-mod, because it would require a divisor >$FFFF and the maximum divisor is $FFFF). It's also about 2.1 x faster!

2. The blitter bug. This was due to the graphic cursor's x coordinate being updated to point after the bitmap and then using that value to calculate the pixelShift. Hence the pixelShift was only correct if the bitmap was an exact number of tiles wide. This was easily corrected and the test case which exhibits the problem no longer fails.

3. I found a videoSync glitch again! Two pixel synchronisation cases were the wrong way round leading to the Clock+6 case being 2 cycles too short and the Clock+7 case being two cycles too long. I reversed a branch condition to fix this - now videoSync is 100% stable in PAL and NTSC even when editing :-)

4. A memory sizing error. The new firmware checks memory sizes, but on 8Kb RAM FIGnitions it could incorrectly report 32Kb of RAM if memory at address -1 was modified.

OK. And this is the big one, pending a formal announcement, Firmware 0.9.9 is now complete :-) Weyhey!!!

Tomorrow I start on 1.0.0. However, here's an interesting facet you'll enjoy, 0.9.9 is significantly faster! These are the new benchmarks (as an image).



Most of the speed improvements come from u/ being about twice as fast now! But a little improvement comes from very slightly faster jumping and also the extra performance due to the new horizontal pixel sync code. But, the system is about 20% faster when executing Forth :-)

Also, I've managed to claw back a little Flash space: there's now ... wait for it...

wait for it....




















A whole 54 bytes free in the ROM :-) Yay, whew! In reality I'll be able to gain a few extra bytes in the ROM for version 1.0.0.

My one remaining job before the formal release are a document listing the new features and changes to 0.9.9. I still haven't integrated the Linux build mods to FIGnition, sorry about that; it will come, along with a proper github update.

Meanwhile, have a look at the candidate release!

-cheers from Julz
Candidate0.9.9Distro.zip

Julian Skidmore

unread,
Mar 12, 2014, 4:22:33 AM3/12/14
to FIGnition
Hi folks,

So much for the candidate ROM, I found a bug with the editor's z command - it didn't return the cursor to the top, left-hand corner! That's fixed in my build now (48b free).

-cheers from Julz
Reply all
Reply to author
Forward
0 new messages