Skip to content

bugg(er)ed code for 80x24 display driver needs fixing

1 message · 2006-03-16 → 2006-03-16 · Yahoo Group era · View archive on archive.org

Participants: Andrew Owen

Preserved from the Timex/Sinclair 2068 Yahoo Group (2001–2019), which is no longer online. Text reproduced from the archive.org archive; email addresses masked.

Messages

1. bugg(er)ed code for 80x24 display driver needs fixing

Andrew Owen · Thu, 16 Mar 2006 00:02

Here's my first stab at the display driver. It fails to work at all. I'll be going over the 
individual parts to see what might be going wrong but if anything jumps out at you feel 
free to tell me. It's designed for speed of execution rather than size or readability. Any 
ideas on speeding it up would also be welcome.

[code]
    org 50000       ; should leave enough room

CHAR:   defb    'A'     ; character
COL:    defb    0       ; column
ROW:    defb    0       ; row

; convert the row to the base screen address

    ld  a,(ROW)     ; get the row
    push    af      ; save it
    and #18     ; mask off bit 3-4
    ld  e,a     ; store high byte of offset in E
    pop af      ; retrieve it
    and #07     ; mask off bit 0-2
    rlca            ; shift
    rlca            ; five
    rlca            ; bits
    rlca            ; to the
    rlca            ; left
    ld  d,a     ; store low byte of offset in D

; add the column offset and calculate the routine to use

    ld  a,(COL)     ; get the column
    push    af      ; save it
    and #18     ; mask off bit 0-2
    ex  af,af'      ; store number of routine to use
    pop af      ; retrieve it
    and #78     ; mask off bit 3-6
    rrca            ; shift three
    rrca            ; bits to
    rrca            ; the right

    ld  hl,16385    ; REAL base location
    add hl,de       ; add the offset

    and a       ; test for zero
    jr  z,next      ; to next part if so

    ld  de,#03      ; amount to add

plus_3: add hl,de       ; increment by three
    dec a       ; reduce the count
    jr  nz,plus_3   ; keep going    

next:   ex  de,hl       ; put the result back in DE

; get the location in memory of the character

    ld  a,(CHAR)    ; get the character
    ld  hl,#00      ; clear HL
    ld  l,a     ; CHAR to low byte of HL
    add hl,hl       ; multiply
    add hl,hl       ; by
    add hl,hl       ; eight
    ld  de,FONT-#0100   ; offset to FONT
    add hl,de       ; HL holds address of first byte of
                ; character map in FONT_1

; HL now points to the location of the first byte of char data in FONT_1
; DE points to the first screen byte in SCREEN_1
; A' holds the offset to the routine

    exx         ; use alternate register set
    ld  e,a     ; offset to E
    ld  d,#00       ; prepare to add
    ld  hl,table    ; base address of table
    add hl,de       ; add E
    ld  e,(hl)      ; fetch offset to E
    add hl,de       ; add offset for address of handling routine
    push    hl      ; push the address on machine stack.
    exx         ; restore normal register set
    ret         ; make an indirect jump forward to routine.

table:  defb    pos_0 - #   ; offset
    defb    pos_1 - #   ;
    defb    pos_2 - #   ;
    defb    pos_3 - #   ;
    defb    pos_4 - #   ;
    defb    pos_5 - #   ;
    defb    pos_6 - #   ;
    defb    pos_7 - #   ;

; -------------------------------
; WRITE A CHARACTER TO THE SCREEN
; -------------------------------
;
; There are eight separate routines called based on the first three bits of the
; column value.

; HL points to the first byte of a character in FONT_1
; DE points to the first byte of the block of screen addresses

pos_4:  ld  bc,#2001    ; offset to SCREEN_2 +1
    ex  de,hl       ; swap registers
    add hl,bc       ; 16-bit addition
    ex  de,hl       ; swap registers
                ; DE now points to SCREEN_2 +1
                ; routine continues into pos_0



pos_0:  ld  c,#08       ; 8 bytes to write

pos_0a: ld  a,(de)      ; read byte at destination
    and #03     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back
    inc d       ; point to next screen location
    inc hl      ; point to next font data
    dec c       ; adjust counter
    jr  nz,pos_0a   ; loop 8 times
    ret         ; done



pos_1:  ld  bc,#0300    ; offset to FONT_2
    add hl,bc       ; HL addresses FONT_2
    ld  c,#08       ; 8 bytes to write

pos_1a: ld  a,(de)      ; read byte at destination
    and #fc     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    push    bc      ; save counter
    push    de      ; save screen address
    push    hl      ; save font address

    ld  bc,#2000    ; offset to SCREEN_2
    ex  de,hl       ; swap registers
    add hl,bc       ; 16-bit addition
    ex  de,hl       ; swap registers
                ; DE now points to SCREEN_2
    ld  bc,#0300    ; offset to FONT_3
    add hl,bc       ; HL addresses FONT_3

    ld  a,(de)      ; read byte at destination
    and #0f     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    pop hl      ; restore pointer to FONT_2
    pop de      ; restore pointer to SCREEN_1
    pop bc      ; restore counter

    inc d       ; point to next screen location
    inc hl      ; point to next font data
    dec c       ; adjust counter
    jr  nz,pos_1a   ; loop 8 times
    ret         ; done



