2 * Main memory for FM-7 [FM7_MAINMEM/MAINMEM_UTIL]
10 #include "fm7_mainmem.h"
12 void FM7_MAINMEM::initialize(void)
15 diag_load_basicrom = false;
16 diag_load_bootrom_bas = false;
17 diag_load_bootrom_dos = false;
18 diag_load_bootrom_mmr = false;
19 diag_load_bootrom_bubble = false;
20 diag_load_bootrom_bubble_128k = false;
21 diag_load_bootrom_sfd8 = false;
22 diag_load_bootrom_2hd = false;
24 #if defined(_FM77AV_VARIANTS)
25 dictrom_connected = false;
28 for(i = 0x00; i < 0x80; i++) {
35 window_enabled = false;
37 #ifdef _FM77AV_VARIANTS
40 dictrom_enabled = false;
41 dictram_enabled = false;
43 initiator_enabled = true;
44 boot_ram_write = true;
46 #if defined(_FM7) || defined(_FM77AV_VARIANTS)
47 bootmode = config.boot_mode & 3;
49 bootmode = config.boot_mode & 7;
51 basicrom_fd0f = false;
52 is_basicrom = ((bootmode & 0x03) == 0) ? true : false;
55 i = FM7_MAINMEM_OMOTE;
56 memset(fm7_mainmem_omote, 0x00, 0x8000 * sizeof(uint8_t));
60 memset(fm7_mainmem_ura, 0x00, 0x7c00 * sizeof(uint8_t));
62 i = FM7_MAINMEM_VECTOR;
63 memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
65 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
66 defined(_FM77_VARIANTS)
67 extram_pages = FM77_EXRAM_BANKS;
68 #if defined(_FM77_VARIANTS)
69 if(extram_pages > 3) extram_pages = 3;
71 if(extram_pages > 12) extram_pages = 12;
73 if(extram_pages > 0) {
74 i = FM7_MAINMEM_EXTRAM;
75 fm7_mainmem_extram = (uint8_t *)malloc(extram_pages * 0x10000);
76 if(fm7_mainmem_extram != NULL) {
77 memset(fm7_mainmem_extram, 0x00, extram_pages * 0x10000);
82 #if defined(_FM77_VARIANTS)
83 memset(fm77_shadowram, 0x00, 0x200);
85 #if defined(_FM77_VARIANTS) || defined(_FM8)
86 for(i = 0; i < 8; i++) memset(fm7_bootroms[i], 0xff, 0x200);
87 #elif defined(_FM7) || defined(_FMNEW7)
88 for(i = 0; i < 4; i++) memset(fm7_bootroms[i], 0xff, 0x200);
92 // FM-8 HAS TWO TYPE of BOOTROM.
93 // See http://www.mindspring.com/~thasegaw/rpcg/fm8_boot.html .
99 diag_load_sm11_14 = false;
100 diag_load_sm11_15 = false;
102 tmpb = (read_bios(_T(ROM_FM8_SM11_14), tmpp, 0x800) >= 0x800);
105 memcpy(fm7_bootroms[0], &(tmpp[0x000]), 0x200); // BASIC
106 memcpy(fm7_bootroms[2], &(tmpp[0x200]), 0x200); // BUBBLE
107 memcpy(fm7_bootroms[1], &(tmpp[0x400]), 0x200); // DOS 320K
108 memcpy(fm7_bootroms[3], &(tmpp[0x600]), 0x200); // DEBUG
109 this->out_debug_log(_T("NOTE: LOADING BULK BOOTROM SM11-14 OK."));
110 diag_load_sm11_14 = true;
112 if(read_bios(_T(ROM_FM8_BOOT_BASIC), fm7_bootroms[0], 0x200) >= 0x1e0) {
113 diag_load_bootrom_bas = true;
115 if(read_bios(_T(ROM_FM8_BOOT_DOS), fm7_bootroms[1], 0x200) >= 0x1e0) {
116 diag_load_bootrom_dos = true;
118 if(read_bios(_T(ROM_FM8_BOOT_BUBBLE_128K), fm7_bootroms[2], 0x200) >= 0x1e0) {
119 diag_load_bootrom_bubble_128k = true;
120 } else if(read_bios(_T(ROM_FM8_BOOT_BUBBLE), fm7_bootroms[2], 0x200) >= 0x1e0) {
121 diag_load_bootrom_bubble = true;
123 if(read_bios(_T(ROM_FM8_BOOT_DEBUG), fm7_bootroms[3], 0x200) >= 0x1e0) {
124 //diag_load_bootrom_debug = true;
130 tmpb = (read_bios(_T(ROM_FM8_SM11_15), tmpp, 0x800) >= 0x800);
133 memcpy(fm7_bootroms[4], &(tmpp[0x000]), 0x200); // Basic
134 memcpy(fm7_bootroms[6], &(tmpp[0x200]), 0x200); // BUBBLE
135 memcpy(fm7_bootroms[5], &(tmpp[0x400]), 0x200); // DOS 320K
136 memcpy(fm7_bootroms[7], &(tmpp[0x600]), 0x200); // DOS 8INCH
137 this->out_debug_log(_T("NOTE: LOADING BULK BOOTROM SM11-15 OK."));
138 diag_load_sm11_15 = true;
140 memcpy(fm7_bootroms[4], fm7_bootroms[0], 0x200); // Basic
141 memcpy(fm7_bootroms[5], fm7_bootroms[1], 0x200); // DOS 5Inch
142 memcpy(fm7_bootroms[6], fm7_bootroms[2], 0x200); // BUBBLE
143 if(read_bios(_T(ROM_FM8_BOOT_DOS_FD8), fm7_bootroms[7], 0x200) >= 0x1e0) {
144 diag_load_bootrom_sfd8 = true;
147 if(tmpp != NULL) free(tmpp);
150 #elif defined(_FM7) || defined(_FMNEW7)
151 // FM-7 HAS TWO TYPE ROM.
152 // See, http://www.mindspring.com/~thasegaw/rpcg/fm7rom.html .
153 diag_load_tl11_11 = false;
154 diag_load_tl11_12 = false;
158 tmpp = malloc(0x800);
159 if(tmpp != NULL) memset(tmpp, 0xff, 0x800);
160 # if defined(_FMNEW7)
161 // For FM-NEW7, If you have TL11-12, load first.
163 diag_load_tl11_12 = (read_bios(_T(ROM_FM7_BOOT_TL11_12), tmpp, 0x800) >= 0x800);
165 if(diag_load_tl11_12) {
166 memcpy(fm7_bootroms[0], &(tmpp[0x000]), 0x200);
167 memcpy(fm7_bootroms[2], &(tmpp[0x200]), 0x200);
168 memcpy(fm7_bootroms[1], &(tmpp[0x400]), 0x200);
169 memcpy(fm7_bootroms[3], &(tmpp[0x600]), 0x200);
170 diag_load_bootrom_bas = true;
171 diag_load_bootrom_dos = true;
172 diag_load_bootrom_bubble = true;
173 this->out_debug_log(_T("NOTE: LOADING BULK BOOTROM TL11-12 OK"));
176 if(!diag_load_tl11_12) {
179 tmpb = (read_bios(_T(ROM_FM7_BOOT_TL11_11), tmpp, 0x800) >= 0x800);
182 # if defined(_FMNEW7)
183 this->out_debug_log(_T("NOTE: LOADING BULK BOOTROM TL11-11 (FALLBACK) OK"));
185 this->out_debug_log(_T("NOTE: LOADING BULK BOOTROM TL11-11 OK"));
187 memcpy(fm7_bootroms[0], &(tmpp[0x000]), 0x200);
188 memcpy(fm7_bootroms[2], &(tmpp[0x200]), 0x200);
189 memcpy(fm7_bootroms[1], &(tmpp[0x400]), 0x200);
190 memcpy(fm7_bootroms[3], &(tmpp[0x600]), 0x200);
191 diag_load_bootrom_bas = true;
192 diag_load_bootrom_dos = true;
193 diag_load_bootrom_bubble = true;
194 diag_load_tl11_11 = true;
196 if(read_bios(_T(ROM_FM7_BOOT_BASIC), fm7_bootroms[0], 0x200) >= 0x1e0) {
197 diag_load_bootrom_bas = true;
199 if(read_bios(_T(ROM_FM7_BOOT_DOS), fm7_bootroms[1], 0x200) >= 0x1e0) {
200 diag_load_bootrom_dos = true;
202 if(read_bios(_T(ROM_FM7_BOOT_BUBBLE_7), fm7_bootroms[2], 0x200) >= 0x1e0) {
203 diag_load_bootrom_bubble = true;
206 if(tmpp != NULL) free(tmpp);
209 #elif defined(_FM77_VARIANTS)
210 // FM-77 HAS ONE TYPE ROM.
211 // See, http://www.mindspring.com/~thasegaw/rpcg/fm7rom.html .
215 tmpp = malloc(0x1000);
217 diag_load_wb11_12 = false;
219 tmpb = (read_bios(_T(ROM_FM77_BOOT_WB11_12), tmpp, 0x1000) >= 0x1000);
222 diag_load_wb11_12 = true;
223 this->out_debug_log(_T("NOTE: LOADING BULK BOOTROM WB11-12 OK."));
224 memcpy(fm7_bootroms[2], &(tmpp[0x000]), 0x200); // Basic (MMR)
225 memcpy(fm7_bootroms[5], &(tmpp[0x200]), 0x200); // Bubble (128K)
226 memcpy(fm7_bootroms[6], &(tmpp[0x400]), 0x200); // Bubble (32K)
227 memcpy(fm7_bootroms[4], &(tmpp[0x600]), 0x200); // Reserve
228 memcpy(fm7_bootroms[0], &(tmpp[0x800]), 0x200); // Basic
229 memcpy(fm7_bootroms[1], &(tmpp[0xa00]), 0x200); // DOS (320K)
230 memcpy(fm7_bootroms[3], &(tmpp[0xc00]), 0x200); // DOS (1M)
231 memcpy(fm7_bootroms[7], &(tmpp[0xe00]), 0x200); // Reserve 2
232 diag_load_bootrom_bas = true;
233 diag_load_bootrom_dos = true;
234 diag_load_bootrom_mmr = true;
235 diag_load_bootrom_2hd = true;
237 if(read_bios(_T(ROM_FM7_BOOT_BASIC), fm7_bootroms[0], 0x200) >= 0x1e0) {
238 diag_load_bootrom_bas = true;
241 if(read_bios(_T(ROM_FM7_BOOT_DOS), fm7_bootroms[1], 0x200) >= 0x1e0) {
242 diag_load_bootrom_dos = true;
244 if(read_bios(_T(ROM_FM7_BOOT_MMR), fm7_bootroms[2], 0x200) >= 0x1e0) {
245 diag_load_bootrom_mmr = true;
247 memcpy(fm7_bootroms[2], fm7_bootroms[0], 0x200); // Copy Fallback
248 diag_load_bootrom_mmr = false;
250 if(read_bios(_T(ROM_FM7_BOOT_2HD), fm7_bootroms[3], 0x200) >= 0x1e0) {
251 diag_load_bootrom_2hd = true;
254 if(read_bios(_T(ROM_FM77_BOOT_BUBBLE_128K), fm7_bootroms[5], 0x200) >= 0x1e0) { // Bubble 128K
255 //diag_load_bootrom_dos = true;
257 if(read_bios(_T(ROM_FM7_BOOT_BUBBLE_7), fm7_bootroms[6], 0x200) >= 0x1e0) { // Bubble 32K
258 //diag_load_bootrom_dos = true;
261 if(tmpp != NULL) free(tmpp);
263 i = FM7_MAINMEM_BOOTROM_RAM;
264 memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8_t)); // RAM
265 # elif defined(_FM77AV_VARIANTS)
266 i = FM7_MAINMEM_AV_PAGE0;
267 memset(fm7_mainmem_mmrbank_0, 0x00, 0x10000 * sizeof(uint8_t));
269 i = FM7_MAINMEM_AV_PAGE2;
270 memset(fm7_mainmem_mmrbank_2, 0x00, 0x10000 * sizeof(uint8_t));
272 i = FM7_MAINMEM_INITROM;
273 diag_load_initrom = false;
274 memset(fm7_mainmem_initrom, 0xff, 0x2000 * sizeof(uint8_t));
276 if(read_bios(_T(ROM_FM77AV_INITIATOR), fm7_mainmem_initrom, 0x2000) >= 0x2000) diag_load_initrom = true;
277 this->out_debug_log(_T("77AV INITIATOR ROM READING : %s"), diag_load_initrom ? "OK" : "NG");
279 if(read_bios(_T(ROM_FM7_BOOT_MMR), fm77av_hidden_bootmmr, 0x200) < 0x1e0) {
280 memcpy(fm77av_hidden_bootmmr, &fm7_mainmem_initrom[0x1a00], 0x200);
281 diag_load_bootrom_mmr = true;
283 fm77av_hidden_bootmmr[0x1fe] = 0xfe;
284 fm77av_hidden_bootmmr[0x1fe] = 0x00;
286 i = FM7_MAINMEM_BOOTROM_RAM;
287 memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8_t)); // RAM
289 if(diag_load_initrom) diag_load_bootrom_bas = true;
290 if(diag_load_initrom) diag_load_bootrom_dos = true;
292 if((config.boot_mode & 0x03) == 0) {
293 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1800], 0x1e0 * sizeof(uint8_t));
295 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1a00], 0x1e0 * sizeof(uint8_t));
297 fm7_bootram[0x1fe] = 0xfe; // Set reset vector.
298 fm7_bootram[0x1ff] = 0x00; //
301 this->out_debug_log(_T("BOOT ROM (basic mode) READING : %s"), diag_load_bootrom_bas ? "OK" : "NG");
302 this->out_debug_log(_T("BOOT ROM (DOS mode) READING : %s"), diag_load_bootrom_dos ? "OK" : "NG");
304 #if defined(_FM77_VARIANTS)
305 this->out_debug_log(_T("BOOT ROM (MMR mode) READING : %s"), diag_load_bootrom_mmr ? "OK" : "NG");
306 this->out_debug_log(_T("BOOT ROM (2HD mode) READING : %s"), diag_load_bootrom_2hd ? "OK" : "NG");
308 if(diag_load_bootrom_bubble_128k) {
309 this->out_debug_log(_T("BOOT ROM (BUBBLE 128K) READING : %s"), "OK");
310 } else if(diag_load_bootrom_bubble) {
311 this->out_debug_log(_T("BOOT ROM (BUBBLE 32K) READING : %s"), "OK");
313 this->out_debug_log(_T("BOOT ROM (BUBBLE 32K) READING : %s"), "NG");
315 this->out_debug_log(_T("BOOT ROM (2HD mode) READING : %s"), diag_load_bootrom_2hd ? "OK" : "NG");
316 #elif defined(_FM7) || defined(_FM7)
317 if(diag_load_bootrom_bubble) {
318 this->out_debug_log(_T("BOOT ROM (BUBBLE mode) READING : %s"), "OK");
320 this->out_debug_log(_T("BOOT ROM (BUBBLE mode) READING : %s"), "NG");
323 this->out_debug_log(_T("BOOT ROM (MMR mode) READING : %s"), diag_load_bootrom_mmr ? "OK" : "NG");
327 #if !defined(_FM77AV_VARIANTS)
328 for(i = 0; i <= 3; i++) {
329 uint8_t *p = fm7_bootroms[i];
330 p[0x1fe] = 0xfe; // Set reset vector.
335 i = FM7_MAINMEM_RESET_VECTOR;
336 fm7_mainmem_reset_vector[0] = 0xfe;
337 fm7_mainmem_reset_vector[1] = 0x00;
339 i = FM7_MAINMEM_BASICROM;
340 memset(fm7_mainmem_basicrom, 0xff, 0x7c00 * sizeof(uint8_t));
343 if(read_bios(_T(ROM_FM7_FBASICV30L20), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
344 diag_load_basicrom = true;
345 } else if(read_bios(_T(ROM_FM7_FBASICV30L10), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
346 diag_load_basicrom = true;
347 } else if(read_bios(_T(ROM_FM7_FBASICV30L00), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
348 diag_load_basicrom = true;
349 } else if(read_bios(_T(ROM_FM7_FBASICV30), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
350 diag_load_basicrom = true;
354 if(read_bios(_T(ROM_FM8_FBASICV10), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) diag_load_basicrom = true;
356 this->out_debug_log(_T("BASIC ROM READING : %s"), diag_load_basicrom ? "OK" : "NG");
358 i = FM7_MAINMEM_BIOSWORK;
359 memset(fm7_mainmem_bioswork, 0x00, 0x80 * sizeof(uint8_t));
360 #if defined(CAPABLE_DICTROM)
361 diag_load_dictrom = false;
362 i = FM7_MAINMEM_DICTROM;
363 memset(fm7_mainmem_dictrom, 0xff, 0x40000 * sizeof(uint8_t));
364 if(read_bios(_T(ROM_FM77AV_DICTIONARY), fm7_mainmem_dictrom, 0x40000) == 0x40000) diag_load_dictrom = true;
365 this->out_debug_log(_T("DICTIONARY ROM READING : %s"), diag_load_dictrom ? "OK" : "NG");
366 dictrom_connected = diag_load_dictrom;
368 i = FM7_MAINMEM_BACKUPED_RAM;
369 diag_load_learndata = false;
370 memset(fm7_mainmem_learndata, 0x00, 0x2000 * sizeof(uint8_t));
372 if(read_bios(_T(RAM_FM77AV_DIC_BACKUP), fm7_mainmem_learndata, 0x2000) == 0x2000) diag_load_learndata = true;
373 this->out_debug_log(_T("DICTIONARY BACKUPED RAM READING : %s"), diag_load_learndata ? "OK" : "NG");
374 if(!diag_load_learndata) write_bios(_T("USERDIC.DAT"), fm7_mainmem_learndata, 0x2000);
377 i = FM7_MAINMEM_77AV40_EXTRAROM;
378 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
379 diag_load_extrarom = false;
380 memset(fm7_mainmem_extrarom, 0xff, sizeof(fm7_mainmem_extrarom));
381 if(read_bios(_T(ROM_FM77AV40EX_EXTSUB), fm7_mainmem_extrarom, 0xc000) == 0xc000) diag_load_extrarom = true;
382 this->out_debug_log(_T("AV40SX/EX EXTRA ROM READING : %s"), diag_load_extrarom ? "OK" : "NG");
385 update_all_mmr_jumptable();
388 void FM7_MAINMEM::release()
390 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
391 defined(_FM77_VARIANTS)
392 if(fm7_mainmem_extram != NULL) free(fm7_mainmem_extram);
394 #if !defined(_FM77AV_VARIANTS)
396 for(i = 0; i < 4; i++) {
397 if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]);
398 fm7_bootroms[i] = NULL;
401 #if defined(CAPABLE_DICTROM)
402 write_bios(_T("USERDIC.DAT"), fm7_mainmem_learndata, 0x2000);
404 // MEMORY::release();
407 void FM7_MAINMEM::init_data_table(void)
412 data_func_table_t *p;
413 memset(data_table, 0x00, sizeof(data_table));
415 main_begin = 0x30000;
417 main_begin = 0x00000;
419 for(addr = main_begin; addr < (main_begin + 0x8000); addr += 0x80) {
421 data_table[paddr].read_data = &fm7_mainmem_omote[addr & 0x7fff];
422 data_table[paddr].write_data = &fm7_mainmem_omote[addr & 0x7fff];
424 for(addr = main_begin + 0x8000; addr < (main_begin + 0xfc00); addr += 0x80) {
426 data_table[paddr].read_func = &FM7_MAINMEM::read_ura_basicrom;
427 data_table[paddr].write_func = &FM7_MAINMEM::write_ura_basicrom;
430 addr = main_begin + 0xfc00;
432 data_table[paddr].read_data = fm7_mainmem_bioswork;
433 data_table[paddr].write_data = fm7_mainmem_bioswork;
436 addr = main_begin + 0xfc80;
438 data_table[paddr].read_func = &FM7_MAINMEM::read_shared_ram;
439 data_table[paddr].write_func = &FM7_MAINMEM::write_shared_ram;
441 for(addr = main_begin + 0xfd00; addr < (main_begin + 0xfe00); addr += 0x80) {
443 data_table[paddr].read_func = &FM7_MAINMEM::read_mmio;
444 data_table[paddr].write_func = &FM7_MAINMEM::write_mmio;
446 for(addr = main_begin + 0xfe00; addr < (main_begin + 0x10000); addr += 0x80) {
448 data_table[paddr].read_func = &FM7_MAINMEM::read_bootrom;
449 data_table[paddr].write_func = &FM7_MAINMEM::write_bootrom;
452 #if defined(_FM77AV_VARIANTS)
453 for(addr = 0x00000; addr < 0x10000; addr += 0x80) {
455 data_table[paddr].read_data = &fm7_mainmem_mmrbank_0[addr & 0xffff];
456 data_table[paddr].write_data = &fm7_mainmem_mmrbank_0[addr & 0xffff];
458 for(addr = 0x10000; addr < 0x20000; addr += 0x80) {
460 data_table[paddr].read_func = &FM7_MAINMEM::read_direct_access;
461 data_table[paddr].write_func = &FM7_MAINMEM::write_direct_access;
463 # if defined(CAPABLE_DICTROM)
464 for(addr = 0x20000; addr < 0x30000; addr += 0x80) {
466 data_table[paddr].read_func = &FM7_MAINMEM::read_page2;
467 data_table[paddr].write_func = &FM7_MAINMEM::write_page2;
470 for(addr = 0x20000; addr < 0x30000; addr += 0x80) {
472 data_table[paddr].read_data = &fm7_mainmem_mmrbank_2[addr & 0xffff];
473 data_table[paddr].write_data = &fm7_mainmem_mmrbank_2[addr & 0xffff];
476 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
477 int pages = extram_pages;
478 if((pages > 0) && (pages < 12) && (fm7_mainmem_extram != NULL)) {
479 for(addr = 0x40000; addr < (0x40000 + extram_pages * 0x10000) ; addr += 0x80) {
481 data_table[paddr].read_data = &fm7_mainmem_extram[addr - 0x40000];
482 data_table[paddr].write_data = &fm7_mainmem_extram[addr - 0x40000];
486 #elif defined(_FM77_VARIANTS)
487 int pages = extram_pages;
488 if((pages > 0) && (pages < 4) && (fm7_mainmem_extram != NULL)) {
489 for(addr = 0x00000; addr < (extram_pages * 0x10000) ; addr += 0x80) { // Thanks to Ryu Takegami
491 data_table[paddr].read_data = &fm7_mainmem_extram[addr];
492 data_table[paddr].write_data = &fm7_mainmem_extram[addr];
498 bool FM7_MAINMEM::get_loadstat_basicrom(void)
500 return diag_load_basicrom;
503 bool FM7_MAINMEM::get_loadstat_bootrom_bas(void)
505 return diag_load_bootrom_bas;
508 bool FM7_MAINMEM::get_loadstat_bootrom_dos(void)
510 return diag_load_bootrom_dos;
513 uint32_t FM7_MAINMEM::read_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size)
519 if((name == NULL) || (ptr == NULL)) return 0;
520 s = create_local_path(name);
521 if(s == NULL) return 0;
523 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
524 blocks = fio.Fread(ptr, size, 1);
527 return blocks * size;
530 uint32_t FM7_MAINMEM::write_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size)
536 if((name == NULL) || (ptr == NULL)) return 0;
537 s = create_local_path(name);
538 if(s == NULL) return 0;
540 fio.Fopen(s, FILEIO_WRITE_BINARY);
541 blocks = fio.Fwrite(ptr, size, 1);
544 return blocks * size;