home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.tar / ftp.whtech.com / Geneve / 9640news / CAT14 / RDWRTG.ARK < prev    next >
Text File  |  2006-10-19  |  19KB  |  515 lines

  1. ?
  2.                      A Graphics Programming Language (GPL)
  3.                                     Primer &
  4.                       Routine to Read/Edit Text from KSCAN
  5.                             by Mack McCormick
  6.  
  7.           I have always avoided delving into the study of GPL because I felt
  8.      it was too difficult, cumbersome, executed too slowly, and had little
  9.      to offer.  Boy, was I wrong.  It makes writing routines used by BASIC a
  10.      snap in assembler.  For example, I recently needed a routine to read
  11.      text from the screen which would allow full editing including erase,
  12.      insert, delete, quit, bonk tone at right margin, and enter/up
  13.      arrow/down arrow.  I also wanted the neat auto-repeat feature used by
  14.      TI where there is a slight pause before the key takes off repeating.  I
  15.      began to consider writing the routine but then remembered that an
  16.      identical routine resided in GPL in GROM (Graphics Read Only Memory) in
  17.      the console.  I first consided using the routine from GROM but then
  18.      remembered that it added the screen offset of >60 to each character and
  19.      I didn't need that.  I could have done some fancy trick to make it work
  20.      but decided to convert GPL to 9900 assembler code.
  21.  
  22.           You'll find two programs here.  One to link you to the routine in
  23.      console GROM from a CALL LOAD from E/A BASIC and the identical (almost)
  24.      routine in 9900 assembler code ready to link into any program you may
  25.      have that needs this utility.  I've included in the 9900 routine the
  26.      actual GPL code used by the Pre-Scan routine of the monitor so you may
  27.      see what conversions were necessary.  Try reading the GPL instructions
  28.      (marked with three *) to get a flavor for GPL).  If the GPL gets in the
  29.      way if using the routine in your program you may delete the GPL
  30.      statements though they will have no effect if they remain.
  31.  
  32.           It has really become obvious to me why TI invented GPL though I
  33.      used to condem them for it.  The major reason is that it saves about
  34.      41% more code than straight assembler.  GROM as you may know is only
  35.      used by TI and is a chip which supplies a byte at a time to a memory
  36.      mapped address and auto-increments to the next byte (like VDP RAM)
  37.      unless you change the address to be read from.  It's a great way to
  38.      save memory.  TI calls it medium speed memory.  It is 6K bytes big and
  39.      resides on 8K boundaries.  It is an ideal medium to hold the console
  40.      BASIC routines because the TMS9900 CPU chip in the console can only
  41.      directly address 64K.  The GPL actually does not execute any code.  GPL
  42.      is interpreted in console ROM beginning at >0024 and extending to >D18.
  43.      This interpreter is straight assembler code which acts as directed by
  44.      the GPL bytes coming from the GROM.  Hence you see one reason TI BASIC
  45.      is slow.  It is an interpreted by GPL and GPL is interpreted by
  46.      assembler.  Two interpretations! Instructions in GPL usually have two
  47.      operands and most instructions can access RAM, GROM, or VDP RAM.  Most
  48.      instructions are single byte operands unless the operand is preceded by
  49.      a D for double operand.  GPL uses two stacks a data stack at >83A0 and
  50.      a subroutine address stack at >8380 (this allows arbitrary nesting of
  51.      subroutines).  Here are a few types of instructions:
  52.      DATA TRANSFER -Single/Double Byte
  53.      -Block to Block
  54.      -Formatted Block Moves
  55.      ARITHMETIC -add, subtract, multiply, divide, negate, absolute val.
  56.      LOGICAL -AND, XOR, Shifts.
  57.      CONDITION -Arithmetic and Logical
  58.      BRANCHING -Conditional/Uncond
  59.      BIT MANIPULATION -Set, reset, test.
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.      SUBROUTINE -Call, Return
  67.      STACK OPNS -Push and Pop
  68.      MISC -Random Number, KSCAN, Coincidence Detection, Sound, I/O
  69.           The closest language to GPL is assembler and any experienced
  70.      assembler programmer should have little difficulty learning GPL.  One
  71.      major difference is the use of MACRO instructions by the assembler such
  72.      as REPEAT....UNTIL and IF....THEN....ELSE.  Very similar in this
  73.      respect to 99000 assembly language.
  74.           A few words about how memory is addressed.  Here are a few of the
  75.      most common ways and their syntax.  5 represents the decimal byte 5.
  76.      >33 represents hex 33.  &110011 represents binary 110011.  #5506
  77.      represents the decimal number 5506.  :A: is the ASCII equivalent >41.
  78.           Well this has been a *very* general overview of GPL.  Let's look
  79.      at some actual GPL source code and my intrepretation of the 9900
  80.      assembler equivalent.  This routine could have been shortened but I
  81.      tried to keep it as close to GPL as possible.  Hope you enjoy it.  If
  82.      you have questions just ask.  My 6 GPL manuals cover thousands of pages
  83.      and we have just skimmed the surface here.  I plan to write a GPL
  84.      disassembler and interpreter to convert GPL to 9900 object code within
  85.      the next six months if my schedule permits.  That should make the job
  86.      easy!
  87.        DEF  START
  88.        REF  KSCAN,VSBW,VSBR,GPLLNK
  89.  
  90. * JUST A LITTLE ROUTINE TO TEST SUBROUTINE *
  91. START  LWPI WS
  92.        MOVB @H00,@KEYVAL SCAN ENTIRE KEYBOARD
  93. LOOP   BL   @READLN
  94.        DATA >002,>2FE    START, END POSITONS
  95.        JMP  LOOP
  96.  
  97. ********************************************************************************
  98. * This is the console GPL READLN routine at (>2A42 in GROM 1) converted to 9900
  99. * assembler. Interprets BACKSPACE, INSERT, DELETE, and FORWARD. Uses SCRATCH
  100. * PAD RAM. Total number of characters may be limited by changing the start
  101. * value of ARG+2 (upper limit) and entering at READL1. VARW is the start address
  102. * of the field. VARA is the current highest write address.
  103. * Entering at READL1 allows us to pre-specify the minimum number of characters
  104. * to be read for default creation.
  105. * Entering at READ00 allows specification of the initial cursor position. In
  106. * this case ARG+6 has to be set to the cursor position and ARG+4<>0.
  107. * Programmer responsibility to insure that VARW <= ARG+6 <= VARA <= ARG+2
  108. * ARG+4 indicates if the line has been changed. If so, ARG+4=0.
  109. * This is a possible call:
  110. * BL   @READLN
  111. * DATA >1DF,>35D   LOWER,UPPER SCREEN LIMITS
  112. ********************************************************************************
  113.  
  114. * EQUATES *
  115. WS     EQU  >8300        MY WORKSPACE
  116. ARG    EQU  >835C
  117. VARW   EQU  >8320        ABS LOWER LIMIT
  118. VARA   EQU  >832A        CURRENT END OF LINE
  119. TEMP   EQU  0            R0 USED FOR TEMP STORAGE
  120. TEMP1  EQU  1            R1 USED FOR ADDL TEMP STORAGE
  121. R1LB   EQU  WS+3
  122. TEMP2  EQU  2
  123. TEMP3  EQU  3
  124. TIMER  EQU  >8379        VDP TIMER INC EVERY 1/60 SEC.
  125. KEYVAL EQU  >8374        KEYBOARD TO SCAN
  126. RKEY   EQU  >8375        KEY CODE
  127. STATUS EQU  >837C        GPL STATUS BYTE
  128.  
  129. * CONSTANTS * (Should be EQU with byte values in code to save memory.)
  130. H00    BYTE 0
  131. H01    BYTE 1
  132. HFF    BYTE >FF
  133. H508   DATA 508
  134. H60    DATA 60
  135. H14    BYTE 14
  136. H766   DATA 766
  137.  
  138. BREAK  BYTE >02
  139. DLETE  BYTE >03
  140. INSRT  BYTE >04
  141. CLRLN  BYTE >07
  142. BACK   BYTE >08
  143. FORW   BYTE >09
  144. DOWN   BYTE >0A
  145. MVUP   BYTE >0B
  146. CHRTN  BYTE >0D
  147. CURSOR BYTE >1E
  148. SPACE  BYTE >20
  149. VARV   BYTE 0            (This is at >8301 in GPL but I use >8300 for workspace)
  150. VAR1   DATA 0            AUTO REPEAT COUNTER (This is 1 byte at >830D in GPL)
  151.  
  152. EVEN
  153.  
  154. READLN
  155. * The GPL code stores >35D at ARG+2 but to give more utility replaced with the
  156. * next two lines of code.
  157. ***    DST  >35D,@ARG+2  GPL DOUBLE STORE
  158.        MOV  *R11+,@VARW  START ADDRESS OF THE FIELD
  159.        MOV  *R11+,@ARG+2 UPPER LIMIT
  160. ***    DST  @VARW,@VARA
  161.        MOV  @VARW,@VARA  NOTHING ENTERED YET
  162. * VARA SHOULD POINT TO A SPACE LOCATION OR END OF FIELD
  163.  
  164. READL1
  165. ***    ST   1,@ARG+4     STORE BYTE=1 TO ARG+4
  166.        MOVB @H01,@ARG+4  MEANS NO CHANGE IN LINE
  167. READL2
  168. ***    DST  @VARW,@ARG+5 HAD TO USE ARG+6 BECAUSE OF WORD BOUNDARY PROBLEMS
  169.        MOV  @VARW,@ARG+6 POSITION CURSOR AT START OF FIELD
  170. READ00
  171. ***    CLR  @VAR1        CLEAR BYTE. I HAD TO USE WORD BECAUSE 9900 IS SO MUCH
  172. ***                      FASTER
  173.        CLR  @VAR1    COUNTER FOR AUTO REPEAT
  174. * This is where we return to exit INSERT mode.
  175. READ01
  176. ***    CLR  @ARG+7       USED ARG+8 BECAUSE HAD TO USE ARG+6 & ARG+7 ALREADY
  177.        MOVB @H00,@ARG+8   NORMAL OPERATION MODE
  178. ***    ST   CURSOR,@VARV
  179.        MOVB @CURSOR,@VARV VARV USED FOR CURSOR/CHARACTER
  180. READ$1
  181. * Input 1 char and alternate cursor and character for blink
  182. ***    EX   @VARV,RAM(@ARG+5) EXCHANGE @VARG WITH WHATS AT LOCATION ARG+5 IN VDP
  183.        MOV  @ARG+6,TEMP  EXCHANGE VARV,ARG+6
  184.        BLWP @VSBR
  185.        SWPB TEMP1
  186.        MOVB @VARV,TEMP1
  187.        BLWP @VSBW
  188.        MOVB @R1LB,@VARV
  189.  
  190. ***    CLR  @TIMER
  191.        MOVB @H00,@TIMER  SET VDP TIMER TO ZERO
  192.  
  193. ***    $REPEAT           MACRO. REPEAT CODE UNTIL $UNTIL IS TRUE
  194. L00001 LIMI 2            ENABLE INTERRUPTS SO THE VDP TIMER (>8379) CAN INC
  195.        LIMI 0            DISABLE INTERRUPTS SO THE VDP WON'T GET MESSED UP
  196. ***    SCAN              SCAN THE KEYBOARD
  197.        BLWP @KSCAN       SCAN FOR A CHARACTER
  198. ***    BS   READ$2       BRANCH ON COND BIT (EQ) SET
  199.        MOVB @STATUS,@STATUS   EQUAL BIT SET?
  200.        JNE  READ$2       FOUND A NEW CHARACTER
  201. ***    INC  @VAR1        INCREMENT THE BYTE @VAR1 BY ONE
  202.        INC  @VAR1   INC AUTO-REPEAT COUNTER
  203. ***    $IF @RKEY .NE. >FF THEN  MACRO. IF RKEY NOT EQ >FF THEN EXECUTE THE
  204. ***                      FOLLOWING CODE OTHERWISE SKIP TO THE $END IF TERMINATOR
  205.        CB   @RKEY,@HFF   OLD KEY?
  206.        JEQ  L00002       YEP
  207. ***        $IF  @VAR1 .HE. 254 THEN  HIGHER OR EQUAL
  208.        C    @VAR1,@H508  HOLD OLD KEY FOR A WHILE
  209. *                        HAD TO DOUBLE 254 TO SLOW DOWN ASSEMBLY CODE
  210.        JLT  L00002       BEFORE STARTING REPEAT
  211. ***    SUB  30,@VAR1     SUBTRACT BYTE
  212.        S    @H60,@VAR1   CONTROL REPEAT RATE
  213. ***    B    READ$3       UNCONDITIONAL BRANCH
  214.        JMP  READ$3
  215. ***        $END IF
  216. ***    $END IF
  217. ***    $UNTIL @TIMER .H. 14  TERMINATOR FOR REPEAT UNTIL HIGHER THAN 14
  218. L00002 CB   @TIMER,@H14
  219.        JLE  L00001       TIME NEXT CHARACTER SWITCH
  220. ***    BR   READ$1       BRANCH COND BIT RESET. USED TO SAVE ONE BYTE OF MEMORY
  221.        JMP  READ$1       RESTART CHAR BLINK CYCLE
  222. READ$2
  223. ***    CLR  @VAR1
  224.        CLR  @VAR1   CLEAR AUTO REPEAT COUNTER
  225. READ$3
  226. ***    $IF  @VARV .NE. CURSOR THEN
  227.        CB   @VARV,@CURSOR IF NE EXCHANGE AGAIN
  228.        JEQ  L00003
  229.  
  230. ***    EX   @VARV,RAM(@ARG+5)
  231.        MOV  @ARG+6,TEMP  EXCHANGE VARV,ARG+6
  232.        BLWP @VSBR
  233.        SWPB TEMP1
  234.        MOVB @VARV,TEMP1
  235.        BLWP @VSBW
  236.        MOVB @R1LB,@VARV
  237.  
  238. ***    $END IF
  239. ***    $IF @RKEY .L. : : THEN   IF RKEY LESS THAN SPACE THEN EXECUTE CODE
  240.  
  241. L00003 CB   @RKEY,@SPACE IF .LT. SPACE THEN CONTROL CHAR
  242.        JLT  L00004
  243.        B    @L0000C
  244.  
  245. * THIS IS WHERE YOU WOULD TRAP ALL CONTROL CODES *
  246. *  HANDLE BREAK CHAR FIRST
  247. *      CB   @RKEY,@BREAK
  248. *      JNE  LABLE
  249.  
  250. * BACK ARROW - SPACE BACK ONE POSITION
  251. ***    $END IF
  252. ***    $IF @RKEY .EQ. BACK GOTO RBACK  GOTO's DO NOT REQUIRE AN END IF TERM
  253. L00004 CB   @RKEY,@BACK  BACK ARROW?
  254.        JNE  B00002       TO FIX OUT OF RANGE ERROR
  255.        B    @RBACK
  256.  
  257. * RIGHT ARROW - FORWARD SPACE
  258. ***    $IF  @RKEY .EQ. FORW GOTO FORW
  259. B00002 CB   @RKEY,@FORW
  260.        JNE  B00003       TO FIX OUT OF RANGE ERROR
  261.        B    @RFORW
  262.  
  263. * INSERT  *
  264. ***    $IF @RKEY .EQ. INSRT THEN
  265. B00003 CB   @RKEY,@INSRT
  266.        JNE  L00005
  267. ***    ST   1,@ARG+8
  268.        MOVB @H01,@ARG+8  SET INSERT MODE FLAG
  269. ***    $END IF
  270.  
  271. * DELETE - DELETE THE CURRENT CHAR
  272. ***    $IF @RKEY .EQ. DLETE THEN
  273. L00005 CB   @RKEY,@DLETE
  274.        JNE  L00006
  275. ***    CLR  @ARG+4
  276.        MOVB @H00,@ARG+4  INDICATE A CHANGE IN LINE
  277. ***    $IF @VARA .DNE. @ARG+6 THEN  THE D MEANS DOUBLE OR WORD OF MEMORY COMPARE
  278.        C    @VARA,@ARG+6 EMPTY LINE?
  279.        JEQ  L0001F       YEP.
  280. ***    DST  @VARA,@ARG
  281.        MOV  @VARA,@ARG   MOVE EVERYTHING FROM THE RIGHT
  282. ***    DSUB @ARG+5,@ARG  DOUBLE BYTE (WORD) SUBTRACT
  283.        S    @ARG+6,@ARG  OF THE CURSOR TO THE LEFT
  284. ***    MOVE @ARG FROM RAM(1(ARG+6)) TO RAM(@ARG+5) THIS IS A BLOCK MOVE OF @ARG
  285. ***    BYTES OF VDP RAM FROM WHATS AT ADDR ARG+6 PLUS 1 TO WHATS AT ADDRESS
  286. ***    ARG+6. IN SHORT MOVE EVERYTHING ON SCREEN ONE BYTE LOWER.
  287.        MOV  @ARG,TEMP2   COUNTER
  288.        MOV  @ARG+6,TEMP
  289.  
  290.        INC  TEMP         MOVE @ARG FROM RAM(1(ARG+6)) TO RAM(@ARG+6)
  291. L00008 BLWP @VSBR
  292.        DEC  TEMP
  293.        BLWP @VSBW
  294.        INCT TEMP
  295.        DEC  TEMP2
  296.        JNE  L00008
  297.  
  298. ***    DDEC @VARA        DECREMENT THE WORD (DOUBLE) AT VARA
  299.        DEC  @VARA        PRE-UPDATE END OF STRING
  300.  
  301. ***    $IF RAM(@VARA) .EQ. : :+OFFSET GOTO READ01 OFFSET IS SCREEN OFFSET >60
  302.        MOV  @VARA,TEMP
  303.        BLWP @VSBR
  304.        CB   @TEMP1,@SPACE
  305.        JNE  B00001       TO RESOLVE OUT OF RG ERROR
  306.        B    @READ01
  307. ***    DINC @VARA        INCREMENT THE WORD OF MEMORY AT VARA
  308. B00001 INC  @VARA
  309.  
  310. ***    ST   : :+OFFSET,RAM(@VARA)
  311. L0001F MOV  @VARA,TEMP
  312.        LI   TEMP1,>2000
  313.        BLWP @VSBW
  314. ***    BR   READ01
  315.        B    @READ01
  316.  
  317. * CLEAR - Clear the entire input line
  318. ***    $IF @RKEY .EQ. CLRLN THEN
  319. L00006 CB   @RKEY,@CLRLN
  320.        JNE  L00009
  321. ***    $REPEAT
  322. ***    ST   : :+OFFSET,RAM(@VARA)
  323.        MOVB @SPACE,TEMP1
  324. CLRLIN
  325.        MOV  @VARA,TEMP   SO WE CAN FIDDLE WITH VALUE
  326.        BLWP @VSBW
  327.        DEC  @VARA        PRE-UPDATE END OF LINE
  328. ***    $UNTIL @VARA .DL. @VARW  DOUBLE LESS THAN
  329.        C    @VARA,@VARW  UP TO AND INCL FIRST POS
  330.        JHE  CLRLIN
  331. ***    DINC @VARA
  332.        INC  @VARA        UNDO LAST SUBTRACTION
  333.        CLR  @ARG+4
  334.        MOVB @H00,@ARG+4  INDICATE CHANGE
  335. ***    BR   READL2
  336.        B    @READL2      RESTART EVERYTHING
  337. ***    $END IF
  338.  
  339. * GENERAL EXIT POINT
  340. ***    $IF @RKEY .NE. CHRTN THEN
  341. L00009 CB   @RKEY,@CHRTN ONLY REACT ON CR/UP/DOWN
  342.        JEQ  L0000A
  343. ***    $IF @RKEY .NE. MVUP THEN
  344.        CB   @RKEY,@MVUP
  345.        JEQ  L0000A
  346. ***    $IF @RKEY .NE. DOWN GOTO READ$1
  347.        CB   @RKEY,@DOWN
  348.        JEQ  L0000A
  349.        B    @READ$1
  350. ***    $END IF
  351. ***    $END IF
  352. ***    $IF @VARA .DEQ. @ARG+2 THEN  DOUBLE EQUAL
  353. L0000A C    @VARA,@ARG+2 CHECK FOR BLOCK ON LAST POSITION
  354.        JNE  L0000B
  355. ***    $IF RAM(@VARA) .NE. : :+OFFSET THEN
  356.        MOV  @VARA,TEMP
  357.        BLWP @VSBR
  358.        CB   TEMP1,@SPACE  BLOCKED?
  359.        JEQ  L0000B
  360. ***    DINC @VARA
  361.        INC  @VARA        POINT BEYOND LAST CHAR IN LINE
  362. ***    $END IF
  363. ***    $END IF
  364. L0000B RT                ENTER THE CURRENT LINE
  365. ***    $END IF (THIS IS FROM THE $IF THAT CHECKED FOR CTRL CODES)
  366.  
  367. * INSERT ROUTINE *
  368. ***    $IF @ARG+8 .NE. 0 THEN INSERT
  369. L0000C CB   @ARG+8,@H00  INSERT MODE
  370.        JEQ  L0000D
  371. READ$4
  372. ***    DST  @VARA,@ARG
  373.        MOV  @VARA,@ARG   USE ARG AS TEMP FOR INSERT
  374. ***    $WHILE @ARG .DH. @ARG+6
  375. L0000F C    @ARG,@ARG+6  MOVE EVERYTHING UP TO CURSOR LOCATION
  376.        JLE  L0000E
  377. ***    DDEC @ARG
  378.        DEC  @ARG         COPY LOWER LOCATION TO HIGHER ONE
  379. ***    ST   RAM(@ARG),RAM(1(ARG)) GO FROM HIGH TO LOW IN VDP RAM
  380.        MOV  @ARG,TEMP
  381.        BLWP @VSBR
  382.        INC  TEMP
  383.        BLWP @VSBW
  384.        JMP  L0000F
  385. ***    $SEND WHILE       TERMINATOR FOR WHILE
  386. ***    $IF @VARA .DL. @ARG+2 THEN
  387. L0000E C    @VARA,@ARG+2 ONLY UPDATE VARA AS UPPER
  388.        JHE  L0000D
  389. ***    DINC @VARA
  390.        INC  @VARA        HASN'T BEEN REACHED YET
  391. ***    $END IF
  392. ***    $END IF
  393. ***    ST   @RKEY,RAM(@ARG+6)
  394. L0000D MOVB @RKEY,TEMP1  DISPLAY THE CHARACTER
  395.        MOV  @ARG+6,TEMP
  396.        BLWP @VSBW
  397. ***    CLR  @ARG+4
  398.        MOVB @H00,@ARG+4  INDICATE CHANGE IN LINE
  399. READ05
  400. ***    $IF @ARG+5 .DEQ. @ARG+2 THEN
  401.        C    @ARG+6,@ARG+2 HIT RIGHT MARGIN?
  402.        JNE  L0002F
  403. ***    CALL TONE2        CALL ANOTHER GPL ROUTINE IN THIS CASE BONK
  404.        MOVB @H00,@STATUS CLEAR THE STATUS BYTE BEFORE ACCESSING GPL
  405.        BLWP @GPLLNK      GIVE A BAD RESPONSE TONE
  406.        DATA >0036
  407. ***    BR   READ$1
  408.        B    @READ$1      STAY IN CURRENT MODE
  409. ***    $END IF
  410. ***    DINC @ARG+6
  411. L0002F INC  @ARG+6       UPDATE CURRENT ADDRESS
  412. ***    IF @ARG+6 .DH. @VARA THEN
  413.        C    @ARG+6,@VARA CHECK FOR LAST NEW HIGH LIMIT
  414.        JLE  L00010
  415. ***    DST  @ARG+5,@VARA
  416.        MOV  @ARG+6,@VARA UPDATE NEW HIGH LIMIT
  417. ***    $END IF
  418. ***    $IF @VARA .DL. >2FE GOTO READ$1
  419. L00010 C    @VARA,@H766
  420.        JHE  L00011       TO FIX OUT OF RANGE PROBLEM
  421.        B    @READ$1      STILL SOME SPACE TO GO
  422. L00011
  423. * This is where we could scroll the screen if needed
  424. * UPDATE POINTERS IF YOU SCROLL *
  425. ***    CALL SCROLL       SCROLL THE SCREEN
  426. ***    DSUB 28,@VARA
  427. *      S    @H28,@VARA   BACK TO START OF LINE
  428. ***    DSUB 32,@VARW
  429. *      S    @H32,@VARW   BACKUP START LINE ADDRESS
  430. ***    DSUB 32,@ARG+2
  431. *      S    @H32,@ARG+2  ABSOLUTE HIGH LIMIT BACKS UP TOO
  432. ***    DSUB 32,@ARG+6
  433. *      S    @H32,@ARG+6  CURRENT CURSOR POSITION ALSO
  434. ***    BR   READ$1
  435.        B    @READ$1      START WITH SOMETHING ELSE
  436.  
  437. * FORWARD CURSOR MOVE
  438. RFORW
  439. ***    CLR  @ARG+8
  440.        MOVB @H00,@ARG+8  LEAVE INSERT MODE
  441. ***    BR   READ05
  442.        B    @READ05      USE REST OF LOGIC
  443.  
  444. * BACK CURSOR MOVE
  445. RBACK
  446. ***    $IF @ARG+5 .DH. @VARW
  447.        C    @ARG+6,@VARW CHECK BOTTOM RANGE
  448.        JLE  L00012
  449. ***    DDEC @ARG+6
  450.        DEC  @ARG+6
  451. ***    $END IF
  452. ***    BR   READ01
  453. L00012 B    @READ01
  454.  
  455.        END
  456.  
  457. ****************************************
  458. * THIS IS A ROUTINE TO DIRECTLY ACCESS *
  459. * THE GROM READLN ROUTINE. USE CALL    *
  460. * LOAD("DSK1.FILENAME") AND CALL LINK  *
  461. * ("DSK1.START") FROM E/A BASIC TO SEE *
  462. * IT BECAUSE OF SCREEN OFFSET.         *
  463. ****************************************
  464.  
  465.        DEF  START
  466.  
  467. GPLWS  EQU  >83E0        ADDRESS FOR GPL WORK SPACE
  468.  
  469. H00    BYTE 0
  470. WS     BSS  >20          MY WORKSPACE
  471.        EVEN
  472.  
  473. START
  474.        LWPI WS           POINT TO MY WORKSPACE
  475.  
  476.        LI   R0,>2
  477.        MOV  R0,@>8320    START SCREEN ADDRESS FOR SCAN
  478.  
  479.        MOVB @H00,@>837C  CLEAR THE STATUS BYTE SO WE DON'T GET AN ERROR
  480.        BLWP @GPLLNK      LINK TO THE ROUTINE IN GROM
  481.        DATA >2A42
  482.  
  483.        MOVB @H00,@>837C  RETURN TOTHE CALLING PROGRAM ON ENTER
  484.        LWPI GPLWS
  485.        B    @>0070
  486.  
  487. * YOU COULD HAVE PLACED AN END STATEMENT HERE AND REF'd GPLLNK INSTEAD
  488. * OF USING THIS ROUTINE.
  489. * GPLLNK ROUTINE *
  490.  
  491. GPLLNK DATA UTILWS,XGPL  VECTOR FOR THE GPLLNK BLWP
  492.  
  493. UTILWS EQU  >2094
  494. SUBSTK EQU  >8373
  495. FLAG2  EQU  >8349
  496. SVGPRT EQU  >2030
  497.  
  498. H20    BYTE >20
  499. EVEN
  500.  
  501. XGPL
  502.      MOVB @SUBSTK,R1
  503.      SRL  R1,8
  504.      MOV  *R14+,@>8304(R1)
  505.      SOCB @H20,@FLAG2
  506.      LWPI GPLWS
  507.      MOV  @SVGPRT,R11
  508.      RT
  509.  
  510.        END
  511.  
  512. Download complete.  Turn off Capture File.
  513.  
  514.  
  515.