a800xl_utils/screen/
mod.rs1use crate::cio::{Cmd, IOCB};
2use crate::consts;
3use ufmt_write::uWrite;
4
5pub fn show_cursor(visible: bool) {
7 unsafe {
8 *crate::consts::CRSINH = !visible as u8;
9 }
10}
11
12pub fn clear_atract() {
14 unsafe { *consts::ATRACT = 0 }
15}
16
17pub fn gotoxy(x: i16, y: i16) {
19 unsafe {
20 **consts::OLDADR = *consts::OLDCHR;
21 *consts::OLDADR = (*consts::SAVMSC).add(40 * y as usize + x as usize);
22 let c = **consts::OLDADR;
23 *consts::OLDCHR = c;
24 if *consts::CRSINH == 0 {
25 **consts::OLDADR |= 0x80;
26 }
27 set_pos(x, y);
28 }
29}
30
31pub fn set_pos(x: i16, y: i16) {
33 unsafe {
34 *consts::COLCRS = x as u16;
35 *consts::ROWCRS = y as u8;
36 }
37}
38
39pub fn set_start_pos(x: i16, y: i16) {
42 unsafe {
43 *consts::OLDCOL = x as u16;
44 *consts::OLDROW = y as u8;
45 }
46}
47
48pub fn init_graphics(mode: u8, open_mode: u8) {
52 IOCB::new(6)
53 .cmd(Cmd::Open as u8)
54 .buffer(b"S:\x9b")
55 .icax1(open_mode)
56 .icax2(mode)
57 .call();
58}
59
60pub fn close_graphics() {
62 IOCB::new(6).cmd(Cmd::Close as u8).call();
63}
64
65pub fn draw_line(x: i16, y: i16, dx: i16, dy: i16) {
67 set_start_pos(x, y);
68 draw_to(dx, dy);
69}
70
71pub fn draw_to(dx: i16, dy: i16) {
73 set_pos(dx, dy);
74 IOCB::new(6).cmd(17).icax1(12).icax2(0).call();
75}
76
77pub fn set_color(color: u8) {
79 unsafe {
80 *consts::ATACHR = color;
81 }
82}
83
84pub fn plot(x: i16, y: i16) {
85 set_pos(x, y);
86 let color = unsafe { *consts::ATACHR };
87 IOCB::new(6)
88 .cmd(Cmd::PutBytes as u8)
89 .buffer(&[])
90 .call_with_a(color);
91}
92
93pub fn clrscr() {
95 let scr_slice = unsafe {
97 let scr_addr = *consts::SAVMSC;
98 core::slice::from_raw_parts_mut(scr_addr, 40 * 24)
99 };
100 scr_slice.fill(0);
101}
102
103pub fn atascii_to_screen(b: u8) -> u8 {
105 (match b & 0x7f {
106 0..=31 => b + 64,
107 32..=95 => b - 32,
108 _ => b,
109 }) | (b & 128)
110}
111
112pub struct ScreenMemoryWriter<'a> {
115 buffer: &'a mut [u8],
116 written: usize,
117}
118
119impl<'a> ScreenMemoryWriter<'a> {
120 pub fn new(buffer: &'a mut [u8]) -> ScreenMemoryWriter<'a> {
121 ScreenMemoryWriter { buffer, written: 0 }
122 }
123}
124
125impl<'a> uWrite for ScreenMemoryWriter<'a> {
126 type Error = ();
127
128 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
129 for b in s.bytes().map(atascii_to_screen) {
130 if self.written >= self.buffer.len() {
131 return Err(());
132 }
133 self.buffer[self.written] = b;
134 self.written += 1;
135 }
136 Ok(())
137 }
138}