i6502/acia6551_test.go

189 lines
3.7 KiB
Go

package i6502
import (
"testing"
"github.com/stretchr/testify/assert"
)
func AciaSubject() (*Acia6551, chan []byte) {
output := make(chan []byte)
acia, _ := NewAcia6551(output)
return acia, output
}
func TestNewAcia6551(t *testing.T) {
output := make(chan []byte)
acia, err := NewAcia6551(output)
assert.Nil(t, err)
assert.EqualValues(t, 0x4, acia.Size())
}
func TestAciaAsMemory(t *testing.T) {
assert.Implements(t, (*Memory)(nil), new(Acia6551))
}
func TestAciaReset(t *testing.T) {
a, _ := AciaSubject()
a.Reset()
assert.EqualValues(t, a.tx, 0)
assert.True(t, a.txEmpty)
assert.EqualValues(t, a.rx, 0)
assert.False(t, a.rxFull)
assert.False(t, a.txIrqEnabled)
assert.False(t, a.rxIrqEnabled)
assert.False(t, a.overrun)
assert.EqualValues(t, 0, a.controlData)
}
func TestAciaReaderWithTxEmpty(t *testing.T) {
a, _ := AciaSubject()
// Nothing to read
assert.True(t, a.txEmpty)
value := make([]byte, 1)
bytesRead, _ := a.Read(value)
assert.EqualValues(t, 0, bytesRead)
}
func TestAciaWriteByteAndReader(t *testing.T) {
var value []byte
a, o := AciaSubject()
done := make(chan bool)
go func() {
value = <-o
done <- true
}()
// CPU writes data
a.WriteByte(aciaData, 0x42)
<-done
assert.EqualValues(t, 0x42, value[0])
}
func TestAciaWriterAndReadByte(t *testing.T) {
a, _ := AciaSubject()
// System writes a single byte
bytesWritten, _ := a.Write([]byte{0x42})
if assert.EqualValues(t, 1, bytesWritten) {
assert.EqualValues(t, 0x42, a.ReadByte(aciaData))
}
// System writes multiple bytes
bytesWritten, _ = a.Write([]byte{0x42, 0x32, 0xAB})
if assert.EqualValues(t, 3, bytesWritten) {
assert.EqualValues(t, 0xAB, a.ReadByte(aciaData))
}
}
func TestAciaCommandRegister(t *testing.T) {
a, _ := AciaSubject()
assert.False(t, a.rxIrqEnabled)
assert.False(t, a.txIrqEnabled)
a.WriteByte(aciaCommand, 0x02) // b0000 0010 RX Irq enabled
assert.True(t, a.rxIrqEnabled)
assert.False(t, a.txIrqEnabled)
a.WriteByte(aciaCommand, 0x04) // b0000 0100 TX Irq enabled
assert.False(t, a.rxIrqEnabled)
assert.True(t, a.txIrqEnabled)
a.WriteByte(aciaCommand, 0x06) // b0000 0110 RX + TX Irq enabled
assert.True(t, a.rxIrqEnabled)
assert.True(t, a.txIrqEnabled)
assert.EqualValues(t, 0x06, a.ReadByte(aciaCommand))
}
func TestAciaControlRegister(t *testing.T) {
a, _ := AciaSubject()
a.WriteByte(aciaControl, 0xB8)
assert.EqualValues(t, 0xB8, a.ReadByte(aciaControl))
}
func TestAciaStatusRegister(t *testing.T) {
a, _ := AciaSubject()
a.rxFull = false
a.txEmpty = false
a.overrun = false
assert.EqualValues(t, 0x00, a.ReadByte(aciaStatus))
a.rxFull = true
a.txEmpty = false
a.overrun = false
assert.EqualValues(t, 0x08, a.ReadByte(aciaStatus))
a.rxFull = false
a.txEmpty = true
a.overrun = false
assert.EqualValues(t, 0x10, a.ReadByte(aciaStatus))
a.rxFull = false
a.txEmpty = false
a.overrun = true
assert.EqualValues(t, 0x04, a.ReadByte(aciaStatus))
}
func TestAciaIntegration(t *testing.T) {
var value []byte
output := make(chan []byte)
done := make(chan bool)
// Create a system
// * 32kB RAM at 0x0000-7FFFF
// * ACIA at 0x8800-8803
ram, _ := NewRam(0x8000)
acia, _ := NewAcia6551(output)
bus, _ := NewAddressBus()
bus.Attach(ram, 0x0000)
bus.Attach(acia, 0x8800)
cpu, _ := NewCpu(bus)
program := []byte{
0xA9, 0x00, // LDA #$00
0x8D, 0x01, 0x88, // STA AciaStatus (Reset)
0xA9, 0x42, // LDA #$42
0x8D, 0x00, 0x88, // STA AciaData (Write)
0xAD, 0x00, 0x88, // LDA AciaData (Read)
}
cpu.LoadProgram(program, 0x0200)
cpu.Steps(2)
go func() {
value = <-output
done <- true
}()
acia.Write([]byte{0xAB})
cpu.Steps(3)
<-done
// value := make([]byte, 1)
// bytesRead, _ := acia.Read(value)
assert.EqualValues(t, 0x42, value[0])
assert.EqualValues(t, 0xAB, cpu.A)
}