cleared in the v6809 that should not have been.
#include "dis6809.h"
#include <stdio.h>
-#include <string>
+#include <string.h>
#include "v6809.h"
#include "log.h"
boff = mainCPU.RdMem(addr++);
sprintf(tmp, "($%02X,PC)", boff);
break;
- case 13:
+ case 13:
woff = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1);
addr += 2;
sprintf(tmp, "($%04X,PC)", woff);
static FILE * log_stream = NULL;
static uint32 logSize = 0;
-bool InitLog(char * path)
+bool InitLog(const char * path)
{
log_stream = fopen(path, "wrt");
extern "C" {
#endif
-bool InitLog(char *);
+bool InitLog(const char *);
void LogDone(void);
void WriteLog(const char * text, ...);
#define __DEBUG__
+#define LOG_PIA1_IO
+
using namespace std;
#define SOUNDROM "ROMs/sg.snd"
V6808REGS soundCPU;
uint8 color[16];
uint32 palette[256];
+bool paletteDirty = false;
// Local variables
// 6809 memory functions
//
+#ifdef LOG_PIA1_IO
+char piaRegsName[4][10] = { "PORTA", "PACTL", "PORTB", "PBCTL" };
+#endif
uint8 RdMem6809(uint16 addr)
{
uint8 b;
b = grom[addr];
}
-//Is $C80E COUNT240? Hmm... No.
+ // A wee kludge (though I doubt it reads from anywhere other than $CB00)...
+ if ((addr & 0xFF00) == 0xCB00)
+ b = gram[0xCB00] & 0xFC; // Only bits 2-7 are connected...
+
+ // More kludge...
+ if ((addr == 0xC80C) && (gram[0xC80D] & 0x04)) // Read PORTA and DDR is set to Output
+ ClearLine(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ
+
+ if ((addr == 0xC80E) && (gram[0xC80F] & 0x04)) // Read PORTB and DDR is set to Output
+ ClearLine(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ
//temp...
/*extern uint16 pcr;
//if (addr >= 0xC000 && addr <= 0xCBFF)
if (addr == 0x9C59)
WriteLog("RdMem: Reading address %04X [=%02X, PC=%04X]\n", addr, b, pcr);//*/
-/*if (addr >= 0xC80D && addr <= 0xC80F)
- WriteLog("V6809 RdMem: Reading address %04X [=%02X, PC=%04X]\n", addr, b, mainCPU.pc);//*/
-
+#ifdef LOG_PIA1_IO
+/*if (addr >= 0xC80C && addr <= 0xC80F)
+ WriteLog("V6809 RdMem: Reading PIA (%s) address %04X [<-%02X, PC=%04X]\n", piaRegsName[addr&0x03], addr, b, GetCurrentV6809PC());//*/
+#endif
return b;
}
// A better strategy here would probably be to set a flag when the color register changes,
// then change it before doing the render.
// ALSO: This approach doesn't take the color to the edges of the screen
+#warning "This should only touch memory right before a render. !!! FIX !!!"
color[addr - 0xC000] = b;
+#if 0
for(uint32 addr=0x0007; addr<0x97F7; addr++)
{
uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF;
scrBuffer[saddr + 1] = palette[color[sb & 0x0F]];
}
}
+#else
+ paletteDirty = true;
+#endif
}
#endif
else if (addr == 0xC80E)
sram[0x0402] = b; // Connect PIAs in 6809 & 6808
soundCPU.cpuFlags |= V6808_ASSERT_LINE_IRQ; // Start sound IRQ
}
+
+#ifdef LOG_PIA1_IO
+//if (addr >= 0xC80C && addr <= 0xC80F)
+if (addr == 0xC80D)
+ WriteLog("V6809 WrMem: Writing PIA (%s) address %04X [->%02X, PC=%04X]\n", piaRegsName[addr&0x03], addr, b, GetCurrentV6809PC());//*/
+#endif
}
//
//
// Load a file into RAM/ROM image space
//
-bool LoadImg(char * filename, uint8 * ram, int size)
+bool LoadImg(const char * filename, uint8 * ram, int size)
{
FILE * fp = fopen(filename, "rb");
if (fp == NULL)
return false;
- fread(ram, 1, size, fp);
+ size_t ignoredResult = fread(ram, 1, size, fp);
fclose(fp);
return true;
if (fp != NULL)
{
- fwrite(gram + 0xCC00, 1, 1024, fp);
+ size_t ignoredResult = fwrite(gram + 0xCC00, 1, 1024, fp);
fclose(fp);
}
else
return false;
// This is kinda crappy--we don't do any sanity checking here!!!
- fread(gram, 1, 0x10000, fp);
- fread(sram, 1, 0x10000, fp);
- fread(&mainCPU, 1, sizeof(V6809REGS), fp);
- fread(&soundCPU, 1, sizeof(V6808REGS), fp);
+ size_t ignoredResult = fread(gram, 1, 0x10000, fp);
+ ignoredResult = fread(sram, 1, 0x10000, fp);
+ ignoredResult = fread(&mainCPU, 1, sizeof(V6809REGS), fp);
+ ignoredResult = fread(&soundCPU, 1, sizeof(V6808REGS), fp);
fclose(fp);
for(int i=0x0006; i<0x97F8; i++) // Set up backbuffer... ;-)
if (fp != NULL)
{
- fwrite(gram, 1, 0x10000, fp);
- fwrite(sram, 1, 0x10000, fp);
- fwrite(&mainCPU, 1, sizeof(V6809REGS), fp);
- fwrite(&soundCPU, 1, sizeof(V6808REGS), fp);
+ size_t ignoredResult = fwrite(gram, 1, 0x10000, fp);
+ ignoredResult = fwrite(sram, 1, 0x10000, fp);
+ ignoredResult = fwrite(&mainCPU, 1, sizeof(V6809REGS), fp);
+ ignoredResult = fwrite(&soundCPU, 1, sizeof(V6808REGS), fp);
fclose(fp);
}
else
#endif
// Zero out memory
- for(long i=0; i<0x10000; i++)
- gram[i] = grom[i] = sram[i] = srom[i] = 0;
+// for(long i=0; i<0x10000; i++)
+// gram[i] = grom[i] = sram[i] = srom[i] = 0;
+ memset(gram, 0, 0x10000);
+ memset(grom, 0, 0x10000);
+ memset(sram, 0, 0x10000);
+ memset(srom, 0, 0x10000);
// Set up V6809 & V6808 execution contexts
-
- memset(&mainCPU, sizeof(V6809REGS), 0);
+
+ memset(&mainCPU, 0, sizeof(V6809REGS));
mainCPU.RdMem = RdMem6809;
mainCPU.WrMem = WrMem6809;
mainCPU.cpuFlags |= V6809_ASSERT_LINE_RESET;
- memset(&soundCPU, sizeof(V6808REGS), 0);
+ memset(&soundCPU, 0, sizeof(V6808REGS));
soundCPU.RdMem = RdMem6808;
soundCPU.WrMem = WrMem6808;
soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET;
InitializeEventList(); // Clear the event list before we use it...
SetCallbackTime(FrameCallback, 16666.66666667); // Set frame to fire at 1/60 s interval
// SetCallbackTime(BlinkTimer, 250000); // Set up blinking at 1/4 s intervals
- SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame
+// SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame
+ SetCallbackTime(ScanlineCallback, 520.83333334/2.0); // Set scanline callback at 1/64 of frame
// SetCallbackTime(ScanlineCallback, 520.83333334*32.00); // Set scanline callback at 1/32 of frame
startTicks = SDL_GetTicks();
if (keys[SDLK_F6]) // Reset the 6808 (F6)
soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET;
- RenderScreenBuffer2(); // 1 frame = 1/60 sec ~ 16667 cycles
+#if 0
+//Grr...
+for(int i=0; i<16; i++)
+ WrMem6809(0xC000 + i, gram[0x9C26 + i]);//*/
+#endif
+
+ if (paletteDirty)
+ {
+ for(uint32 addr=0x0007; addr<0x97F7; addr++)
+ {
+ uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF;
+
+ if (sy > 5 && sy < 246)
+ {
+ uint32 saddr = 8 + sx + ((sy - 6) * 320); // Calc screen address
+ uint8 sb = gram[addr];
+
+ scrBuffer[saddr + 0] = palette[color[sb >> 4]];
+ scrBuffer[saddr + 1] = palette[color[sb & 0x0F]];
+ }
+ }
+
+ paletteDirty = false;
+ }
+
+ RenderScreenBuffer(); // 1 frame = 1/60 sec ~ 16667 cycles
SetCallbackTime(FrameCallback, 16666.66666667);
- while (SDL_GetTicks() - startTicks < 16); // Wait for next frame...
+//Hmm. Yield some time?
+//This works, but doesn't seem to yield much CPU--maybe 10%
+//SDL_Delay(2);
+//The following works much better--yields as much as 50%
+ // Wait for next frame...
+ while (SDL_GetTicks() - startTicks < 16)
+ SDL_Delay(1);
+
startTicks = SDL_GetTicks();
}
{
// CA1 of PIA 1 maps to $C80C-F... <-- Count240 is in PIA1...
// What about COUNT240???
+// COUNT240 asserts between scanlines 240-256, and clears everywhere else. so !!! FIX !!!
+#if 0
+ // NOTE that this is writing to CA1!!!
+ pia_1_ca1_w(0, 0); // COUNT240 off
+ pia_1_ca1_w(0, 1); // COUNT240 on
+ pia_1_cb1_w(0, scanline & 0x20); // Signal into CB1
+ // NOTE: The reads to $CB00 are at a granularity of 4, not 8
+ { 0xcb00, 0xcb00, williams_video_counter_r },
+READ_HANDLER( williams_video_counter_r )
+{
+ return cpu_getscanline() & 0xFC;
+}
+#endif
+// mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;
//wil wok? Yes, but still screws up on the demo...
/* if (gram[0xCB00] & 0x20)
if (gram[0xC80F] & 0x01)
mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+
if ((gram[0xCB00] & 0x20) && (gram[0xC80F] & 0x01))
mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+/* if ((gram[0xCB00] >= 0xF0) && (gram[0xCB00] & 0x20) && (gram[0xC80F] & 0x01))
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+
+// Hmm. No. But this *should* do it... Why doesn't it???
+/*
+The problem is that this is already asserted above, by virtue of the fact that
+240 = $F0 = bit 5 is set! So this does nothing! So obviously, the above IRQ assertion
+is wrong--just need to figure out how the write of $20 and $00 affects the PBCTRL in the PIA.
+It looks like Stargate never asserts the COUNT240 IRQ, and could be because of the above...
+*/
+ if ((gram[0xCB00] >= 240) && (gram[0xC80D] & 0x09)) // Do COUNT240 IRQ (if enabled!)
+ mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
+
//Is $C80E COUNT240? Hmm... Doesn't seem to be. Bleh.
/* if (gram[0xCB00] >= 240)
gram[0xC80E] = 0xFF;
gram[0xC80E] = 0x00;//*/
// gram[0xC80E] = (gram[0xCB00] >= 240 ? 0xFF : 0x00);
- gram[0xCB00] += 8; // Update video counter...
+ // This should set everything between $CB00-CBFF...
+// gram[0xCB00] += 8; // Update video counter...
+ gram[0xCB00] += 4; // Update video counter...
- SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame
+// SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame
+ SetCallbackTime(ScanlineCallback, 520.83333334/2.0); // Set scanline callback at 1/64 of frame
}
*/
+#if 0
+
+#define PIA_IRQ1 (0x80)
+#define PIA_IRQ2 (0x40)
+
+#define IRQ1_ENABLED(c) ( (((c) >> 0) & 0x01))
+#define C1_LOW_TO_HIGH(c) ( (((c) >> 1) & 0x01))
+#define C1_HIGH_TO_LOW(c) (!(((c) >> 1) & 0x01))
+#define OUTPUT_SELECTED(c) ( (((c) >> 2) & 0x01))
+#define IRQ2_ENABLED(c) ( (((c) >> 3) & 0x01))
+#define STROBE_E_RESET(c) ( (((c) >> 3) & 0x01))
+#define STROBE_C1_RESET(c) (!(((c) >> 3) & 0x01))
+#define C2_SET(c) ( (((c) >> 3) & 0x01))
+#define C2_LOW_TO_HIGH(c) ( (((c) >> 4) & 0x01))
+#define C2_HIGH_TO_LOW(c) (!(((c) >> 4) & 0x01))
+#define C2_SET_MODE(c) ( (((c) >> 4) & 0x01))
+#define C2_STROBE_MODE(c) (!(((c) >> 4) & 0x01))
+#define C2_OUTPUT(c) ( (((c) >> 5) & 0x01))
+#define C2_INPUT(c) (!(((c) >> 5) & 0x01))
+
+WRITE8_DEVICE_HANDLER( pia6821_ca1_w )
+{
+ pia6821_state *p = get_token(device);
+
+ /* limit the data to 0 or 1 */
+ data = data ? TRUE : FALSE;
+
+ LOG(("PIA #%s: set input CA1 = %d\n", device->tag, data));
+
+ /* the new state has caused a transition */
+ if ((p->in_ca1 != data) &&
+ ((data && C1_LOW_TO_HIGH(p->ctl_a)) || (!data && C1_HIGH_TO_LOW(p->ctl_a))))
+ {
+ LOG(("PIA #%s: CA1 triggering\n", device->tag));
+
+ /* mark the IRQ */
+ p->irq_a1 = TRUE;
+
+ /* update externals */
+ update_interrupts(device);
+
+ /* CA2 is configured as output and in read strobe mode and cleared by a CA1 transition */
+ if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a) && STROBE_C1_RESET(p->ctl_a))
+ set_out_ca2(device, TRUE);
+ }
+
+ /* set the new value for CA1 */
+ p->in_ca1 = data;
+ p->in_ca1_pushed = TRUE;
+}
+
+WRITE8_DEVICE_HANDLER( pia6821_cb1_w )
+{
+ pia6821_state *p = get_token(device);
+
+ /* limit the data to 0 or 1 */
+ data = data ? 1 : 0;
+
+ LOG(("PIA #%s: set input CB1 = %d\n", device->tag, data));
+
+ /* the new state has caused a transition */
+ if ((p->in_cb1 != data) &&
+ ((data && C1_LOW_TO_HIGH(p->ctl_b)) || (!data && C1_HIGH_TO_LOW(p->ctl_b))))
+ {
+ LOG(("PIA #%s: CB1 triggering\n", device->tag));
+
+ /* mark the IRQ */
+ p->irq_b1 = 1;
+
+ /* update externals */
+ update_interrupts(device);
+
+ /* If CB2 is configured as a write-strobe output which is reset by a CB1
+ transition, this reset will only happen when a read from port B implicitly
+ clears the IRQ B1 flag. So we handle the CB2 reset there. Note that this
+ is different from what happens with port A. */
+ }
+
+ /* set the new value for CB1 */
+ p->in_cb1 = data;
+ p->in_cb1_pushed = TRUE;
+}
+
+static void update_interrupts(const device_config *device)
+{
+ pia6821_state *p = get_token(device);
+ int new_state;
+
+ /* start with IRQ A */
+ new_state = (p->irq_a1 && IRQ1_ENABLED(p->ctl_a)) || (p->irq_a2 && IRQ2_ENABLED(p->ctl_a));
+
+ if (new_state != p->irq_a_state)
+ {
+ p->irq_a_state = new_state;
+ devcb_call_write_line(&p->irq_a_func, p->irq_a_state);
+ }
+
+ /* then do IRQ B */
+ new_state = (p->irq_b1 && IRQ1_ENABLED(p->ctl_b)) || (p->irq_b2 && IRQ2_ENABLED(p->ctl_b));
+
+ if (new_state != p->irq_b_state)
+ {
+ p->irq_b_state = new_state;
+ devcb_call_write_line(&p->irq_b_func, p->irq_b_state);
+ }
+}
+
+static void control_b_w(const device_config *device, UINT8 data)
+{
+ pia6821_state *p = get_token(device);
+ int temp;
+
+ /* bit 7 and 6 are read only */
+ data &= 0x3f;
+
+ LOG(("PIA #%s: control B write = %02X\n", device->tag, data));
+
+ /* update the control register */
+ p->ctl_b = data;
+
+ if (C2_SET_MODE(p->ctl_b))
+ /* set/reset mode - bit value determines the new output */
+ temp = C2_SET(p->ctl_b);
+ else
+ /* strobe mode - output is always high unless strobed */
+ temp = TRUE;
+
+ set_out_cb2(device, temp);
+
+ /* update externals */
+ update_interrupts(device);
+}
+
+static void control_a_w(const device_config *device, UINT8 data)
+{
+ pia6821_state *p = get_token(device);
+
+ /* bit 7 and 6 are read only */
+ data &= 0x3f;
+
+ LOG(("PIA #%s: control A write = %02X\n", device->tag, data));
+
+ /* update the control register */
+ p->ctl_a = data;
+
+ /* CA2 is configured as output */
+ if (C2_OUTPUT(p->ctl_a))
+ {
+ int temp;
+
+ if (C2_SET_MODE(p->ctl_a))
+ /* set/reset mode - bit value determines the new output */
+ temp = C2_SET(p->ctl_a);
+ else
+ /* strobe mode - output is always high unless strobed */
+ temp = TRUE;
+
+ set_out_ca2(device, temp);
+ }
+
+ /* update externals */
+ update_interrupts(device);
+}
+
+
+CTRL REGISTER:
+
+B7 B6 B5 B4 B3 B2 B1 B0
+--------------------------------------------------
+IRQA(B)1 IRQA(B)2 CA(B)2 Ctrl DDR CA(B)1 Ctrl
+
+Bits 6 & 7 are RO. IRQs are cleared on read of PORTA when not in DDR mode
+DDR: 0: DDR selected, 1: Output register selected
+CA1(CB1) Ctrl: B0: 0/1 Dis/enable interrupt IRQA(B)
+ B1: 0/1 IRQ set by Hi-to-Lo/Lo-to-Hi transition on CA(B)1
+CA2(CB2) Ctrl: If B5==0, B4 & B3 are similar to B1 & B0
+
+Entering main loop...
+V6809 WrMem: Writing PIA (PACTL) address C80D [->00, PC=F4DC] --> Set DDR on PORTA, IRQs off
+V6809 WrMem: Writing PIA (PORTA) address C80C [->00, PC=F4DF] --> Set DDR to all input on PORTA
+V6809 WrMem: Writing PIA (PACTL) address C80D [->3C, PC=F4E4] --> Set Output on PORTA, Set CA2 = 1, disable IRQA1
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->00, PC=F4E7] --> Set DDR on PORTB, IRQs off
+V6809 WrMem: Writing PIA (PORTB) address C80E [->C0, PC=F4EC] --> Set DDR to output on 6,7 input on 0-5 on PORTB
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->3C, PC=F4F1] --> Set Output on PORTA, Set CB2 = 1, disable IRQB1
+V6809 WrMem: Writing PIA (PORTB) address C80E [->C0, PC=F4F6] --> Send 1s on bits 6 & 7 on PORTB
+V6809 WrMem: Writing PIA (PACTL) address C80D [->34, PC=F523] --> Set Output on PORTA, Set CA2 = 0, disable IRQA1
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=F526] --> Set Output on PORTB, Set CB2 = 0, disable IRQB1
+V6809 WrMem: Writing PIA (PORTB) address C80E [->00, PC=F529] --> Send 0s on bits 6 & 7 on PORTB
+V6809 WrMem: Writing PIA (PORTA) address C80C [->00, PC=6076] --> Do nothing
+V6809 WrMem: Writing PIA (PACTL) address C80D [->00, PC=6076] --> Set DDR on PORTA, IRQs off
+V6809 WrMem: Writing PIA (PORTA) address C80C [->00, PC=607B] --> Set DDR to all input on PORTA
+V6809 WrMem: Writing PIA (PACTL) address C80D [->34, PC=607B] --> Set Output on PORTA, Set CA2 = 0, disable IRQA1
+V6809 WrMem: Writing PIA (PORTB) address C80E [->00, PC=6076] --> Send 0s on bits 6 & 7 on PORTB
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->00, PC=6076] --> Set DDR on PORTB, IRQs off
+V6809 WrMem: Writing PIA (PORTB) address C80E [->FF, PC=607B] --> Set DDR to all output on PORTB
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=607B] --> Set Output on PORTB, Set CB2 = 0, enable IRQB1
+V6809 WrMem: Writing PIA (PORTB) address C80E [->3F, PC=6088] --> Send $3F on PORTB
+V6809 WrMem: Writing PIA (PORTB) address C80E [->0C, PC=60DB] --> Send $0C on PORTB
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] --> Set Output on PORTB, Set CB2 = 0, disable IRQB1
+ 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] --> Clear IRQBs
+ 6809 RdMem: Reading PIA (PORTA) address C80C [=00, PC=075B] --> Clear IRQAs
+ 6809 RdMem: Reading PIA (PORTA) address C80C [=00, PC=07B9] --> Clear IRQAs
+
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644] --> Set Output on PORTB, Set CB2 = 0, enable IRQB1
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3] --> Set Output on PORTB, Set CB2 = 0, disable IRQB1
+ 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6] --> Clear IRQBs
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3]
+ 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3]
+ 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3]
+ 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3]
+ 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->35, PC=1644]
+V6809 WrMem: Writing PIA (PBCTL) address C80F [->34, PC=15C3]
+ 6809 RdMem: Reading PIA (PORTB) address C80E [=0C, PC=15C6]
+
+#endif
5 Test: Operand=01111111 prior to execution?
6 Test: Set equal to result or N(+)C after shift has occurred.
7 Test: Sign bit of most significant byte or result=1?
- 8 Test: 2's compliment overflow from subtraction of least
+ 8 Test: 2's compliment overflow from subtraction of least
significant bytes?
9 Test: Result less than zero? (Bit 15=1)
A Load Condition Code Register from Stack.
- B Set when interrupt occurs. If previously set, a NMI is
+ B Set when interrupt occurs. If previously set, a NMI is
required to exit the wait state.
C Set according to the contents of Accumulator A.
*2 +-----------------+
+> C -> 76543210 -+
- *3 C <- 76543210 <- 0(Data)
+ *3 C <- 76543210 <- 0(Data)
+-+
- *4 À>76543210 -> C
+ *4 �>76543210 -> C
*5 (Data)0 -> 76543210 -> C
{
tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
regs.cc &= 0xFD; // CLV
- (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
regs.clock += 6;
}
static void Op0E(void) // JMP DP
regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
}
regs.cc &= 0xF1; // CL NZV
- if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
regs.clock += 2;
}
{
}
static void Op40(void) // NEGA
-{
+{
regs.a = 256 - regs.a;
(regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
(regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
regs.clock += 2;
}
-static void Op49(void) // ROLA
+static void Op49(void) // ROLA
{
tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
(tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
regs.clock += 2;
}
static void Op50(void) // NEGB
- {
+ {
regs.b = 256 - regs.b;
// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
static void Op5C(void) // INCB
{
regs.b++;
- (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
regs.clock += 2;
regs.clock += 2;
}
static void Op60(void) // NEG IDX
- {
+ {
addr = DecodeIDX(regs.RdMem(regs.pc++));
tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
regs.WrMem(addr, res);
regs.clock += 6;
}
static void Op6C(void) // INC IDX
- {
+ {
addr = DecodeIDX(regs.RdMem(regs.pc++));
tmp = regs.RdMem(addr) + 1;
regs.WrMem(addr, tmp);
static void Op6D(void) // TST IDX
{
tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
- (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
regs.clock += 6;
}
static void Op6E(void) // JMP IDX
regs.clock += 6;
}
static void Op70(void) // NEG ABS
- {
+ {
addr = FetchW();
tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
regs.WrMem(addr, res);
regs.clock += 7;
}
static void Op7C(void) // INC ABS
- {
+ {
uint8 tmp; uint16 addr;
addr = FetchW();
tmp = regs.RdMem(addr) + 1;
{
uint8 tmp = regs.RdMem(FetchW());
- (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
+ (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
regs.clock += 7;
}
regs.clock += 7;
}
static void Op80(void) // SUBA #
-{
- uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+{
+ uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
regs.a -= tmp;
(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
}
static void Op82(void) // SBCA #
{
- tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+ tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.a = addr & 0xFF; // Set accumulator
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
regs.clock += 2;
}
static void Op8B(void) // ADDA #
-{
+{
tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
(addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.a = addr & 0xFF; // Set accumulator
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 3;
}
static void Op90(void) // SUBA DP
- {
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ {
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
regs.a -= tmp;
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void Op92(void) // SBCA DP
{
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.a = addr & 0xFF; // Set accumulator
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
regs.clock += 4;
}
static void Op9B(void) // ADDA DP
-{
+{
tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
addr = (uint16)regs.a + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.a = addr & 0xFF; // Set accumulator
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 5;
}
static void OpA0(void) // SUBA IDX
- {
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+ {
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
regs.a -= tmp;
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpA2(void) // SBCA IDX
{
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.a = addr & 0xFF; // Set accumulator
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 4;
}
static void OpAB(void) // ADDA IDX
-{
+{
tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
addr = (uint16)regs.a + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.a = addr & 0xFF; // Set accumulator
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 5;
}
static void OpB0(void) // SUBA ABS
- {
- tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+ {
+ tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
regs.a -= tmp;
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpB2(void) // SBCA ABS
{
- tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+ tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.a = addr; // Set accumulator
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 5;
}
static void OpBB(void) // ADDA ABS
-{
+{
tmp = regs.RdMem(FetchW());
addr = (uint16)regs.a + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
{
addr = FetchW();
regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
- regs.pc = addr; // Go to absolute address (Not indir)
+ regs.pc = addr; // Go to absolute address (Not indir)
regs.clock += 8;
}
}
static void OpC0(void) // SUBB #
- {
- tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+ {
+ tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpC2(void) // SBCB #
{
- tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+ tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.b = addr & 0xFF; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 2;
}
static void OpCB(void) // ADDB #
-{
+{
tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
(addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.b = addr & 0xFF; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 3;
}
static void OpD0(void) // SUBB DP
-{
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpD2(void) // SBCB DP
{
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.b = addr; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 4;
}
static void OpDB(void) // ADDB DP
-{
+{
tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
addr = (uint16)regs.b + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.b = addr & 0xFF; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 5;
}
static void OpE0(void) // SUBB IDX
-{
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpE2(void) // SBCB IDX
{
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.b = addr; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 4;
}
static void OpEB(void) // ADDB IDX
-{
+{
tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
addr = (uint16)regs.b + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
regs.b = addr; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.clock += 5;
}
static void OpF0(void) // SUBB ABS
- {
- tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+ {
+ tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpF2(void) // SBCB ABS
{
- tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+ tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.b = addr & 0xFF; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
regs.clock += 5;
- }
+ }
static void OpFB(void) // ADDB ABS
-{
+{
tmp = regs.RdMem(FetchW());
addr = (uint16)regs.b + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
+ ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.b = addr & 0xFF; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.cc &= 0xFD; // CLV
(regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
- regs.clock += 6;
+ regs.clock += 6;
}
static void Op10DF(void) // STS DP
{
regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
regs.clock += 19;
- context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
- regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+// Apparently, not done here!
+// context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+// regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
}
}
#ifdef __DEBUG__
{
return regs.clock;
}
+
+//
+// Get the PC of the currently executing CPU
+//
+uint16 GetCurrentV6809PC(void)
+{
+ return regs.pc;
+}
+
+// Set a line of the currently executing CPU
+void SetLine(uint32 line)
+{
+ regs.cpuFlags |= line;
+}
+
+// Clear a line of the currently executing CPU
+void ClearLine(uint32 line)
+{
+ regs.cpuFlags &= ~line;
+}
void Execute6809(V6809REGS *, uint32); // Function to execute 6809 instructions
uint32 GetCurrentV6809Clock(void); // Get the clock of the currently executing CPU
+uint16 GetCurrentV6809PC(void); // Get the PC of the currently executing CPU
+void SetLine(uint32 line); // Set a line of the currently executing CPU
+void ClearLine(uint32 line); // Clear a line of the currently executing CPU
#endif // __V6809_H__
}
// Set icon (mainly for Win32 target--though seems to work under KDE as well...!)
- SDL_Surface * iconSurf = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32, 128,
+ SDL_Surface * iconSurf = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32, 128,
MASK_R, MASK_G, MASK_B, MASK_A);
SDL_WM_SetIcon(iconSurf, NULL);
SDL_FreeSurface(iconSurf);
if (settings.useOpenGL)
sdlemu_close_opengl();
- SDL_JoystickClose(joystick);
+// SDL_JoystickClose(joystick);
SDL_FreeSurface(surface);
- SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER);
+// SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER);
SDL_Quit();
}
# OpenGL options: 1 - use OpenGL rendering, 0 - use old style rendering
-useOpenGL = 1
+useOpenGL = 0
# OpenGL filtering type: 1 - blurry, 0 - sharp