@@ -87,6 +87,57 @@ static inline void lcd_crsr_update(void) {
87
87
}
88
88
}
89
89
90
+ static inline uint8_t lcd_crsr_pixel (uint32_t crsrOffset ) {
91
+ return lcd .crsrImageBytes [crsrOffset >> 2 ] >> ((~crsrOffset & 3 ) * 2 ) & 3 ;
92
+ }
93
+
94
+ static void lcd_drawcrsr (void * output , uint32_t rowWidth , lcd_crsr_state_t * crsrRegs , bool crsrIsLarge , uint32_t size ) {
95
+ uint32_t crsrSize = (crsrIsLarge + 1 ) * 32 ;
96
+ uint32_t crsrClipX = crsrRegs -> crsrClip & 0xFF ;
97
+ uint32_t crsrClipY = crsrRegs -> crsrClip >> 8 ;
98
+ if ((crsrClipX | crsrClipY ) >= crsrSize ) {
99
+ return ;
100
+ }
101
+ uint32_t crsrCol = crsrRegs -> crsrXY & 0xFFFF ;
102
+ if (crsrCol >= rowWidth ) {
103
+ return ;
104
+ }
105
+ uint32_t crsrWidth = crsrSize - crsrClipX ;
106
+ if (crsrWidth > rowWidth - crsrCol ) {
107
+ crsrWidth = rowWidth - crsrCol ;
108
+ }
109
+ uint32_t crsrHeight = crsrSize - crsrClipY ;
110
+ uint32_t crsrRow = crsrRegs -> crsrXY >> 16 ;
111
+ uint32_t crsrRowOffset = ((crsrRegs -> crsrImage * crsrSize + crsrClipY ) * crsrSize + crsrClipX ) & 0xFFF ;
112
+ uint32_t * out = output ;
113
+ uint32_t outRowOffset = crsrRow * rowWidth + crsrCol ;
114
+ uint32_t crsrPalette [4 ] = {
115
+ lcd_rgb888out (lcd_bgr888swap (lcd .crsrPalette0 , 0xFF )),
116
+ lcd_rgb888out (lcd_bgr888swap (lcd .crsrPalette1 , 0xFF )),
117
+ 0x000000 ,
118
+ 0xFFFFFF
119
+ };
120
+ do {
121
+ if (outRowOffset >= size ) {
122
+ return ;
123
+ }
124
+ uint32_t i = crsrWidth ;
125
+ if (i > size - outRowOffset ) {
126
+ i = size - outRowOffset ;
127
+ }
128
+ uint32_t crsrOffset = crsrRowOffset ;
129
+ uint32_t * outPtr = out + outRowOffset ;
130
+ do {
131
+ uint8_t pixel = lcd_crsr_pixel (crsrOffset );
132
+ * outPtr = (pixel & 2 ? * outPtr : 0 ) ^ crsrPalette [pixel ];
133
+ crsrOffset ++ ;
134
+ outPtr ++ ;
135
+ } while (-- i );
136
+ crsrRowOffset += crsrSize ;
137
+ outRowOffset += rowWidth ;
138
+ } while (-- crsrHeight );
139
+ }
140
+
90
141
void emu_set_lcd_callback (bool (* callback )(void * ), void * data ) {
91
142
lcd .gui_callback = callback ;
92
143
lcd .gui_callback_data = data ;
@@ -106,6 +157,9 @@ void emu_lcd_drawframe(void *output) {
106
157
memcpy (output , panel .display , sizeof (panel .display ));
107
158
} else if (lcd .control & 1 << 11 ) {
108
159
emu_lcd_drawmem (output , lcd .data , lcd .data_end , lcd .control , LCD_SIZE );
160
+ if (unlikely (lcd .crsrControl )) {
161
+ lcd_drawcrsr (output , lcd .CPL , & lcd .crsrRegs [1 ], lcd .crsrConfig & 1 , LCD_SIZE );
162
+ }
109
163
}
110
164
}
111
165
@@ -226,8 +280,7 @@ static uint32_t lcd_process_pixel(uint32_t ticks, uint16_t bgr565) {
226
280
assert (lcd .curCol < lcd .CPL );
227
281
uint32_t crsrColOffset = lcd .curCol - lcd .curCrsrCol ;
228
282
if (unlikely (crsrColOffset < lcd .curCrsrWidth )) {
229
- uint32_t crsrOffset = lcd .curCrsrOffset + crsrColOffset ;
230
- uint8_t crsrPixel = lcd .crsrImageBytes [crsrOffset >> 2 ] >> ((~crsrOffset & 3 ) * 2 ) & 3 ;
283
+ uint8_t crsrPixel = lcd_crsr_pixel (lcd .curCrsrOffset + crsrColOffset );
231
284
bgr565 = (crsrPixel & 2 ? bgr565 : 0 ) ^ lcd .crsrPalette [crsrPixel ];
232
285
}
233
286
panel .clock_pixel (bgr565 );
@@ -490,7 +543,7 @@ static uint8_t lcd_read(const uint16_t pio, bool peek) {
490
543
if (index >= 0x800 ) { return lcd .crsrImageBytes [index - 0x800 ]; }
491
544
} else if (index < 0xE00 ) {
492
545
if (!peek ) {
493
- cpu . cycles -- ;
546
+ sched_rewind_cpu ( 1 ); /* safely handle underflow */
494
547
}
495
548
if (index == 0xC00 ) { return lcd .crsrControl | (lcd .crsrRegs [0 ].crsrImage << 4 ); }
496
549
if (index == 0xC04 ) { return lcd .crsrConfig ; }
0 commit comments