        XDEF    _interpret       ; Bitmap-to-Ascii function
        XDEF    _CopyFont        ; Copies a font and aligns it to 16 bit.
        XREF    _CharData        ; Font data
        XREF    _SrcData
        XREF    _CharLoc
        XREF    _CharKern
        XREF    _Modulo
        XREF    _FontWidth
        XREF    _FontHeight
        XREF    _Underscore
        XREF    _TrueUnderscore
        XREF    _LoChar
        XREF    _HiChar
        XREF    _IFlags

        XDEF   _myActivateWindow

        SECTION CODE

USC     equ 1                   ; Interpreted char was underscored
PUSC    equ 2                   ; Prevoius char was underscored
PUS     equ 4                   ; Pending underscored space
CHEIGHT equ 24                  ; Max height of unpacked character

_interpret:
        link    a5,#0
        movem.l d1-d6/a1,-(sp)   ; Free a couple of registers
        move.l  8(a5),a1         ; Bitmap
        move.w  (a1),d2          ; First row
        moveq   #0,d4            ; Code
        move.b  _LoChar,d4       ; First char
        move.w  _FontWidth,d0
        asl.w   #1,d0            ; Times two for words
        lea     MaskTable,a0
        move.w  0(a0,d0.w),d3    ; d3 := mask
        move.l  _CharData,a0     ; Char image data
        bclr.b  #PUS,_IFlags     ; No pending-underscored-space
.lp1
        cmpi.b  #31,d4           ; Into printable characters yet?
        bhi     .Search          ; If yes, go and start searching
        addq    #1,d4            ; Move to next char
        adda.l  #CHEIGHT*2,a0    ; Increment bitmap ptr also
        bra     .lp1             ; Back to check again
.Search
        cmp.w   (a0),d2          ; Compare first word
        bne     .tryinverted     ; Not this one
        bclr.b  #USC,_IFlags     ; Assume not underscored
        moveq   #1,d5            ; current word
        moveq   #0,d6            ; Modulo
.morerows
        addq    #2,d6            ; Add modulo - next bit row in image data
        move.w  0(a0,d6.w),d1    ; Character row
        cmp.w   0(a1,d6.w),d1
        beq     .stdmatch        ; Rows matched
        cmp.w   _Underscore,d5   ; Could it be the underscore line?
        bne     .tryinverted     ; Nope
        tst.b   _TrueUnderscore  ; Use true underscore?
        beq     .uscmatch        ; No. Let's hope it's okay
        moveq   #0,d1            ;   00000000
        move.w  0(a0,d6.w),d0    ;   00110000
        or.w    d0,d1            ;   00110000
        rol.l   #2,d1            ; 0011000000
        or.w    d0,d1            ; 0011110000
        ror.l   #1,d1            ;  X01111000
        eor.w   d3,d1            ;   10000111
        or.w    d0,d1            ;   10110111
        move.w  0(a1,d6.w),d0
        eor.w   d0,d1            ;   Zero if equal
                                 ; But, let's skip the last bit since it
                                 ; may be affected by the next character
        lsr.w   #1,d1            ; Shift one step right
        and.w   d3,d1            ; Mask out last bit
        bne     .tryinverted
.uscmatch
        bset.b  #USC,_IFlags     ; Set underscored flag
.stdmatch
        addq    #1,d5            ; Next row in bitmap
        cmp.w   _FontHeight,d5   ; Are we done?
        bne     .morerows        ; Not yet
        cmp.b   #' ',d4           ; Space
        bne     .notuspace
        ; Space. Check for underscore
        btst.b  #USC,_IFlags     ; Underscored char?
        beq     .notuspace       ; Nope, everything ok
        ; Underscored space. Check if previous char was underscored
        btst.b  #PUSC,_IFlags    ; Previous char underscored?
        bne     .okuspace        ; Yep, ok underscored space
        ; Previous char not underscored. Set pending-underscored-space flag
        ; and go on to check if the normal underscore char matches
        bset.b  #PUS,_IFlags
        bra     .tryinverted

.notuspace
.okuspace
        bclr.b  #PUSC,_IFlags    ; Clear previous-underscored
        btst.b  #USC,_IFlags     ; Underscored char?
        beq     .interpreted     ; Nope
        bset.b  #PUSC,_IFlags    ; Set previous-underscored
        bra     .interpreted     ; Got it

.tryinverted
        move.w  (a0),d1          ; Copy first row
        eor.w   d3,d1            ; and invert the bits
        cmp.w   d2,d1            ; Compare inverted rows
        bne     .trybold         ; No match
        moveq   #1,d5            ; current row
        moveq   #0,d6            ; Modulo
.moreinverted
        addq    #2,d6
        move.w  0(a0,d6.w),d1    ; Character row
        eor.w   d3,d1            ; and invert the bits
        cmp.w   0(a1,d6.w),d1
        bne     .trybold         ; Rows didn't match
        addq    #1,d5            ; Next row in bitmap
        cmp.w   _FontHeight,d5   ; Are we done?
        bne     .moreinverted    ; Not yet
        bra     .interpreted     ; Got it

.trybold
        move.w  (a0),d1          ; Copy first row
        lsr.w   #1,d1            ; Shift one step left
        or.w    (a0),d1          ; Make bold
        and.w   d3,d1            ; and mask out unwanted bits
        cmp.w   d2,d1            ; Compare bold rows
        bne     .trynext         ; No match
        moveq   #1,d5            ; current row
        moveq   #0,d6            ; Modulo
.morebold
        addq    #2,d6
        move.w  0(a0,d6.w),d1    ; Character row
        lsr.w   #1,d1            ; Shift one step left
        or.w    0(a0,d6.w),d1    ; Make bold
        and.w   d3,d1            ; and mask out unwanted bits
        cmp.w   0(a1,d6.w),d1
        bne     .trynext         ; Rows didn't match
        addq    #1,d5            ; Next row in bitmap
        cmp.w   _FontHeight,d5   ; Are we done?
        bne     .morebold        ; Not yet
        bra     .interpreted     ; Got it

.trynext
        adda.l  #CHEIGHT*2,a0    ; Try next character, 32 bytes/char
        cmp.b   _HiChar,d4       ; Tried all chars?
        beq     .nomore          ; No more to try
        addq    #1,d4            ; Next char
        bra     .Search

.nomore
        move.l  #0,d4            ; Not found
        btst.b  #PUS,_IFlags     ; Hey, perhaps it was an underscored space?
        beq     .interpreted     ; Nope, return not-found
        move.l  #' ',d4

.interpreted
        move.l  d4,d0
        movem.l (sp)+,d1-d6/a1
        unlk    a5
        rts


_CopyFont:
        movem.l d2-d6/a2/a3/a5,-(sp)   ; Free a couple of registers
        moveq   #0,d0
        moveq   #0,d6               ; Don't shift if no kerning data
        move.l  _CharData,a2        ; a2 := Destination area
        move.l  _CharLoc,a3
        move.l  _CharKern,a5
        move.b  _LoChar,d5
        move.w  _Modulo,d3

.NextChar
        move.w  (a3)+,d0            ; Get char location
        move.w  d0,d1
        and.w   #15,d1              ; Shift amount
        eori.b  #15,d1              ; Negate shift value
        addq.b  #1,d1               ; d1 := Shift Amount
        cmpa.l  #0,a5               ; Check for kerning data
        beq     .nokern             ; No kerning to adjust for
        move.w  (a5)+,d6            ; Kerning

.nokern
        move.l  _SrcData,a0
        lsr.w   #3,d0               ; Byte offset
        bclr    #0,d0               ; But we deal in words
        adda.w  d0,a0               ; a0 := chardata

        move.w  (a3)+,d0            ; Get char width
        asl.w   #1,d0               ; Times two for words
        lea     MaskTable,a1
        move.w  0(a1,d0.w),d2       ; d2 := mask

        moveq   #0,d4
        move.w  _FontHeight,d4
        move.l  a2,a1               ; a1 := Destination area
        adda.w  #CHEIGHT*2,a2       ; a2 to next dest area
        bra     .loop
.copyrow
        move.l  (a0),d0             ; Get character row
        adda.w  d3,a0               ; Add modulo -- To next row
        lsr.l   d1,d0               ; Shift data to bit 0 alignment
        and.w   d2,d0               ; Mask out unwanted bits
        lsr.w   d6,d0               ; Shift according to kerning
        move.w  d0,(a1)+            ; Save row
.loop
        dbra    d4,.copyrow         ; Do all rows

        cmp.b   _HiChar,d5          ; Finished?
        beq     .copydone           ; Yes
        addq    #1,d5               ; Next char
        bra     .NextChar           ; Nope -- do next.

.copydone
        movem.l (sp)+,d2-d6/a2/a3/a5
        rts

MaskTable
        dc.w    $0000
        dc.w    $8000
        dc.w    $c000
        dc.w    $e000
        dc.w    $f000
        dc.w    $f800
        dc.w    $fc00
        dc.w    $fe00
        dc.w    $ff00
        dc.w    $ff80
        dc.w    $ffc0
        dc.w    $ffe0
        dc.w    $fff0
        dc.w    $fff8
        dc.w    $fffc
        dc.w    $fffe
        dc.w    $ffff


_myActivateWindow:
        rts

        END
