<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Thu, 22 Jul 2010 18:27:29 +0200
From   : rick@... (Rick Murray)
Subject: Spitting expletives

OMG.

Well... THAT has been an odyssey into the unknown.

"What?", you might ask (if you care... ;-) ).

Simple. An accurate emulation of the SBC instruction.

For the non-microcode bunch-of-transistors that is the 6502, the 
behaviour of the flags in SBC is actually fairly complicated.

I have finally (hopefully correctly!) arrived at:
--8<--------
     Case &HE1, &HE5, &HE9, &HED, &HF1, &HF2, &HF5, &HF9, &HFD:
       ' SBC        SuBtract memory with acc with Carry
       '            A,fC = A - mem - (!fC)
       '            Affects CZVN

       If (CPU.PS.D = False) Then
         ' Calculate to a temporary place
         CPU.Addr = CPU.A - CPU.Temp - _
                    (IIf((CPU.PS.C = True), 0&, 1&))
                    ' NOTE that carry set = no subtract, else -1
         If ((CPU.Addr) < 0) Then
           ' less than zero? flag a carry has occurred, then
           ' correct the result to fit into a byte
           SBCCarry = True
           CPU.Addr = 256 + CPU.Addr ' casting is 'painful' in VB
         Else
           SBCCarry = False
         End If

         ' Carry is CLEAR if a borrow occurred, love the 6502! :-)
         CPU.PS.C = SBCCarry Xor True

         ' Overflow?
         If ((CPU.A And &H80) <> (CPU.Addr And &H80)) Then
           ' bit 7 is different between orig/final so sign has changed...
           CPU.PS.V = True
           ' ...except when the result is less than zero (a borrow)...
           If (SBCCarry = True) Then CPU.PS.V = False
         Else
           CPU.PS.V = False
         End If

         ' Assign the result
         CPU.A = CByte(CPU.Addr And 255&)

         ' And the last two...
         CPU.PS.N = (CPU.A > 127)
         CPU.PS.Z = (CPU.A = 0)

       ' Else
       '   ...no support for BCD maths mode...
       End If
--8<--------

BTW, you can, no doubt, optimise this a *lot*, but I am coding for 
(extreme) clarity, not to be clever. [*]

To give an example, the above in B-Em is:
--8<--------
tempw=a-(temp+(p.c?0:1));    \
tempv=(short)a-(short)(temp+(p.c?0:1));            \
p.v=((a^(temp+(p.c?0:1)))&(a^(unsigned char)tempv)&0x80); \
p.c=tempv>=0;\
a=tempw&0xFF;              \
setzn(a);                  \
--8<--------
Which is small, tight, and implemented as a macro (!). It is also a PITA 
to take apart and relate to other things to figure out what exactly is 
going on, so I ignored it and wrote my own.

But... hey... It's pretty complex, this SBC instruction. For instance:
--8<--------
    10DIM CODE% 256
    15P% = CODE%
    20[
    25  OPT 0
    30  LDA #0
    35  SEC
    40  SBC #1
    45  RTS
    50]
    55R = USR(CODE%)
    60PRINT ~R
 >RUN
197F
B00000FF
 >
--8<--------

All well and proper, until you look at the flags:
   C = Unset (a borrow occurred)
   N = Set as 255 is a signed negative
   V = Unset - the sign of the result is not wrong?
       0 (b7 clear) -> 255 (b7 set) is not a sign change!?
   Z = Unset, ain't zero!

Oh, and 'B' is returned as set. Is this a bug in BeebEm, or does BASIC 
do something pretty weird when returning? I was under the impression 
that the BRK flag only really existed in the value pushed to the stack.


Well... In various tests, my emulator appears to match BeebEm and 6502 
Simulator. *Finally*.


Best wishes,

Rick.


* - I am thinking of adding support for Rob's TCP/IP<>Econet extensions 
into the ADLC module, so theoretically my emulator will, eventually, be 
able to function as a working server emulator. However it was never 
intended to work in that way, per se (there are enough competent Beeb 
emulators around already); it was specifically written to permit 
revisions to the firmware (cf. mass storage on SD cards, etc) to be 
prototyped virtually without the grief of 
erasing/blowing/fitting/testing EPROMs and a real FileStore. And, let's 
face it, also because I felt like writing an emulator in VisualBasic 
because it was a pretty insane thing to do. ;-) But, hey, when it is all 
working, at least it will *feel* like using a real FileStore (ie, quick 
as treacle). Dah-duh, authenticity guaranteed! :-) :-) :-)

-- 
Rick Murray, eeePC901 & ADSL WiFI'd into it, all ETLAs!
BBC B: DNFS, 2 x 5.25" floppies, EPROM prog, Acorn TTX
E01S FileStore, A3000/A5000/RiscPC/various PCs/blahblah...
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>