ph00524: add emulator
This commit is contained in:
parent
7c663f42ca
commit
be255f2e6f
8 changed files with 605 additions and 0 deletions
102
modules/ph00524/emu/i8255.go
Normal file
102
modules/ph00524/emu/i8255.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
// i8255 is a generic Intel 8255-compatible I/O controller chip.
|
||||
//
|
||||
// Only mode 0 is supported.
|
||||
type i8255 struct {
|
||||
pa, pb, pc uint8
|
||||
|
||||
onOut func(port i8255Port)
|
||||
onIn func(port i8255Port)
|
||||
}
|
||||
|
||||
type i8255Port string
|
||||
|
||||
const (
|
||||
PA i8255Port = "PA"
|
||||
PB i8255Port = "PB"
|
||||
PC i8255Port = "PC"
|
||||
)
|
||||
|
||||
func (i *i8255) getPort(p i8255Port) uint8 {
|
||||
switch p {
|
||||
case PA:
|
||||
return i.pa
|
||||
case PB:
|
||||
return i.pb
|
||||
case PC:
|
||||
return i.pc
|
||||
default:
|
||||
log.Fatalf("invalid port")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (i *i8255) Out(addr, value uint8) {
|
||||
switch addr {
|
||||
case 0:
|
||||
i.pa = value
|
||||
if i.onOut != nil {
|
||||
i.onOut(PA)
|
||||
}
|
||||
case 1:
|
||||
i.pb = value
|
||||
if i.onOut != nil {
|
||||
i.onOut(PB)
|
||||
}
|
||||
case 2:
|
||||
i.pc = value
|
||||
if i.onOut != nil {
|
||||
i.onOut(PC)
|
||||
}
|
||||
case 3:
|
||||
if (value >> 7) == 0 {
|
||||
// BSR mode
|
||||
bitno := (value >> 1) & 0b111
|
||||
bitval := value & 1
|
||||
if bitval == 1 {
|
||||
i.pc |= (1 << bitno)
|
||||
} else {
|
||||
i.pc &= 0xff ^ (1 << bitno)
|
||||
}
|
||||
} else {
|
||||
// Input/Output mode
|
||||
gaMode := (value >> 5) & 0b11
|
||||
gbMode := (value >> 5) & 0b11
|
||||
if gaMode != 0 {
|
||||
log.Fatalf("I8255 implementation only supports mode 0 on Port A")
|
||||
}
|
||||
if gbMode != 0 {
|
||||
log.Fatalf("I8255 implementation only supports mode 0 on Port B")
|
||||
}
|
||||
// Don't care about the rest (input/output settings per group/port).
|
||||
}
|
||||
default:
|
||||
log.Printf("I8255: invalid out")
|
||||
}
|
||||
}
|
||||
|
||||
func (i *i8255) In(addr uint8) uint8 {
|
||||
switch addr {
|
||||
case 0:
|
||||
if i.onIn != nil {
|
||||
i.onIn(PA)
|
||||
}
|
||||
return i.pa
|
||||
case 1:
|
||||
if i.onIn != nil {
|
||||
i.onIn(PB)
|
||||
}
|
||||
return i.pb
|
||||
case 2:
|
||||
if i.onIn != nil {
|
||||
i.onIn(PC)
|
||||
}
|
||||
return i.pc
|
||||
default:
|
||||
log.Printf("I8255: invalid in")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue