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