int main (int argc, char *argv[]) { DWORD sp1, sp2; WORD c; int i; LIN_ADDR b; struct multiboot_info *mbi; sp1 = get_sp(); mbi = ll_init(); if (mbi == NULL) { message("Error in LowLevel initialization code...\n"); l1_exit(-1); } message("Starting..."); c = ll_context_save(); message("CX=%x\n",c); for (i = 0; i < 0x4F000; i++); dos_mem_init(); b = dos_alloc(BSIZE); vm86_init(b, BSIZE); l1_int_bind(0x40, reflect); l1_int_bind(0x15, reflect); l1_int_bind(0x10, int0x10); l1_irq_bind(6, reflect); l1_irq_bind(15, reflect); l1_irq_bind(14, reflect); irq_unmask(6); irq_unmask(15); irq_unmask(14); disk_demo(); sp2 = get_sp(); message("End reached!\n"); message("Actual stack : %lx - ", sp2); message("Begin stack : %lx\n", sp1); message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-("); ll_end(); return 1; }
void gem_main(void) { WORD i; sh_rdinf(); /* get start of emudesk.inf */ if (!gl_changerez) /* can't be here because of rez change, */ process_inf1(); /* so see if .inf says we need to change rez */ if (gl_changerez) { switch(gl_changerez) { #if CONF_WITH_ATARI_VIDEO case 1: /* ST(e) or TT display */ Setscreen(-1L,-1L,gl_nextrez-2,0); initialise_palette_registers(gl_nextrez-2,0); break; #endif #if CONF_WITH_VIDEL case 2: /* Falcon display */ Setscreen(-1L, -1L, FALCON_REZ, gl_nextrez); initialise_palette_registers(FALCON_REZ,gl_nextrez); break; #endif } gsx_wsclear(); /* avoid artefacts that may show briefly */ /* * resolution change always resets the default drive to the * boot device. TOS3 issues a Dsetdrv() when this happens, * which Hatari's GEMDOS drive emulation uses to keep track * of the current drive. we do the same. */ dos_sdrv(bootdev); } ml_ocnt = 0; gl_changerez = FALSE; mn_init(); /* initialise variables for menu_register() */ num_accs = count_accs(); /* puts ACC names in acc_name[] */ D.g_acc = NULL; if (num_accs) D.g_acc = dos_alloc(num_accs*sizeof(AESPROCESS)); if (D.g_acc) memset(D.g_acc,0x00,num_accs*sizeof(AESPROCESS)); else num_accs = 0; totpds = num_accs + 2; disable_interrupts(); set_aestrap(); /* set trap#2 -> aestrap */ /* init event recorder */ gl_recd = FALSE; gl_rlen = 0; gl_rbuf = NULL; /* link up all the evb's to the event unused list */ eul = NULL; for (i = 0; i < 2; i++) ev_init(D.g_int[i].a_evb,EVBS_PER_PD); for (i = 0; i < num_accs; i++) ev_init(D.g_acc[i].a_evb,EVBS_PER_PD); /* initialize sync blocks */ wind_spb.sy_tas = 0; wind_spb.sy_owner = NULL; wind_spb.sy_wait = 0; /* * init processes - TODO: should go in gempd or gemdisp. */ /* initialize list and unused lists */ nrl = drl = NULL; dlr = zlr = NULL; fph = fpt = fpcnt = 0; /* init initial process */ for(i=totpds-1; i>=0; i--) { rlr = pd_index(i); if (i < 2) { rlr->p_uda = &D.g_int[i].a_uda; rlr->p_cda = &D.g_int[i].a_cda; } else { rlr->p_uda = &D.g_acc[i-2].a_uda; rlr->p_cda = &D.g_acc[i-2].a_cda; } rlr->p_qaddr = rlr->p_queue; rlr->p_qindex = 0; memset(rlr->p_name, ' ', AP_NAMELEN); rlr->p_appdir[0] = '\0'; /* by default, no application directory */ /* if not rlr then initialize his stack pointer */ if (i != 0) rlr->p_uda->u_spsuper = &rlr->p_uda->u_supstk; rlr->p_pid = i; rlr->p_stat = 0; } curpid = 0; rlr->p_pid = curpid++; rlr->p_link = NULL; /* end of process init */ /* restart the tick */ enable_interrupts(); /* * screen manager process init. this process starts out owning the mouse * and the keyboard. it has a pid == 1 */ gl_mowner = ctl_pd = iprocess("SCRENMGR", ctlmgr); /* * run the accessories and the desktop until termination * (for shutdown or resolution change) */ aes_run_rom_program(accdesk_start); /* restore previous trap#2 address */ disable_interrupts(); unset_aestrap(); enable_interrupts(); if (D.g_acc) dos_free((LONG)D.g_acc); }
/* Note: this file originally loaded the icon data from a file (deskhi.icn or desklo.icn). But due to endianness problems and for ROM-ing the desktop, I changed this behaviour so that the icons are included in the program file now. Hope there aren't too much faults in this new version of this function. See icons.c, too. - THH Note 2: this function was greatly rewritten in 2012 to use "real" ICONBLKs in icons.c, so that they can be generated by a resource editor - RFB */ static void app_rdicon(void) { WORD mask[NUM_IBLKS], data[NUM_IBLKS]; char copied[NUM_IBLKS]; char *p; WORD *addr; LONG temp; WORD i, j, n, iwb, ih; WORD num_mask, num_data, num_wds, num_bytes; /* * First, we copy the ICONBLKs to the g_iblist[] array: * g_iblist[] points to the transformed data/transformed mask * & is referenced by act_chkobj() in deskact.c, insa_icon() * in deskins.c, and win_bldview() in deskwin.c */ memcpy(G.g_iblist, icon_rs_iconblk, NUM_IBLKS*sizeof(ICONBLK)); /* * Then we initialise g_origmask[]: * g_origmask[i] points to the untransformed mask & is * referenced by act_chkobj() in deskact.c */ for (i = 0; i < NUM_IBLKS; i++) G.g_origmask[i] = (UWORD *)icon_rs_iconblk[i].ib_pmask; /* * Determine the number of mask and data icons actually used * (different ICONBLKs can point to the same mask and/or data) * and set mask[n] = mask# for iconblk n * data[n] = data# for iconblk n */ for (i = 0; i < NUM_IBLKS; i++) mask[i] = data[i] = -1; for (i = 0, num_mask = num_data = 0; i < NUM_IBLKS; i++) { if (mask[i] < 0) { mask[i] = num_mask; addr = icon_rs_iconblk[i].ib_pmask; for (j = i+1; j < NUM_IBLKS; j++) if (icon_rs_iconblk[j].ib_pmask == addr) mask[j] = num_mask; num_mask++; } if (data[i] < 0) { data[i] = num_data; addr = icon_rs_iconblk[i].ib_pdata; for (j = i+1; j < NUM_IBLKS; j++) if (icon_rs_iconblk[j].ib_pdata == addr) data[j] = num_data; num_data++; } } /* * Calculate the size of each icon in words & bytes. We * assume that all icons are the same w,h as the first */ num_wds = (icon_rs_iconblk[0].ib_wicon * icon_rs_iconblk[0].ib_hicon) / 16; num_bytes = num_wds * 2; /* * Allocate memory for the mask/data icons, and copy them * FIXME: we should check that memory is allocated successfully */ maskstart = dos_alloc(num_mask*num_bytes); memset(copied, 0x00, NUM_IBLKS); for (i = 0, p = maskstart; i < NUM_IBLKS; i++) { n = mask[i]; if (!copied[n]) /* only copy mask once */ { memcpy(p+n*num_bytes, (char *)icon_rs_iconblk[i].ib_pmask, num_bytes); copied[n] = 1; } } datastart = dos_alloc(num_data*num_bytes); memset(copied, 0x00, NUM_IBLKS); for (i = 0, p = datastart; i < NUM_IBLKS; i++) { n = data[i]; if (!copied[n]) /* only copy data once */ { memcpy(p+n*num_bytes, icon_rs_iconblk[i].ib_pdata, num_bytes); copied[n] = 1; } } /* * Fix up the ICONBLKs */ for (i = 0; i < NUM_IBLKS; i++) { temp = mask[i] * num_bytes; G.g_iblist[i].ib_pmask = (WORD *)(maskstart + temp); temp = data[i] * num_bytes; G.g_iblist[i].ib_pdata = (WORD *)(datastart + temp); G.g_iblist[i].ib_ytext = icon_rs_iconblk[0].ib_hicon; G.g_iblist[i].ib_wtext = 12 * gl_wschar; G.g_iblist[i].ib_htext = gl_hschar + 2; } /* * Finally we do the transforms */ iwb = icon_rs_iconblk[0].ib_wicon / 8; ih = icon_rs_iconblk[0].ib_hicon; for (i = 0, p = maskstart; i < num_mask; i++, p += num_bytes) gsx_trans((LONG)p, iwb, (LONG)p, iwb, ih); for (i = 0, p = datastart; i < num_data; i++, p += num_bytes) gsx_trans((LONG)p, iwb, (LONG)p, iwb, ih); }
/* * File Selector input routine that takes control of the mouse * and keyboard, searchs and sort the directory, draws the file * selector, interacts with the user to determine a selection * or change of path, and returns to the application with * the selected path, filename, and exit button. */ WORD fs_input(BYTE *pipath, BYTE *pisel, WORD *pbutton, BYTE *pilabel) { register WORD touchob, value, fnum; WORD curr, count, sel; WORD mx, my; LONG tree; ULONG bitmask; BYTE *ad_fpath, *ad_fname, *ad_ftitle; WORD drive; WORD dclkret, cont, newlist, newsel, newdrive; register BYTE *pstr; GRECT pt; BYTE locstr[LEN_ZPATH+1], mask[LEN_ZFNAME+1], selname[LEN_FSNAME]; OBJECT *obj; TEDINFO *tedinfo; curr = 0; count = 0; /* get out quick if path is */ /* nullptr or if pts to null. */ if (pipath == NULL) return(FALSE); /* if path string is empty, */ /* set reasonable default */ if (*pipath == '\0') { strcpy(pipath,"A:\\*.*"); *pipath += dos_gdrv(); } /* get memory for the filename buffer */ /* & the array that points to it */ for (nm_files = MAX_NM_FILES; nm_files >= MIN_NM_FILES; nm_files /= 2) { ad_fsnames = (BYTE *)dos_alloc(nm_files*(LEN_FSNAME+sizeof(BYTE *))); if (ad_fsnames) break; } if (!ad_fsnames) return(FALSE); g_fslist = (LONG *)(ad_fsnames+nm_files*LEN_FSNAME); strcpy(locstr, pipath); tree = ad_fstree; /* init strings in form */ obj = ((OBJECT *)tree) + FTITLE; tedinfo = (TEDINFO *)obj->ob_spec; ad_ftitle = (BYTE *)tedinfo->te_ptext; set_mask(mask, locstr); /* save caller's mask */ strcpy(ad_ftitle, mask); /* & copy to title line */ obj = ((OBJECT *)tree) + FSDIRECT; tedinfo = (TEDINFO *)obj->ob_spec; ad_fpath = (BYTE *)tedinfo->te_ptext; inf_sset(tree, FSDIRECT, locstr); obj = ((OBJECT *)tree) + FSSELECT; tedinfo = (TEDINFO *)obj->ob_spec; ad_fname = (BYTE *)tedinfo->te_ptext; fmt_str(pisel, selname); /* selname[] is without dot */ inf_sset(tree, FSSELECT, selname); obj = ((OBJECT *)tree) + FSTITLE; obj->ob_spec = pilabel ? (LONG)pilabel : (LONG)rs_str(ITEMSLCT); /* set drive buttons */ obj = ((OBJECT *)tree) + DRIVE_OFFSET; for (drive = 0, bitmask = 1; drive < NM_DRIVES; drive++, bitmask <<= 1, obj++) { if (drvbits & bitmask) obj->ob_state &= ~DISABLED; else obj->ob_state |= DISABLED; } select_drive(tree,locstr[0]-'A',0); /* set clip and start */ /* form fill-in by */ /* drawing the form */ gsx_sclip(&gl_rfs); fm_dial(FMD_START, &gl_rfs); ob_draw(tree, ROOT, 2); /* init for while loop */ /* by forcing initial */ /* fs_newdir call */ sel = 0; newsel = FALSE; cont = newlist = TRUE; while( cont ) { touchob = (newlist) ? 0x0 : fm_do(tree, FSSELECT); gsx_mxmy(&mx, &my); if ( newlist ) { fs_sel(sel, NORMAL); if ( (touchob == FSOK) || (touchob == FSCANCEL) ) ob_change(tree, touchob, NORMAL, TRUE); inf_sset(tree, FSDIRECT, locstr); pstr = fs_pspec(locstr, NULL); strcpy(pstr, mask); fs_newdir(locstr, mask, tree, &count); curr = 0; sel = touchob = 0; newlist = FALSE; } value = 0; dclkret = ((touchob & 0x8000) != 0); switch( (touchob &= 0x7fff) ) { case FSOK: case FSCANCEL: cont = FALSE; break; case FUPAROW: case FDNAROW: value = 1; break; case FSVSLID: ob_actxywh(tree, FSVELEV, &pt); /* anemic slidebars pt.g_x -= 3; pt.g_w += 6; */ if ( !inside(mx, my, &pt) ) { touchob = (my <= pt.g_y) ? FUPAROW : FDNAROW; value = NM_NAMES; break; } /* drop through */ case FSVELEV: fm_own(TRUE); value = gr_slidebox(tree, FSVSLID, FSVELEV, TRUE); fm_own(FALSE); value = curr - mul_div(value, count-NM_NAMES, 1000); if (value >= 0) touchob = FUPAROW; else { touchob = FDNAROW; value = -value; } break; case F1NAME: case F2NAME: case F3NAME: case F4NAME: case F5NAME: case F6NAME: case F7NAME: case F8NAME: case F9NAME: fnum = touchob - F1NAME + 1; if ( fnum > count ) break; if ( (sel) && (sel != fnum) ) fs_sel(sel, NORMAL); if ( sel != fnum) { sel = fnum; fs_sel(sel, SELECTED); } /* get string and see */ /* if file or folder */ inf_sget(tree, touchob, selname); if (selname[0] == ' ') /* a file was selected */ { /* copy to selection */ newsel = TRUE; if (dclkret) cont = FALSE; } else /* a folder was selected: */ { /* insert name before mask */ pstr = fs_pspec(locstr, NULL); unfmt_str(selname+1, pstr); pstr += strlen(pstr); *pstr++ = '\\'; strcpy(pstr, mask); newlist = TRUE; } break; case FCLSBOX: pstr = fs_back(locstr, NULL); if (*pstr-- != '\\') /* ignore strange path string */ break; if (*pstr != ':') /* not at root of drive, so back up */ { pstr = fs_back(locstr, pstr); if (*pstr == '\\') /* we must have at least X:\ */ strcpy(pstr+1, mask); } newlist = TRUE; break; default: drive = touchob - DRIVE_OFFSET; if ((drive < 0) || (drive >= NM_DRIVES))/* not for us */ break; if (drive == locstr[0] - 'A') /* no change */ break; obj = ((OBJECT *)tree) + touchob; if (obj->ob_state & DISABLED) /* non-existent drive */ break; strcpy(locstr, "A:\\*.*"); locstr[0] += drive; newdrive = TRUE; break; } if (!newlist && !newdrive && path_changed(locstr)) /* path changed manually */ { if (ad_fpath[0] != locstr[0]) /* drive has changed */ newdrive = TRUE; else newlist = TRUE; strcpy(locstr, ad_fpath); } if (newdrive) { select_drive(tree, touchob-DRIVE_OFFSET,1); newdrive = FALSE; newlist = TRUE; } if (newlist) { inf_sset(tree, FSDIRECT, locstr); set_mask(mask, locstr); /* set mask */ selname[1] = '\0'; /* selected is empty */ newsel = TRUE; } if (newsel) { strcpy(ad_fname, selname + 1); ob_draw(tree, FSSELECT, MAX_DEPTH); if (!cont) ob_change(tree, FSOK, SELECTED, TRUE); newsel = FALSE; } if (value) curr = fs_nscroll(tree, &sel, curr, count, touchob, value); } /* return path and */ /* file name to app */ strcpy(pipath, locstr); unfmt_str(ad_fname, selname); strcpy(pisel, selname); /* start the redraw */ fm_dial(FMD_FINISH, &gl_rfs); /* return exit button */ *pbutton = inf_what(tree, FSOK, FSCANCEL); dos_free((LONG)ad_fsnames); return( TRUE ); }
void disk_demo(void) { X_REGS16 ir,or; X_SREGS16 sr; char*dosptr; /* reset */ ir.h.ah = 0x00; ir.h.al = 0; ir.h.dl = 0; ir.x.di = 0; sr.es = 0; vm86_callBIOS(0x13, &ir, &or, &sr); message("reset finished.\n"); ir.h.ah = 0x08; ir.h.al = 0; ir.h.dl = 0; ir.x.di = 0; sr.es = 0; vm86_callBIOS(0x13, &ir, &or, &sr); if (or.x.cflag &0x01) { message("Failed to get the floppy drive parameters...\n"); return; } message("Drives: %d\n", or.h.dl); message("Drive Type: 0x%x\n", or.h.bl); message("Cylinders: %d\n", or.h.ch + ((WORD) (or.h.cl& 0xC0) << 2) + 1); message("Sectors: %d\n", or.h.cl & 0x3F); message("..."); #if 0 ir.h.ah = 0x04; ir.h.al = 8; /* Let's verify 8 sectors... */ ir.h.dl = 0; ir.h.ch = 0; /* Cylonder 0 */ ir.h.cl = 1; /* Sector 0 */ ir.h.dh = 0; /* Head 0 */ #else dosptr = dos_alloc(512); ir.h.ah = 2; ir.h.al = 1; ir.h.ch = 0; /* C */ ir.h.cl = 1; /* S */ ir.h.dh = 0; /* H */ ir.h.dl = 0; sr.es = DOS_SEG(dosptr); ir.x.bx = DOS_OFF(dosptr); #endif message("Read a sector:"); vm86_callBIOS(0x13, &ir, &or, &sr); message("Bytes: %s\n",&dosptr[0x36]); dos_free(dosptr,512); if (or.x.cflag &0x01) { message("failed...\n"); return; } message("Ok!!!\n"); }