8-Bit BTCS - 6502 Reverse Engineering Project

Any developer realated stuff
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

In case anyone was interested, I had a look at the C64 Programmer's Reference Guide regarding multicoloured character sets. I believe that the dungeon graphics are displayed using such a scheme, with each dungeon tile being displayed as an 8x8 character.

Consider: http://www.codebase64.com/doku.php?id=m ... chacking13

I think this is highly relevent to what we've been working on lately, in particular designing a prototype program that lets people redesign the Wine Cellar.

Here is the information from the C64PRG such:

Code: Select all

   All of the graphics abilities of the Commodore 64 come from the 6567
  Video Interface Chip (also known as the VIC-II chip). This chip gives a
  variety of graphics modes, including a 40 column by 25 line text display,
  a 320 by 200 dot high resolution display, and SPRITES, small movable
  objects which make writing games simple. And if this weren't enough,
  many of the graphics modes can be mixed on the same screen. It is
  possible, for example, to define the top half of the screen to be in
  high resolution mode, while the bottom half is in text mode. And SPRITES
  will combine with anything! More on sprites later. First the other
  graphics modes.
    The VIC-II chip has the following graphics display modes:



  A) CHARACTER DISPLAY MODES

     1) Standard Character Mode
            a)ROM characters
            b)RAM programmable characters
     2) Multi-Color Character Mode
            a)ROM characters
            b)RAM programmable characters

     3) Extended Background Color Mode
            a)ROM characters
            b)RAM programmable characters


  B) BIT MAP MODES

     1) Standard Bit Map Mode
     2) Multi-Color Bit Map Mode


  C) SPRITES

     1) Standard Sprites
     2) Multi-Color Sprites



  GRAPHICS LOCATIONS

    Some general information first. There are 1000 possible locations on
  the Commodore 64 screen. Normally, the screen starts at location 1024
  ($0400 in HEXadecimal notation) and goes to location 2023. Each of
  these locations is 8 bits wide. This means that it can hold any integer
  number from 0 to 255. Connected with screen memory is a group of 1000
  locations called COLOR MEMORY or COLOR RAM. These start at location 55296
  ($D800 in HEX) and go up to 56295. Each of the color RAM locations is 4
  bits wide, which means that it can hold any integer number from 0 to 15.
  Since there are 16 possible colors that the Commodore 64 can use, this
  works out well.
    In addition, there are 256 different characters that can be displayed
  at any time. For normal screen display, each of the 1000 locations in
  screen memory contains a code number which tells the VIC-II chip which
  character to display at that screen location.
    The various graphics modes are selected by the 47 CONTROL registers in
  the VIC-II chip. Many of the graphics functions can be controlled by
  POKEing the correct value into one of the registers. The VIC-II chip is
  located starting at 53248 ($D000 in HEX) through 53294 ($D02E in HEX).


  VIDEO BANK SELECTION

    The VIC-II chip can access ("see") 16K of memory at a time. Since there
  is 64K of memory in the Commodore 64, you want to be able to have the
  VIC-II chip see all of it. There is a way. There are 4 possible BANKS
  (or sections) of 16K of memory. All that is needed is some means of
  controlling which 16K bank the VIC-II chip looks at. In that way, the
  chip can "see" the entire 64K of memory. The BANK SELECT bits that allow
  you access to all the different sections of memory are located in the
  6526 COMPLEX INTERFACE ADAPTER CHIP #2 (CIA #2). The POKE and PEEK BASIC
  statements (or their machine language versions) are used to select a
  bank, by controlling bits 0 and 1 of PORT A of CIA#2 (location 56576 (or
  $DD00 HEX)). These 2 bits must be set to outputs by setting bits 0 and 1
  of location 56578 ($DD02,HEX) to change banks. The following example
  shows this:

    POKE 56578,PEEK(56578)OR 3: REM MAKE SURE BITS 0 AND 1 ARE OUTPUTS
    POKE 56576,(PEEK(56576)AND 252)OR A: REM CHANGE BANKS

    "A" should have one of the following values:




  +-------+------+-------+----------+-------------------------------------+
  | VALUE | BITS |  BANK | STARTING |  VIC-II CHIP RANGE                  |
  |  OF A |      |       | LOCATION |                                     |
  +-------+------+-------+----------+-------------------------------------+
  |   0   |  00  |   3   |   49152  | ($C000-$FFFF)*                      |
  |   1   |  01  |   2   |   32768  | ($8000-$BFFF)                       |
  |   2   |  10  |   1   |   16384  | ($4000-$7FFF)*                      |
  |   3   |  11  |   0   |       0  | ($0000-$3FFF) (DEFAULT VALUE)       |
  +-------+------+-------+----------+-------------------------------------+



    This 16K bank concept is part of everything that the VIC-II chip does.
  You should always be aware of which bank the VIC-II chip is pointing at,
  since this will affect where character data patterns come from, where the
  screen is, where sprites come from, etc. When you turn on the power of
  your Commodore 64, bits 0 and 1 of location 56576 are automatically set
  to BANK 0 ($0000-$3FFF) for all display information.




  +-----------------------------------------------------------------------+
  | *NOTE: The Commodore 64 character set is not available to the VIC-II  |
  | chip in BANKS 1 and 3. (See character memory section.)                |
  +-----------------------------------------------------------------------+



  SCREEN MEMORY

    The location of screen memory can be changed easily by a POKE to
  control register 53272 ($D018 HEX). However, this register is also used
  to control which character set is used, so be careful to avoid disturbing
  that part of the control register. The UPPER 4 bits control the location
  of screen memory. To move the screen, the following statement should be
  used:


  POKE53272,(PEEK(53272)AND15)OR A



  Where "A" has one of the following values:
  +---------+------------+-----------------------------+
  |         |            |         LOCATION*           |
  |    A    |    BITS    +---------+-------------------+
  |         |            | DECIMAL |        HEX        |
  +---------+------------+---------+-------------------+
  |     0   |  0000XXXX  |      0  |  $0000            |
  |    16   |  0001XXXX  |   1024  |  $0400 (DEFAULT)  |
  |    32   |  0010XXXX  |   2048  |  $0800            |
  |    48   |  0011XXXX  |   3072  |  $0C00            |
  |    64   |  0100XXXX  |   4096  |  $1000            |
  |    80   |  0101XXXX  |   5120  |  $1400            |
  |    96   |  0110XXXX  |   6144  |  $1800            |
  |   112   |  0111XXXX  |   7168  |  $1C00            |
  |   128   |  1000XXXX  |   8192  |  $2000            |
  |   144   |  1001XXXX  |   9216  |  $2400            |
  |   160   |  1010XXXX  |  10240  |  $2800            |
  |   176   |  1011XXXX  |  11264  |  $2C00            |
  |   192   |  1100XXXX  |  12288  |  $3000            |
  |   208   |  1101XXXX  |  13312  |  $3400            |
  |   224   |  1110XXXX  |  14336  |  $3800            |
  |   240   |  1111XXXX  |  15360  |  $3C00            |
  +---------+------------+---------+-------------------+
  +-----------------------------------------------------------------------+
  | * Remember that the BANK ADDRESS of the VIC-II chip must be added in. |
  | You must also tell the KERNAL'S screen editor where the screen is as  |
  | follows: POKE 648, page (where page = address/256, e.g., 1024/256= 4, |
  | so POKE 648,4).                                                       |
  +-----------------------------------------------------------------------+

  COLOR MEMORY

    Color memory can NOT move. It is always located at locations 55296
  ($D800) through 56295 ($DBE7). Screen memory (the 1000 locations starting
  at 1024) and color memory are used differently in the different graphics
  modes. A picture created in one mode will often look completely different
  when displayed in another graphics mode.

  CHARACTER MEMORY

    Exactly where the VIC-II gets it character information is important to
  graphic programming. Normally, the chip gets the shapes of the characters



  you want to be displayed from the CHARACTER GENERATOR ROM. In this chip
  are stored the patterns which make up the various letters, numbers,
  punctuation symbols, and the other things that you see on the keyboard.
  One of the features of the Commodore 64 is the ability to use patterns
  located in RAM memory. These RAM patterns are created by you, and that
  means that you can have an almost infinite set of symbols for games,
  business applications, etc.
    A normal character set contains 256 characters in which each character
  is defined by 8 bytes of data. Since each character takes up 8 bytes this
  means that a full character set is 256*8=2K bytes of memory. Since the
  VIC-II chip looks at 16K of memory at a time, there are 8 possible
  locations for a complete character set. Naturally, you are free to use
  less than a full character set. However, it must still start at one of
  the 8 possible starting locations.
    The location of character memory is controlled by 3 bits of the VIC-II
  control register located at 53272 ($D018 in HEX notation). Bits 3,2, and
  1 control where the characters' set is located in 2K blocks. Bit 0 is ig-
  nored. Remember that this is the same register that determines where
  screen memory is located so avoid disturbing the screen memory bits. To
  change the location of character memory, the following BASIC statement
  can be used:

    POKE 53272,(PEEK(53272)AND240)OR A

  Where A is one of the following values:
  +-----+----------+------------------------------------------------------+
  |VALUE|          |            LOCATION OF CHARACTER MEMORY*             |
  | of A|   BITS   +-------+----------------------------------------------+
  |     |          |DECIMAL|         HEX                                  |
  +-----+----------+-------+----------------------------------------------+
  |   0 | XXXX000X |     0 | $0000-$07FF                                  |
  |   2 | XXXX001X |  2048 | $0800-$0FFF                                  |
  |   4 | XXXX010X |  4096 | $1000-$17FF ROM IMAGE in BANK 0 & 2 (default)|
  |   6 | XXXX011X |  6144 | $1800-$1FFF ROM IMAGE in BANK 0 & 2          |
  |   8 | XXXX100X |  8192 | $2000-$27FF                                  |
  |  10 | XXXX101X | 10240 | $2800-$2FFF                                  |
  |  12 | XXXX110X | 12288 | $3000-$37FF                                  |
  |  14 | XXXX111X | 14336 | $3800-$3FFF                                  |
  +-----+----------+-------+----------------------------------------------+
  +-----------------------------------------------------------------------+
  | * Remember to add in the BANK address.                                |
  +-----------------------------------------------------------------------+

  104   PROGRAMMING GRAPHICS
