Presentation of assembler code for quick reader
*************comprehension

Synopsis

Some bloke wrote code that was difficult to understand. I rewrote it in such a way that the object code would be the same, and yet the source would be clear to the reader. I felt that some important principles were demonstrated.

An Aside

I returned to this in June 2006 because I just found the listings that illustrate the point I wanted to make. That is included below.

September 2009. This item invoked a hostile response when posted in 2006, including the suggestion that I should do it in some easy and established way. I followed this up and explored some "Bit Font Editor" programs. One that looks as if it is free on the web, but what you get for nothing is only a 15 day evaluation, is "Bit Font Creator". This looks good, and I would use it if I had the work for it. In a task such as that described here, it won't do anything that you can't do just as easily here for nothing. If you use Bit Font Creator, your task might run smoothly, but you still will end up with code that is full of apparently meaningless magic numbers, and a maintenance problem. So unless you know how to incorporate a Bit Font program into your make file, read on for maintainable code. I still offer this suggestion to readers with my head held high.

August 2015. I have just discovered that the version of this on my website is “broken”. Fixed now.

You will see below that I have included the hex number fields (under shelter of the comment operator ";") to provide a contrast of the readability of the hex and pictorial representations, and to show how my contributions fit into the original code. In the 2006 posting of this, there was actually a mistake with the matching of the hex and pictorial, which I have only just discovered now. I hadn't picked it up before, and neither had those people who had read the article earlier and furnished comments. This proves my point. The mistake was obscure and not easily picked up BECAUSE it involved a mismatch of MAGIC NUMBERS.

Here is the article that set me off:











As I understand it, it is common for c compilers to have provision for entering data as hexadecimal, but not as binary. If the data to be entered has meaning as a pattern of bits, but not as a hex number, then this limitation can lead to obscurity. The obscurity in turn leads to increased probability of mistakes and more difficult maintenance. I have discussed this with expert c programmers, and we have surmised that the limitation can be overcome by establishing an ad hoc local presentation format with a bunch of #define statements. The example I have here is assembler code, not c, so the solution lies with the "equ" directive.

The original author of the code snippet in question wanted to present some pixel patterns. Perhaps he laid out his pixel patterns on graph paper, and then worked out which bits should be "1" and which should be "0", then grouped them together into bytes and transformed them to hexadecimal numbers. Then he would have had to turn to his editor and entered them into his program. Alternatively, maybe he used a Bit Font Editor. If so, he didn't say that in his article.

The result was:

       fcb              $00,$00,$0f,$11,$11,$0f,$01,$0e
       fcb              $02,$00,$06,$02,$02,$02,$12,$0c
       fcb              $00,$00,$1e,$11,$11,$1e,$10,$10
       fcb              $00,$00,$0d,$13,$11,$0f,$01,$01
       fcb              $00,$00,$11,$11,$11,$0f,$01,$0e

Now look at that bit pattern. Look at the lovely curves of the shape that is created by those pixels! Isn't it great!? NO IT ISN'T.
The shape of the figure that is mapped out by those pixels is completely obscured! What this programmer actually wrote into his file is just a bunch of MAGIC NUMBERS.

There is another way. The pixel pattern in question is an 8 by 8 pattern of dots in a dot matrix character presentation for a liquid crystal display. Why not write out the desired pattern so that we can see the character in the 8 by 8 format in the listing? I chose the underscore character as a character that makes a minimum impact on the white background, and the octothorp "#" (sometimes called "hash") as a character that makes a nice contrasty blotch that occupies the centre of the character location. The particular requirement is for a byte to represent each row of pixels. Thus we need to map a row of underscores and octothorps that visually represent the row of pixels as they would appear on the display to a form that the assembler can use. Here is my mapping in a file called bit_patt.ern You will notice that I have used the assembler's binary notion facility here. If I had been writing a file of "#define" to go into a c program, I could have made the file use hexadecimal notation. It would have just taken longer to create. It would be tedious indeed to write out that mapping, but this is a perfect application for a simple BASIC compiler. Here is my BASIC program that generates the mapping . I bet I wrote the BASIC program and generated the file that establishes the mapping in less time that the other bloke took to set out his pixels with the graph paper. Now all I have to write in the assembler file is:
INCLUDE bit_patt.ern
and I have human readable application specific byte presentation available in my assembler file.

This enables me to write my program in a way that shows what the pixel pattern will look like. Now, just imagine that some special character has to be generated in the application and a new pixel pattern is required for it. Which program would be easiest to edit to add the new character? The one with the hexadecimal data, or mine?

