forked from WartyMN/F256-FileManager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsys.c
401 lines (299 loc) · 12.5 KB
/
sys.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
/*
* lib_sys.c
*
* Created on: Mar 22, 2022
* Author: micahbly
*/
// THIS IS A CUT-DOWN VERSION OF the OS/f lib_sys.c file, just enough to power Lich King
// adapted for Foenix F256 Jr starting November 29, 2022
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
// project includes
#include "sys.h"
#include "app.h"
#include "comm_buffer.h"
#include "memory.h"
// C includes
#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// cc65 includes
#include "f256.h"
#include "text.h"
/*****************************************************************************/
/* Definitions */
/*****************************************************************************/
uint8_t io_bank_value_kernel; // stores value for the physical bank pointing to C000-DFFF whenever we change it, so we can restore it.
uint8_t overlay_bank_value_kernel; // stores value for the physical bank pointing to A000-BFFF whenever we change it, so we can restore it.
/*****************************************************************************/
/* Global Variables */
/*****************************************************************************/
extern char* global_string_buff1;
/*****************************************************************************/
/* Private Function Prototypes */
/*****************************************************************************/
/*****************************************************************************/
/* Private Function Definitions */
/*****************************************************************************/
/*****************************************************************************/
/* Public Function Definitions */
/*****************************************************************************/
/*****************************************************************************/
/* Private Function Prototypes */
/*****************************************************************************/
// convert a decimal number to BCD format (for use with RTC)
uint8_t Sys_DecimalToBCD(uint8_t dec_number);
/*****************************************************************************/
/* Private Function Definitions */
/*****************************************************************************/
// convert a decimal number to BCD format (for use with RTC)
uint8_t Sys_DecimalToBCD(uint8_t dec_number)
{
uint8_t bcd_number = 0;
while (dec_number >= 10)
{
++bcd_number;
dec_number -= 10;
}
bcd_number = bcd_number << 4;
return (bcd_number | dec_number);
}
// // interrupt 1 is PS2 keyboard, interrupt 2 is A2560K keyboard
// void Sys_InterruptKeyboard(void)
// {
// kbd_handle_irq();
// }
//
// // interrupt 4 is PS2 mouse
// void Sys_InterruptMouse(void);
// **** Debug functions *****
// void Sys_Print(System* the_system)
// {
// DEBUG_OUT(("System print out:"));
// DEBUG_OUT((" address: %p", the_system));
// DEBUG_OUT((" num_screens_: %i", the_system->num_screens_));
// DEBUG_OUT((" model_number_: %i", the_system->model_number_));
// }
// void Sys_PrintScreen(Screen* the_screen)
// {
// DEBUG_OUT(("Screen print out:"));
// DEBUG_OUT((" address: %p", the_screen));
// DEBUG_OUT((" id_: %i", the_screen->id_));
// DEBUG_OUT((" vicky_: %p", the_screen->vicky_));
// DEBUG_OUT((" width_: %i", the_screen->width_));
// DEBUG_OUT((" height_: %i", the_screen->height_));
// DEBUG_OUT((" text_cols_vis_: %i", the_screen->text_cols_vis_));
// DEBUG_OUT((" text_rows_vis_: %i", the_screen->text_rows_vis_));
// DEBUG_OUT((" text_mem_cols_: %i", the_screen->text_mem_cols_));
// DEBUG_OUT((" text_mem_rows_: %i", the_screen->text_mem_rows_));
// DEBUG_OUT((" text_ram_: %p", the_screen->text_ram_));
// DEBUG_OUT((" text_attr_ram_: %p", the_screen->text_attr_ram_));
// DEBUG_OUT((" text_font_ram_: %p", the_screen->text_font_ram_));
// DEBUG_OUT((" bitmap_[0]: %p", the_screen->bitmap_[0]));
// DEBUG_OUT((" bitmap_[1]: %p", the_screen->bitmap_[1]));
// DEBUG_OUT((" text_font_height_: %i", the_screen->text_font_height_));
// DEBUG_OUT((" text_font_width_: %i", the_screen->text_font_width_));
// }
/*****************************************************************************/
/* Public Function Definitions */
/*****************************************************************************/
// **** CONSTRUCTOR AND DESTRUCTOR *****
// **** System Initialization functions *****
// **** Event-handling functions *****
// see MCP's ps2.c for real examples once real machine available
// // interrupt 1 is PS2 keyboard, interrupt 2 is A2560K keyboard
// void Sys_InterruptKeyboard(void)
// {
// printf("keyboard!\n");
// return;
// }
//
// // interrupt 4 is PS2 mouse
// void Sys_InterruptMouse(void)
// {
// printf("mouse!\n");
// return;
// }
// **** Screen mode/resolution/size functions *****
// //! Switch machine into text mode
// //! @param the_system: valid pointer to system object
// //! @param as_overlay: If true, sets text overlay mode (text over graphics). If false, sets full text mode (no graphics);
// void Sys_SetModeText(bool as_overlay)
// {
// // LOGIC:
// // On an A2560K or X, the only screen that has a text/graphics mode is the Channel B screen
//
// Sys_SwapIOPage(VICKY_IO_PAGE_REGISTERS);
//
// if (as_overlay)
// {
// // switch to text mode with overlay by setting graphics mode bit, setting bitmap engine enable bit, and setting graphics mode overlay
// R8(VICKY_MASTER_CTRL_REG_L) = (GRAPHICS_MODE_TEXT | GRAPHICS_MODE_TEXT_OVER | GRAPHICS_MODE_GRAPHICS | GRAPHICS_MODE_EN_BITMAP);
// R8(BITMAP_CTRL) = 0x01;
//
// // c256foenix, discord 2022/03/10
// // Normally, for example, if you setup everything to be in bitmap mode, and you download an image in VRAM and you can see it properly... If you turn on overlay, then you will see on top of that same image, your text that you had before.
// // Mstr_Ctrl_Text_Mode_En = $01 ; Enable the Text Mode
// // Mstr_Ctrl_Text_Overlay = $02 ; Enable the Overlay of the text mode on top of Graphic Mode (the Background Color is ignored)
// // Mstr_Ctrl_Graph_Mode_En = $04 ; Enable the Graphic Mode
// // Mstr_Ctrl_Bitmap_En = $08 ; Enable the Bitmap Module In Vicky
// // all of these should be ON
// }
// else
// {
// R8(VICKY_MASTER_CTRL_REG_L) = (GRAPHICS_MODE_TEXT);
// // disable bitmap
// R8(BITMAP_CTRL) = 0x00;
// }
//
// Sys_RestoreIOPage();
// }
// //! Change video mode to the one passed.
// //! @param the_screen: valid pointer to the target screen to operate on
// //! @param new_mode: One of the enumerated screen_resolution values. Must correspond to a valid VICKY video mode for the host machine. See VICKY_IIIA_RES_800X600_FLAGS, etc. defined in a2560_platform.h
// //! @return returns false on any error/invalid input.
// bool Sys_SetVideoMode(uint8_t new_mode)
// {
// uint8_t new_mode_flag;
//
// if (new_mode == RES_320X240)
// {
// new_mode_flag = VICKY_RES_320X240_FLAGS;
// }
// else if (new_mode == RES_320X200)
// {
// new_mode_flag = VICKY_RES_320X200_FLAGS;
// }
// else
// {
// LOG_ERR(("%s %d: specified video mode is not legal for this screen %u", __func__, __LINE__, new_mode));
// return false;
// }
//
// //DEBUG_OUT(("%s %d: specified video mode = %u, flag=%u", __func__, __LINE__, new_mode, new_mode_flag));
//
// Sys_SwapIOPage(VICKY_IO_PAGE_REGISTERS);
//
// //DEBUG_OUT(("%s %d: vicky before = %x", __func__, __LINE__, *the_screen->vicky_ ));
// R8(VICKY_MASTER_CTRL_REG_H) = R8(VICKY_MASTER_CTRL_REG_H) & new_mode_flag;
// //DEBUG_OUT(("%s %d: vicky after = %x", __func__, __LINE__, *the_screen->vicky_ ));
//
// Sys_RestoreIOPage();
//
// // teach screen about the new settings
// if (Sys_DetectScreenSize() == false)
// {
// LOG_ERR(("%s %d: Changed screen resolution, but the selected resolution could not be handled", __func__, __LINE__, new_mode));
// return false;
// }
//
// // tell the MCP that we changed res so it can update it's internal col sizes, etc. - this function is not exposed in MCP headers yet
// //sys_text_setsizes();
//
// return true;
// }
//! Enable or disable the hardware cursor in text mode, for the specified screen
//! @param the_system: valid pointer to system object
//! @param the_screen: valid pointer to the target screen to operate on
//! @param enable_it: If true, turns the hardware blinking cursor on. If false, hides the hardware cursor;
void Sys_EnableTextModeCursor(bool enable_it)
{
// LOGIC:
// bit 0 is enable/disable
// bit 1-2 are the speed of flashing
// bit 3 is solid (0) or flashing (1)
Sys_SwapIOPage(VICKY_IO_PAGE_REGISTERS);
R8(VICKY_TEXT_CURSOR_ENABLE) = (uint8_t)enable_it;
Sys_RestoreIOPage();
//DEBUG_OUT(("%s %d: cursor enabled now=%u", __func__, __LINE__, enable_it));
}
// disable the I/O bank to allow RAM to be mapped into it
// current MMU setting is saved to the 6502 stack
void Sys_DisableIOBank(void)
{
asm("lda $01"); // Stash the current IO page at ZP_OLD_IO_PAGE
asm("sta %b", ZP_OLD_IO_PAGE);
R8(MMU_IO_CTRL) = 4; // set only bit 2
}
// change the I/O page
// current IO setting is saved for later restoration
void Sys_SwapIOPage(uint8_t the_page_number)
{
asm("lda $01"); // Stash the current IO page at ZP_OLD_IO_PAGE
asm("sta %b", ZP_OLD_IO_PAGE);
R8(MMU_IO_CTRL) = the_page_number;
}
// restore the previous IO page setting, which was saved by Sys_SwapIOPage()
void Sys_RestoreIOPage(void)
{
asm("lda %b", ZP_OLD_IO_PAGE); // we stashed the previous IO page at ZP_OLD_IO_PAGE
asm("sta $01"); // switch back to the previous IO setting
}
// update the system clock with a date/time string in YY/MM/DD HH:MM format
// returns true if format was acceptable (and thus update of RTC has been performed).
bool Sys_UpdateRTC(char* datetime_from_user)
{
static uint8_t string_offsets[5] = {12,9,6,3,0}; // array is order by RTC order of min-hr-day-month-year
static uint8_t rtc_offsets[5] = {0,2,2,3,1}; // starting at min=d692
static uint8_t bounds[5] = {60,24,31,12,99}; // starting at min=d692
uint8_t old_rtc_control;
uint8_t i;
int8_t this_digit;
int8_t tens_digit;
uint8_t rtc_array[5];
uint8_t* rtc_addr;
for (i = 0; i < 5; i++)
{
this_digit = datetime_from_user[string_offsets[i]];
if (this_digit < CH_ZERO || this_digit > CH_NINE)
{
return false;
}
tens_digit = this_digit - CH_ZERO;
this_digit = datetime_from_user[string_offsets[i] + 1];
if (this_digit < CH_ZERO || this_digit > CH_NINE)
{
return false;
}
rtc_array[i] = (this_digit - CH_ZERO) + (tens_digit * 10);
}
//sprintf(global_string_buff1, "%02X %02X %02X %02X %02X", rtc_array[4], rtc_array[3], rtc_array[2], rtc_array[1], rtc_array[0]);
//Text_DrawStringAtXY(0, 3, global_string_buff1, COLOR_BRIGHT_YELLOW, COLOR_BLACK);
// check if any of the numbers are too high
for (i = 0; i < 5; i++)
{
if (rtc_array[i] > bounds[i])
{
return false;
}
}
// numbers are all good, convert to BCD
for (i = 0; i < 5; i++)
{
rtc_array[i] = Sys_DecimalToBCD(rtc_array[i]);
}
//sprintf(global_string_buff1, "20%02X-%02X-%02X %02X:%02X", rtc_array[4], rtc_array[3], rtc_array[2], rtc_array[1], rtc_array[0]);
//Text_DrawStringAtXY(25, 3, global_string_buff1, COLOR_BRIGHT_YELLOW, COLOR_BLACK);
asm("SEI"); // disable interrupts in case some other process has a role here
// need to have vicky registers available
Sys_SwapIOPage(VICKY_IO_PAGE_REGISTERS);
asm("SEI"); // disable interrupts in case some other process has a role here
// stop RTC from updating external registers. Required!
old_rtc_control = R8(RTC_CONTROL);
R8(RTC_CONTROL) = old_rtc_control | 0x08; // stop it from updating external registers
rtc_addr = (uint8_t*)RTC_MINUTES;
for (i = 0; i < 5; i++)
{
R8(MMU_IO_CTRL) = VICKY_IO_PAGE_REGISTERS; // just make sure i/o page is still up.
rtc_addr += rtc_offsets[i];
R8(rtc_addr) = rtc_array[i];
}
// restore timer control to what it had been
R8(RTC_CONTROL) = old_rtc_control;
Sys_RestoreIOPage();
asm("CLI"); // restore interrupts
return true;
}