Original hardware back then had very little capability. You could store multiple screens of pixels in video memory, which allowed for double-buffering, but that's about it. If you're interested in reading all about it, you can check out one of the EGA/CGA/VGA programming books, many of which are readily available online for free (e.g. see this book EGA/VGA: A Programmer's Reference Guide).
There were no sprite capabilities written into the hardware, so the software was responsible for drawing the sprites. Most games were written with a double buffer scheme, either in main memory or video memory. For main memory, an area of memory was dedicated for storing the next frame's pixels, and then blitted using something like REPZ MOVS, which was a relatively fast string copy command (about 3 + pixel count clock cycles). For video memory, the next frame is drawn in the video buffer, then the page offset was changed to flip pages; this method was the ideal method for maximum performance, since you saved tens of thousands of clock cycles by not having to blit every frame.
So, during startup, the game would load the sprite data into memory, and each frame, it would draw the background, then each sprite, using either an image mask or a "transparent" color (typically 0, but it was programmer's choice, since it's all in software), then halt for a vsync signal before using an efficient string copy command to avoid screen tearing (where you'd see parts from two different frames), or a page flip, whichever was appropriate, then go back to the start of the loop to handle the next frame.
The graphics memory is laid out in a straight line as far as memory addresses are concerned, so it was necessary to figure out the coordinate for where each pixel was via x times screen width plus y. On really old processors, this was too slow to perform millions of times per second, as multiplication was hideously expensive in clock cycles, so programmers often had to resort to something like:
pixel = (x << 6) + (x << 8) + y
<< is the shift-bit-left operator. Three adds and two shifts could be done in 10 clock cycles, while a single IMUL took at least 80 clock cycles. This is the difference between 60 frames per second and about 10, just optimizing pixel placement code. A lot of games were written in assembler back then, or at least the video graphics parts, simply because there were only so many clock cycles to go around, and compilers back then were quite literal (today's compilers can optimize nearly as well, or better than, most human programmers).
At any rate, if you're interested in seeing what CGA programming looked like, you could check out some open-source software, such as this repository that includes a ton of CGA code. GitHub has topics for CGA, EGA and VGA, which contains at least a few interesting source codes you might want to check out.
Most commercial games never released their source code, so it can be hard to track down specific examples. That said, you can also try your hand at disassembly/decompilation. Modern tools of this nature produce at least somewhat legible code, especially for binaries that are that old, assuming you can get your hands on the original executable somehow. There are abandonware sites you can look for that host games from companies that no longer exist as well. Using disassembly tools on those would likely be enlightening, most of the software back then was relatively small in size and pretty easy to read with some practice.