This sort of stuff used to be really common. When I first started programming on networks we were using something called Z-NET (800kbps running over coax[1]). The receive buffer was 128 bytes long.
Myself and another school boy wrote enough of a connection based networking system that we could reliably send about 100 bytes of data into that receive buffer. By having our 'protocol stack' then CALL the buffer itself we would execute the code that we had just sent (i.e. the machine code).
Building up from 100 byte chunks we built a network monitoring and management system which allowed things like screen mirroring, chat programs, taking control of the keyboard and broadcast functionality. The entire thing was written in assembly language.
The actual protocol stack was loaded into a part of the BIOS of the machine that was unused and we just grabbed a bunch of NOPs and over wrote them. In the end Research Machines were kind enough to send us the spec. of Z-Net (which they considered somewhat secret) as we'd already reverse engineered the entire thing by disassembling the operating system.
For the people who do not have CONFIG.SYS / DEBUG.COM / MASM kung-fu , please do not give up.. Google, wiki and read up. The journey will be fascinating.
Put your lenses on for jump-offs produced by Google on keywords TSR and LIM EMS for further mind-bending fun.
For more about the redirector interface specifically, look up the sub-functions of AH=11h and AH=12h of INT 2F. Originally undocumented, this blog article mentions why they were designed the way it is.
Kids, I am old enough to have written a DOS TSR in 8086 assembler! Sadly, you likely have no idea what I'm talking about. Suffice to say, I understand this article completely.
Hey, you and me both, brother! Some of the most fun I've had programming was writing an assembly TSR that would scrape the screen buffer of the PAL BBS game Flash Attack (I think that was name of it, anyway) to calculate the firing angles for me.
I also tied into the keyboard hooks so that I could build an entire decoy base with a single key press (just some simple buffer stuffing) along with a cool little "death blossom" attack.
I am 29 now. Guilty of the crime of TSR at 13. I officially declare everyone who's commenting on this thread brothers including the brave soul who visited us from the world of Ruby.
My first professional coding job was to write a DOS TSR for a modem driver. It was the first TSR I wrote, worked well, and .. set me off on over two decades of experience in embedded systems and now mobile development.
Without the pain of INT13 behind me, I doubt I'd have gotten so far.
It makes more sense when you know that 'A20 line' stands for '20th address line', and 2^20 (two to the 20th power) is one megabyte, so you need 20 bits to give unique addresses to all of the bytes in one megabyte.
Since those lines start counting at A0, it's the 21st bit.
The thing is, with 20 bits you can address one megabyte, but without a 21st line, any calculated offset (be it indirect addressing or, more commonly, segments) will roll over.
For compatibility with some ancient programs that exploited the rollover (access 0xfffff+0x400 -> 0x3ff), 80286+ gained the "A20 Gate", which allows to simulate the rollover effect (by always forcing A20, the 21st line, to 0) or not (in which case you can go above 1MB using offsets).
Note that the A20 Gate is only active in 16bit modes, otherwise even more fun trickery becomes possible (since half the 32bit accesses with A20 pulled low would change, too)
This was a fun read, and what is scary is how much of this memory is fresh as newly plucked fruits with uncounted boxes full of APIs that have long gone to dust sitting besides it.
I miss DJGPP. When I was first learning C back in the days when DOS ruled my world, DJGPP is almost invariably what I used. I clicked the "by DJ Delorie" link on his page and saw that he now works for Redhat working on GCC. Strange or not, that continuity brought a smile to my face.
Also found this quote on the History of DJGPP page: DJGPP was born around 1989 (originally called djgcc), when Richard Stallman spoke at a meeting of the Northern New England Unix Users Group (NNEUUG) at Data General, where I then worked. I asked if the FSF ever planned on porting gcc to MS-DOS (I wanted to use it to write a 32-bit operating system for PCs), and he said it couldn't be done because gcc was too big and MS-DOS was a 16-bit operating system. Challenge in hand, I began.
Well... I don't want to brag much about it, but on the Apple II+ (I relied on rotines in ROM and it wouldn't work on a plain II) I did a "window stacker" in about 1K of 6502 code... People used it for dialog boxes.
Neat stuff -- note that the Linux kernel (and probably others, I'd guess) uses a similar technique to tag code/data that's only used during initialization. It gets put in a dedicated section of the kernel (or module thereof) that's discarded once it's up and running so it can reclaim some space. (See include/linux/init.h in the kernel source tree.)
Myself and another school boy wrote enough of a connection based networking system that we could reliably send about 100 bytes of data into that receive buffer. By having our 'protocol stack' then CALL the buffer itself we would execute the code that we had just sent (i.e. the machine code).
Building up from 100 byte chunks we built a network monitoring and management system which allowed things like screen mirroring, chat programs, taking control of the keyboard and broadcast functionality. The entire thing was written in assembly language.
The actual protocol stack was loaded into a part of the BIOS of the machine that was unused and we just grabbed a bunch of NOPs and over wrote them. In the end Research Machines were kind enough to send us the spec. of Z-Net (which they considered somewhat secret) as we'd already reverse engineered the entire thing by disassembling the operating system.
[1] http://en.wikipedia.org/wiki/Link_480Z#Z-Net