@@ -21,6 +21,8 @@ const T_IS_ZERO: u8 = 0x02;
2121const T_ENABLED : u8 = 0x01 ;
2222
2323// SCR bits
24+ const S_SW_INIT : u8 = 0x20 ;
25+ const S_SW_READ : u8 = 0x10 ;
2426const S_HW_READ : u8 = 0x04 ;
2527const S_HW_STAT : u8 = 0x02 ;
2628const S_HW_ABORT : u8 = 0x01 ;
@@ -35,6 +37,7 @@ pub struct HardwareState {
3537 reload_value : u16 ,
3638 zero_flag : bool ,
3739 interrupt_requested : bool ,
40+ software_read_counter : Option < u8 > ,
3841}
3942impl Default for HardwareState {
4043 fn default ( ) -> Self {
@@ -45,6 +48,7 @@ impl Default for HardwareState {
4548 reload_value : 0 ,
4649 zero_flag : false ,
4750 interrupt_requested : false ,
51+ software_read_counter : None ,
4852 }
4953 }
5054}
@@ -56,6 +60,7 @@ pub struct Hardware {
5660 reload_value : u16 ,
5761 zero_flag : bool ,
5862 interrupt_requested : bool ,
63+ software_read_counter : Option < u8 > ,
5964 memory : Rc < RefCell < Memory > > ,
6065 controller_state : Option < Arc < AtomicU16 > > ,
6166}
@@ -69,6 +74,7 @@ impl Hardware {
6974 reload_value : state. reload_value ,
7075 zero_flag : state. zero_flag ,
7176 interrupt_requested : state. interrupt_requested ,
77+ software_read_counter : state. software_read_counter ,
7278 memory,
7379 controller_state : None ,
7480 }
@@ -90,6 +96,7 @@ impl Hardware {
9096 reload_value : self . reload_value ,
9197 zero_flag : self . zero_flag ,
9298 interrupt_requested : self . interrupt_requested ,
99+ software_read_counter : self . software_read_counter ,
93100 }
94101 }
95102
@@ -100,6 +107,7 @@ impl Hardware {
100107 self . reload_value = state. reload_value ;
101108 self . zero_flag = state. zero_flag ;
102109 self . interrupt_requested = state. interrupt_requested ;
110+ self . software_read_counter = state. software_read_counter ;
103111 }
104112
105113 pub fn claim_controller_state ( & mut self ) -> Arc < AtomicU16 > {
@@ -167,6 +175,8 @@ impl Hardware {
167175 let mut memory = self . memory . borrow_mut ( ) ;
168176 let value = memory. read_byte ( SCR ) ;
169177 let mut new_value = value | S_HW_READ ;
178+
179+ // hardware reads
170180 if value & S_HW_ABORT != 0 {
171181 // hardware read was cancelled
172182 self . next_controller_read = u64:: MAX ;
@@ -178,6 +188,25 @@ impl Hardware {
178188 . min ( self . cycle + HARDWARE_READ_CYCLES ) ;
179189 new_value |= S_HW_STAT ;
180190 }
191+
192+ // software reads
193+ if value & S_SW_INIT != 0 {
194+ // software read has begun
195+ self . software_read_counter = Some ( 31 ) ;
196+ } else if let Some ( count) = self . software_read_counter {
197+ let expected_read_bit = if count & 1 == 1 { S_SW_READ } else { 0 } ;
198+ let actual_read_bit = value & S_SW_READ ;
199+ if expected_read_bit == actual_read_bit {
200+ // caller has toggled a bit
201+ if count == 0 {
202+ // read complete
203+ self . read_controller ( & mut memory) ;
204+ self . software_read_counter = None ;
205+ } else {
206+ self . software_read_counter = Some ( count - 1 ) ;
207+ }
208+ }
209+ }
181210 memory. write_byte ( SCR , new_value) ;
182211 }
183212
@@ -210,7 +239,13 @@ impl Hardware {
210239 self . correct_tcr ( ) ;
211240 if self . cycle >= self . next_controller_read {
212241 // hardware read completed
213- self . read_controller ( ) ;
242+ let mut memory = self . memory . borrow_mut ( ) ;
243+ self . read_controller ( & mut memory) ;
244+
245+ // Mark in SCR that we've finished reading
246+ let scr = memory. read_byte ( SCR ) ;
247+ memory. write_byte ( SCR , scr & !S_HW_STAT ) ;
248+
214249 self . next_controller_read = u64:: MAX ;
215250 }
216251 }
@@ -257,28 +292,23 @@ impl Hardware {
257292 memory. write_byte ( TCR , tcr) ;
258293 }
259294
260- fn read_controller ( & self ) {
295+ fn read_controller ( & self , memory : & mut Memory ) {
261296 let input_state = match self . controller_state . as_ref ( ) {
262297 Some ( state) => state. load ( Ordering :: Relaxed ) ,
263298 None => 0x0000 ,
264299 } ;
265300 let sdlr = input_state & 0xff ;
266301 let sdhr = ( input_state >> 8 ) & 0xff ;
267- let mut memory = self . memory . borrow_mut ( ) ;
268302 memory. write_halfword ( SDLR , sdlr) ;
269303 memory. write_halfword ( SDHR , sdhr) ;
270-
271- // Mark in SCR that we've finished reading
272- let scr = memory. read_byte ( SCR ) ;
273- memory. write_byte ( SCR , scr & !S_HW_STAT ) ;
274304 }
275305}
276306
277307#[ cfg( test) ]
278308mod tests {
279309 use crate :: emulator:: hardware:: {
280- Hardware , HARDWARE_READ_CYCLES , SCR , SDHR , SDLR , S_HW_ABORT , S_HW_READ , S_HW_STAT , TCR ,
281- THR , TLR , T_CLEAR_ZERO , T_ENABLED , T_INTERRUPT , T_IS_ZERO ,
310+ Hardware , HARDWARE_READ_CYCLES , SCR , SDHR , SDLR , S_HW_ABORT , S_HW_READ , S_HW_STAT ,
311+ S_SW_INIT , S_SW_READ , TCR , THR , TLR , T_CLEAR_ZERO , T_ENABLED , T_INTERRUPT , T_IS_ZERO ,
282312 } ;
283313 use crate :: emulator:: memory:: Memory ;
284314 use std:: cell:: RefCell ;
@@ -500,4 +530,26 @@ mod tests {
500530 assert_eq ! ( memory. borrow( ) . read_byte( SDLR ) , 0x00 ) ;
501531 assert_eq ! ( memory. borrow( ) . read_byte( SCR ) , S_HW_READ | S_HW_ABORT ) ;
502532 }
533+
534+ #[ test]
535+ fn performs_software_read ( ) {
536+ let ( mut hardware, memory) = get_hardware ( ) ;
537+
538+ // "start" pushing a button on the controller
539+ let state = hardware. claim_controller_state ( ) ;
540+ state. store ( 0x1002 , Ordering :: Relaxed ) ;
541+
542+ // Begin software read
543+ set_scr ( & mut hardware, & memory, S_SW_INIT ) ;
544+ assert_eq ! ( memory. borrow( ) . read_byte( SDHR ) , 0x00 ) ;
545+ assert_eq ! ( memory. borrow( ) . read_byte( SDLR ) , 0x00 ) ;
546+
547+ for _ in 0 ..16 {
548+ set_scr ( & mut hardware, & memory, S_SW_READ ) ; // set this bit
549+ set_scr ( & mut hardware, & memory, 0 ) ; // clear this bit
550+ }
551+
552+ assert_eq ! ( memory. borrow( ) . read_byte( SDHR ) , 0x10 ) ;
553+ assert_eq ! ( memory. borrow( ) . read_byte( SDLR ) , 0x02 ) ;
554+ }
503555}
0 commit comments