New books from Apress

Andy Armstrong andy at hexten.net
Sun May 21 11:14:51 BST 2006


On 21 May 2006, at 10:58, Peter Corlett wrote:
> Well.. the 6502's memory isn't a flat 64kB area of RAM: it's RAM,  
> ROM, MMIO
> and bank-switched. There's lots of inefficient frobbing of status  
> registers.
> Some instructions change how they work based on the status  
> registers, in
> particular BCD mode. Suddenly the code explodes with special cases  
> and it's
> not fun to hack on any more.

I'm inclined to concentrate on emulating a BBC 65C02 second processor.

Decimal mode is the /only/ processor mode and it only impacts  
(AFAICR) on ADC and SBC.

> We use Perl to avoid code that's not fun to hack on. So let's see  
> what Perl
> gives us:
>
> We don't have a switch() statement which initially looks like a  
> deficiency,
> but forces us to step back and look for a different approach. An  
> array of
> coderefs looks good. It gets better when you realise that to  
> support BCD
> mode, you can have a parallel array with the appropriate instructions
> replaced. Switch between them as appropriate.

You are /so/ looking over my shoulder :)

my @decode = (
     inst(                       # 00 BRK
         i_push('($pc + 1) >> 8', '($pc + 1)'),
         i_set_flag($B),
         i_push('$p'),
         i_set_flag($I),
         i_jmp_i($BREAK)
     ),
     inst(i_ora(i_zpix())),      # 01 ORA (zp, x)
     $bad_inst,                  # 02

etc etc

The various microcode primitives like i_push() return a fragment of  
Perl, inst just wraps them all in eval "sub { $code }" to turn them  
into a coderef.

> Memory would obviously be a 65,536-element array. Some other  
> approaches
> might suggest themselves, until you realise that MMIO is suddenly  
> easy once
> you have tied scalars on the job. Bank-switching? That's what splice 
> () is
> for.

I'm working with a flat 64k address space for now :)

> But we're still emulating a dumb apprach in a clever way.
>
> Keep the 65,536-element memory array. Have a parallel array of  
> coderefs.
> When you come to execute code, check the coderef and if it doesn't  
> exist,
> start scanning forwards in memory and create a suitable coderef.  
> Tie the
> memory scalars to notify you on writes to catch self-modifying code  
> and thus
> invalidate the coderefs. Hey presto, a crude JIT. There's plenty of  
> gotchas
> (this is a *hard* problem with lots of edge cases), but it'd be  
> educational
> and potentially less horrible to debug than a C implementation.

Yeah, I've been thinking about that - but the edge cases seem pretty  
quickly to overwhelm everything else.

-- 
Andy Armstrong, hexten.net



More information about the london.pm mailing list