~


    The ROM IMAGE in the above table refers to the character generator ROM.
  It appears in place of RAM at the above locations in bank 0. it  also
  appears in the corresponding RAM at locations 36864-40959 ($9000-$9FFF)
  in bank 2. Since the VIC-II chip can only access 16K of memory at a time,
  the ROM character patterns appear in the 16K block of memory the VIC-II
  chip looks at. Therefore, the system was designed to make the VIC-II chip
  think that the ROM characters are at 4096-8191 ($1000-$1FFF) when your
  data is in bank 0, and 36864-40959 ($9000-$9FFF) when your data is in
  bank 2, even though the character ROM is actually at location 53248-57343
  ($D000-$DFFF). This imaging only applies to character data as seen by the
  VIC-II chip. It can be used for programs, other data, etc., just like any
  other RAM memory.

  +-----------------------------------------------------------------------+
  | NOTE: If these ROM images got in the way of your own graphics, then   |
  | set the BANK SELECT BITS to one of the BANKS without the images       |
  | (BANKS 1 or 3). The ROM patterns won't be there.                      |
  +-----------------------------------------------------------------------+

   The location and contents of the character set in ROM are as follows:

  +-----+-------------------+-----------+---------------------------------+
  |     |       ADDRESS     |   VIC-II  |                                 |
  |BLOCK+-------+-----------+   IMAGE   |            CONTENTS             |
  |     |DECIMAL|    HEX    |           |                                 |
  +-----+-------+-----------+-----------+---------------------------------+
  |  0  | 53248 | D000-D1FF | 1000-11FF | Upper case characters           |
  |     | 53760 | D200-D3FF | 1200-13FF | Graphics characters             |
  |     | 54272 | D400-D5FF | 1400-15FF | Reversed upper case characters  |
  |     | 54784 | D600-D7FF | 1600-17FF | Reversed graphics characters    |
  |     |       |           |           |                                 |
  |  1  | 55296 | D800-D9FF | 1800-19FF | Lower case characters           |
  |     | 55808 | DA00-DBFF | 1A00-1BFF | Upper case & graphics characters|
  |     | 56320 | DC00-DDFF | 1C00-1DFF | Reversed lower case characters  |
  |     | 56832 | DE00-DFFF | 1E00-1FFF | Reversed upper case &           |
  |     |       |           |           | graphics characters             |
  +-----+-------+-----------+-----------+---------------------------------+

    Sharp-eyed readers will have just noticed something. The locations
  occupied by the character ROM are the same as the ones occupied by the
  VIC-II chip control registers. This is possible because they don't occupy
  the same locations at the same time. When the VIC-II chip needs to access


  character data the ROM is switched in. It becomes an image in the 16K
  bank of memory that the VIC-II chip is looking at. Otherwise, the area is
  occupied by the I/O control registers, and the character ROM is only
  available to the VIC-II chip.
    However, you may need to get to the character ROM if you are going to
  use programmable characters and want to copy some of the character ROM
  for some of your character definitions. In this case you must switch out
  the I/O register, switch in the character ROM, and do your copying. When
  you're finished, you must switch the 1/0 registers back in again. During
  the copying process (when I/O is switched out) no interrupts can be
  allowed to take place. This is because the I/O registers are needed to
  service the interrupts. If you forget and perform an interrupt, really
  strange things happen. The keyboard should not be read during the copying
  process. To turn off the keyboard and other normal interrupts that occur
  with your Commodore 64, the following POKE should be used:

    POKE 56334,PEEK(56334)AND254   (TURNS INTERRUPTS OFF)


    After you are finished getting characters from the character ROM, and
  are ready to continue with your program, you must turn the keyboard scan
  back on by the following POKE:

    POKE 56334,PEEK(56334)OR1      (TURNS INTERRUPTS ON)


    The following POKE will switch out 1/0 and switch the CHARACTER ROM in:

    POKE 1,PEEK(1)AND251


    The character ROM is now in the locations from 53248-57343 ($D000-
  $DFFF).
    To switch I/O back into $D000 for normal operation use the following
  POKE:

    POKE 1,PEEK(1)OR 4




  STANDARD CHARACTER MODE

    Standard character mode is the mode the Commodore 64 is in when you
  first turn it on. It is the mode you will generally program in.
    Characters can be taken from ROM or from RAM, but normally they are
  taken from ROM. When you want special graphics characters for a program,
  all you have to do is define the new character shapes in RAM, and tell
  the VIC-II chip to get its character information from there instead of
  the character ROM. This is covered in more detail in the next section.
    In order to display characters on the screen in color, the VIC-II chip
  accesses the screen memory to determine the character code for that
  location on the screen. At the same time, it accesses the color memory to
  determine what color you want for the character displayed. The character
  code is translated by the VIC-II into the starting address of the 8-byte
  block holding your character pattern. The 8-byte block is located in
  character memory.
    The translation isn't too complicated, but a number of items are com-
  bined to generate the desired address. First the character code you use
  to POKE screen memory is multiplied by 8. Next add the start of char-
  acter memory (see CHARACTER MEMORY section). Then the Bank Select Bits
  are taken into account by adding in the base address (see VIDEO BANK
  SELECTION section). Below is a simple formula to illustrate what happens:

  CHARACTER ADDRESS = SCREEN CODE*8+(CHARACTER SET*2048)+(BANK*16384)


  CHARACTER DEFINITIONS

    Each character is formed in an 8 by 8 grid of dots, where each dot may
  be either on or off. The Commodore 64 character images are stored in the
  Character Generator ROM chip. The characters are stored as a set of 8
  bytes for each character, with each byte representing the dot pattern of
  a row in the character, and each bit representing a dot. A zero bit means
  that dot is off, and a one bit means the dot is on.
    The character memory in ROM begins at location 53248 (when the I/O
  is switched off). The first 8 bytes from location 53248 ($D000) to 53255
  ($D007) contain the pattern for the @ sign, which has a character code
  value of zero in the screen memory. The next 8 bytes, from location



  53256 ($D008) to 53263 ($D00F), contain the information for forming the
  letter A.

       IMAGE     BINARY       PEEK

        **      00011000       24
       ****     00111100       60
      **  **    01100110      102
      ******    01111110      126
      **  **    01100110      102
      **  **    01100110      102
      **  **    01100110      102
		00000000	0

    Each complete character set takes up 2K (2048 bits) of memory, 8 bytes
  per character and 256 characters. Since there are two character sets, one
  for upper case and graphics and the other with upper and lower case, the
  character generator ROM takes up a total of 4K locations.


  PROGRAMMABLE CHARACTERS

    Since the characters are stored in ROM, it would seem that there is no
  way to change them for customizing characters. However, the memory
  location that tells the VIC-II chip where to find the characters is a
  programmable register which can be changed to point to many sections of
  memory. By changing the character memory pointer to point to RAM, the
  character set may be programmed for any need.
    If you want your character set to be located in RAM, there are a few
  VERY IMPORTANT things to take into account when you decide to actually
  program your own character sets. In addition, there are two other
  important points you must know to create your own special characters:

    1) It is an all or nothing process. Generally, if you use your own
       character set by telling the VIC-II chip to get the character
       information from the area you have prepared in RAM, the standard
     Commodore 64 characters are unavailable to you. To solve this, you
     must copy any letters, numbers, or standard Commodore 64 graphics you
     intend to use into your own character memory in RAM. You can pick and
     choose, take only the ones you want, and don't even have to keep them
     in order!




    2) Your character set takes memory space away from your BASIC program.
       Of course, with 38K available for a BASIC program, most applications
       won't have problems.


  +-----------------------------------------------------------------------+
  | WARNING: You must be careful to protect the character set from being  |
  | overwritten by your BASIC program, which also uses the RAM.           |
  +-----------------------------------------------------------------------+

    There are two locations in the Commodore 64 to start your character set
  that should NOT be used with BASIC: location 0 and location 2048. The
  first should not be used because the system stores important data on
  page 0. The second can't be used because that is where your BASIC program
  starts! However, there are 6 other starting positions for your custom
  character set.
    The best place to put your character set for use with BASIC while
  experimenting is beginning at 12288 ($3000 in HEX). This is done by
  POKEing the low 4 bits of location 53272 with 12. Try the POKE now, like
  this:

    POKE 53272,(PEEK(53272)AND240)+12

    Immediately, all the letters on the screen turn to garbage, This is
  because there are no characters set up at location 12288 right now...
  only random bytes. Set the Commodore 64 back to normal by hitting the
  <RUN/STOP> key and then the <RESTORE> key.
    Now let's begin creating graphics characters. To protect your char-
  acter set from BASIC, you should reduce the amount of memory BASIC
  thinks it has. The amount of memory in your computer stays the same...
  it's just that you've told BASIC not to use some of it. Type:

    PRINT FRE(0)-(SGN(FRE(0))<0)*65535

    The number displayed is the amount of memory space left unused. Now
  type the following:

    POKE 52148:POKE56,48:CLR

  Now type:

    PRINT FRE(0)-(SGN(FRE(0))<0)*65535



  See the change? BASIC now thinks it has less memory to work with. The
  memory you just claimed from BASIC is where you are going to put your
  character set, safe from actions of BASIC.
    The next step is to put your characters into RAM. When you begin, there
  is random data beginning at 12288 ($3000 HEX). You must put character
  patterns in RAM (in the same style as the ones in ROM) for the VIC-II
  chip to use.
    The following program moves 64 characters from ROM to your character
  set RAM:

