Architecture-depend CTK implmeentation has been all rewritten by assembler for performance and memory reasons.

This commit is contained in:
matsutsuka 2007-09-19 12:46:15 +00:00
parent b2a6d163fc
commit 8d7bb2119c
6 changed files with 1721 additions and 709 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,432 +0,0 @@
;;;
;;;
;;; ctk-conio_arch-asm.hS
;;;
;;; Architecture depend ctk-conio implementation.
;;; This assembler source contributes basically saving for speed and memory.
;;;
;;; @author Takahide Matsutsuka <markn@markn.org>
;;;
;;; $Id: ctk-conio_arch-asm.hS,v 1.1 2007/09/11 12:12:59 matsutsuka Exp $
;;;
;; uses preprocessor to enable definitions
#include "ctk_arch-def.h"
;; export symbols
.globl _cputc_arch
.globl _cputs_arch
.globl _cputsn_arch
.globl _chline_arch
.globl _cvline_arch
.globl _gotoxy_arch
.globl _cclear_arch
.globl _revers_arch
.globl _clip_arch
.globl _ctk_draw_init
.globl _ctk_draw_clear
.globl _ctk_draw_clear_window
;; import symbols
.globl _info
.if 0
.globl _ctk_arch_window_x
.globl _ctk_arch_window_y
.globl _ctk_arch_window_h
.globl _ctk_arch_window_w
.endif
.area _DATA
_ctk_arch_reversed:
.ds 1
.area _CODE
;; ---------------------------------
;; void cputc(char ch);
;; Stack; ixl ixh retl reth ch
;; AF__DEHL____
;; return void
;; ---------------------------------
_cputc_arch:
push ix
ld ix, #_info
ld a, CURSY(ix)
cp a, CY1(ix) ; cursy - cy1
jr c, _cputc_arch_ret ; cusy < cy1
cp a, CY2(ix) ; cursy - cy2
jr z, _cputc_arch_next1
jr nc, _cputc_arch_ret ; cursy > cy2
_cputc_arch_next1:
cp a, #SCREEN_HEIGHT ; cursy - SCREEN_HEIGHT
jr z, _cputc_arch_next2
jr nc, _cputc_arch_ret ; cursy > SCREEN_HEIGHT
_cputc_arch_next2:
ld a, CURSX(ix)
cp a, #SCREEN_WIDTH ; cursx - SCREEN_WIDTH
jr nc, _cputc_arch_ret
;; calculate offset
ld a, CURSY(ix)
ld hl, #0
ld de, #SCREEN_WIDTH
_cputc_arch_loop:
or a
jr z, _cputc_arch_calcx
add hl, de
dec a
jr _cputc_arch_loop
_cputc_arch_calcx:
ld d, #0
ld e, CURSX(ix)
add hl, de
;; putchar
push hl
ld hl, #6
add hl, sp
ld a, (hl)
pop hl
ld de, #VRAM_CHAR
push hl
add hl, de
ld (hl), a
pop hl
;; putattr
ld de, #VRAM_ATTR
add hl, de
ld de, #_ctk_arch_reversed
ld a, (de)
or a
jr z, _cputc_arch_normal
ld (hl), #COLOR_REVERSED
jr _cputc_arch_ret
_cputc_arch_normal:
ld (hl), #COLOR_NORMAL
_cputc_arch_ret:
inc CURSX(ix)
pop ix
ret
;; ---------------------------------
;; void cputs_arch(char *str);
;; Stack; ixl ixh retl reth strl strh
;; AFB_DEHL____
;; return void
;; ---------------------------------
_cputs_arch:
push ix
ld hl, #4
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ld b, #0 ; max length
_cputs_arch_loop:
ld a, (de)
or a
jr z, _cputs_arch_ret
push bc
push de
push af
inc sp
call _cputc_arch
inc sp
pop de
pop bc
inc de
djnz _cputs_arch_loop
_cputs_arch_ret:
pop ix
ret
;; ---------------------------------
;; void cputsn(char *str, unsigned char length);
;; Stack; ixl ixh retl reth length
;; AFB_DEHL____
;; return void
;; ---------------------------------
_cputsn_arch:
push ix
ld ix, #4
add ix, sp
ld e, 0(ix)
ld d, 1(ix)
ld b, 2(ix)
jr _cputs_arch_loop ; take over B and DE
;; ---------------------------------
;; void chline(unsigned char length);
;; Stack; ixl ixh retl reth length
;; AFB_DEHL____
;; return void
;; ---------------------------------
_chline_arch:
push ix
ld hl, #4
add hl, sp
ld b, (hl)
ld a, #CH_HOLILINE
_chline_arch_loop:
push bc
push af
inc sp
call _cputc_arch
dec sp
pop af
pop bc
djnz _chline_arch_loop
pop ix
ret
;; ---------------------------------
;; void cvline(unsigned char length);
;; Stack; ixl ixh retl reth length
;; AFB_DEHL____
;; return void
;; ---------------------------------
_cvline_arch:
push ix
ld hl, #4 ; subject to change
add hl, sp
ld b, (hl) ; length
ld a, #CH_VERTLINE
ld ix, #_info
_cvline_arch_loop:
push bc
push af
inc sp
call _cputc_arch
dec sp
pop af
pop bc
inc CURSY(ix)
dec CURSX(ix)
djnz _cvline_arch_loop
pop ix
ret
;; ---------------------------------
;; void gotoxy(unsigned char x, unsigned char y)
;; Stack; ixl ixh retl reth x y
;; AF____HL____
;; return void
;; ---------------------------------
_gotoxy_arch:
push ix
ld hl, #4
add hl, sp
ld ix, #_info
ld a, (hl)
ld CURSX(ix), a
inc hl
ld a, (hl)
ld CURSY(ix), a
pop ix
ret
;; ---------------------------------
;; void clearTo(char x)
;; Stack; ixl ixh retl reth x
;; AF__DEHL____
;; return void
;; ---------------------------------
_cclear_arch:
push ix
ld ix, #_info
ld hl, #4
add hl, sp
_cclear_arch_loop:
ld a, (hl) ; x
cp a, CURSX(ix)
jr z, _cclear_arch_ret
jr c, _cclear_arch_ret
ld a, #CH_SPACE
push hl
push af
inc sp
call _cputc_arch
inc sp
pop hl
jr _cclear_arch_loop
_cclear_arch_ret:
ld a, (hl)
ld CURSX(ix), a
pop ix
ret
;; ---------------------------------
;; void revers_arch(unsigned char reverse)
;; Stack; retl reth reverse
;; A_____HL____
;; return void
;; ---------------------------------
_revers_arch:
ld hl, #2
add hl, sp
ld a, (hl)
ld hl, #_ctk_arch_reversed
ld (hl), a
ret
;; ---------------------------------
;; void clip_arch(unsigned char clip1, unsigned char clip2)
;; Stack; retl reth clip1 clip2
;; A_____HL____
;; return void
;; ---------------------------------
_clip_arch:
push ix
ld ix, #_info
ld hl, #4
add hl, sp
ld a, (hl)
ld CY1(ix), a
inc hl
ld a, (hl)
ld CY2(ix), a
pop ix
ret
;; ---------------------------------
;; void ctk_draw_init(void)
;; Stack; retl reth
;; _F____HL____ AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_init:
push ix
ld ix, #_info
ld h, #SCREEN_HEIGHT
ld l, #0
ld CY1(ix), l
ld CY2(ix), h
push hl
call _ctk_draw_clear
pop hl
pop ix
ret
;; ---------------------------------
;; ctk_draw_clear(unsigned char clipy1, unsigned char clipy2);
;; Stack; retl reth clipy1 clipy2
;; AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_clear:
ld hl, #2
add hl, sp
ld d, (hl) ; clipy1
inc hl
ld e, (hl) ; clipy2
ld c, #0
_ctk_draw_clear_loop:
ld a, d
cp a, e ; d - e (clipy1 - clipy2)
ret nc ; ret if clipy1 >= clipy2
push de
ld b, d
push bc
call _gotoxy_arch
pop bc
ld a, #SCREEN_WIDTH
push af
inc sp
call _cclear_arch
inc sp
pop de
inc d
jr _ctk_draw_clear_loop
.if 0
;; ---------------------------------
;; void ctk_draw_clear_window(struct ctk_window *window,
;; unsigned char focus,
;; unsigned clipy1,
;; unsigned clipy2);
;; Stack; retl reth windowl windowh focus clipy1 clipy2
;; AFBCDEHL____
;; return void
;; ---------------------------------
_ctk_draw_clear_get_value:
;; param; de=window, hl=offset
;; return a=value
;; A___________
push de
ld a, (hl)
add a, e
ld e, a
ld a, d
adc #0
ld d, a
ld a, (de)
pop de
ret
_ctk_draw_clear_window:
push ix
ld ix, #4
add ix, sp
ld l, 3(ix)
ld h, 4(ix)
push hl
call _clip_arch
pop hl
ld e, 0(ix)
ld d, 1(ix) ; #_window
ld hl, #_ctk_arch_window_y
call _ctk_draw_clear_get_value
ld b, a
inc b
inc b ; window->y + 2
ld hl, #_ctk_arch_window_h
call _ctk_draw_clear_get_value
ld c, a ; window->h
ld hl, #_ctk_arch_window_x
call _ctk_draw_clear_get_value
ld h, a
inc h ; window->x + 1
push hl
ld hl, #_ctk_arch_window_w
call _ctk_draw_clear_get_value
pop hl
ld l, a ; window->w
ld a, b ; i
_ctk_draw_clear_window_loop:
cp a, c ; i - h
jr nc, _ctk_draw_clear_window_ret
ld d, a
ld e, h ; d=i, e=window->x+1
push af
push hl
push de
call _gotoxy_arch
pop de
pop hl
ld a, h
add a, l ; window->x + 1+ window->w
push hl
push af
inc sp
call _cclear_arch
inc sp
pop af
pop hl
inc a
jr _ctk_draw_clear_window_loop
_ctk_draw_clear_window_ret:
pop ix
ret
void
ctk_draw_clear_window(struct ctk_window *window,
unsigned char focus,
unsigned char ctk_arch_clipy1,
unsigned char ctk_arch_clipy2) {
clip_arch(clipy1, clipy2);
h = window->y + 2 + window->h;
for(i = window->y + 2; i < h; ++i) {
gotoxy(window->x + 1, i)
cclear(window->x + 1 + window->w);
}
.endif

View file

@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ctk-conio_arch.c,v 1.1 2007/09/11 12:12:59 matsutsuka Exp $
* $Id: ctk-conio_arch.c,v 1.2 2007/09/19 12:46:15 matsutsuka Exp $
*
*/
@ -43,278 +43,59 @@
#include "ctk/ctk-draw.h"
#include "contiki-conf.h"
#include "ctk/ctk_arch.h"
#include "ctk/ctk-conio_arch.h"
#include <stddef.h>
struct screen_info {
char cursx; // +0
char cursy; // +1
char cy1; // +2
char cy2; // +3
};
struct screen_info info;
#if 0
const unsigned char ctk_arch_window_x = offsetof(struct ctk_window, x);
const unsigned char ctk_arch_window_y = offsetof(struct ctk_window, y);
const unsigned char ctk_arch_window_h = offsetof(struct ctk_window, h);
const unsigned char ctk_arch_window_w = offsetof(struct ctk_window, w);
#endif
unsigned char ctk_draw_windowtitle_height = 1;
/*---------------------------------------------------------------------------*/
/*
* w: widget
* x, y: screen position of client drawing area (left, top)
* focus: boolean
* Offset constants for assembler
*/
static void draw_widget(struct ctk_widget *w,
unsigned char x, unsigned char y,
unsigned char focus) {
unsigned char xpos, ypos, xscroll;
unsigned char i, j;
char c, *text;
const u8_t off_widget_x = offsetof(struct ctk_widget, x);
const u8_t off_widget_y = offsetof(struct ctk_widget, y);
const u8_t off_widget_w = offsetof(struct ctk_widget, w);
const u8_t off_widget_h = offsetof(struct ctk_widget, h);
const u8_t off_widget_type = offsetof(struct ctk_widget, type);
const u8_t off_widget_window = offsetof(struct ctk_widget, window);
const u8_t off_widget_label_text = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_label, text);
const u8_t off_widget_button_text = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_button, text);
const u8_t off_widget_textentry_text = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_textentry, text);
const u8_t off_widget_textentry_xpos = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_textentry, xpos);
const u8_t off_widget_textentry_ypos = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_textentry, ypos);
const u8_t off_widget_textentry_state = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_textentry, state);
#if CTK_CONF_ICONS
unsigned char len;
const u8_t off_widget_icon_title = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_icon, title);
const u8_t off_widget_icon_textmap = offsetof(struct ctk_widget, widget) +
offsetof(struct ctk_widget_icon, textmap);
#endif /* CTK_CONF_ICONS */
xpos = x + w->x;
ypos = y + w->y;
revers_arch(focus & CTK_FOCUS_WIDGET);
gotoxy_arch(xpos, ypos);
const u8_t off_window_x = offsetof(struct ctk_window, x);
const u8_t off_window_y = offsetof(struct ctk_window, y);
const u8_t off_window_h = offsetof(struct ctk_window, h);
const u8_t off_window_w = offsetof(struct ctk_window, w);
const u8_t off_window_inactive = offsetof(struct ctk_window, inactive);
const u8_t off_window_active = offsetof(struct ctk_window, active);
const u8_t off_window_next = offsetof(struct ctk_window, next);
const u8_t off_window_focused = offsetof(struct ctk_window, focused);
if (w->type == CTK_WIDGET_SEPARATOR) {
chline_arch(w->w);
} else if (w->type == CTK_WIDGET_LABEL) {
text = w->widget.label.text;
for(i = 0; i < w->h; ++i) {
gotoxy_arch(xpos, ypos);
cputsn_arch(text, w->w);
cclear_arch(xpos + w->w);
++ypos;
text += w->w;
}
} else if (w->type == CTK_WIDGET_BUTTON) {
cputc_arch('[');
cputsn_arch(w->widget.button.text, w->w);
cputc_arch(']');
} else if (w->type == CTK_WIDGET_HYPERLINK) {
cputsn_arch(w->widget.button.text, w->w);
} else if (w->type == CTK_WIDGET_TEXTENTRY) {
text = w->widget.textentry.text;
xscroll = 0;
if(w->widget.textentry.xpos >= w->w - 1) {
xscroll = w->widget.textentry.xpos - w->w + 1;
}
for(j = 0; j < w->h; ++j) {
gotoxy_arch(xpos, ypos);
if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT &&
w->widget.textentry.ypos == j) {
revers_arch(0);
cputc_arch('>');
for(i = 0; i < w->w; ++i) {
c = text[i + xscroll];
revers_arch(i == w->widget.textentry.xpos - xscroll);
cputc_arch((c == 0) ? CH_SPACE : c);
}
revers_arch(0);
cputc_arch('<');
} else {
cputc_arch(CH_VERTLINE);
cputsn_arch(text, w->w);
cclear_arch(xpos + w->w + 1);
cputc_arch(CH_VERTLINE);
}
++ypos;
text += w->w;
}
#if CTK_CONF_ICONS
} else if (w->type == CTK_WIDGET_ICON) {
if(w->widget.icon.textmap != NULL) {
for(i = 0; i < 3; ++i) {
gotoxy_arch(xpos, ypos);
cputc_arch(w->widget.icon.textmap[0 + 3 * i]);
cputc_arch(w->widget.icon.textmap[1 + 3 * i]);
cputc_arch(w->widget.icon.textmap[2 + 3 * i]);
++ypos;
}
x = xpos;
len = strlen(w->widget.icon.title);
if(x + len >= SCREEN_WIDTH) {
x = SCREEN_WIDTH - len;
}
gotoxy_arch(x, ypos);
cputs_arch(w->widget.icon.title);
}
#endif /* CTK_CONF_ICONS */
}
revers_arch(0);
}
/*---------------------------------------------------------------------------*/
void
ctk_draw_widget(struct ctk_widget *w,
unsigned char focus,
unsigned char clipy1,
unsigned char clipy2) {
struct ctk_window *win = w->window;
unsigned char posx, posy;
clip_arch(clipy1, clipy2);
posx = win->x + 1;
posy = win->y + 2;
if(w == win->focused) {
focus |= CTK_FOCUS_WIDGET;
}
draw_widget(w, posx, posy, focus);
}
/*---------------------------------------------------------------------------*/
void
ctk_draw_clear_window(struct ctk_window *window,
unsigned char focus,
unsigned char clipy1,
unsigned char clipy2) {
unsigned char i;
unsigned char x1, x2, y1, y2;
x1 = window->x + 1;
x2 = x1 + window->w;
y1 = window->y + 2;
y2 = y1 + window->h;
clip_arch(clipy1, clipy2);
for(i = y1; i < y2; ++i) {
gotoxy_arch(x1, i);
cclear_arch(x2);
}
}
/*---------------------------------------------------------------------------*/
static void draw_window_sub(struct ctk_window *window, unsigned char focus) {
unsigned char x, y;
unsigned char x1, y1, x2;
struct ctk_widget *w;
unsigned char wfocus;
x = window->x;
y = window->y + 1;
x1 = x + 1;
y1 = y + 1;
x2 = x1 + window->w;
// |_
gotoxy_arch(x, y1);
cvline_arch(window->h);
cputc_arch(CH_LLCORNER);
chline_arch(window->w);
cputc_arch(CH_LRCORNER);
// -
gotoxy_arch(x, y);
cputc_arch(CH_ULCORNER);
chline_arch(window->w);
cputc_arch(CH_URCORNER);
// |
gotoxy_arch(x2, y1);
cvline_arch(window->h);
/* Draw inactive widgets. */
for(w = window->inactive; w != NULL; w = w->next) {
draw_widget(w, x1, y1, focus);
}
/* Draw active widgets. */
for(w = window->active; w != NULL; w = w->next) {
wfocus = focus;
if(w == window->focused) {
wfocus |= CTK_FOCUS_WIDGET;
}
draw_widget(w, x1, y1, wfocus);
}
}
/*---------------------------------------------------------------------------*/
void ctk_draw_window(struct ctk_window *window, unsigned char focus,
unsigned char clipy1, unsigned char clipy2,
unsigned char draw_borders) {
clip_arch(clipy1, clipy2);
focus = focus & CTK_FOCUS_WINDOW;
draw_window_sub(window, focus);
}
/*---------------------------------------------------------------------------*/
void ctk_draw_dialog(struct ctk_window *dialog) {
clip_arch(0, SCREEN_HEIGHT);
ctk_draw_clear_window(dialog, 0, 0, SCREEN_HEIGHT);
draw_window_sub(dialog, CTK_FOCUS_DIALOG);
}
/*---------------------------------------------------------------------------*/
#if CTK_CONF_MENUS
static void draw_menu(struct ctk_menu *m, struct ctk_menu *open) {
#if CC_CONF_UNSIGNED_CHAR_BUGS
unsigned char x2;
unsigned int x, y;
#else
unsigned char x2;
unsigned char x, y;
const u8_t off_menu_title = offsetof(struct ctk_menu, title);
const u8_t off_menu_active = offsetof(struct ctk_menu, active);
const u8_t off_menu_nitems = offsetof(struct ctk_menu, nitems);
const u8_t off_menu_items = offsetof(struct ctk_menu, items);
const u8_t off_menu_next = offsetof(struct ctk_menu, next);
const u8_t off_menuitem_title = offsetof(struct ctk_menuitem, title);
const u8_t size_menuitem = sizeof(struct ctk_menuitem);
const u8_t off_menus_open = offsetof(struct ctk_menus, open);
const u8_t off_menus_menus = offsetof(struct ctk_menus, menus);
const u8_t off_menus_desktopmenu = offsetof(struct ctk_menus, desktopmenu);
#endif
x = info.cursx;
cputs_arch(m->title);
cputc_arch(CH_SPACE);
if (m == open) {
x2 = info.cursx;
if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
}
for(y = 0; y < m->nitems; y++) {
if(y == m->active) {
revers_arch(0);
}
gotoxy_arch(x, y + 1);
if(m->items[y].title[0] == '-') {
chline_arch(CTK_CONF_MENUWIDTH);
} else {
cputs_arch(m->items[y].title);
}
cclear_arch(x + CTK_CONF_MENUWIDTH);
revers_arch(1);
}
gotoxy_arch(x2, 0);
}
}
/*---------------------------------------------------------------------------*/
void ctk_draw_menus(struct ctk_menus *menus) {
struct ctk_menu *m;
clip_arch(0, SCREEN_HEIGHT);
/* Draw menus */
gotoxy_arch(0, 0);
revers_arch(1);
for(m = menus->menus->next; m != NULL; m = m->next) {
draw_menu(m, menus->open);
}
cclear_arch(SCREEN_WIDTH - strlen(menus->desktopmenu->title) - 1);
/* Draw desktopmenu */
draw_menu(menus->desktopmenu, menus->open);
revers_arch(0);
}
#endif /* CTK_CONF_MENUS */
/*---------------------------------------------------------------------------*/
/* Returns width and height of screen. */
unsigned char ctk_draw_width(void) {
return SCREEN_WIDTH;
}
unsigned char ctk_draw_height(void) {
return SCREEN_HEIGHT;
}