*----------------------------------------------------------------*
*          FILENAME -  DISP.ASM                                  *
*  Derived from - "Circle 521" Improved Lower Case On LCDs       *
*  by Jay Sarno                                                  *
*  page 100        ELECTRONIC DESIGN AUGUST 1996                 *
*----------------------------------------------------------------*
*  SYNOPSYS                                                      *
*  Work in Progress                                              *
*                                                                *
*                                                                *
*                                                                *
*----------------------------------------------------------------*
*  PROJECT   I just wanted to make a point                       *
*----------------------------------------------------------------*
* REVISION HISTORY   typed in from magazine. 07-10-96            *
* 1. Added EXTERN declaration to cover subroutines that are not  *
*     here                                                       *
* 2. Appended "a" to the beginning of all labels that start with *
*     "1"                                                        *
*    to meet X68C11 assembler requirements.                      *
* Assembles without error, but no listing generated.             *
* 3. Added a "CODE" directive.                                   *
*                                                                *
*----------------------------------------------------------------*
*
        LINKLIST
        LIST ON

        EXTERN set_lcd_write,send_lcd_cntl,send_lcd_data



        CODE




******************************************************************
*     LOAD_CG - Call this routine as part of system              *
*               initialization.                                  *
*       It loads the first 5 programmable characters in the      *
*       LCD display with improved versions of                    *
*      "g", "j", "p", "q" and "y".                               *
******************************************************************
load_cg:
        jsr     set_lcd_write   ;display's R/W bit low (write)
        ldab    #$40            ;sets display to receive CG data
        jsr     send_lcd_cntl   ;set the CG address register to 0
        ldx     #a1c_char_gen   ;point to the table with the new
                                ; g,j,p,q,y
        ldy     #40             ;set up a loopcounter

lcg_loop:
        ldab    0,x             ;get a row of CG bits
        jsr     send_lcd_data   ;send it to the LCD display
        inx                     ;advance the pointer
        dey                     ;decrement the loopcounter
        bne     lcg_loop
        rts

a1c_char_gen:

; Jay Sarno's pixel pattern table looked like this -

;       fcb     $00,$00,$0f,$11,$11,$0f,$01,$0e
;       fcb     $02,$00,$06,$02,$02,$02,$12,$0c
;       fcb     $00,$00,$1e,$11,$11,$1e,$10,$10
;       fcb     $00,$00,$0d,$13,$11,$0f,$01,$01
;       fcb     $00,$00,$11,$11,$11,$0f,$01,$0e

; Actual pixel patterns are completely obscured by this
; presentation.

; Try a binary presentation where each "1" is represented by a "#
; for maximum visual impression, and each "0" by a "_" for min.
; visual impact. This will cause each byte to be represented by a
; label made up of "#" and "_" characters.

; We need to provide a numeric value for each of these labels.
; The BASIC program DISPMAC.BAS builds a file bit_patt.ern
; that does this.

        INCLUDE bit_patt.ern


;       fcb     $00,$00,$0f,$11,$11,$0f,$01,$0e

        fcb A________
        fcb A________
        fcb A____####
        fcb A___#___#
        fcb A___#___#
        fcb A____####
        fcb A_______#
        fcb A____###_

;       fcb     $02,$00,$06,$02,$02,$02,$12,$0c

        fcb A______#_
        fcb A________
        fcb A_____##_
        fcb A______#_
        fcb A______#_
        fcb A______#_
        fcb A___#__#_
        fcb A____##__

;       fcb     $00,$00,$1e,$11,$11,$1e,$10,$10

        fcb A________
        fcb A________
        fcb A___####_
        fcb A___#___#
        fcb A___#___#
        fcb A___####_
        fcb A___#____
        fcb A___#____


;  This is the data he had for a "q"
;  I guess you had to see it on the display
;  It looks like a funny q to me. Anyway, it is very easy
;  to edit the character in the field of "_" and "#" characters.

;       fcb     $00,$00,$0d,$13,$11,$0f,$01,$01

        fcb A________
        fcb A________
        fcb A____##_#
        fcb A___#__##
        fcb A___#___#
        fcb A____####
        fcb A_______#
        fcb A_______#


;       fcb     $00,$00,$11,$11,$11,$0f,$01,$0e

        fcb A________
        fcb A________
        fcb A___#___#
        fcb A___#___#
        fcb A___#___#
        fcb A____####
        fcb A_______#
        fcb A____###_



*****************************************************************
*      DISPLAY_CHAR - The character in B is sent to the display.*
*      Any lower case character with a descender is translated  *
*      to the "improved" character code.                        *
*****************************************************************
display_char:
        jsr     set_lcd_write   ;display's R/W bit low (write)
        clra                    ;count
        ldx     #chars_to_fix   ;points to table of 1c chars to
                                ;change

a1c_hunt_loop:
        cmpb    0,x             ;see if a match to a descender
                                ;character
        beq     a1c_translate   ;if it matches, translate it
        inx                     ;next character to check
        inca                    ;keep count
        cmpa    #5
        blo     a1c_hunt_loop
        bra     char_ok_as_is   ;this char doesn't match any
                                ;in the table

a1c_translate:
        tab                     ;the "count" is the translated
                                ;char code

char_ok_as_is:
        jsr     send_lcd_data   ;send it to the LCD display
        rts

chars_to_fix:
        fcb     'g','j','p','q','y'


        end