Skip to content

m68kemu.library: loading, ExecBase, screens and bitplanes (runs SysInfo) - #1856

Open
terminills wants to merge 12 commits into
aros-development-team:masterfrom
terminills:m68k-2-loading
Open

terminills wants to merge 12 commits into
aros-development-team:masterfrom
terminills:m68k-2-loading

Conversation

@terminills

Copy link
Copy Markdown
Contributor

Depends on #1855 (included; review the last eleven commits).

  • copied seglists relocated with GSLI_68KRELOCS; native BPTRs (file handles, locks, seglists) map to 32-bit handles; ReadArgs results copied into the program's memory
  • every fake library base is a struct Library with the native version; FindName() on the fake ExecBase lists finds thunked libraries; OpenResource; manual thunk tables sized from their contents
  • a library is probed without a volume requester; m68k libraries without a native replacement are found in LIBS68K: (or SYS:Libs68k/), with the Resident found in any hunk; StackSwap
  • the program's screen gets real bitplanes behind it, mirrored onto the screen; LoadRGB4 count is a word; VBlankFrequency/PowerSupplyFrequency in ExecBase
  • gadgets translated, heap frees validated, FPU instructions trapped (the core is a 68LC040)
  • the module depends on the headers of the libraries it calls (a fresh tree failed on proto/log.h)

Every stage of this series builds for pc-x86_64 on current master. QEMU: SysInfo 4.4 from Aminet runs to its event loop, shows its panel and pages.

…RELOCS)

On a non-68k host LoadSeg() relocates a hunk file to the addresses of
its own segments and nothing can run it there; an emulator copies the
segments into its own memory and needs to relocate them again. Record
every 32-bit relocation the loader applies (hunk, offset, target, kind)
in the seglist's segdata node, in the same allocation, and hand the
table out through a new GetSegListInfo() tag. A failed allocation marks
the table lost rather than handing out a partial one.
A program that opens an optional library (LZX opens arp.library) made
the loader try LIBS68K:name with requesters enabled; with no such assign
dos put up "Please insert volume LIBS68K" and the program waited on it
forever. Turn requesters off for the three probes, as programs do.
…dArgs results

Three things a 68k program needs on a 64-bit host and did not get:

LoadHunks copied the segments dos had relocated to their host addresses
into containment without relocating them again, so every absolute
pointer pointed at host memory; a program without relocations was the
only kind that ran. Apply the list dos now keeps with the seglist
(GSLI_68KRELOCS), the exact inverse of what the loader did.

A native BPTR is a 64-bit pointer and the thunks moved it through 32-bit
registers; with memory above 4 GB a file handle lost its top half and
the first Write() took dos down. Hand the m68k side an index into a
per-context table instead (same native BPTR, same handle), in the
generator's bptr class and the manual dos thunks; Close/UnLock/FreeArgs
release the slot.

ReadArgs() filled the m68k array with native pointers: strings, /N
longs and /M string arrays the program could not reach. Copy them into
one containment block per call and free it in FreeArgs().
…d OpenResource

Each manual table's count was a literal; an added entry fell off the end
and the dispatcher took the generated thunk instead. OpenResource was one
of those generated thunks and returned a native resource base, a 64-bit
pointer the 68k side then called through. A resource the emulator does
not thunk now reads as absent, as a missing library does.
…he native version

A fake base was four bytes; a program reading lib_Version through it
read whatever followed. AROS's own startup compares dos.library's
version with the one the program was built against and exits with
RETURN_FAIL, so every AROS-built 68k command but Echo stopped after a
few instructions. Lay out a full struct Library behind the jump table
and copy the native library's version and revision into it.
…ed libraries

The lists in the fake ExecBase are empty. SysInfo looks expansion.library
up with FindName(&SysBase->LibList, ...) instead of opening it, assumes
the result and calls FindConfigDev() through it, so it jumped through
zero. Answer a lookup in LibList with the thunked base, setting it up on
demand as OpenLibrary() does; devices and resources still read as absent.
What a classic system-friendly program needs beyond library calls, found
by running SysInfo until it stopped asking for things:

- the fake graphics, intuition and dos bases carry their full m68k layout
  synced from the native library; OpenScreen/CloseScreen keep
  IntuitionBase.ActiveScreen/FirstScreen and GfxBase.ActiView pointing at
  the program's screen (SysInfo takes &ActiveScreen->ViewPort unchecked)
