Created
July 15, 2018 20:32
-
-
Save randrews/6831f4c646067743b71412f82ea1ccd5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void init_lcd(); | |
void set_xy(char row, char col, char chip); | |
void draw_sprite(const char const *sprite, char chip); | |
void asm_helpers(); | |
const char CS2 = 0x10; | |
const char CS1 = 0x08; | |
const char arrow[8] = { | |
0b00010000, | |
0b00100000, | |
0b01000000, | |
0b11111111, | |
0b01000000, | |
0b00100000, | |
0b00010000, | |
0b00000000 | |
}; | |
void main() { | |
init_lcd(); | |
set_xy(2, 32, CS1); | |
draw_sprite(arrow, CS1); | |
__asm__("halt"); | |
} | |
void draw_sprite(const char const *sprite, char chip) { | |
sprite; chip; | |
__asm | |
push ix | |
push bc | |
push af | |
push hl | |
ld b, #8 ; Number of columns to draw | |
ld hl,#12 ; Offset from SP for "chip" | |
add hl,sp | |
ld c,(hl) ; "chip" in c | |
ld ix, #10 | |
add ix, sp | |
ld h, 1(ix) | |
ld l, (ix) ; hl is now the address of the first byte of "sprite" | |
spriteDrawLoop: | |
; Move a byte of the sprite to IO 0: | |
ld a, (hl) | |
out (#0),a | |
; Write it | |
ld a,c | |
call #sendDataToChip | |
inc hl ; Next byte, loop | |
djnz spriteDrawLoop | |
pop hl | |
pop af | |
pop bc | |
pop ix | |
__endasm; | |
} | |
void asm_helpers() { | |
// I want a few handy routines in ASM I can call, but, | |
// I can't just embed ASM wherever I want, it can only | |
// be in a function. So this function does nothing but | |
// give me a place to stick ASM that other functions' | |
// embedded ASM can call. | |
// LD1 | LD2 | RST | CS2 | CS1 | R/W | D/I | E | |
__asm | |
jp endASMHelpers | |
; Uses register A, expects CS1 or CS2 to be in a, sends command to that chip | |
sendToChip: | |
cpl | |
and #0x38 ; and it with 38 to turn off that CS | |
; Output with E low: | |
out (#1),a | |
inc a | |
out (#1),a ; Output again with E high | |
ld a,#0x38 ; Back to neutral | |
out (#1),a | |
ret | |
; Uses register A, expects CS1 or CS2 to be in a, sends data to that chip | |
sendDataToChip: | |
cpl | |
and #0x38 ; and it with 38 to turn off that CS | |
or #0x02 ; Turn on the D/I pin | |
; Output with E low: | |
out (#1),a | |
inc a | |
out (#1),a ; Output again with E high | |
ld a,#0x38 ; Back to neutral | |
out (#1),a | |
ret | |
; Uses register A, sends command to both LCD chips | |
sendToBothChips: | |
; DI low, CS1 low, pulse E: | |
ld a,#0x30 | |
out (#1),a | |
ld a,#0x31 | |
out (#1),a | |
ld a,#0x38 ; Both CSs back up | |
out (#1),a | |
; DI low, CS2 low, pulse E: | |
ld a,#0x28 | |
out (#1),a | |
ld a,#0x29 | |
out (#1),a | |
ld a,#0x38 ; Both CSs back up | |
out (#1),a | |
ret | |
endASMHelpers: | |
__endasm; | |
} | |
void set_xy(char row, char col, char chip) { | |
row; col; chip; | |
__asm | |
push ix | |
push af | |
push bc | |
ld ix,#8 | |
add ix,sp ; row is 0(ix), col is 1(ix), chip is 2(ix) | |
; Set column | |
ld a,#0x40 ; 64+y is the command to set the column | |
add a,1(ix) | |
out (#0),a | |
ld a,2(ix) ; ld the chip select pin into A and send a cmd | |
call #sendToChip | |
; Set row | |
ld a,#0xb8 ; b8+x sets the row | |
add a,(ix) | |
out (#0),a | |
ld a,2(ix) | |
call #sendToChip | |
pop bc | |
pop af | |
pop ix | |
__endasm; | |
} | |
void init_lcd() { | |
asm_helpers(); | |
__asm | |
push af | |
; Reset LCD by pulsing RST low | |
ld a,#0 | |
out (#1),a | |
ld a,#0x38 | |
out (#1),a | |
; Turn screen on by sending 0x3f command | |
ld a,#0x3f | |
out (#0),a | |
call #sendToBothChips | |
; Set Y column to 0 on both chips | |
ld a,#0x40 ; 64+y is the command to set the column | |
out (#0),a | |
call #sendToBothChips | |
; Set X row to 0 on both chips | |
ld a,#0xb8 ; b8+x sets the row | |
out (#0),a | |
call #sendToBothChips | |
pop af | |
__endasm; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment