2068 Print Command Compiler

Authors

Publication

Pub Details

Date

Pages

See all articles from SyncWare News v2 n5

Machine code (MC) programming is fantastic for writing programs that move fast, and is essential for programs that must move or sort a large amount of data or move it in a way that causes smooth action on the screen, such as a moving graphics game.

Before I lose the readers who would like to program in machine code, but have been afraid to try, let me say two things:

  1. if you can start with an idea and turn it into a BASIC program, YOU CAN LEARN TO PROGRAM IN M/C, and
  2. if you are leery of trying, you can rest assured that there is no program that you can enter into your computer that will cause a permanent problem. ALL program crashes can be “fixed” with the power switch or reset button, so don’t be afraid to experiment.

Assembly language is the ideal method for programming MC on the Timex, but some other languages allow you to write using BASIC-like words, which are then converted to machine- code before running. This lets you work in a high level language, but the program runs with the faster speed of the lower level language. (Such is the case with BASIC compilers, like the one available from JRC Software, which I have used with good results, and languages such as PASCAL and FORTRAN.)

No matter which way you decide to go (and it is quite acceptable to mix the methods), it is beneficial to know how to use ROM calls. These are routines in the computer’s BASIC operating system which you can use from within your own program. As a result, you don’t “re-invent the wheel.” For those TS2068 owners who are interested, but have not noticed the enticing menu of ROM call “goodies” in Sync Ware News Vol. 2, No. 1, I call them to your attention and recommend that you study them.

This article addresses itself to one of the calls in particular; the PRINT routine at 2159h (8537d). The author, Ray Kingsley, points out the fact that you can put the message in memory, point the system variable CH_ADD to the location of the start of the message, and call the PRINT routine. He also very helpfully mentions that if you can get the floating point form of the numbers that you use (e.g. AT 3,5; or FLASH 1; etc.) into the memory area in the same form as it is in the PRINT statement, then the AT, TAB, INK, PAPER, etc. instructions will work as well.

Note also that BASIC variables will work (e.g. TAB x) if the variable is defined before the PRINT routine is called. Also, since all of the instructions associated with PRINT use integer numbers less than 255, you can use a command like PRINT FLASH PEEK 40000. You must pre-set location 40000 (or wherever you choose) from inside your MC program before calling the PRINT routine.

The following program will allow you to enter PRINT statements in any line from 1 to 999, one PRINT statement per line. RUN 1000 will then compile your PRINT statements into machine code using a ROM call. The program will first ask you to where you want the code located, and then place into memory an 18-byte driver routine (explained later). This is followed by the message AT/TAB/PAPER etc., and then a report of the memory location to call for the PRINT work which was contained in the line. The line number of the source line is also displayed.

1000 LET get=PEEK 23635+256*PEEK 23636: REM prog
1010 INPUT "ENTER start address.";put
1020 IF PEEK (get+4)<>245 THEN PRINT "The last address used was ";put-1: STOP
1030 PRINT " LINE ";(256*PEEK get+PEEK (get_1));"starts AT ";put
1040 LET p1=put+18: DATA 42,93,92,229,33,p1-(INT (p1/256)*256),INT (p1/256),34,93,92,205,89,33,225,34,93,92,201
1050 RESTORE 1040: FOR r=1 TO 18: READ x: POKE put,x: LET put=put+1: NEXT r
1060 LET get=get+5
1070 IF PEEK get=14 THEN FOR r=1 TO 6: POKE put,PEEK get: LET get=get+1: LET put=put+1: NEXT r
1080 IF PEEK get=13 THEN POKE put, PEEK get: LET put=put+1: LET get=get+1: GO TO 1020
1090 POKE put,PEEK get: LET put=put+1: LET get=get+1: GO TO 1070

The routine is shown in listing 1, and operates as follows:

  1. 1000 – Gets the start of the program area where the PRINT statements are located 1010 – Tell the computer where to put the code 1020 – If the first token word is not a PRINT (CHR$ 245) then stop the program.
  2. 1030 – Display the line # and the memory location to call.
  3. 1040 – Set pi to the current value of PUT+18 (just past the driver routine) and also the DATA for setting up the driver. Notice that formulas and variables are legal in a DATA statement.
  4. 1050 – Start DATA at line 1040, POKE the 18 bytes of machine code.
  5. 1060 – Jump over the bytes with the line # (2), line length (1), and the PRINT (1 byte).
  6. 1070 – If the “get” byte is the numbers slug, then POKE the next 6 bytes.
  7. 1080 – If the “get” byte is the END OF LINE (ENTER) character, then POKE the ENTER and start the next BASIC line.
  8. 1090 – If not, POKE the “get” byte and go look at the next one.

The 18 bytes of the driver for each PRINT statement are much like Mr. Kingsley suggested, except it starts by getting the current value of CH__ADD (in this case 60018 if the driver code starts at 60000), call the PRINT routine, put the old CH__ADD value back and then return.

In order to preserve the original CH_ADD value as this system does, your machine code must CALL the address that is shown on the screen, instead of JPing to it. The CH_ADD variable may be changed to any value you like as long as you stay in machine code, but MUST be restored to its initial value if your program ever returns to BASIC.

ADDR  WRITE    LABEL     MNEMONIC
================================END=8000
EA60 2A535C LD HL,(prog)
EA63 E5 PUSH HL
EA64 2172EA LD HL,EA72
EA67 CD5921 CALL 2159
EA6A E1 POP HL
EA6B 22535C LD (prog),HL
EA6E C9 RET

Products

 

Downloadable Media

 
Scroll to Top