2019-07-30 08:05:21 +00:00
|
|
|
//
|
|
|
|
// main.c
|
|
|
|
// 6502
|
|
|
|
//
|
|
|
|
// Created by Tamas Rudnai on 7/14/19.
|
2020-07-13 17:16:37 +00:00
|
|
|
// Copyright © 2019, 2020 Tamas Rudnai. All rights reserved.
|
2020-07-13 17:10:33 +00:00
|
|
|
//
|
|
|
|
// This file is part of Steve ][ -- The Apple ][ Emulator.
|
|
|
|
//
|
|
|
|
// Steve ][ is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// Steve ][ is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with Steve ][. If not, see <https://www.gnu.org/licenses/>.
|
2019-07-30 08:05:21 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef __6502_INSTR_BRANCH_H__
|
|
|
|
#define __6502_INSTR_BRANCH_H__
|
|
|
|
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BRA( int8_t reladdr ) {
|
|
|
|
m6502.PC += reladdr;
|
2020-02-23 00:37:54 +00:00
|
|
|
#ifdef CLK_ABSOLUTE_PRECISE
|
2020-05-05 15:35:57 +00:00
|
|
|
uint8_t pg = m6502.PC >> 8;
|
2020-02-23 00:37:54 +00:00
|
|
|
m6502.clktime += m6502.PC >> 8 == pg ? 1 : 2;
|
|
|
|
#else
|
2020-05-06 23:07:19 +00:00
|
|
|
// m6502.clktime++;
|
2020-02-23 00:37:54 +00:00
|
|
|
#endif
|
2019-09-15 11:02:22 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
if ( reladdr == -2 ) {
|
2019-09-17 09:12:05 +00:00
|
|
|
dbgPrintf2("Infinite Loop at %04X!\n", m6502.PC);
|
2019-09-15 11:02:22 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
dbgPrintf("BRA %04X ", m6502.PC);
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BCC Branch on Carry Clear
|
|
|
|
|
|
|
|
branch on C = 0 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BCC oper 90 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BCC( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BCC ");
|
2019-09-22 08:31:09 +00:00
|
|
|
disPrintf(disassembly.inst, "BCC");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( ! m6502.C ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BCS Branch on Carry Set
|
|
|
|
|
|
|
|
branch on C = 1 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BCS oper B0 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BCS( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BCS ");
|
2019-11-28 04:27:32 +00:00
|
|
|
disPrintf(disassembly.inst, "BCS");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( m6502.C ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BNE Branch on Result not Zero
|
|
|
|
|
|
|
|
branch on Z = 0 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BNE oper D0 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BNE( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BNE ");
|
2019-09-22 08:31:09 +00:00
|
|
|
disPrintf(disassembly.inst, "BNE");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( ! m6502.Z ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BEQ Branch on Result Zero
|
|
|
|
|
|
|
|
branch on Z = 1 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BEQ oper F0 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BEQ( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BEQ ");
|
2019-09-22 08:31:09 +00:00
|
|
|
disPrintf(disassembly.inst, "BEQ");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( m6502.Z ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BPL Branch on Result Plus
|
|
|
|
|
|
|
|
branch on N = 0 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BPL oper 10 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BPL( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BPL ");
|
2019-09-22 08:31:09 +00:00
|
|
|
disPrintf(disassembly.inst, "BPL");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( ! m6502.N ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BMI Branch on Result Minus
|
|
|
|
|
|
|
|
branch on N = 1 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BMI oper 30 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BMI( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BMI ");
|
2019-09-22 08:31:09 +00:00
|
|
|
disPrintf(disassembly.inst, "BMI");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( m6502.N ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BVC Branch on Overflow Clear
|
|
|
|
|
|
|
|
branch on V = 0 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BVC oper 50 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BVC( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BVC ");
|
2019-09-22 08:31:09 +00:00
|
|
|
disPrintf(disassembly.inst, "BVC");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( ! m6502.V ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
BVS Branch on Overflow Set
|
|
|
|
|
|
|
|
branch on V = 1 N Z C I D V
|
2019-09-10 07:00:00 +00:00
|
|
|
- - - - - -
|
2019-07-30 08:05:21 +00:00
|
|
|
|
|
|
|
addressing assembler opc bytes cyles
|
|
|
|
--------------------------------------------
|
|
|
|
relative BVC oper 70 2 2**
|
|
|
|
**/
|
2019-09-15 11:02:22 +00:00
|
|
|
INLINE void BVS( int8_t reladdr ) {
|
2019-07-30 08:05:21 +00:00
|
|
|
dbgPrintf("BVS ");
|
2019-09-22 08:31:09 +00:00
|
|
|
disPrintf(disassembly.inst, "BVS");
|
2020-05-02 04:52:51 +00:00
|
|
|
if ( m6502.V ) {
|
2019-09-10 07:00:00 +00:00
|
|
|
BRA( reladdr );
|
2019-09-11 07:11:45 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
dbgPrintf("-no-");
|
|
|
|
}
|
2019-07-30 08:05:21 +00:00
|
|
|
}
|
|
|
|
|
2020-08-02 22:00:42 +00:00
|
|
|
/**
|
|
|
|
BBR BBS - Branch on Bit Reset or Set
|
|
|
|
|
|
|
|
BBR and BBS test the specified zero page location and branch if the specified bit is clear (BBR) or set (BBS).
|
|
|
|
Note that as with TRB, the term reset in BBR is used to mean clear.
|
|
|
|
|
|
|
|
On the 6502 and 65C02, bit 7 is typically the most convenient bit to use for I/O and software flags because
|
|
|
|
it can be tested by several instructions, such as BIT and LDA. BBR and BBS can test any of the 8 bits without
|
|
|
|
affecting any flags or using any registers. Unlike other branch instructions, BBR and BBS always take the same
|
|
|
|
number of cycles (five) whether the branch is taken or not. It is often useful to test bit 0, for example, to test
|
|
|
|
whether a byte is even or odd. However, the usefulness of BBR and BBS is somewhat limited for a couple of reasons.
|
|
|
|
First, there is only a single addressing mode for these instructions -- no indexing by X or Y, for instance.
|
|
|
|
Second, they are restricted to zero page locations. For software flags this may be just fine, but it may not be very
|
|
|
|
convenient (or cost effective) to add any additional address decoding hardware that may be necessary to
|
|
|
|
map I/O locations to the zero page.
|
|
|
|
|
|
|
|
The addressing mode is a combination of zero page addressing and relative addressing -- really just a juxtaposition of the two.
|
|
|
|
The bit to test is typically specified as part of the instruction name rather than the operand, i.e.
|
|
|
|
|
|
|
|
Flags affected: none
|
|
|
|
|
|
|
|
OP LEN CYC MODE FLAGS SYNTAX
|
|
|
|
-- --- --- ---- ----- ------
|
|
|
|
0F 3 5 zp,rel ........ BBR0 $12,LABEL
|
|
|
|
1F 3 5 zp,rel ........ BBR1 $12,LABEL
|
|
|
|
2F 3 5 zp,rel ........ BBR2 $12,LABEL
|
|
|
|
3F 3 5 zp,rel ........ BBR3 $12,LABEL
|
|
|
|
4F 3 5 zp,rel ........ BBR4 $12,LABEL
|
|
|
|
5F 3 5 zp,rel ........ BBR5 $12,LABEL
|
|
|
|
6F 3 5 zp,rel ........ BBR6 $12,LABEL
|
|
|
|
7F 3 5 zp,rel ........ BBR7 $12,LABEL
|
|
|
|
8F 3 5 zp,rel ........ BBS0 $12,LABEL
|
|
|
|
9F 3 5 zp,rel ........ BBS1 $12,LABEL
|
|
|
|
AF 3 5 zp,rel ........ BBS2 $12,LABEL
|
|
|
|
BF 3 5 zp,rel ........ BBS3 $12,LABEL
|
|
|
|
CF 3 5 zp,rel ........ BBS4 $12,LABEL
|
|
|
|
DF 3 5 zp,rel ........ BBS5 $12,LABEL
|
|
|
|
EF 3 5 zp,rel ........ BBS6 $12,LABEL
|
|
|
|
FF 3 5 zp,rel ........ BBS7 $12,LABEL
|
|
|
|
|
|
|
|
**/
|
|
|
|
#define BBR(n) INLINE void BBR##n( uint8_t src, int8_t reladdr ) { \
|
|
|
|
dbgPrintf("BBR"#n" "); \
|
|
|
|
disPrintf(disassembly.inst, "BBR"#n); \
|
|
|
|
if ( ! (src & (1 << n) ) ) { \
|
|
|
|
BRA( reladdr ); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
BBR(0)
|
|
|
|
BBR(1)
|
|
|
|
BBR(2)
|
|
|
|
BBR(3)
|
|
|
|
BBR(4)
|
|
|
|
BBR(5)
|
|
|
|
BBR(6)
|
|
|
|
BBR(7)
|
|
|
|
|
|
|
|
#define BBS(n) INLINE void BBS##n( uint8_t src, int8_t reladdr ) { \
|
|
|
|
dbgPrintf("BBS"#n" "); \
|
|
|
|
disPrintf(disassembly.inst, "BBS"#n); \
|
|
|
|
if ( (src & (1 << n) ) ) { \
|
|
|
|
BRA( reladdr ); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
BBS(0)
|
|
|
|
BBS(1)
|
|
|
|
BBS(2)
|
|
|
|
BBS(3)
|
|
|
|
BBS(4)
|
|
|
|
BBS(5)
|
|
|
|
BBS(6)
|
|
|
|
BBS(7)
|
|
|
|
|
2019-07-30 08:05:21 +00:00
|
|
|
#endif // __6502_INSTR_BRANCH_H__
|