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