View file

@ -27,10 +27,10 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ctk_arch-def.h,v 1.1 2007/09/11 12:12:59 matsutsuka Exp $
* $Id: ctk_arch-def.h,v 1.2 2007/09/19 12:46:15 matsutsuka Exp $
*
*/
/*
* \file
* ctk_arch-def.h
@ -106,7 +106,7 @@
#define CH_CURS_RIGHT 0x1c
#define CH_ENTER 0x0d
#define CH_ESC 0x1b
#define CH_STOP 0x03
#define CH_STOP 0x03
#define CH_DEL 0x08
/* Contiki toolkit options */
@ -136,16 +136,28 @@
/* Key used to switch the frontmost window. */
#define CTK_CONF_WINDOWSWITCH_KEY CH_F3
/* Key used to move down a widget. */
#define CTK_CONF_WIDGETDOWN_KEY CH_TAB
#define CTK_CONF_WIDGETDOWN_KEY CH_TAB
/* Key used to move up a widget. */
#define CTK_CONF_WIDGETUP_KEY CH_F5
/* Defines which key that is to be used for activating the menus */
#define CTK_CONF_MENU_KEY CH_F1
/* offsets of struct screen_info for assembler */
#define CURSX 0
#define CURSY 1
#define CY1 2
#define CY2 3
/* Imported symbols from ctk.h */
#define _CTK_FOCUS_NONE 0
#define _CTK_FOCUS_WIDGET 1
#define _CTK_FOCUS_WINDOW 2
#define _CTK_FOCUS_DIALOG 4
#define _CTK_WIDGET_SEPARATOR 1
#define _CTK_WIDGET_LABEL 2
#define _CTK_WIDGET_BUTTON 3
#define _CTK_WIDGET_HYPERLINK 4
#define _CTK_WIDGET_TEXTENTRY 5
#define _CTK_WIDGET_BITMAP 6
#define _CTK_WIDGET_ICON 7
#define _CTK_TEXTENTRY_NORMAL 0
#define _CTK_TEXTENTRY_EDIT 1
#endif /* __CTK_ARCH_DEF_H__ */