pos_2:  ld  bc,#0C00    ; offset to FONT_5
    add hl,bc       ; HL addresses FONT_5
    inc de      ; next column
    ld  c,#08       ; 8 bytes to write

pos_2a: push    bc      ; save counter
    push    de      ; save screen address
    push    hl      ; save font address

    ld  bc,#1FFF    ; offset to SCREEN_2
    ex  de,hl       ; swap registers
    add hl,bc       ; 16-bit addition
    ex  de,hl       ; swap registers
                ; DE now points to SCREEN_2

    ld  bc,#0300    ; offset to FONT_4
    sbc hl,bc       ; HL addresses FONT_4

    ld  a,(de)      ; read byte at destination
    and #f0     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    pop hl      ; restore pointer to FONT_5
    pop de      ; restore pointer to SCREEN_1
    pop bc      ; restore counter

    ld  a,(de)      ; read byte at destination
    and #3f     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    inc d       ; point to next screen location
    inc hl      ; point to next font data
    dec c       ; adjust counter
    jr  nz,pos_2a   ; loop 8 times
    ret         ; done



pos_7:  ld  bc,#2001    ; offset to SCREEN_2 +1
    ex  de,hl       ; swap registers
    add hl,bc       ; 16-bit addition
    ex  de,hl       ; swap registers
                ; DE now points to SCREEN_2 +1
                ; routine continues into pos_3



pos_3:  ld  bc,#0f00    ; offset to FONT_6
    add hl,bc       ; HL addresses FONT_6
    inc de      ; next column
    ld  c,#08       ; 8 bytes to write

pos_3a: ld  a,(de)      ; read byte at destination
    and #c0     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back
    inc d       ; point to next screen location
    inc hl      ; point to next font data
    dec c       ; adjust counter
    jr  nz,pos_3a   ; loop 8 times
    ret         ; done



pos_5:  ld  bc,#0600    ; offset to FONT_3
    add hl,bc       ; HL addresses FONT_3
    inc de      ; next column
    inc de      ; next column
    ld  c,#08       ; 8 bytes to write

pos_5a: push    bc      ; save counter
    push    de      ; save screen address
    push    hl      ; save font address

    ld  bc,#1FFF    ; offset to SCREEN_2
    ex  de,hl       ; swap registers
    add hl,bc       ; 16-bit addition
    ex  de,hl       ; swap registers
                ; DE now points to SCREEN_2

    ld  bc,#0300    ; offset to FONT_2
    sbc hl,bc       ; HL addresses FONT_2

    ld  a,(de)      ; read byte at destination
    and #fc     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    pop hl      ; restore pointer to FONT_3
    pop de      ; restore pointer to SCREEN_1
    pop bc      ; restore counter

    ld  a,(de)      ; read byte at destination
    and #0f     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    inc d       ; point to next screen location
    inc hl      ; point to next font data
    dec c       ; adjust counter
    jr  nz,pos_5a   ; loop 8 times
    ret         ; done



pos_6:  ld  bc,#0600    ; offset to FONT_4
    add hl,bc       ; HL addresses FONT_4
    inc de      ; next column
    inc de      ; next column
    ld  c,#08       ; 8 bytes to write

pos_6a: ld  a,(de)      ; read byte at destination
    and #f0     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    push    bc      ; save counter
    push    de      ; save screen address
    push    hl      ; save font address

    ld  bc,#2000    ; offset to SCREEN_2
    ex  de,hl       ; swap registers
    add hl,bc       ; 16-bit addition
    ex  de,hl       ; swap registers
                ; DE now points to SCREEN_2
    ld  bc,#0300    ; offset to FONT_5
    add hl,bc       ; HL addresses FONT_5

    ld  a,(de)      ; read byte at destination
    and #3f     ; mask area used by new character
    or  (hl)        ; combine with character from font
    ld  (de),a      ; write it back

    pop hl      ; restore pointer to FONT_4
    pop de      ; restore pointer to SCREEN_1
    pop bc      ; restore counter

    inc d       ; point to next screen location
    inc hl      ; point to next font data
    dec c       ; adjust counter
    jr  nz,pos_6a   ; loop 8 times
    ret         ; done



; --------------------
; PRE-SHIFTED 6x8 FONT
; --------------------
;
; 96 character font in all four possible positions

FONT:   defb    #00,#00,#00,#00,#00,#00,#00,#00

[/code]

Indexed under

Video upgrades (composite, RGB, HDMI) · Machine code, Z80 & assemblers