start tok64 page110.prg
  5 printchr$(142)               :rem switch to upper case
  10 poke52,48:poke 56,48:clr    :rem reserve memory for characters
  20 poke56334,peek(56334)and254 :rem turn off keyscan interrupt timer
  30 poke1,peek(1)and251         :rem switch in character
  40 fori=0to511:pokei+12288,peek(i+53248):next
  50 poke1,peek(1)or4            :rem switch in i/o
  60 poke56334,peek(56334)or1    :rem restart keyscan interrupt timer
  70 end
stop tok64

    Now POKE location 53272 with (PEEK(53272)AND240)+12. Nothing happens,
  right? Well, almost nothing. The Commodore 64 is now getting it's
  character information from your RAM, instead of from ROM. But since we
  copied the characters from ROM exactly, no difference can be seen... yet.
    You can easily change the characters now. Clear the screen and type
  an @ sign. Move the cursor down a couple of lines, then type:

  FOR I=12288 TO 12288+7:POKE 1,255-PEEK(I):NEXT

  You just created a reversed @ sign!

  +-----------------------------------------------------------------------+
  | TIP: Reversed characters are just characters with their bit patterns  |
  | in character memory reversed.                                         |
  +-----------------------------------------------------------------------+

    Now move the cursor up to the program again and hit <RETURN> again to
  re-reverse the character (bring it back to normal). By looking at the
  table of screen display codes, you can figure out where in RAM each
  character is. Just remember that each character takes eight memory
  locations to store. Here's a few examples just to get you started:



  +-----------+--------------+--------------------------------------------+
  | CHARACTER | DISPLAY CODE |      CURRENT STARTING LOCATION IN RAM      |
  +-----------+--------------+--------------------------------------------+
  |     @     |       0      |                    1228                    |
  |     A     |       1      |                   12296                    |
  |     !     |      33      |                   12552                    |
  |     >     |      62      |                   12784                    |
  +-----------+--------------+--------------------------------------------+

    Remember that we only took the first 64 characters. Something else will
  have to be done if you want one of the other characters.
    What if you wanted character number 154, a reversed Z? Well, you could
  make it yourself, by reversing a Z, or you could copy the set of reversed
  characters from the ROM, or just take the one character you want from ROM
  and replace one of the characters you have in RAM that you don't need.

    Suppose you decide that you won't need the > sign. Let's replace the
  > sign with the reversed Z. Type this:


    FOR I=0 TO 7:POKE 12784+I,255-PEEK(I+12496):NEXT

    Now type a > sign. It comes up as a reversed Z. No matter how many
  times you type the >, it comes out as a reversed Z. (This change is
  really an illusion. Though the > sign looks like a reversed Z, it still
  acts like a > in a program. Try something that needs a > sign. It will
  still work fine, only it will look strange.)
    A quick review: You can now copy characters from ROM into RAM. You can
  even pick and choose only the ones you want. There's only one step left
  in programmable characters (the best step!)... making your own
  characters.
    Remember how characters are stored in ROM? Each character is stored as
  a group of eight bytes. The bit patterns of the bytes directly control
  the character. If you arrange 8 bytes, one on top of another, and write
  out each byte as eight binary digits, it forms an eight by eight matrix,
  looking like the characters. When a bit is a one, there is a dot at that
  location. When a bit is a zero, there is a space at that location. When
  creating your own characters, you set up the same kind of table in
  memory. Type NEW and then type this program:

    10 FOR I=12448 TO 12455: READ A:POKE I,A:NEXT
    20 DATA 60, 66, 165, 129, 165, 153, 66, 60



  Now type RUN. The program will replace the letter T with a smile face
  character. Type a few T's to see the face. Each of the numbers in the
  DATA statement in line 20 is a row in the smile face character. The
  matrix for the face looks like this:


           76543210          BINARY      DECIMAL

          +--------+
    ROW 0 |  ****  |        00111100        60
        1 | *    * |        01000010        66
        2 |* *  * *|        10100101       165
        3 |*      *|        10000001       129
        4 |* *  * *|        10100101       165
        5 |*  **  *|        10011001       153
        6 | *    * |        01000010        66
    ROW 7 |  ****  |        00111100        60
          +--------+


                               7 6 5 4 3 2 1 0

                              +-+-+-+-+-+-+-+-+
                            0 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+
                            1 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+
                            2 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+
                            3 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+
                            4 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+
                            5 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+
                            6 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+
                            7 | | | | | | | | |
                              +-+-+-+-+-+-+-+-+

                 Figure 3-1. Programmable Character Worksheet.



    The Programmable Character Worksheet (Figure 3-1) will help you design
  your own characters. There is an 8 by 8 matrix on the sheet, with row
  numbers, and numbers at the top of each column. (if you view each row as
  a binary word, the numbers are the value of that bit position. Each is a
  power of 2. The leftmost bit is equal to 128 or 2 to the 7th power, the
  next is equal to 64 or 2 to the 6th, and so on, until you reach the
  rightmost bit (bit 0) which is equal to 1 or 2 to the 0 power.)
    Place an X on the matrix at every location where you want a dot to be
  in your character. When your character is ready you can create the DATA
  statement for your character.
    Begin with the first row. Wherever you placed an X, take the number at
  the top of the column (the power-of-2 number, as explained above) and
  write it down. When you have the numbers for every column of the first
  row, add them together. \Mite this number down, next to the row. This is
  the number that you will put into the DATA statement to draw this row.
    Do the same thing with all of the other rows (1-7). When you are
  finished you should have 8 numbers between 0 and 255. If any of your
  numbers are not within range, recheck your addition. The numbers must be
  in this range to be correct! If you have less than 8 numbers, you missed
  a row. It's OK if some are 0. The 0 rows are just as important as the
  other numbers.
    Replace the numbers in the DATA statement in line 20 with the numbers
  you just calculated, and RUN the program. Then type a T. Every time you
  type it, you'll see your own character!
    If you don't like the way the character turned out, just change the
  numbers in the DATA statement and re-RUN the program until you are happy
  with your character.
    That's all there is to it!



  +-----------------------------------------------------------------------+
  | HINT: For best results, always make any vertical lines in your        |
  | characters at least 2 dots (bits) wide. This helps prevent CHROMA     |
  | noise (color distortion) on your characters when they are displayed   |
  | on a TV screen.                                                       |
  +-----------------------------------------------------------------------+





    Here is an example of a program using standard programmable characters:



start tok64 page114.prg
  10 rem * example 1 *
  20 rem creating programmable characters
  31 poke 56334,peek(56334)and254: rem turn off kb
  32 poke 1,peek(1)and251: rem turn off i/o
  35 for i=0to63: rem character range to be copied
  36 for j=0to7: rem copy all 8 bytes per character
  37 poke 12288+I*8+j,peek(53248+i*8+j): rem copy a byte
  38 next j:next i: rem goto next byte or character
  39 poke 1,peek(1)or4:poke 56334,peek(56334)or1: rem turn on i/O and kb
  40 poke 53272,(peek(53272)and240)+12: rem set char pointer to mem. 12288
  60 for char=60to63: rem program characters 60 thru 63
  80 for byte=0to7: rem do all 8 bytes of a character
  100 read number: rem read in 1/8th of character data
  120 poke 12288+(8*char)+byte,number: rem store the data in memory
  140 next byte:next char: rem also could be next byte, char
  150 print chr$(147)tab(255)chr$(60);
  155 print chr$(61)tab(55)chr$(62)chr$(63)
  160 rem line 150 puts the newly defined characters on the screen
  170 get a$: rem wait for user to press a key
  180 if a$=""then goto170: rem if no keys were pressed, try again!
  190 poke 53272,21: rem return to normal characters
  200 data 4,6,7,5,7,7,3,3: rem data for character 60
  210 data 32,96,224,160,224,224,192,192: rem data for character 61
  220 data 7,7,7,31,31,95,143,127: rem data for character 62
  230 data 224,224,224,248,248,248,240,224: rem data for character 63
  240 end
