func (d *Device) Handler(s *cpu.Storage) { switch s.A { case ClearBuffer: d.buf = d.buf[:0] case GetNextKey: s.C = 0 if sz := len(d.buf); sz > 0 { s.C = d.buf[0] copy(d.buf, d.buf[1:]) d.buf = d.buf[:sz-1] } case GetKeyState: s.C = d.state[s.B&0xff] case SetInterruptId: d.id = s.B } }
func (k *Keyboard) Handler(s *cpu.Storage) { switch s.A { case ClearBuffer: k.buf = k.buf[:0] case GetNextKey: s.C = 0 if sz := len(k.buf); sz > 0 { s.C = k.buf[0] copy(k.buf, k.buf[1:]) k.buf = k.buf[:sz-1] } case GetKeyState: s.C = 0 if int(s.B) < len(k.keys) { s.C = cpu.Word(k.keys[s.B] & 1) } case SetInterruptId: k.id = s.B } }
func (d *Device) Handler(s *cpu.Storage) { switch s.A { case PollState: s.B = d.state s.C = d.error case MapRegion: d.mem = s.Mem[s.X : s.X+(s.Y*VertexSize)] d.state = StateRunning case Rotate: d.angle = s.X % 360 d.state = StateTurning } }
func (d *Device) Handler(s *cpu.Storage) { switch s.A { case PollDevice: s.B = d.state s.C = d.error case SetInterrupt: d.id = s.X case ReadSector: if d.state != StateReady && d.state != StateReadyWP { s.B = 0 switch d.state { case StateNoMedia: d.setError(ErrNoMedia) case StateBusy: d.setError(ErrBusy) } return } s.B = 1 go d.ReadSector(s.X, s.Mem[s.Y:s.Y+WordsPerSector]) case WriteSector: if d.state != StateReady { s.B = 0 switch d.state { case StateNoMedia: d.setError(ErrNoMedia) case StateBusy: d.setError(ErrBusy) case StateReadyWP: d.setError(ErrProtected) } return } s.B = 1 go d.WriteSector(s.X, s.Mem[s.Y:s.Y+WordsPerSector]) } }
func (d *Device) Handler(s *cpu.Storage) { switch s.A { case SetInterval: d.ticker.Stop() d.ticks = 0 if s.B > 0 { d.ticker = time.NewTicker( time.Duration(1e9) / (60 / time.Duration(s.B))) } case GetTicks: s.C = d.ticks case SetInterruptId: d.id = s.B } }
func (c *Clock) Handler(s *cpu.Storage) { switch s.A { case SetInterval: c.ticker.Stop() c.ticks = 0 if s.B > 0 { c.ticker = time.NewTicker( time.Duration(1e9) / (60 / time.Duration(s.B))) } case GetTicks: s.C = c.ticks case SetInterruptId: c.id = s.B } }
func (d *Device) Handler(s *cpu.Storage) { switch s.A { case PollDevice: d.Lock() s.A = cpu.Word(d.state) s.B = cpu.Word(d.error) s.C = cpu.Word(len(d.buf)) d.Unlock() case SetInterrupt: atomic.StoreUint32(&d.id, uint32(s.X)) case Connect: go d.connect(byte(s.X>>8), byte(s.X), byte(s.Y>>8), byte(s.Y), s.Z) case Disconnect: go d.disconnect() case Send: if s.Y == 0 || s.Y > MaxBuffer { d.setError(ErrInvalidBufferSize) return } go d.send(s.Mem[s.X : s.X+s.Y]) case Receive: if s.Y == 0 || s.Y > MaxBuffer { s.B = 0 d.setError(ErrInvalidBufferSize) return } s.A = s.Y sz := cpu.Word(len(d.buf)) if s.A > sz { s.A = sz } go d.receive(s.Mem[s.X : s.X+s.A]) } }
func (h *HMD2043) Handler(s *cpu.Storage) { switch s.A { case QueryMediaPresent: if h.media == nil { s.A = ErrorNoMedia s.B = 0 return } s.A, s.B = ErrorNone, 0 if isSupported(h.media) { s.B = 1 } case QueryMediaParams: if h.media == nil { s.A, s.B, s.C, s.X = ErrorNoMedia, 0, 0, 0 return } s.A = ErrorNone s.B = h.media.SectorSize() s.C = h.media.SectorCount() s.X = 0 if h.media.WriteLocked() { s.X = 1 } case QueryDeviceFlags: s.A, s.B = ErrorNone, h.flags case UpdateDeviceFlags: s.A, h.flags = ErrorNone, s.B case QueryInterruptType: s.A, s.B = ErrorNone, h.lastint case SetInterruptId: s.A, h.id = ErrorNone, s.B case ReadSectors: if h.media == nil { s.A, s.B, s.C, s.X = ErrorNoMedia, 0, 0, 0 return } if h.busy { return } h.busy = true s.A = ErrorNone if h.flags&NonBlocking == 0 { err := h.media.Read(s.B, s.Mem[s.X:s.X+s.C]) if err != nil { s.A = ErrorInvalidSector } h.busy = false return } s.A = ErrorNone go func() { h.media.Read(s.B, s.Mem[s.X:s.X+s.C]) h.busy = false h.lastint = TypeReadComplete h.int(h.id) }() case WriteSectors: if h.media == nil { s.A, s.B, s.C, s.X = ErrorNoMedia, 0, 0, 0 return } if h.busy { return } h.busy = true if h.flags&NonBlocking == 0 { err := h.media.Write(s.B, s.Mem[s.X:s.X+s.C]) if err != nil { s.A = ErrorInvalidSector } h.busy = false return } s.A = ErrorNone go func() { h.media.Write(s.B, s.Mem[s.X:s.X+s.C]) h.busy = false h.lastint = TypeWriteComplete h.int(h.id) }() case QueryMediaQuality: if h.media == nil { s.A, s.B, s.C, s.X = ErrorNoMedia, 0, 0, 0 return } if h.busy { return } // TODO: Find some metric to determine if the type of media. // The HMU1440 spec defines no manufacturer or device ids we can check. // Assume AuthenticHITMedia for now. s.A, s.B = ErrorNone, AuthenticHITMedia } }