mirror of https://github.com/trudnai/Steve2.git
215 lines
6.7 KiB
C
215 lines
6.7 KiB
C
//
|
|
// main.c
|
|
// 6502
|
|
//
|
|
// Created by Tamas Rudnai on 7/14/19.
|
|
// Copyright © 2019, 2020 Tamas Rudnai. All rights reserved.
|
|
//
|
|
// 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/>.
|
|
//
|
|
|
|
#ifndef __6502_INSTR_COMPARE_TEST_H__
|
|
#define __6502_INSTR_COMPARE_TEST_H__
|
|
|
|
/**
|
|
BIT Test Bits in Memory with Accumulator
|
|
|
|
bits 7 and 6 of operand are transfered to bit 7 and 6 of SR (N,V);
|
|
the zeroflag is set to the result of operand AND accumulator.
|
|
|
|
A AND M, M7 -> N, M6 -> V N Z C I D V
|
|
M7 + - - - M6
|
|
|
|
addressing assembler opc bytes cyles
|
|
--------------------------------------------
|
|
zeropage BIT oper 24 2 3
|
|
absolute BIT oper 2C 3 4
|
|
|
|
**/
|
|
INSTR void BIT( uint8_t src ) {
|
|
dbgPrintf("BIT(%02X) ", src);
|
|
disPrintf(disassembly.inst, "BIT");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_NV(src);
|
|
set_flags_Z(m6502.A & src);
|
|
#endif
|
|
}
|
|
INSTR void BITI( uint8_t src ) {
|
|
dbgPrintf("BIT(%02X) ", src);
|
|
disPrintf(disassembly.inst, "BIT");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_Z(m6502.A & src);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
TRB - Test and Reset Bits
|
|
|
|
TRB can be one the more confusing instructions for a couple of reasons.
|
|
|
|
First, the term reset is used to refer to the clearing of a bit, whereas the term clear had been used consistently before, such as CLC
|
|
which stands for CLear Carry. Second, the effect on the Z flag is determined by a different function than the effect on memory.
|
|
|
|
TRB has the same effect on the Z flag that a BIT instruction does. Specifically, it is based on whether the result of a bitwise AND of the
|
|
accumulator with the contents of the memory location specified in the operand is zero. Also, like BIT, the accumulator is not affected.
|
|
|
|
The accumulator determines which bits in the memory location specified in the operand are cleared and which are not affected.
|
|
The bits in the accumulator that are ones are cleared (in memory), and the bits that are zeros (in the accumulator) are not affected (in memory).
|
|
This is the same as saying that the resulting memory contents are the bitwise AND of the memory contents with the complement of the
|
|
accumulator (i.e. the exclusive-or of the accululator with $FF).
|
|
|
|
OP LEN CYC MODE FLAGS SYNTAX
|
|
-- --- --- ---- ----- ------
|
|
14 2 5 zp ......Z. TRB $12
|
|
1C 3 6 abs ......Z. TRB $3456
|
|
|
|
**/
|
|
INSTR void TRB( uint16_t addr ) {
|
|
dbgPrintf("TRB(%02X) ", src);
|
|
disPrintf(disassembly.inst, "TRB");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_Z( WRLOMEM[addr] & m6502.A );
|
|
WRLOMEM[addr] &= ~m6502.A;
|
|
#endif
|
|
}
|
|
INSTR void TRB_zp( uint16_t addr ) {
|
|
dbgPrintf("TRB(%02X) ", src);
|
|
disPrintf(disassembly.inst, "TRB");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_Z( WRZEROPG[addr] & m6502.A );
|
|
WRZEROPG[addr] &= ~m6502.A;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
TSB - Test and Set Bits
|
|
|
|
TSB, like TRB, can be confusing. For one, like TRB, the effect on the Z flag is determined by a different function than the effect on memory.
|
|
|
|
TSB, like TRB, has the same effect on the Z flag that a BIT instruction does. Specifically, it is based on whether the result of a bitwise AND
|
|
of the accumulator with the contents of the memory location specified in the operand is zero. Also, like BIT (and TRB), the accumulator is not affected.
|
|
|
|
The accumulator determines which bits in the memory location specified in the operand are set and which are not affected. The bits in the
|
|
accumulator that are ones are set to one (in memory), and the bits that are zeros (in the accumulator) are not affected (in memory).
|
|
This is the same as saying that the resulting memory contents are the bitwise OR of the memory contents with the accumulator.
|
|
|
|
Flags affected: Z
|
|
|
|
OP LEN CYC MODE FLAGS SYNTAX
|
|
-- --- --- ---- ----- ------
|
|
04 2 5 zp ......Z. TSB $12
|
|
0C 3 6 abs ......Z. TSB $3456
|
|
|
|
**/
|
|
INSTR void TSB( uint16_t addr ) {
|
|
dbgPrintf("TSB(%02X) ", src);
|
|
disPrintf(disassembly.inst, "TSB");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_Z( WRLOMEM[addr] & m6502.A );
|
|
WRLOMEM[addr] |= m6502.A;
|
|
#endif
|
|
}
|
|
INSTR void TSB_zp( uint16_t addr ) {
|
|
dbgPrintf("TSB(%02X) ", src);
|
|
disPrintf(disassembly.inst, "TSB");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_Z( WRZEROPG[addr] & m6502.A );
|
|
WRZEROPG[addr] |= m6502.A;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
CMP Compare Memory with Accumulator
|
|
|
|
A - M N Z C I D V
|
|
+ + + - - -
|
|
|
|
addressing assembler opc bytes cyles
|
|
--------------------------------------------
|
|
immidiate CMP #oper C9 2 2
|
|
zeropage CMP oper C5 2 3
|
|
zeropage,X CMP oper,X D5 2 4
|
|
absolute CMP oper CD 3 4
|
|
absolute,X CMP oper,X DD 3 4*
|
|
absolute,Y CMP oper,Y D9 3 4*
|
|
(indirect,X) CMP (oper,X) C1 2 6
|
|
(indirect),Y CMP (oper),Y D1 2 5*
|
|
**/
|
|
#ifndef DISASSEMBLER
|
|
INSTR void _CMP( uint8_t src ) {
|
|
set_flags_NZC( (int16_t)m6502.A - src );
|
|
}
|
|
#endif
|
|
INSTR void CMP( uint8_t src ) {
|
|
dbgPrintf("CMP(%02X) ", src);
|
|
disPrintf(disassembly.inst, "CMP");
|
|
|
|
#ifndef DISASSEMBLER
|
|
_CMP(src);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
CPX Compare Memory and Index X
|
|
|
|
X - M N Z C I D V
|
|
+ + + - - -
|
|
|
|
addressing assembler opc bytes cyles
|
|
--------------------------------------------
|
|
immidiate CPX #oper E0 2 2
|
|
zeropage CPX oper E4 2 3
|
|
absolute CPX oper EC 3 4
|
|
**/
|
|
INSTR void CPX( uint8_t src ) {
|
|
dbgPrintf("CPX(%02X) ", src);
|
|
disPrintf(disassembly.inst, "CPX");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_NZC( (int16_t)m6502.X - src );
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
CPY Compare Memory and Index Y
|
|
|
|
Y - M N Z C I D V
|
|
+ + + - - -
|
|
|
|
addressing assembler opc bytes cyles
|
|
--------------------------------------------
|
|
immidiate CPY #oper C0 2 2
|
|
zeropage CPY oper C4 2 3
|
|
absolute CPY oper CC 3 4
|
|
**/
|
|
INSTR void CPY( uint8_t src ) {
|
|
dbgPrintf("CPY(%02X) ", src);
|
|
disPrintf(disassembly.inst, "CPY");
|
|
|
|
#ifndef DISASSEMBLER
|
|
set_flags_NZC( (int16_t)m6502.Y - src );
|
|
#endif
|
|
}
|
|
|
|
#endif // __6502_INSTR_COMPARE_TEST_H__
|
|
|