View file

@ -0,0 +1,525 @@
;;;
;;;
;;; libconio_arch-asm.hS
;;;
;;; Architecture depend libconio implementation.
;;; This assembler source contributes basically saving for speed and memory.
;;;
;;; @author Takahide Matsutsuka <markn@markn.org>
;;;
;;; $Id: libconio_arch-asm.cS,v 1.1 2007/09/19 12:46:15 matsutsuka Exp $
;;;
;; uses preprocessor to enable definitions
#include "ctk_arch-def.h"
;; export symbols
.globl _cputc_arch
.globl _cputs_arch
.globl _cputsn_arch
.globl _chline_arch
.globl _cvline_arch
.globl _gotoxy_arch
.globl _clearto_arch
.globl _revers_arch
.globl _clip_arch
.globl _wherex_arch
.globl _drawbox_arch
.globl _drawicon_arch
.globl _clearbox_arch
.globl _newline_arch
.area _DATA
_screen_cursor:
.ds 1 ; x
.ds 1 ; y
_screen_clips:
.ds 1 ; clip y1
.ds 1 ; clip y2
_screen_reversed:
.ds 1
.area _CODE
_libconio_arch_asm_start::
.if 0
;; input: B = y, C = x
;; output: HL = offset
;; ______HL____
_calc_offset:
push af
push de
ld a, b
ld hl, #0
ld de, #SCREEN_WIDTH
_calc_offset_loop:
or a
jr z, _calc_offset_calcx
add hl, de
dec a
jr _calc_offset_loop
_calc_offset_calcx:
ld d, #0
ld e, c
add hl, de
pop de
pop af
ret
.endif
;; ---------------------------------
;; void cputc(char ch);
;; Stack; retl reth ch
;; AFBCDEHL____
;; return A=1 if output is succeeded, A=0 if not
;; ---------------------------------
_cputc_arch:
ld hl, #2
add hl, sp
ld a, (hl)
;; ------------
;; A = char
;; AFBCDEHL____
;; ------------
_cputc_arch_asm:
push af
ld bc, (#_screen_cursor) ;B=y, C=x
ld de, (#_screen_clips) ;D=cy2, E=cy1
ld a, b
cp a, e
jr c, _cputc_arch_ret_false ; if (cursy < cy1)
cp a, d
jr z, _cputc_arch_next1
jr nc, _cputc_arch_ret_false ; if (cursy > cy2)
_cputc_arch_next1:
cp a, #SCREEN_HEIGHT ; cursy - SCREEN_HEIGHT
jr z, _cputc_arch_next2
jr nc, _cputc_arch_ret_false ; if (cursy > SCREEN_HEIGHT)
_cputc_arch_next2:
ld a, c
cp a, #SCREEN_WIDTH ; cursx - SCREEN_WIDTH
jr nc, _cputc_arch_ret_false ; if (cursx >= SCREEN_WIDTH)
;; calculate offset
.if 0
call _calc_offset
.else
ld a, b ; A=y
ld hl, #0
ld de, #SCREEN_WIDTH
_cputc_arch_loop:
or a
jr z, _cputc_arch_calcx
add hl, de
dec a
jr _cputc_arch_loop
_cputc_arch_calcx:
ld d, #0
ld e, c
add hl, de
.endif
;; putchar
pop af
ld de, #VRAM_CHAR
push hl
add hl, de
ld (hl), a
pop hl
;; putattr
ld de, #VRAM_ATTR
add hl, de
ld a, (#_screen_reversed)
or a
jr z, _cputc_arch_normal
ld (hl), #COLOR_REVERSED
jr _cputc_arch_ret
_cputc_arch_normal:
ld (hl), #COLOR_NORMAL
ld a, #0x01
_cputc_arch_ret:
ld hl, #_screen_cursor
inc (hl)
ret
_cputc_arch_ret_false:
pop af
xor a
jr _cputc_arch_ret
;; ---------------------------------
;; void cputs_arch(char *str);
;; Stack; retl reth strl strh
;; AFB_DEHL____
;; return void
;; ---------------------------------
_cputs_arch:
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ld b, #SCREEN_WIDTH ; max length
;; ------------
;; B = nchars
;; DE = str
;; AFB_DEHL____
;; ------------
_cputs_arch_loop:
ld a, (de)
or a
ret z
push bc
push de
call _cputc_arch_asm
pop de
pop bc
inc de
djnz _cputs_arch_loop
ret
;; ---------------------------------
;; void cputsn(char *str, unsigned char length);
;; Stack; retl reth strl strh length
;; AFB_DEHL____
;; return void
;; ---------------------------------
_cputsn_arch:
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
inc hl
ld b, (hl)
jr _cputs_arch_loop ; take over B and DE
;; ---------------------------------
;; void chline(unsigned char length);
;; Stack; retl reth length
;; AFB_DEHL____
;; return void
;; ---------------------------------
_chline_arch:
ld hl, #2
add hl, sp
ld b, (hl)
;; ------------
;; B = length
;; AFB_DEHL____
;; ------------
_chline_arch_asm:
ld a, #CH_HOLILINE
_chline_arch_loop:
push bc
push af
call _cputc_arch_asm
pop af
pop bc
djnz _chline_arch_loop
ret
;; ---------------------------------
;; void cvline(unsigned char length);
;; Stack; retl reth length
;; AFB_DEHL____
;; return void
;; ---------------------------------
_cvline_arch:
ld hl, #2
add hl, sp
ld b, (hl) ; length
;; ------------
;; B = length
;; AFB_DEHL____
;; ------------
_cvline_arch_asm:
ld a, #CH_VERTLINE
ld hl, (#_screen_cursor) ; H=y, L=x
_cvline_arch_loop:
push hl
push bc
push af
call _cputc_arch_asm
pop af
pop bc
pop hl
inc h
ld (#_screen_cursor), hl
djnz _cvline_arch_loop
ret
;; ---------------------------------
;; void gotoxy(unsigned char x, unsigned char y)
;; Stack; retl reth x y
;; _F__DEHL____
;; return void
;; ---------------------------------
_gotoxy_arch:
ld hl, #2
add hl, sp
ld d, (hl) ; x
inc hl
ld e, (hl) ; y
;; ------------
;; D = x, E = y
;; ______HL____
;; ------------
_gotoxy_arch_asm:
ld l, d ; L=x
ld h, e ; H=y
ld (#_screen_cursor), hl
ret
;; ---------------------------------
;; void clearto_arch(unsigned char to)
;; Stack; retl reth to
;; AFBCDEHL____
;; return void
;; ---------------------------------
_clearto_arch:
ld hl, #2
add hl, sp
ld a, (hl)
_clearto_arch_loop:
ld hl, #_screen_cursor
cp (hl) ; to - cursx
ret z
ret c
push af
ld a, #CH_SPACE
call _cputc_arch_asm
or a
pop af
ret z
jr _clearto_arch_loop
;; ---------------------------------
;; void revers_arch(unsigned char reverse)
;; Stack; retl reth reverse
;; A_____HL____
;; return void
;; ---------------------------------
_revers_arch:
ld hl, #2
add hl, sp
ld a, (hl)
ld (#_screen_reversed), a
ret
;; ---------------------------------
;; void clip_arch(unsigned char clip1, unsigned char clip2)
;; Stack; retl reth clip1 clip2
;; ____________
;; return void
;; ---------------------------------
_clip_arch:
push af
push hl
push de
ld hl, #0x08
add hl, sp
ld de, #_screen_clips
ld a, (hl)
ld (de), a
inc hl
inc de
ld a, (hl)
ld (de), a
pop de
pop hl
pop af
ret
;; ---------------------------------
;; unsigned char wherex_arch()
;; Stack; retl reth
;; A_____HL____
;; return void
;; ---------------------------------
_wherex_arch:
ld a, (#_screen_cursor)
ld l, a
ret
;; ---------------------------------
;; void drawbox_arch(unsigned char x, y, w, h)
;; Stack; retl reth x y w h
;; AFBCDEHL____
;; return void
;; ---------------------------------
_drawbox_arch:
ld hl, #2
add hl, sp
ld d, (hl) ; x
inc hl
ld e, (hl) ; y
inc hl
ld c, (hl) ; w
inc hl
ld b, (hl) ; h
inc e
call _gotoxy_arch_asm ; (x, y + 1)
dec e
push de
push bc
call _cvline_arch_asm
ld a, #CH_LLCORNER
call _cputc_arch_asm
pop bc
push bc ; Stack; BC DE
ld b, c ; w
call _chline_arch_asm
ld a, #CH_LRCORNER
call _cputc_arch_asm
pop bc
pop de
call _gotoxy_arch_asm ; (x, y)
push de
push bc ; Stack; BC DE
ld a, #CH_ULCORNER
call _cputc_arch_asm
pop bc
push bc ; Stack; BC DE
ld b, c
call _chline_arch_asm
ld a, #CH_URCORNER
call _cputc_arch_asm
pop bc ; B = h
pop de
ld a, d
inc a
add a, c
ld d, a ; D = x + 1 + w
inc e ; E = y + 1
call _gotoxy_arch_asm
call _cvline_arch_asm
ret
.if CTK_CONF_ICONS
;; ---------------------------------
;; void drawicon_arch(char* textmap, char *title);
;; Stack; retl reth textmapl textmaph titlel titleh
;; AFBCDEHL____
;; return void
;; ---------------------------------
_drawicon_arch:
ld hl, #_screen_cursor
ld b, (hl) ; x
inc hl
ld c, (hl) ; y
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl) ; DE = textmap
ld a, e
or d
ret z ; if (textmap == NULL) return;
ld a, #3 ; loop counter
_drawicon_arch_loop:
push af
push de
ld d, b
ld e, c
call _gotoxy_arch_asm
pop de
push bc
ld b, #3
call _cputs_arch_loop ; DE = DE + 3
pop bc
pop af
inc c ; y++
dec a
jr z, _drawicon_arch_title
jr _drawicon_arch_loop
;; B = x, C = y
_drawicon_arch_title:
ld hl, #4
add hl, sp
ld e, (hl)
inc hl
ld d, (hl) ; DE = title
ld h, d
ld l, e
xor a
push de
ld d, #0
_drawicon_arch_title_strlen:
ld a, (hl)
or a
jr z, _drawicon_arch_title_setpos
inc hl
inc d
jr _drawicon_arch_title_strlen
_drawicon_arch_title_setpos:
ld h, d ; H = len
ld a, d
pop de
add a, b
cp a, #SCREEN_WIDTH ; x + len - SCREEN_WIDTH
jr c, _drawicon_arch_title_show
ld a, #SCREEN_WIDTH
sub h
ld b, a
;; B = x, C = y, DE = title, H = len
_drawicon_arch_title_show:
push de
ld d, b
ld e, c
call _gotoxy_arch_asm
pop de
ld b, #SCREEN_WIDTH
call _cputs_arch_loop
ret
.endif
;; ---------------------------------
;; void clearbox_arch(unsigned char x, y, w, h)
;; Stack; retl reth x y w h
;; AFBCDEHL____
;; return void
;; ---------------------------------
_clearbox_arch:
ld hl, #2
add hl, sp
ld d, (hl) ; x
inc hl
ld e, (hl) ; y
inc hl
ld c, (hl) ; w
inc hl
ld b, (hl) ; h
ld a, d
add a, c
ld c, a ; to_x
_clearbox_arch_loop:
call _gotoxy_arch_asm ; (x, y + 1)
push de
push bc
ld a, c
call _clearto_arch_loop
pop bc
pop de
inc e
djnz _clearbox_arch_loop
ret
_newline_arch:
ld hl, #_screen_cursor
xor a
ld (hl), a
inc hl
ld a, (hl)
inc a
cp a, #SCREEN_HEIGHT
jr nc, _newline_arch_scroll
ld (hl), a
ret
_newline_arch_scroll:
;; TODO: attr and specific impl
dec a
ld (hl), a
ld hl, #VRAM_CHAR + #SCREEN_WIDTH
ld de, #VRAM_CHAR
ld bc, #SCREEN_HEIGHT * #SCREEN_WIDTH - #SCREEN_WIDTH
ldir
ret
_libconio_arch_asm_end::

View file

@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ctk-conio_arch.h,v 1.1 2007/09/11 12:12:59 matsutsuka Exp $
* $Id: libconio_arch.h,v 1.1 2007/09/19 12:46:15 matsutsuka Exp $
*
*/
@ -38,8 +38,8 @@
* Takahide Matsutsuka <markn@markn.org>
*/
#ifndef __CTK_CONIO_ARCH_H__
#define __CTK_CONIO_ARCH_H__
#ifndef __LIBCONIO_ARCH_H__
#define __LIBCONIO_ARCH_H__
void cputc_arch(char c);
void cputs_arch(char *str);
@ -47,8 +47,16 @@ void cputsn_arch(char *str, unsigned char len);
void chline_arch(unsigned char length);
void cvline_arch(unsigned char length);
void clip_arch(unsigned char clip1, unsigned char clip2);
unsigned char wherex_arch();
void gotoxy_arch(unsigned char x, unsigned char y);
void cclear_arch(char x);
void clearto_arch(unsigned char to);
void revers_arch(unsigned char reversed);
void drawbox_arch(unsigned char x, unsigned char y,
unsigned char w, unsigned char h);
void drawicon_arch(unsigned char x, unsigned char y,
char* textmap, char* title);
void clearbox_arch(unsigned char x, unsigned char y,
unsigned char w, unsigned char h);
void newline_arch();
#endif /* __CTK_CONIO_ARCH_H__ */
#endif /* __LIBCONIO_ARCH_H__ */