diff options
-rw-r--r-- | Start.c | 134 | ||||
-rw-r--r-- | VBR.S | 49 |
2 files changed, 136 insertions, 47 deletions
@@ -25,6 +25,7 @@ ** 09-May-91 RHS RamDrive Grösse wird jetzt richtig gelesen ** ** 16-Jun-91 CHH TimerB Bug behoben. ** ** 16-Jun-91 CHW/CHH Läuft jetzt unter 2.0 ("chip memory" :-() ** +** 29-Jul-20 CHW Aufgeräumt, VBR und SaveChipMem repariert ** ** ** ****************************************************************************/ @@ -49,20 +50,23 @@ #include <chlib.h> extern void exit(long); -extern void kprintf(char *, ...); +extern void RawPrintfFunc(char *, ...); + +extern __regargs void *GetVBR(void); +extern __regargs void SetVBR(register void *vbr); extern struct ExecBase *SysBase; extern struct DosLibrary *DOSBase; extern BPTR StdErr; /* Standard Error output stream */ extern BYTE NewOS; -extern struct Custom __far custom; +extern struct Custom volatile __far custom; extern char ExecModuleStart,ExecModuleEnd; struct GfxBase *GfxBase; struct IntuitionBase *IntuitionBase; -char ident[] = "$VER: Exec V4.5 (" __DATE__ ") by Christian A. Weber"; +char ident[] = "$VER: Start V5.0 (" __DATE__ ") by Christian A. Weber"; char CLI_Template[] = "NS=NOSAVE/S,NF=NOFAST/S,CS=CHIPSIZE/N"; char CLI_Help[] = "Usage: Start [NOSAVE] [NOFAST] [CHIPSIZE size]"; struct @@ -102,16 +106,16 @@ ULONG radunit; /* Unit-Nummer der RAD-Disk */ UBYTE *fastbase; /* Startadresse des FAST-RAMs für Exec */ ULONG fastsize; /* Grösse des FAST-RAMs für Exec */ +struct Screen *screen; /* Wir öffnen einen Customscreen um Picasso- oder UAE-Screenmodes abzuschalten */ + UWORD dmaconsave,intenasave; ULONG attnflags,vblankfreq,sysbplcon0; -ULONG oldcacr,oldvbr; +ULONG oldcacr; +void *oldvbr; ULONG oldssp,oldusp; /* Gerettete Supervisor- und User-Stackpointer */ ULONG stacktop; /* Obergrenze des Chip-RAMs für Exec */ -ULONG GetVBR(void) { return 0; } /* Macht das Sinn?? */ -void SetVBR(ULONG vbr) { } - #ifdef DEBUG /***************************************************************************/ @@ -120,9 +124,9 @@ void SetVBR(ULONG vbr) { } local void Maus(UWORD col) { LONG i; - while((*(UBYTE *)0xbfe001)&0x40) + while((*(volatile UBYTE *)0xbfe001)&0x40) custom.color[0]=col; - while(!((*(UBYTE *)0xbfe001)&0x40)) + while(!((*(volatile UBYTE *)0xbfe001)&0x40)) ; for(i=0; i<200000; ++i) custom.color[0]=(UWORD)i; @@ -158,7 +162,6 @@ local void FreeChipRAMSaveBuffers(void) FreeMem(mc,mc->Size+sizeof(*mc)); } chipmemlist = NULL; - printf("Saved Chip-RAM = %ld bytes.\n",size); } @@ -170,7 +173,9 @@ local BOOL SaveChipRAM(void) struct MemHeader *mrh; struct MemChunk *mc; struct Mem *dc, *olddc = (struct Mem *)&chipmemlist; - ULONG last=0; + UBYTE *chipBlockStart = NULL; /* Retten von Adresse 0 an */ + ULONG size; + BOOL done = FALSE; if(!(mrh=(struct MemHeader *)FindName(&SysBase->MemList,"Chip Memory"))) { @@ -183,40 +188,50 @@ local BOOL SaveChipRAM(void) } } - for (mc = mrh->mh_First;; mc=mc->mc_Next) + /* Alle nicht freien Memory-Bereiche retten */ + for (mc = mrh->mh_First; !done; mc = mc->mc_Next) { - ULONG size; + /* Am Schluss muss noch der Bereich bis ans Ende des Chip RAMs gerettet werden */ if (mc == NULL) - mc = (struct MemChunk *)(SysBase->MaxLocMem - sizeof(*mc)); + { + mc = (struct MemChunk *)SysBase->MaxLocMem; - size = (ULONG)mc - (ULONG)last + sizeof(*mc); - if ((ULONG)last < (ULONG)mc) /* avoid crash on A4000 emu */ - break; + /* auf UAE mit 4MB Chip-RAM ist MaxLocMem dubioserweise $200000 statt $400000, dann sind wir fertig. */ + if ((UBYTE *)mc < chipBlockStart) + { + RawPrintfFunc("All done.\n"); + break; + } -#ifdef VERBOSE - kprintf("$%06lx-$%06lx (%lu bytes)", last, last+size-1, size); -#endif + RawPrintfFunc("mc is null, now saving from $%08lx to MaxLocMem ($%08lx)\n", chipBlockStart, SysBase->MaxLocMem); + done = TRUE; + + } - if (dc = AllocMem(size + sizeof(struct Mem), MEMF_FAST)) + /* Wir retten das RAM zwischen den mc-Bereichen und den mc selbst. */ + size = (UBYTE *)mc - chipBlockStart + sizeof (*mc); + + if (dc = AllocMem(size + sizeof(*dc), MEMF_FAST)) { #ifdef VERBOSE - kprintf("\t -> $%08lx\n", dc+1); + RawPrintfFunc("Saving $%06lx-$%06lx (%lu bytes) to $%08lx\n", chipBlockStart, chipBlockStart + size-1, size, dc); #endif - dc->Next=NULL; - dc->Address=(void *)last; - dc->Size=size; - CopyMem((void *)last,(void *)(dc+1),size); - last=(ULONG)mc+mc->mc_Bytes; - olddc->Next=dc; olddc=dc; - - if(mc==(struct MemChunk *)(SysBase->MaxLocMem-sizeof(*mc))) - break; + dc->Next = NULL; + dc->Address = (void *)chipBlockStart; + dc->Size = size; + CopyMem(chipBlockStart, (void *)(dc+1), size); + chipBlockStart = (UBYTE *)mc + mc->mc_Bytes; + olddc->Next = dc; + olddc = dc; } else { Enable(); //DisownBlitter(); - printf("Can't allocate %lu bytes FAST RAM\n",size+sizeof(struct Mem)); +#ifdef VERBOSE + RawPrintfFunc("Can't allocate %lu bytes FAST RAM to save $%06lx-$%06lx\n", size, chipBlockStart, chipBlockStart + size-1); +#endif + printf("Can't allocate %lu bytes FAST RAM to save $%06lx-$%06lx\n", size, chipBlockStart, chipBlockStart + size-1); FreeChipRAMSaveBuffers(); return FALSE; } @@ -235,10 +250,11 @@ local void KickResource(char *name) ciabase[0x29] = 0x7F; /* Alle Interrupt-Request-Bits setzen */ } + /***************************************************************************/ /* Alles freigeben, back to DOS */ -__saveds void ExitRoutine(ULONG D0, ULONG D1, void *A0, void *A1) +__saveds void __asm ExitRoutine(register __d0 ULONG D0, register __d1 ULONG D1, register __a0 void *A0, register __a1 void *A1) { int i; static char text[100]; @@ -273,7 +289,13 @@ __saveds void ExitRoutine(ULONG D0, ULONG D1, void *A0, void *A1) Enable(); RemakeDisplay(); - FreeChipRAMSaveBuffers(); /* Chip-SaveBuffer freigeben */ + if (screen) + { + CloseScreen(screen); + screen = NULL; + } + + FreeChipRAMSaveBuffers(); if (fastbase) { @@ -286,7 +308,7 @@ __saveds void ExitRoutine(ULONG D0, ULONG D1, void *A0, void *A1) *(UBYTE *)0xbfed01=0x82; - printf("Last message: %s\nD0=%08lx D1=%08lx A0=%08lx A1=%08lx\n",text,D0,D1,A0,A1); + printf("Exec returned: %s\nD0=%08lx D1=%08lx A0=%08lx A1=%08lx\n",text,D0,D1,A0,A1); CloseLibrary((struct Library *)IntuitionBase); CloseLibrary((struct Library *)GfxBase); @@ -325,7 +347,9 @@ int GetDriveVars(char *drive) } next: ; } - while(ldn=BADDR(ldn->dn_Next)); + + while(ldn=BADDR(ldn->dn_Next)) + ; Permit(); return found; @@ -363,7 +387,7 @@ radok: if(*(ULONG *)radmem == FFSMAGIC) /* 'DOS1' am Anfang ? */ { ULONG execentry; - kprintf("RAMDrive: $%08lx (%ldK)\n",radmem,radsize>>10); + RawPrintfFunc("RAMDrive: $%08lx (%ldK)\n",radmem,radsize>>10); usestacktop = stacktop = (ULONG)SysBase->MaxLocMem; @@ -377,22 +401,35 @@ radok: } } - kprintf("Chip RAM: $00000000 (%ldK)\n",usestacktop>>10); + RawPrintfFunc("Chip RAM: $00000000 (%ldK)\n",usestacktop>>10); + + + if (!(screen = OpenScreenTags(NULL, SA_Width,320, SA_Height,200, SA_Depth,1, SA_Type,CUSTOMSCREEN, TAG_DONE))) + { + Puts("Can't open screen!"); + ExitRoutine(); + } if(!argv.NoFast) /* Grössten freien FAST-RAM-Block reservieren */ { if(fastsize = AvailMem(MEMF_FAST|MEMF_LARGEST) & ~0xff) { + /* Platz lassen für gerettetes Chip-Ram und 10K Reserve */ fastsize -= (stacktop-AvailMem(MEMF_CHIP)+10000); + + /* Mehr als 2MB Fast-RAM gibt's nicht. Sei sparsam! */ + if (fastsize > 2000000) + fastsize = 2000000; + if((fastsize >= 10000L) && (fastbase = AllocMem(fastsize,MEMF_FAST))) { - kprintf("Fast RAM: $%08lx (%ldK)\n",fastbase,fastsize>>10); + RawPrintfFunc("Fast RAM: $%08lx (%ldK)\n",fastbase,fastsize>>10); } else { - kprintf("Not enough FAST RAM available (largest: %ld)", fastsize); - fastsize=0; + RawPrintfFunc("Not enough FAST RAM available (largest: %ld)", fastsize); + fastsize = 0; } } else Puts("No FAST RAM available."); @@ -418,7 +455,8 @@ radok: if(!argv.NoSave) /* CHIP-RAM retten */ { - if(!SaveChipRAM()) return RETURN_ERROR; + if(!SaveChipRAM()) + return RETURN_ERROR; } else Puts("CHIP RAM will not be saved."); @@ -430,14 +468,18 @@ radok: oldssp = (ULONG)SuperState(); /* Supervisor-Mode auf Userstack */ putreg(REG_A7,usestacktop-80); /* Neuer Supervisor-Stackpointer */ + RawPrintfFunc("Superstate initiated. New SP=$%08lx\n", usestacktop-80); + custom.intena = 0x7FFF; /* Interrupts sperren */ custom.dmacon = 0x7FFF; /* Und DMA auch */ - custom.color[0] = 0x400; /* Bildschirm dunkelrot */ #if 0 memset(NULL,0,usestacktop); /* CHIP-RAM löschen */ #endif + /* GameExec installieren an Adresse 0 */ + RawPrintfFunc("Installing GameExec (%ld bytes)... ", &ExecModuleEnd-&ExecModuleStart); memcpy(NULL,&ExecModuleStart,&ExecModuleEnd-&ExecModuleStart); + RawPrintfFunc("done.\n"); for(execentry=0; *(ULONG *)execentry!=INITMAGIC; execentry+=2) /* Entry suchen */ ; @@ -459,18 +501,16 @@ radok: register void (* __asm init)( register __d0 LONG, register __d1 LONG, register __d2 LONG, register __d3 LONG, - register __d4 LONG, register __a0 void *,register __a1 void *, register __a2 void *,register __a3 void *); - kprintf("\n%s: Running Exec at $%08lx ...\r\n", ident+6, execentry); + RawPrintfFunc("\n%s: Running Exec at $%08lx ...\r\n", ident+6, execentry); init = (void *)execentry; init( attnflags, /* D0 */ sysbplcon0, /* D1 */ vblankfreq, /* D2 */ - 0, /* D3 : Product-Code */ - (LONG)"MainPrg", /* D4 : MainPrg-Name */ + (LONG)"MainPrg", /* D3 : MainPrg-Name */ radmem, /* A0 : RAD-Startadresse */ (void *)radsize, /* A1 : RAD-Grösse */ fastbase, /* A2 : FAST-Startadresse */ @@ -0,0 +1,49 @@ + IDNT VBR + SECTION text,CODE + + INCLUDE "exec/execbase.i" + + MACHINE MC68010 + + + XREF _RawPrintfFunc + + XDEF @GetVBR,@SetVBR + +@GetVBR: movem.l d1/a0-a1/a5/a6,-(SP) + moveq.l #0,d0 ; Default-Resultat + lea GetSupie(PC),a5 + bra.s CommCont + + +@SetVBR: movem.l d1/a0-a1/a5/a6,-(SP) + lea SetSupie(PC),a5 + +CommCont: movea.l 4.W,a6 + btst.b #AFB_68010,AttnFlags+1(a6) ; 68010 oder neuer + beq.s 1$ ; nein ---> + jsr -30(a6) ; Supervisor ; Get/Set VBR +1$: + movem.l (SP)+,d1/a0-a1/a5/a6 + rts + +GetSupie: movec.l vbr,d0 + move.l d0,-(SP) + pea GetText(PC) + bsr _RawPrintfFunc + addq.w #8,SP + rte + +SetSupie: movec.l a0,vbr + move.l d0,-(SP) + pea SetText(PC) + bsr _RawPrintfFunc + addq.w #8,SP + rte + + +GetText: dc.b "GetVBR -> $%08lx",10,0 +SetText: dc.b "SetVBR($%08lx)",10,0 + + + END |