stop tok64









  MULTI-COLOR MODE GRAPHICS

    Standard high-resolution graphics give you control of very small dots
  on the screen. Each dot in character memory can have 2 possible values,
  1 for on and 0 for off. When a dot is off, the color of the screen is
  used in the space reserved for that dot. If the dot is on, the dot is
  colored with the character color you have chosen for that screen posi-
  tion. When you're using standard high-resolution graphics, all the dots
  within each 8X8 character can either have background color or foreground
  color. In some ways this limits the color resolution within that space.
  For example, problems may occur when two different colored lines cross.
    Multi-color mode gives you a solution to this problem. Each dot in
  multi-color mode can be one of 4 colors: screen color (background color
  register #0), the color in background register #1, the color in back-
  ground color register #2, or character color. The only sacrifice is in
  the horizontal resolution, because each multi-color mode dot is twice as
  wide as a high-resolution dot. This minimal loss of resolution is more
  than compensated for by the extra abilities of multi-color mode.

  MULTI-COLOR MODE BIT

    To turn on multi-color character mode, set bit 4 of the VIC-II control
  register at 53270 ($D016) to a 1 by using the following POKE:

    POKE 53270,PEEK(53270)OR 16

    To turn off multi-color character mode, set bit 4 of location 53270 to
  a 0 by the following POKE:

    POKE 53270,PEEK(53270)AND 239

    Multi-color mode is set on or off for each space on the screen, so that
  multi-color graphics can be mixed with high-resolution (hi-res) graphics.
  This is controlled by bit 3 in color memory. Color memory begins at
  location 55296 ($D800 in HEX). If the number in color memory is less than
  8 (0-7) the corresponding space on the video screen will be standard
  hi-res, in the color (0-7) you've chosen. If the number located in color
  memory is greater or equal to 8 (from 8 to 15), then that space will be
  displayed in multi-color mode.







    By POKEing a number into color memory, you can change the color of the
  character in that position on the screen. POKEing a number from 0 to 7
  gives the normal character colors. POKEing a number between 8 and 15 puts
  the space into multi-color mode. In other words, turning BIT 3 ON in
  color memory, sets MULTI-COLOR MODE. Turning BIT 3 OFF in color memory,
  sets the normal, HIGH-RESOLUTION mode.
    Once multi-color mode is set in a space, the bits in the character
  determine which colors are displayed for the dots. For example, here is
  a picture of the letter A, and its bit pattern:

                          IMAGE    BIT PATTERN

                            **       00011000
                           ****      00111100
                          **  **     01100110
                          ******     01111110
                          **  **     01100110
                          **  **     01100110
                          **  **     01100110
                                     00000000

    In normal or high-resolution mode, the screen color is displayed
  everywhere there is a 0 bit, and the character color is displayed where
  the bit is a 1. Multi-color mode uses the bits in pairs, like so:

                          IMAGE    BIT PATTERN

                           AABB      00011000
                           CCCC      00111100
                         AABBAABB    01100110
                         AACCCCBB    01111110
                         AABBAABB    01100110
                         AABBAABB    01100110
                         AABBAABB    01100110
                                     00000000

    In the image area above, the spaces marked AA are drawn in the
  background #1 color, the spaces marked BB use the background #2 color,
  and the spaces marked CC use the character color. The bit pairs determine
  this, according to the following chart:





  +----------+--------------------------------------+---------------------+
  | BIT PAIR |          COLOR REGISTER              |       LOCATION      |
  +----------+--------------------------------------+---------------------+
  |    00    |  Background #0 color (screen color)  |   53281 ($D021)     |
  |    01    |  Background #l color                 |   53282 ($D022)     |
  |    10    |  Background #2 color                 |   53283 ($D023)     |
  |    11    |  Color specified by the              |   color RAM         |
  |          |  lower 3 bits in color memory        |                     |
  +----------+--------------------------------------+---------------------+




  Type NEW and then type this demonstration program:


start tok64 page117.prg
  100 poke 53281,1: rem set background color #0 to white
  110 poke 53282,3: rem set background color #1 to cyan
  120 poke 53282,8: rem set background color #2 to orange
  130 poke 53270,peek(53270)or16: rem turn on multicolor mode
  140 c=13*4096+8*256: rem set c to point to color memory
  150 printchr$(147)"aaaaaaaaaa"
  160 forl=0to9
  170 pokec+l,8: rem use multi black
  180 next
stop tok64



    The screen color is white, the character color is black, one color
  register is cyan (greenish blue), the other is orange. You're not really
  putting color codes in the space for character color, you're actually
  using references to the registers associated with those colors. This
  conserves memory, since 2 bits can be used to pick 16 colors (background)
  or 8 colors (character). This also makes some neat tricks possible.
  Simply changing one of the indirect registers will change every dot drawn
  in that color. Therefore everything drawn in the screen and background






  colors can be changed on the whole screen instantly. Here is an example
  of changing background color register #1:

start tok64 page118.prg
  100 poke53270,peek(53270)or16: rem turn on multicolor mode
  110 print chr$(147)chr$(18);
  120 print"{orange*2}";: rem type c= & 1 for orange or multicolor black bg
  130 forl=1to22:printchr$(65);:next
  135 fort=1to500:next
  140 print"{blue*2}";: rem type ctrl & 7 for blue color change
  145 fort=1to500:next
  150 print"{black}hit a key"
  160 get a$:if a$=""then160
  170 x=int(rnd(1)*16)
  180 poke 53282,x
  190 goto 160
stop tok64






    By using the <C=> key and the COLOR keys the characters can be changed
  to any color, including multi-color characters. For example, type this
  command:

    POKE 53270,PEEK(53270)OR 16:PRINT"<CTRL+3>";: rem lt.red/ multi-color
  red

    The word READY and anything else you type will be displayed in multi-
  color mode. Another color control can set you back to regular text.






    Here is an example of a program using multi-color programmable
  characters:


start tok64 page119.prg
  10 rem * example 2 *
  20 rem creating multi color programmable characters
  31 poke 56334,peek(56334)and254:poke1,peek(1)and251
  35 fori=0to63:rem character range to be copied from rom
  36 forj=0to7:rem copy all 8 bytes per character
  37 poke 12288+i*8+j,peek(53248+i*8+j):rem copy a byte
  38 next j,i:rem goto next byte or character
  39 poke 1,peek(1)or4:poke 56334,peek(56334)or1:rem turn on i/o and kb
  40 poke 53272,(peek(53272)and240)+12:rem set char pointer to mem. 12288
  50 poke 53270,peek(53270)or16
  51 poke 53281,0:rem set background color #0 to black
  52 poke 53282,2:rem set background color #1 to red
  53 poke 53283,7:rem set background color #2 to yellow
  60 for char=60to63:rem program characters 60 thru 63
  80 for byte=0to7:rem do all 8 bytes of a character
  100 read number:rem read 1/8th of the character data
  120 poke 12288+(8*char)+byte,number:rem store the data in memory
  140 next byte,char
  150 print"{clear}"tab(255)chr$(60)chr$(61)tab(55)chr$(62)chr$(63)
  160 rem line 150 puts the newly defined characters on the screen
  170 get a$:rem wait for user to press a key
  180 if a$=""then170:rem if no keys were pressed, try again
  190 poke53272,21:poke53270,peek(53270)and239:rem return to normal chars
  200 data129,37,21,29,93,85,85,85: rem data for character 60
  210 data66,72,84,116,117,85,85,85: rem data for character 61
  220 data87,87,85,21,8,8,40,0: rem data for character 62
  230 data213,213,85,84,32,32,40,0: rem data for character 63
  240 end
stop tok64






  EXTENDED BACKGROUND COLOR MODE

    Extended background color mode gives you control over the background
  color of each individual character, as well as over the foreground color.
  For example, in this mode you could display a blue character with a
  yellow background on a white screen.
    There are 4 registers available for extended background color mode.
  Each of the registers can be set to any of the 16 colors.
    Color memory is used to hold the foreground color in extended back-
  ground mode. It is used the same as in standard character mode.
    Extended character mode places a limit on the number of different
  characters you can display, however. When extended color mode is on, only
  the first 64 characters in the character ROM (or the first 64 characters
  in your programmable character set) can be used. This is because two of
  the bits of the character code are used to select the background color.
  It might work something like this:
    The character code (the number you would POKE to the screen) of the
  letter "A" is a 1. When extended color mode is on, if you POKED a 1 to
  the screen, an "A" would appear. If you POKED a 65 to the screen
  normally, you would expect the character with character code (CHR$) 129
  to appear, which is a reversed "A." This does NOT happen in extended
  color mode. Instead you get the same unreversed "A" as before, but on a
  different background color. The following chart gives the codes:


  +------------------------+---------------------------+
  |     CHARACTER CODE     | BACKGROUND COLOR REGISTER |
  +------------------------+---------------------------+
  |  RANGE   BIT 7   BIT 6 |  NUMBER       ADDRESS     |
  +------------------------+---------------------------+
  |   0- 63   0       0    |    0       53281 ($D021)  |
  |  64-127   0       1    |    1       53282 ($D022)  |
  | 128-191   1       0    |    2       53283 ($D023)  |
  | 192-255   1       1    |    3       53284 ($D024)  |
  +------------------------+---------------------------+


    Extended color mode is turned ON by setting bit 6 of the VIC-II regis-
  ter to a 1 at location 53265 ($D011 in HEX). The following POKE does it:

    POKE 53265,PEEK(53265)OR 64


  120   PROGRAMMING GRAPHICS
~


    Extended color mode is turned OFF by setting bit 6 of the VIC-II regis-
  ter to a 0 at location 53265 ($D011). The following statement will do
  this:

    POKE 53265,PEEK(53265)AND 191


  BIT MAPPED GRAPHICS

    When writing games, plotting charts for business applications, or other
  types of programs, sooner or later you get to the point where you want
  high-resolution displays.
    The Commodore 64 has been designed to do just that: high resolution is
  available through bit mapping of the screen. Bit mapping is the method in
  which each possible dot (pixel) of resolution on the screen is assigned
  its own bit (location) in memory. If that memory bit is a one, the dot it
  is assigned to is on. If the bit is set to zero, the dot is off.
    High-resolution graphic design has a couple of drawbacks, which is why
  it is not used all the time. First of all, it takes lots of memory to bit
  map the entire screen. This is because every pixel must have a memory bit
  to control it. You are going to need one bit of memory for each pixel
  (or one byte for 8 pixels). Since each character is 8 by 8, and there are
  40 lines with 25 characters in each line, the resolution is 320 pixels
  (dots) by 200 pixels for the whole screen. That gives you 64000 separate
  dots, each of which requires a bit in memory. In other words, 8000 bytes
  of memory are needed to map the whole screen.
    Generally, high-resolution operations are made of many short, simple,
  repetitive routines. Unfortunately, this kind of thing is usually rather
  slow if you are trying to write high-resolution routines in BASIC. How-
  ever, short, simple, repetitive routines are exactly what machine lan-
  guage does best. The solution is to either write your programs entirely
  in machine language, or call machine language, high-resolution sub-
  routines from your BASIC program using the SYS command from BASIC. That
  way you get both the ease of writing in BASIC, and the speed of machine
  language for graphics. The VSP cartridge is also available to add high-
  resolution commands to COMMODORE 64 BASIC.
    All of the examples given in this section will be in BASIC to make them
  clear. Now to the technical details.
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

Alright, so, this is what I'm up to.

I'm currently writing a BASIC program on WinVICE that loads the dungeon layout from disk and displays it on-screen. The idea is that a person can use the cursor keys and SPACEBAR to edit any of the 484 squares on the dungeon to rearrange the dungeon as he/she sees fit, then rewrite the altered bytes back to disk.

I'm going to have to alter the C64 character set to visually represent each square as a character, which means I need help in figuring out how many different configurations a given tile can display.

There's doors, walls, secret doors, and nothing. In each of 4 directions.

Can anyone help?
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

Here's my latest image disk:
http://www.mediafire.com/?sharekey=2273 ... f6e8ebb871

The file again is "SCREEN.PRG"...what I want to do now is make it so that a cursor appears at 0N 0E that moves around, but unfortunately I don't know how to do that.

Requesting assistance. :?
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

WTF WTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTFWTF


The latest incarnation of my would-be Wine Cellars editor (reader at this point):
http://www.mediafire.com/download.php?4zzmo22z54g

I found I was loading the traps code and not the actual dungeon layout code. So I changed the pointer so that it loads the proper code this time, or tries to.

When it gets as far as loading 0N, 6E it aborts with an "?ILLEGAL QUANTITY ERROR" message, meaning it has hit a null character. But there's no null characters where the code is. And the 6 characters it does load should read:

Code: Select all

DtEeee
But instead it gives me:

Code: Select all

DtEees
Could someone, anyone at all, please, very kindly, help me?
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

The latest attempt is successful. Managed to get the program to completely load the physical layout of the Wine Cellars and actually render it on-screen.

The latest disk image is: http://www.mediafire.com/?sharekey=2273 ... f6e8ebb871
"SCREEN8.PRG" is the most complete.

Now, to overcome the character set conflict. :?
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

Well work continues steadily on my prototype "Wine Cellar editor".

Here's what I have so far:
- copy character set from ROM to RAM
- load Wine Cellar map and display it on screen via POKEd memory locations
- render on-screen characters into map
- implement 4-directional scrolling of "cursor" ('twas something of a bitch to get going, by the by)
- begun work on displaying editing menu and implementation of various commands

What I hope to put in in the next, say, 72 hours:
- functional editing menu
- re-write the edited dungeon back to disk successfully
- re-load the edited dungeon into memory and re-edit successfully

Then after that, I hope to transload a few other dungeon levels into the loader so I can tokenize tiles that don't appear in the Wine Cellar (e.g. secret doors and what have you)...
Chaney
Posts: 100
Joined: Tue Jun 27, 2006 7:56 pm
Location: California

Post by Chaney »

Post it when it is remotely functional, and I will gladly beta test if for you.
When in doubt, kick your neighbors dog!
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

Chaney wrote:Post it when it is remotely functional, and I will gladly beta test if for you.
You any good at CBM BASIC V2.0 perchance?
Chaney
Posts: 100
Joined: Tue Jun 27, 2006 7:56 pm
Location: California

Post by Chaney »

Well, considering that I don't know what it is, I am going to have to say, doubtful. lol
When in doubt, kick your neighbors dog!
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

Alright, playtesters. :roll:

So far, what I have is a dungeon READER. Right now, it's set up to read in the physical layout of Kylearan's Amber Tower.

The disk image containing the relevent program is: http://www.mediafire.com/?sharekey=2273 ... f6e8ebb871
The disk image is "8BBK.D64", and "KY.PRG" is the filename. When prompted, insert the BTI DUNGEON disk and let it read in the dungeon. The screen will fill up with garbled characters; when all 22x22 grids are filled in, tap a key and the dungeon should (mostly) transform before your eyes into the familiar level of Kylearan's Tower.

What I need you people to do is to inspect the render and tell me if anything is amiss and provide me with some feedback.

And don't worry, there's no way the program will write to the dungeon disk - yet. If you're that concerned, you can make a backup copy first or just LIST the program before running it.

I await your feedbacks.
User avatar
Horpner
Posts: 224
Joined: Thu Jan 08, 2009 11:53 pm
Location: New England
Contact:

Post by Horpner »

This is an extremely cool program already. It must have been a massive amount of work.

Most of the "bugs" I'm going to point out are probably things you know about already, but here goes anyway.

I really like the way you handled the cursor, with the walls highlighting just right so their two-sided nature is emphasized. However, the cursor is unfortunately invisible when their are no walls at all. Using REVERSE instead of changing the foreground color could be a good solution, or changing both the foreground and background color under the cursor would also work.

On my version, the special characters didn't show up until I moved the cursor the first time. Then the blanks on the screen all became doors to the west, and some of the help text got corrupted, too, as special characters overwrote them. It may be necessary to conserve enough normal characters to display the text and blanks you need in your interface (though I'm only speculating about how the C64's character mapping works). The graphics characters you've created should be written over C64 graphics characters only, if that makes any sense.

In Kylearan's tower there are a few extraneous characters I don't understand, e.g., a Y at 15N 10E, a reverse F next to it, etc. They may well be something that's an upcoming feature, though.

In general, I like the color scheme and the interface so far. They are both pleasant and easy to use.
Death and drek? WTF?
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

The extraenous characters are just wall/door/secret door combinations I haven't POKED in yet. If you look at lines 400-550 that's where I tell the program to change the characters.

As for characters being overwritten, that's because I've taken the ASCII equivalent to what the characters on the disk are and assigned them their wall/door/secret door value. I intend to rectify this by reassigning unused special characters to normal text once I have the reader perfected.

For instance, consider the room with the magic mouth that asks for SINISTER at 2N, 12E. The binary value for this according to your chart elsewhere I believe is: 01100101...which translates to decimal value 101. So I take 101, multiply it by 8 (since there's 8 lines for that character) and add 12288 to the result, and there's my starting POKE for that particular combination.

In the shower just now I realized that I'm forgetting to read in two important bits here - the "name" of the level that appears below the window and whether the dungeon level is shielded (i.e. from APAR/PHDO).


For that matter, I was thinking about how overall to allow people to write a game with no particular size.
Consider that in the existing BTII engine (which is our actual target), the players start off in the AG in city #1 which is named "Tangramayne". City #1 has the following "specials" within buildings: Roscoe's, Review Board, AG, Casino, Casino, Bank, Garth's, and the Dark Domain. Let's suppose the party is slightly suicidal and skips Garth's and heads right for the DD, which is located across town. The party enters the building and is given the option to (T)ake the stairs, at which point the game needs to use a lookup table to know which DUNGEON disk to prompt the player to insert (i.e. A, B, C, W, Z...) as well as the dungeon name, level #, and the byte indicating YES/NO for shielded - it has to grab the TRACK, SECTOR, POSITION# to read the first half of the dungeon, then the T/S/P for the 2nd half, then it has to grab the TSP for the traps/specials layout for each half, then finally the TSP for the actual special-specials for both halves.

Now, let's suppose the party manages to find the stairs down to the 2nd level of the Dark Domain. From here, it needs to know which dungeon disk, direction (are we going down or up away from civilization?)(which would be level +1), shielded yes/no byte, TSP for physical layout, TSP for traps, TSP for special code, TSP for name...and on and on.

It might do well to bear in mind that the Wilderness and six cities are also "dungeons", just disguised to look like outdoors. :?
Chaney
Posts: 100
Joined: Tue Jun 27, 2006 7:56 pm
Location: California

Post by Chaney »

Well, I have a few questions. I have never used the commodore, or any emulators. I downloaded an emulator. When it gets to the part to load the dungeon disc, how do I actually do that?
When in doubt, kick your neighbors dog!
User avatar
Horpner
Posts: 224
Joined: Thu Jan 08, 2009 11:53 pm
Location: New England
Contact:

Post by Horpner »

It depends on which emulator.

With Vice/WinVice you press Alt-8, and then select the disk image (which you can download from this web-site).

With CCS64, you press F9, and then use the arrow keys to find they disk you want to insert, and then press F1 once you've selected it.
Death and drek? WTF?
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

I've sketched out a flow chart of sorts for the BTII engine and how the dungeon levels relate to one another.

http://www.mediafire.com/?sharekey=2273 ... f6e8ebb871

I definitely need some help with this.
Post Reply