Thus it was possible to write a program using the following steps:
1. Write out the Z80 assembly code
2. Convert to opcodes
3. Look up the opcodes in the character map and type the appropriate character on the screen starting at top left
Then you could execute the program by calling screen memory (which was possible from BASIC).
Happy days.
Similarly this made the inclusion of machine code in BASIC programs possible. I would optimize BASIC programs by including machine code subroutines stored as characters in REM statements. It wasn't hard to find those REM statements in memory (as the program was loaded in a fixed location) and call subroutines in the REM statements to speed things up.
IIRC correctly I used the same machine code in REM statement trick on the Research Machines 480Z (http://en.wikipedia.org/wiki/LINK_480Z) but this involved non-printing characters and thus it was not possible to LIST the entire program and so I typically stored all the machine code in lines numbers less than 100.
Which reminds me. On the 480Z there was an 800kbps network using coax. A friend and I disassembled the BIOS and reverse engineered the API (a software interrupt) used for sending and receiving data which enabled us to send arbitrary packets of code to any machine running our interrupt handler.
The receive buffer was only 128 bytes, so we would send the machine code in the packet and the receive handler would execute the packet inside the receive buffer. Amazing how much stuff you can do 128 bytes at a time. We wrote a network management package that used this functionality.
More recently, the JailbreakMe iPhone jailbreak used the screen to store the kernel shellcode, since the framebuffer was in a known memory location in both the kernel and userland.
Thus it was possible to write a program using the following steps:
1. Write out the Z80 assembly code
2. Convert to opcodes
3. Look up the opcodes in the character map and type the appropriate character on the screen starting at top left
Then you could execute the program by calling screen memory (which was possible from BASIC).
Happy days.
Similarly this made the inclusion of machine code in BASIC programs possible. I would optimize BASIC programs by including machine code subroutines stored as characters in REM statements. It wasn't hard to find those REM statements in memory (as the program was loaded in a fixed location) and call subroutines in the REM statements to speed things up.
IIRC correctly I used the same machine code in REM statement trick on the Research Machines 480Z (http://en.wikipedia.org/wiki/LINK_480Z) but this involved non-printing characters and thus it was not possible to LIST the entire program and so I typically stored all the machine code in lines numbers less than 100.
Which reminds me. On the 480Z there was an 800kbps network using coax. A friend and I disassembled the BIOS and reverse engineered the API (a software interrupt) used for sending and receiving data which enabled us to send arbitrary packets of code to any machine running our interrupt handler.
The receive buffer was only 128 bytes, so we would send the machine code in the packet and the receive handler would execute the packet inside the receive buffer. Amazing how much stuff you can do 128 bytes at a time. We wrote a network management package that used this functionality.