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 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 (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 (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 } }