1
- use std:: pin:: Pin ;
1
+ use std:: sync:: atomic:: Ordering ;
2
+ use std:: sync:: Arc ;
3
+ use std:: { pin:: Pin , sync:: atomic:: AtomicBool } ;
2
4
use std:: str:: FromStr ;
3
5
4
6
use async_std:: task:: JoinHandle ;
@@ -31,12 +33,14 @@ const COLORS: [u32; 16] = [
31
33
pub struct TextBuffer {
32
34
chars : Pin < Box < [ u8 ; 1 << 11 ] > > ,
33
35
modifiers : Pin < Box < [ u8 ; 1 << 11 ] > > ,
36
+ modified : Arc < AtomicBool > ,
34
37
handle : JoinHandle < ( ) > ,
35
38
}
36
39
37
- struct BufferPtr {
40
+ struct BufferPtr {
38
41
chars : * const [ u8 ; 1 << 11 ] ,
39
42
modifiers : * const [ u8 ; 1 << 11 ] ,
43
+ modified : Arc < AtomicBool > ,
40
44
}
41
45
42
46
unsafe impl Send for BufferPtr { }
@@ -45,13 +49,15 @@ impl TextBuffer {
45
49
pub fn spawn ( ) -> TextBuffer {
46
50
let chars = Box :: pin ( [ 0 ; 1 << 11 ] ) ;
47
51
let modifiers = Box :: pin ( [ 0 ; 1 << 11 ] ) ;
52
+ let modified = Arc :: new ( AtomicBool :: new ( true ) ) ;
48
53
49
54
let handle = async_std:: task:: spawn ( run_handle ( BufferPtr {
50
55
chars : & * chars,
51
56
modifiers : & * modifiers,
57
+ modified : modified. clone ( ) ,
52
58
} ) ) ;
53
59
54
- TextBuffer { chars, modifiers, handle }
60
+ TextBuffer { chars, modifiers, modified , handle }
55
61
}
56
62
57
63
pub fn get ( & self , addr : u16 ) -> u8 {
@@ -65,7 +71,7 @@ impl TextBuffer {
65
71
}
66
72
67
73
pub fn set ( & mut self , addr : u16 , data : u8 ) {
68
- println ! ( "setting {addr} to {data}" ) ;
74
+ self . modified . store ( true , Ordering :: Relaxed ) ;
69
75
70
76
if addr % 2 == 0 {
71
77
let sub_index = ( addr >> 1 ) as usize ;
@@ -90,7 +96,7 @@ async fn run_handle(buffer: BufferPtr) {
90
96
91
97
let mut window =
92
98
minifb:: Window :: new ( "f8ful" , WIDTH , HEIGHT , opts) . expect ( "should be able to create window" ) ;
93
- // match the VGA standard
99
+ // the actual VGA standard is 75, but this function is very resource intensive and should not run constantly
94
100
window. set_target_fps ( 75 ) ;
95
101
if let Some ( icon) = get_icon ( ) {
96
102
window. set_icon ( icon) ;
@@ -99,35 +105,39 @@ async fn run_handle(buffer: BufferPtr) {
99
105
let mut fb = [ 0x00000000 ; WIDTH * HEIGHT ] ;
100
106
101
107
while window. is_open ( ) {
102
- for y in 0 ..HEIGHT {
103
- for x in 0 ..WIDTH {
104
- let font_x = x % 8 ;
105
- let font_y = y % 16 ;
106
-
107
- let char_x = x / 8 ;
108
- let char_y = y / 16 ;
109
- let char_idx = char_x + char_y * WIDTH / 8 ;
110
- let ( character, modifier) = unsafe { (
111
- ( * buffer. chars ) [ char_idx] ,
112
- ( * buffer. modifiers ) [ char_idx]
113
- ) } ;
114
-
115
- let font_addr = ( ( character as usize ) << 4 ) + font_y;
116
- let lit = FONT [ font_addr] & ( 1 << ( 7 - font_x) ) > 0 ;
117
-
118
- // This part isn't part of the actual CPU,
119
- // the real value will be transmitted via VGA instead of stored.
120
- let fg = COLORS [ ( modifier & 0xf ) as usize ] ;
121
- let bg = COLORS [ ( modifier >> 4 ) as usize ] ;
122
- fb[ x + y * WIDTH ] = if lit { fg } else { bg } ;
108
+ if buffer. modified . load ( Ordering :: Relaxed ) {
109
+ buffer. modified . store ( false , Ordering :: Relaxed ) ;
110
+ for y in 0 ..HEIGHT {
111
+ for x in 0 ..WIDTH {
112
+ let font_x = x % 8 ;
113
+ let font_y = y % 16 ;
114
+
115
+ let char_x = x / 8 ;
116
+ let char_y = y / 16 ;
117
+ let char_idx = char_x + char_y * WIDTH / 8 ;
118
+ let ( character, modifier) = unsafe { (
119
+ ( * buffer. chars ) [ char_idx] ,
120
+ ( * buffer. modifiers ) [ char_idx]
121
+ ) } ;
122
+
123
+ let font_addr = ( ( character as usize ) << 4 ) + font_y;
124
+ let lit = FONT [ font_addr] & ( 1 << ( 7 - font_x) ) > 0 ;
125
+
126
+ // This part isn't part of the actual CPU,
127
+ // the real value will be transmitted via VGA instead of stored.
128
+ let fg = COLORS [ ( modifier & 0xf ) as usize ] ;
129
+ let bg = COLORS [ ( modifier >> 4 ) as usize ] ;
130
+ fb[ x + y * WIDTH ] = if lit { fg } else { bg } ;
131
+ }
123
132
}
124
- }
125
133
126
- window
127
- . update_with_buffer ( & fb, WIDTH , HEIGHT )
128
- . expect ( "unable to write to window" ) ;
134
+ window
135
+ . update_with_buffer ( & fb, WIDTH , HEIGHT )
136
+ . expect ( "unable to write to window" ) ;
137
+ } else {
138
+ window. update ( ) ;
139
+ }
129
140
}
130
-
131
141
}
132
142
133
143
fn get_icon ( ) -> Option < Icon > {
0 commit comments