annotate src/console/Hes_Cpu.h @ 3024:965c0df4ae84

Patch from John Lindgren to skip corrupted frames, from Debian bug #514674.
author Tony Vroon <chainsaw@gentoo.org>
date Thu, 09 Apr 2009 23:58:13 +0100
parents 240bdf781ad0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
1 // PC Engine CPU emulator for use with HES music files
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
2
341
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
3 // Game_Music_Emu 0.5.2
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
4 #ifndef HES_CPU_H
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
5 #define HES_CPU_H
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
6
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
7 #include "blargg_common.h"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
8
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
9 typedef blargg_long hes_time_t; // clock cycle count
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
10 typedef unsigned hes_addr_t; // 16-bit address
2238
240bdf781ad0 eliminate warnings on x86_64.
Yoshiki Yazawa <yaz@cc.rim.or.jp>
parents: 341
diff changeset
11 enum { future_hes_time = INT_MAX / 2 + 1 };
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
12
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
13 class Hes_Cpu {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
14 public:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
15 typedef BOOST::uint8_t uint8_t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
16
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
17 void reset();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
18
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
19 enum { page_size = 0x2000 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
20 enum { page_shift = 13 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
21 enum { page_count = 8 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
22 void set_mmr( int reg, int bank );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
23
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
24 uint8_t const* get_code( hes_addr_t );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
25
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
26 uint8_t ram [page_size];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
27
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
28 // not kept updated during a call to run()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
29 struct registers_t {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
30 BOOST::uint16_t pc;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
31 uint8_t a;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
32 uint8_t x;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
33 uint8_t y;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
34 uint8_t status;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
35 uint8_t sp;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
36 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
37 registers_t r;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
38
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
39 // page mapping registers
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
40 uint8_t mmr [page_count + 1];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
41
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
42 // Set end_time and run CPU from current time. Returns true if any illegal
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
43 // instructions were encountered.
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
44 bool run( hes_time_t end_time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
45
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
46 // Time of beginning of next instruction to be executed
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
47 hes_time_t time() const { return state->time + state->base; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
48 void set_time( hes_time_t t ) { state->time = t - state->base; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
49 void adjust_time( int delta ) { state->time += delta; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
50
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
51 hes_time_t irq_time() const { return irq_time_; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
52 void set_irq_time( hes_time_t );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
53
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
54 hes_time_t end_time() const { return end_time_; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
55 void set_end_time( hes_time_t );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
56
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
57 void end_frame( hes_time_t );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
58
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
59 // Attempt to execute instruction here results in CPU advancing time to
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
60 // lesser of irq_time() and end_time() (or end_time() if IRQs are
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
61 // disabled)
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
62 enum { idle_addr = 0x1FFF };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
63
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
64 // Can read this many bytes past end of a page
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
65 enum { cpu_padding = 8 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
66
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
67 public:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
68 Hes_Cpu() { state = &state_; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
69 enum { irq_inhibit = 0x04 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
70 private:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
71 // noncopyable
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
72 Hes_Cpu( const Hes_Cpu& );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
73 Hes_Cpu& operator = ( const Hes_Cpu& );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
74
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
75 struct state_t {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
76 uint8_t const* code_map [page_count + 1];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
77 hes_time_t base;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
78 blargg_long time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
79 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
80 state_t* state; // points to state_ or a local copy within run()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
81 state_t state_;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
82 hes_time_t irq_time_;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
83 hes_time_t end_time_;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
84
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
85 void set_code_page( int, void const* );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
86 inline int update_end_time( hes_time_t end, hes_time_t irq );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
87 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
88
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
89 inline BOOST::uint8_t const* Hes_Cpu::get_code( hes_addr_t addr )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
90 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
91 return state->code_map [addr >> page_shift] + addr
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
92 #if !BLARGG_NONPORTABLE
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
93 % (unsigned) page_size
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
94 #endif
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
95 ;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
96 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
97
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
98 inline int Hes_Cpu::update_end_time( hes_time_t t, hes_time_t irq )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
99 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
100 if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
101 int delta = state->base - t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
102 state->base = t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
103 return delta;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
104 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
105
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
106 inline void Hes_Cpu::set_irq_time( hes_time_t t )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
107 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
108 state->time += update_end_time( end_time_, (irq_time_ = t) );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
109 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
110
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
111 inline void Hes_Cpu::set_end_time( hes_time_t t )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
112 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
113 state->time += update_end_time( (end_time_ = t), irq_time_ );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
114 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
115
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
116 inline void Hes_Cpu::end_frame( hes_time_t t )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
117 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
118 assert( state == &state_ );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
119 state_.base -= t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
120 if ( irq_time_ < future_hes_time ) irq_time_ -= t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
121 if ( end_time_ < future_hes_time ) end_time_ -= t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
122 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
123
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
124 #endif