A recent post has got me thinking about things I used to do and either cannot or don't do any more.
I think it would be a good idea to document some of them to let the younger generations see what we had to do.
When I first started I didn't have an assembler, hell I hadn't even heard of an assembler, I worked in machine code. Most of the time this was fine, you didn't have a whole lot of instructions to memorise, it was just relative branches that were a problem. You had to count the number of bytes by hand. I can still remember some instructions.0xA0 = ldy # 0xA2 = ldx # 0xA9 lda #
Self modifying code
When I started working on the Atari ST I hated the layout of the graphics display. Drawing lines etc was slow because of it, so my line draw used self modifying code. The idea was simple, use the line colour to create the draw pixel code inside the inner loop, so you do a few extra instructions outside the loop, then the inner loop is as fast as it can be. Oh and yes we had to write code to draw things. We didn't just call a function. We had to know things like Bresenham's line draw and circle draw algorithms and implement then ourselves.
Yes real programmers use goto's :> My AI routines were very complex and I found that calling separate routines was slow and cumbersome. I came up with a way of modularising the code into code blocks of the same length. Using a bit pattern I could then create complex routines as a serious of pseudo opcodes encoded into a bit patterm. A bit was set add this value to the pc, a bit was unset add this value to the pc. This was particularly good in the early x86 machines as stack operations on these chips were awfully slow.
Multiplies and divides were slow....really slow. So we did everything we could to avoid them. We would use relationships like sin(A + B) = sinAcosB + cosAsinB to reduce the number of multiplies in a matrix operation. When the matrix was finally fully formed we could use other tricks to remove multiplies.
Take each term in the matrix and shift it down (divide it by two) store it in an array, repeat. Then 12 * matrix[0,0] reduces to matrix[0,0,8] + matrix[0,0,4] replacing a multiply with an addition.
There were so many maths cheats we would need a whole book to list them.
A friend of mine hated subroutines, as far as he was concerned pushing an address onto the stack, modifying pc, popping an address, modifying pc...... hell what a waste of time. He wrote macros and strung them together. At the end of the program there was a single jump instruction. The only one in his code. Which went back to the start of the program.
Early chips often had opcodes that simply weren't listed in the docs. You would notice a gap in the instruction set and wonder why, so you found out. You wrote a test to see what the instruction did. Often they were useful, but it did take a lot of experimentation to tie down EXACTLY what they did. The z80 was the undisputed king for undocumented features. There were more undocumented opcodes than documented ones!
A good programmer always had a couple of pieces of tape on the side of his TV. When you were working on a routine you would change the border colour just before it, then change it back after the routine had finished. Since we know the time it takes to update the TV screen, we know how long a single scan line on the TV takes to display, so we know how long the routine took.
Handy stuff tape.
Anybody else got any stories