Using The Assembler 05

By Richard Dimond

Originally published in EUG #22

I promised to discuss the making up of screens this issue as I had in mind a program from Electron User which I had converted to a completely Machine Code game and I hope to publish this in the next issue together with an explanation of what I have done.

First, however, are some routines that I have not yet covered and that can be used to make up screens for simple games.

In my first article, I gave a simple routine (uline) for printing a line of the same character. If we use the 'tab' subroutine also given in that article, we can print horizontal or vertical lines of the same character anywhere on the screen. Add these two routines to those already entered:

      .horiz  JSRtab
              INX
              CPXlimit
              BNEhoriz
              RTS

      .vert   JSTtab
              INY
              CPYlimit  
              BNEvert
              RTS
Add limit=&86 to the variables at line 40. Then to use the routines, enter in the main loop:-

For a horizontal line:-

      LDA# <end col> :STAlimit
      LDX# <start col>
      LDY# <line>
      LDA# <char>
      JSR horiz                  }  or JMPhoriz
      RTS                        }
For a vertical line:-
      LDA# <end line> :STAlimit
      LDX# <column>
      LDY# <start line>
      LDA# char
      JMP vert
Blocks of characters can be printed as in BASIC by entering the data -
      EQUS CHR$224+CHR$225+CHR$8+CHR$8+CHR$10+CHR$226+CHR$227
and using the loop:-
      .comms2 STX addr
              STY addr+1
              TAX
              LDY#0
      .clp    LDA (addr),Y
              JSR oswrch
              INY
              DEX
              BNE clp
              RTS
Whilst the loop (comms) is a little more economical in memory and perhaps better programming, this loop is easier to use as it avoids the necessity to reverse all the data. It is used as before:
      LDA# <number of commands>
      LDX# <data> MOD256
      LDY# <data> DIV256
      JMP comms2
Windows can be made up using the data:

Text window:-

      EQUB28:EQUB <left>:EQUB <bottom>:EQUB <right>:EQUB <top>
Graphics window:-
      EQUB24:EQUW <left>:EQUW <bottom>:EQUW <right>:EQUW <top>
Double height lettering can be printed with this routine:-
      .dh     STX db: STY db+1
              LDA#0:STA &70
      .b1     LDY &70:LDA (db),Y
              CMP #13:BEQ b3
              STA &71:INY:STY &70
              LDX #&71:LDY #0
              LDA #10:JSR &fff1
              LDX #1:LDY #0
      .b2     LDA &71,X:STA &CF0,Y
              INY:STA &CF0,Y
              INY:INX
              CPX #9:BNE b2
              LDA #254:JSR oswrch
              LDA #8:JSR oswrch:LDA #10:JSR oswrch
              LDA #255:JSR oswrch
              LDA #11:JSR oswrch
              JMP b1
      .b3     RTS
The variable db=&80 must be added to the variables in line 40. This will hold the address of the STRING to be printed which must have the CR character &0D at the end. The routine is used in the same way as the print routine by:
      LDX # <label> MOD256
      LDY # <label> DIV256
      JMP dh
Note that &70 holds the position in the string of the character being printed and &71 holds the character. The character codes are then split to &72 to &79. These are doubled loaded to &CF0 to &Cff for characters 254 and 255.

The routines given so far should enable you to make up screens for simple games where a clash may be detected by comparing co-ordinates where these are held at say &74 (x, y) and &76 (x1, y1):-

      LDAx:CMPx1:BNE no_clash
      LDAx+1:CMPx12+1:BNE no_clash
      .clash    <clash routine>
      .no_clash RTS
For arcade games of the Repton type a map is needed as in BASIC and this should be entered to a suitable address for the M/code. The data can be saved separately with other similar files so that they can be loaded into the main game.

To load these, we use the OS routine OSCLI (&FFF7). This is used for all * commands. It needs the X and Y registers to be loaded with the address of the command data as for other routines before being called:

      LDX# comm MOD256
      LDY# comm DIV256
      JMP &FFF7
      .comm   EQUS "LOAD map <address>"
While it may not be necessary to add the address (if it is saved to the correct address), it can be put in.

I shall explain more about maps and other routines next time.

Richard Dimond, EUG #22