GeSHi language file for PIC assembler (18Fxxxx)

I occasionally use GeSHi on this site (via the GeSHi Filter Drupal module) to add syntax highlighting to code snippets, but usually not PIC assembler. Even though it lists MPASM among its supported formats, GeSHi highlighting has always been uneven and incomplete, at least when applied to my PIC18F242-based code. For example:

;; ----------------------------------------------
;;  void restart()
;;
;;  Reset the countdown period for the millisecond timer.
;;
restart:
   ; Set up the basic timer operation.
   movlw    b'00001000'
            ; 0------- TMR0ON       ; turn off timer
            ; -0------ T08BIT       ; use 16-bit counter
            ; --0----- T0CS         ; use internal instruction clock
            ; ---X---- TOSE         ; [not used with internal instruction clock]
            ; ----1--- PSA          ; do not prescale timer output
            ; -----XXX T0PSx        ; [not used when prescaler inactive]
   movwf    T0CON
 
   ; Establish the countdown based on calculated MIPS.
   movlw    kTickDelay >> 8
   movwf    TMR0H
   movlw    kTickDelay & 0xff
   movwf    TMR0L
 
   ; Clear the timer interrupt flag.
   bcf      INTCON, TMR0IF
   btfsc    INTCON, TMR0IF          ; is the flag clear now?
     bra    $-2                     ; no, wait for it to change
 
   ; Unmask the timer interrupt and turn on the countdown timer.
   bsf      INTCON, TMR0IE
   bsf      T0CON, TMR0ON
   return

It’s obvious that some opcodes and registers aren’t recognized, and bit names like TMR01E and TMR0ON are completely ignored. Identifying the TMR0H register as TMR plus 0H is just annoying.

I saw that a relatively recent update added a “PIC16” format, and it definitely offered an improvement, which is to say, the opcodes were uniformly ignored:

;; ----------------------------------------------
;;  void restart()
;;
;;  Reset the countdown period for the millisecond timer.
;;
restart:
   ; Set up the basic timer operation.
   movlw    b'00001000'
            ; 0------- TMR0ON       ; turn off timer
            ; -0------ T08BIT       ; use 16-bit counter
            ; --0----- T0CS         ; use internal instruction clock
            ; ---X---- TOSE         ; [not used with internal instruction clock]
            ; ----1--- PSA          ; do not prescale timer output
            ; -----XXX T0PSx        ; [not used when prescaler inactive]
   movwf    T0CON
 
   ; Establish the countdown based on calculated MIPS.
   movlw    kTickDelay >> 8
   movwf    TMR0H
   movlw    kTickDelay & 0xff
   movwf    TMR0L
 
   ; Clear the timer interrupt flag.
   bcf      INTCON, TMR0IF
   btfsc    INTCON, TMR0IF          ; is the flag clear now?
     bra    $-2                     ; no, wait for it to change
 
   ; Unmask the timer interrupt and turn on the countdown timer.
   bsf      INTCON, TMR0IE
   bsf      T0CON, TMR0ON
   return

Finally, I just decided to create a language file (attached) to suit my own needs. It’s far from exhaustive, but at least it identifies the registers on the chip I’m using, as well as fuse values, segment identifiers, bit names, and preprocessor directives supported by mpasm and gpasm. Here’s the kind of highlighting I’ve been looking for:

;; ----------------------------------------------
;;  void restart()
;;
;;  Reset the countdown period for the millisecond timer.
;;
restart:
   ; Set up the basic timer operation.
   movlw    b'00001000'
            ; 0------- TMR0ON       ; turn off timer
            ; -0------ T08BIT       ; use 16-bit counter
            ; --0----- T0CS         ; use internal instruction clock
            ; ---X---- TOSE         ; [not used with internal instruction clock]
            ; ----1--- PSA          ; do not prescale timer output
            ; -----XXX T0PSx        ; [not used when prescaler inactive]
   movwf    T0CON
 
   ; Establish the countdown based on calculated MIPS.
   movlw    kTickDelay >> 8
   movwf    TMR0H
   movlw    kTickDelay & 0xff
   movwf    TMR0L
 
   ; Clear the timer interrupt flag.
   bcf      INTCON, TMR0IF
   btfsc    INTCON, TMR0IF          ; is the flag clear now?
     bra    $-2                     ; no, wait for it to change
 
   ; Unmask the timer interrupt and turn on the countdown timer.
   bsf      INTCON, TMR0IE
   bsf      T0CON, TMR0ON
   return

Still not perfect in every case, but GeSHi does a fairly good job for what it is. The GeSHi Filter module for Drupal provides a very convenient interface, so I’m satisfied with this solution for now. See Non-responsive Flash Memory or Function Pointers in PIC Assembler for a more extensive example.

I have no intention of submitting this language file for inclusion in the official GeSHi release, so it doesn’t bother me that GeSHi’s langcheck.php validation script complains about a few points (the file header comments don’t match a prescribed format, the tab spacing is wrong1, and the file is not described as part of GeSHi). It’s released under GPL v2, though (same as GeSHi), so feel free to use it however you see fit.

1 It’s the same as other “official” language files—4 spaces—so I’m not sure why it fails this test.

AttachmentSize
pic18.php9.66 KB

Comments

thanks ;-)

thanks ;-)