1use core::fmt;
6use std::fmt::{Display, Formatter};
7
8use num_enum::{IntoPrimitive, TryFromPrimitive};
9
10use crate::videotex;
11
12#[repr(u8)]
16#[derive(Debug, Clone, Copy, IntoPrimitive)]
17pub enum RoutingTx {
18 Screen = 0x50,
19 Keyboard = 0x51,
20 Modem = 0x52,
21 Prise = 0x53,
22}
23
24#[repr(u8)]
28#[derive(Debug, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
29pub enum RoutingRx {
30 Screen = 0x58,
31 Keyboard = 0x59,
32 Modem = 0x5A,
33 Prise = 0x5B,
34}
35
36#[repr(u8)]
40#[derive(Debug, Clone, Copy, IntoPrimitive)]
41pub enum Protocol {
42 Pro1 = 0x39,
44 Pro2 = 0x3A,
46 Pro3 = 0x3B,
48}
49
50impl Protocol {
51 pub fn pro1(x: Pro1) -> [u8; 3] {
53 [videotex::C0::ESC.into(), Self::Pro1.into(), x.into()]
54 }
55
56 pub fn pro2(x: Pro2, y: impl Into<u8>) -> [u8; 4] {
58 [
59 videotex::C0::ESC.into(),
60 Self::Pro2.into(),
61 x.into(),
62 y.into(),
63 ]
64 }
65
66 pub fn pro3(x: Pro3, y: impl Into<u8>, z: impl Into<u8>) -> [u8; 5] {
68 [
69 videotex::C0::ESC.into(),
70 Self::Pro3.into(),
71 x.into(),
72 y.into(),
73 z.into(),
74 ]
75 }
76
77 pub fn aiguillage(enable: bool, from: RoutingTx, to: RoutingRx) -> [u8; 5] {
81 Self::pro3(
82 if enable {
83 Pro3::RoutingOn
84 } else {
85 Pro3::RoutingOff
86 },
87 to,
88 from,
89 )
90 }
91}
92
93#[repr(u8)]
95#[derive(Debug, Clone, Copy, IntoPrimitive)]
96pub enum Pro1 {
97 EnqSpeed = 0x74,
98 EnqRom = 0x7B,
100}
101
102#[repr(u8)]
104#[derive(Debug, Clone, Copy, IntoPrimitive)]
105pub enum Pro2 {
106 RoutingTo = 0x62,
107 Start = 0x69,
108 Stop = 0x6A,
109 Prog = 0x6B,
110}
111
112#[repr(u8)]
114#[derive(Debug, Clone, Copy, IntoPrimitive)]
115pub enum Pro3 {
116 RoutingOn = 0x61,
117 RoutingOff = 0x60,
118}
119
120#[repr(u8)]
122#[derive(Debug, Clone, Copy, IntoPrimitive)]
123pub enum Pro2Resp {
124 RepStatus = 0x73,
125 QuerySpeedAnswer = 0x75,
126}
127
128#[repr(u8)]
130#[derive(Debug, Clone, Copy, IntoPrimitive)]
131pub enum Pro3Resp {
132 RoutingFrom = 0x63,
133}
134
135#[repr(u8)]
139#[derive(Debug, Clone, Copy, IntoPrimitive)]
140pub enum FunctionMode {
141 Rouleau = 0x43,
143 Procedure = 0x44,
145 Minuscule = 0x45,
147}
148
149#[derive(Debug, Clone, Copy)]
150pub struct RoutingStatus {
151 pub prise: bool,
152 pub modem: bool,
153 pub keyboard: bool,
154 pub screen: bool,
155}
156
157impl From<u8> for RoutingStatus {
158 fn from(status: u8) -> Self {
159 RoutingStatus {
160 prise: status & 0b1000 != 0,
161 modem: status & 0b0100 != 0,
162 keyboard: status & 0b0010 != 0,
163 screen: status & 0b0001 != 0,
164 }
165 }
166}
167
168#[derive(Debug, Clone, Copy)]
169pub enum Baudrate {
170 B300,
171 B1200,
172 B4800,
173 B9600,
174}
175
176impl Baudrate {
177 pub fn hertz(&self) -> u32 {
178 match self {
179 Baudrate::B300 => 300,
180 Baudrate::B1200 => 1200,
181 Baudrate::B4800 => 4800,
182 Baudrate::B9600 => 9600,
183 }
184 }
185
186 pub fn code(&self) -> u8 {
187 match self {
197 Baudrate::B300 => 0b01_010_010,
198 Baudrate::B1200 => 0b01_100_100,
199 Baudrate::B4800 => 0b01_110_110,
200 Baudrate::B9600 => 0b01_111_111,
201 }
202 }
203
204 pub fn speeds() -> [Self; 4] {
205 [
206 Baudrate::B1200,
207 Baudrate::B300,
208 Baudrate::B4800,
209 Baudrate::B9600,
210 ]
211 }
212}
213
214impl TryFrom<u8> for Baudrate {
215 type Error = u8;
216
217 fn try_from(value: u8) -> Result<Self, Self::Error> {
218 match value {
219 0b01_010_010 => Ok(Baudrate::B300),
220 0b01_100_100 => Ok(Baudrate::B1200),
221 0b01_110_110 => Ok(Baudrate::B4800),
222 0b01_111_111 => Ok(Baudrate::B9600),
223 _ => Err(value),
224 }
225 }
226}
227
228impl Display for Baudrate {
229 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
230 write!(f, "{} bauds", self.hertz())
231 }
232}
233
234pub struct Rom {
238 pub manufacturer: u8,
239 pub model: u8,
240 pub version: u8,
241}
242
243impl From<[u8; 3]> for Rom {
244 fn from(rom: [u8; 3]) -> Self {
245 Rom {
246 manufacturer: rom[0],
247 model: rom[1],
248 version: rom[2],
249 }
250 }
251}