- the child process gets NP_Arguments, so ReadArgs on the transparent
  path sees the command line
- Supervisor() returns with the caller's own SR; a user stack exists
- the interrupt mask is lowered after reset; INTB_VERTB servers run as a
  level 3 autovector at 50 Hz from timer.device's E clock through a stub
  in low memory
- CIA-A and CIA-B are modelled from the same clock (ports, timers, TOD):
  SysInfo times its tests with CIA-A's TOD
- vectors 2-47 default to a stub that stops the program with a message;
  a MOVEC on a control register the core lacks (68040 TT/MMU) reads 0
  and is skipped by advancing the frame's PC before it is written
- PrintIText, DrawImage and DrawBorder translate their structures,
  byte-swapping plane words and coordinates; FindDisplayInfo hands out an
  opaque handle and GetDisplayInfoData copies DISP/DIMS/NAME field-wise
- GetVPModeID answers INVALID_ID for an unknown ViewPort; CloseDevice on
  a request the emulator did not create is ignored
- a program's screen opens in the Workbench's own mode and size (the VESA
  driver has one mode) and is painted once, since the driver pushes
  damaged regions only
- diagnostics (per-call trace, exception trail, instruction ring,
  vector-table write trap) stay in the code behind ctx->trace_calls

SysInfo 4.4 (Aminet util/moni) now opens its screen, draws its panel and
waits for input on pc-x86_64 SMP in QEMU.
…t as a word

Classic programs draw their frames and logos straight into sc_BitMap.
The screen shadow had no planes, so those writes went nowhere and the
panel came up as text on grey. Give the shadow real planes of the size
the program asked for and, on every byte or word the CPU writes into
them, recompose the touched pixels from all planes and put them on the
native screen with WriteChunkyPixels(); OS drawing and plane drawing then
compose the way they do on one set of bitplanes. The window RastPort's
rp_BitMap points at the same planes.

LoadRGB4() takes its count in D0.W; an assembler caller leaves the high
word dirty, the thunk read all of it and the palette never loaded.

Diagnostics come on with ENV:M68KEMU_TRACE instead of a rebuild.
…ions

Gadgets: AddGList/AddGadget handed the program's m68k-layout gadget list
straight to intuition. Each gadget is now copied into a native one with
its Image/Border renders, IntuiText and PropInfo; a map lets RefreshGList,
RemoveGList, ModifyProp, On/OffGadget find the copy and makes an
IntuiMessage's IAddress name the program's own gadget. Selected state and
prop pots are copied back after each message. SysInfo's buttons render as
bevels and its gadget-up messages arrive with the right gadget.

Heap: FreeMem() of a pointer the heap never handed out (SysInfo frees two
garbage pointers while tearing down a device request it never opened)
became the head of the free list, so every later allocation came from the
vector table. Frees outside the heap, with a bad header, or of a block
already free are now ignored.

FPU: Moira implements no FPU instructions; they throw a C++ exception that
never unwinds here and the emulator thread hung inside the instruction.
Run the core as a 68LC040, where F-line instructions take the Line-F trap,
and report a 68040 without FPU in AttnFlags.

Diagnostics: M68KEMU_TRACE=msg starts the trace at the first IntuiMessage;
with tracing on, a watchdog process reports the emulated CPU's position
every two seconds.
… ExecBase

Both read 0, and SysInfo divides its speed-test tick count by
VBlankFrequency: pressing SPEED stopped it with a divide by zero. The
emulator's vertical blank runs at 50 Hz; say so.
…y hunk, StackSwap

m68k libraries without a native replacement belong in LIBS68K:; when that
assign is not set the loader uses SYS:Libs68k/. LIBS:m68k/ and LIBS: are
still searched, but only a hunk file is taken from any of them: LIBS: also
holds the native libraries, which were read and rejected one by one.

The heap allocates top down, so a library's later hunks sit below its
first one and the Resident scan upward from the first hunk missed a
RomTag kept in the data hunk (AKCC's akccplus.library). Record the span
each load occupies and scan all of it.

exec StackSwap() exchanges the program's stack pointer with stk_Pointer.

The loader's informational lines move behind M68KEMU_TRACE.
The emulator includes the protos of log.resource, diskfont, commodities,
workbench and other libraries outside the kernel set; in a fresh build
tree it could be compiled before they were generated and failed on
proto/log.h.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant