GRIP_bool8 GrLink(GRIP_BUF image, GRIP_VALUE size) { unsigned short img_off; /* Offset of binary image */ unsigned short img_size; /* Size of binary image */ unsigned char img_check; /* Checksum of binary image */ unsigned long memory; /* Image memory */ GRIP_BUF_C header; /* Image header */ GRIP_BUF_C core; /* Image core */ int i; /* Check for duplicate GrLink calls */ if (GRIP_Thunked) return 0; /* Sanity check the inputs */ if (image == 0 || size < 16) return 0; /* Check the image header for the proper signature bytes */ header = (GRIP_BUF_C) image; if (header[0] != 'D' || header[1] != 'B') return 0; /* Extract the image offsets from the header */ img_off = ( (header[2] & 0x0F) << 12 ) | ( (header[3] & 0x0F) << 8 ) | ( (header[4] & 0x0F) << 4 ) | ( (header[5] & 0x0F) ); img_size = ( (header[6] & 0x0F) << 12 ) | ( (header[7] & 0x0F) << 8 ) | ( (header[8] & 0x0F) << 4 ) | ( (header[9] & 0x0F) ); img_check = ( (header[10] & 0x0F) << 4 ) | ( (header[11] & 0x0F) ); /* Compute the start of image core */ if ( size < ((img_off + img_size) << 4) ) return 0; core = header + (img_off << 4); /* Verify the checksum */ for (i = 0; i < (img_size << 4); i++) img_check ^= core[i]; if (img_check != 0) return 0; /* Allocate memory for the core */ memory = (unsigned long) DPMI_AllocDOS(img_size, &GRIP_DS); if (!memory) return 0; /* Copy the image */ _dosmemputl(core, img_size << 2, memory); /* Allocate a code selector for the core */ GRIP_CS = DPMI_AllocSel(); if (GRIP_CS == 0) { DPMI_FreeDOS(GRIP_DS); return 0; } if (DPMI_SetBounds(GRIP_CS, memory, img_size << 4) != 0) { DPMI_FreeSel(GRIP_CS); DPMI_FreeDOS(GRIP_DS); return 0; } if (DPMI_SetCodeAR(GRIP_CS) != 0) { DPMI_FreeSel(GRIP_CS); DPMI_FreeDOS(GRIP_DS); return 0; } /* Prepare the thunking layer */ for (i = 0; i < sizeof(GRIP_THUNK); i++) GRIP_Thunk[i] = ((GRIP_BUF_C)core)[i]; *(GRIP_BUF_S)(GRIP_Thunk+0x02) = 0; *(GRIP_BUF_S)(GRIP_Thunk+0x06) = GRIP_CS; *(GRIP_BUF_S)(GRIP_Thunk+0x0C) = GRIP_CS; /* Allocate a debugging selector if GRIP_DEBUG is defined */ #if defined(GRIP_DEBUG) /* I don't know what this does... at least it compiles okay */ GRIP_ES = DPMI_AllocSel(); if (GRIP_ES == 0) { DPMI_FreeSel(GRIP_CS); DPMI_FreeDOS(GRIP_DS); return 0; } if (DPMI_SetBounds(GRIP_ES, 0xB0000, 80*25*2) != 0) { DPMI_FreeSel(GRIP_ES); DPMI_FreeSel(GRIP_CS); DPMI_FreeDOS(GRIP_DS); return 0; } if (DPMI_SetDataAR(GRIP_ES) != 0) { DPMI_FreeSel(GRIP_ES); DPMI_FreeSel(GRIP_CS); DPMI_FreeDOS(GRIP_DS); return 0; } _farpokew(_dos_ds, memory + 0x12, 0xB000); _farpokew(_dos_ds, memory + 0x16, GRIP_ES); #else _farpokew(_dos_ds, memory + 0x12, 0); _farpokew(_dos_ds, memory + 0x16, 0); #endif // Save the data selector _farpokew(_dos_ds, memory + 0x10, 0); _farpokew(_dos_ds, memory + 0x14, GRIP_DS); /* Complete the link */ if (Gr__Link() == 0) { #if defined(GRIP_DEBUG) DPMI_FreeSel(GRIP_ES); #endif DPMI_FreeSel(GRIP_CS); DPMI_FreeDOS(GRIP_DS); return 0; } GRIP_Thunked = 1; return 1; }
void Atari_DisplayScreen(UBYTE * ascreen) { static int lace = 0; unsigned long vga_ptr; UBYTE *scr_ptr; int ypos; vga_ptr = 0xa0000; scr_ptr = &ascreen[first_lno * ATARI_WIDTH + first_col]; if (ypos_inc == 2) { if (lace) { vga_ptr += 320; scr_ptr += ATARI_WIDTH; } lace = 1 - lace; } if (vga_started) /*draw screen only in graphics mode*/ { if(use_vret) v_ret(); /*vertical retrace control */ if (use_vesa) /*draw screen using VESA2*/ switch(video_mode) { case 0: VESA_blit(ascreen+first_col + first_lno*ATARI_WIDTH, 320,200,ATARI_WIDTH,vesa_linelenght,vesa_selector); break; case 1: VESA_blit(ascreen+first_col, 320,240,ATARI_WIDTH,vesa_linelenght,vesa_selector); break; case 2: VESA_blit(ascreen+first_col, 320,240,ATARI_WIDTH,vesa_linelenght*2,vesa_selector); break; case 3: VESA_i_blit(ascreen+first_col, 320,240,ATARI_WIDTH,vesa_linelenght,vesa_selector); break; } else /*draw screen using vga or x-mode*/ switch(video_mode) { case 0: for (ypos = 0; ypos < 200; ypos += ypos_inc) { _dosmemputl(scr_ptr, 320 / 4, vga_ptr); vga_ptr += vga_ptr_inc; scr_ptr += scr_ptr_inc; } break; case 1: x_blit(ascreen+first_col,240,ATARI_WIDTH,80); break; case 2: x_blit(ascreen+first_col,240,ATARI_WIDTH,160); break; case 3: x_blit_i2(ascreen+first_col,240,ATARI_WIDTH,160); break; } } /* if (vga_started) */ }