For you Amiga fans out there (yes, I had one, too (is that a confession?)).
The attached pictures show the "Guru meditation" that I implemented on the Geneve. You can see on the first picture that the program is loaded; then I load the word 0000 to address A000, then I poke the A000 address into the interrupt hook so that this location is executed on the next interrupt.
This is my original text that - if I remember correctly - was published in one issue of Micropendium.
The GURU MEDITATION
Author: Michael Zapf
Suppose you want to write some machine language programs. Normally, it takes several passes until the program finally assembles - after having found the last syntax error. After the first "0000 ERRORS" you load and run it with great expectations ... and nothing happens, at least not what you wanted the program to do. Now, if you are lucky, you can press QUIT (or CTRL-ALT-DEL) for a "warm" boot, and maybe the program is still standing in the RAM so that you can PEEK it via TI BASIC. Otherwise you have to turn your computer off and back on, losing your program in memory.
If you are using a Geneve, there is another threat not experienced by the standard TI user: System kernel RAM locations can be affected so that you cannot reset your computer any more, let alone debug your program. The reason for this is that the program counter is loaded with an unexpected address, and the execution is transferred to a part of memory which probably does not contain executable code. This happens when - subprograms are not terminated correctly (RTWP instead of RT or vice versa)
- subprograms are not called correctly (BLWP instead of BL or v.v.)
- array bounds are exceeded (especially with a list of addresses)
- return adresses are lost or incorrect (forgotten DATA after BL)
- and many more.
One of the TMS9995 processor's most powerful features is the MID flag which is not used, however, by the operating system. Whenever the processor encounters a word that is to be executed but does not represent a valid command, it generates an interrupt of level 2 which is not maskable by LIMI. The interrupt service routine can check the CRU flag 1FDA: It is set when an illegal command has been encountered. The abbrevation MID means "macro instruction detect" which reveals another usage for this feature. Currently, the MID flag is simply cleared by the interrupt service routine.
The following program is intended for the Geneve in GPL mode with standard Editor/Assembler and standard GPL interpreter. Newer versions may require changing of the absolute addresses in GROM or RAM. Assemble this program and load it via LOAD AND RUN once; it remains installed until you clear the memory completely or reload the GPL interpreter. Now take the source code of one of your programs and put a DATA >0000 right into the program text. If you run this bugged program the execution will halt right at this position and the computer will inform you that an error has occured, giving you the values of the WP, PC and ST registers. Press the left mouse button to return to the master title screen; your program remains unchanged. This early execution break can prevent your computer from totally disturbing the memory, but there is surely no guaranty that the computer will not hang. This program was inspired by the "Guru meditation" message of the Commodore Amiga which is more detailed, however.
*** GURU MEDITATION ***
* on Geneve 9640 in GPL Mode
* Version 1.1
* March 14, 1991
* Michael Zapf
* Put this utility in an unused RAM space
TEXT1 TEXT 'Software failure. Press'
TEXT ' left mouse button to continue.'
TEXT2 TEXT 'Guru meditation #'
HEXD TEXT '0123456789ABCDEF'
POINT TEXT '..'
* VDP register settings
VDPREG DATA >8004,>8170,>8203,>8347
* Check MID flag. If not active, return.
START LI R12,>1FDA
START1 SBZ 0 * Clear flag
* Set VDP registers to defined values
LOOP1 MOV *R1+,R0
* Clear the screen
LOOP MOVB R1,*R5
* Load upper and lower case character set
* from GROM to VDP (R5 is VDPWD)
* (to repair probably destroyed character definitions)
* Note: The characters are stored by seven bytes in GROM
* so that a 00 must be inserted before each definition.
LI R0,>06B4 * GROM position
LI R0,>4900 * VDP position
LI R3,96 * No. of characters
JL MOVB R1,*R5 * Insert 00
IL MOVB @>9800,*R5 * Copy seven bytes
* Write texts on screen
* Write values of R13,R14,R15 on screen.
* R3 will be used as a pointer to the RAM location
* of these registers (starting at >83DA).
* R5 is still >8C00 (VDPWD).
* Use the character list HEXD to transfer the nybbles
* (half bytes) to the corresponding ascii char.
DISP MOV *R3+,R4
LI R2,4 * four nybbles per word
LD SRC R4,12 * shift to rightmost nybble
ANDI R1,>000F * mask it
MOVB @HEXD(R1),*R5 * Write char to VDP
DEC R6 * next register
MOVB @POINT,*R5 * Print a "."
FRAME BL @CLRBLK * Clear blink attributes
LI R2,6 * Six rows
LI R0,>5009 * Step forward to columns 72+
* Set blink attribute of columns 0 and 79
* of six consecutive rows
F1 BL @SETADR
MOVB R1,*R5 * column 79
MOVB R1,*R5 * column 0
AI R0,10 * next row
* Set blink attribute of every column in the first row
F2 MOVB R1,*R5
* Set blink attribute of every column in row 6
F3 MOVB R1,*R5
* Check the left mouse button. If depressed, stop blinking
* and return to the master title screen.
MLOOP LI R12,>0038
* Standard routine to set a VDP address.
* Note: Add >4000 for writing to the address
SETADR SWPB R0
* Write the text on screen defined by the following three words:
* DATA screen pos, RAM pos, length
WRITE MOV *R11+,R0
WL MOVB *R1+,*R5
* Initialize the blink attribute table (VDP >1000)
* by writing 00 in all positions
CLRBLK MOV R11,R10
* Paste the B @START into the interrupt routine
* of the console ROM (which is RAM on the Geneve)
* replacing the clearing of the MID flag.
* Normal execution will resume at >035E (see above).