mirror of
https://github.com/romychs/Ocean-240.2-Emulator.git
synced 2026-11-13 09:44:46 +03:00
Support extended-stack, code coverage, PEEKW fn in expr
This commit is contained in:
1 parent
dd39115296
commit
603ebac8a6
9 files changed
+247
-98
No files matched your search
+56
-4
@@ -1,6 +1,18 @@
|
||||
package c99
|
||||
|
||||
import "okemu/z80"
|
||||
import (
|
||||
"errors"
|
||||
"okemu/z80"
|
||||
)
|
||||
|
||||
const (
|
||||
PushValueTypeDefault = iota
|
||||
PushValueTypeCall
|
||||
PushValueTypeRst
|
||||
PushValueTypePush
|
||||
PushValueTypeMaskableInt
|
||||
PushValueTypeNonMaskableInt
|
||||
)
|
||||
|
||||
type Z80 struct {
|
||||
|
||||
@@ -33,8 +45,12 @@ type Z80 struct {
|
||||
intPending bool
|
||||
nmiPending bool
|
||||
|
||||
core z80.MemIoRW
|
||||
memAccess map[uint16]byte
|
||||
core z80.MemIoRW
|
||||
memAccess map[uint16]byte
|
||||
codeCoverageEnabled bool
|
||||
codeCoverage map[uint16]bool
|
||||
extendedStackEnabled bool
|
||||
extendedStack [65536]uint8
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -92,13 +108,17 @@ func New(core z80.MemIoRW) *Z80 {
|
||||
z.intPending = false
|
||||
z.nmiPending = false
|
||||
z.intData = 0
|
||||
z.codeCoverageEnabled = false
|
||||
z.codeCoverage = make(map[uint16]bool)
|
||||
return &z
|
||||
}
|
||||
|
||||
// RunInstruction executes the next instruction in memory + handles interrupts
|
||||
func (z *Z80) RunInstruction() (uint32, *map[uint16]byte) {
|
||||
z.memAccess = map[uint16]byte{}
|
||||
|
||||
if z.codeCoverageEnabled {
|
||||
z.codeCoverage[z.pc] = true
|
||||
}
|
||||
pre := z.cycleCount
|
||||
if z.isHalted {
|
||||
z.execOpcode(0x00)
|
||||
@@ -223,3 +243,35 @@ func (z *Z80) getAltFlags() z80.FlagsType {
|
||||
func (z *Z80) PC() uint16 {
|
||||
return z.pc
|
||||
}
|
||||
|
||||
func (z *Z80) ClearCodeCoverage() {
|
||||
clear(z.codeCoverage)
|
||||
}
|
||||
|
||||
func (z *Z80) SetCodeCoverage(enabled bool) {
|
||||
z.codeCoverageEnabled = enabled
|
||||
if !enabled {
|
||||
clear(z.codeCoverage)
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Z80) CodeCoverage() map[uint16]bool {
|
||||
return z.codeCoverage
|
||||
}
|
||||
|
||||
func (z *Z80) SetExtendedStack(enabled bool) {
|
||||
z.extendedStackEnabled = enabled
|
||||
if enabled {
|
||||
for addr := 0; addr < 65536; addr++ {
|
||||
z.extendedStack[addr] = PushValueTypeDefault
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (z *Z80) ExtendedStack() ([]byte, error) {
|
||||
var err error
|
||||
if !z.extendedStackEnabled {
|
||||
err = errors.New("error, z80: ExtendedStack disabled")
|
||||
}
|
||||
return z.extendedStack[:], err
|
||||
}
|
||||
@@ -28,6 +28,7 @@ func (z *Z80) ww(addr uint16, val uint16) {
|
||||
func (z *Z80) pushW(val uint16) {
|
||||
z.sp -= 2
|
||||
z.ww(z.sp, val)
|
||||
z.extendedStack[z.sp] = PushValueTypePush
|
||||
}
|
||||
|
||||
func (z *Z80) popW() uint16 {
|
||||
|
||||
+9
-1
@@ -20,6 +20,7 @@ func (z *Z80) condJump(condition bool) {
|
||||
// calls to next word in memory
|
||||
func (z *Z80) call(addr uint16) {
|
||||
z.pushW(z.pc)
|
||||
z.extendedStack[z.sp] = PushValueTypeCall
|
||||
z.pc = addr
|
||||
z.memPtr = addr
|
||||
}
|
||||
@@ -1155,21 +1156,28 @@ func (z *Z80) execOpcode(opcode byte) {
|
||||
|
||||
case 0xC7:
|
||||
z.call(0x00) // rst 0
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xCF:
|
||||
z.call(0x08) // rst 1
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xD7:
|
||||
z.call(0x10) // rst 2
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xDF:
|
||||
z.call(0x18) // rst 3
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xE7:
|
||||
z.call(0x20) // rst 4
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xEF:
|
||||
z.call(0x28) // rst 5
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xF7:
|
||||
z.call(0x30) // rst 6
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xFF:
|
||||
z.call(0x38) // rst 7
|
||||
|
||||
z.extendedStack[z.sp] = PushValueTypeRst
|
||||
case 0xC5:
|
||||
z.pushW(z.bc()) // push bc
|
||||
case 0xD5:
|
||||
|
||||
Reference in new issue
Block a user