git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-lib/examples/gb/gb-dtmf/gb-dtmf.c

      1 /* ---------------------------------------- */
      2 /*             GB-DTMF Ver1.0               */
      3 /*                  by                      */
      4 /*              Osamu Ohashi                */
      5 /* ---------------------------------------- */
      6 
      7 #include <gb/gb.h>
      8 #include <stdint.h>
      9 #include <stdio.h>
     10 #include <string.h>
     11 
     12 /* BG data */
     13 #include "frm_lcd.c"	/* Back ground pattern */
     14 #include "brk_btn.c"	/* button image when broken */
     15 #include "prs_btn.c"	/* button image when pressed */
     16 
     17 #include "dtmf_lcd.c"	/* LCD characters */
     18 
     19 /* Sprite data */
     20 #include "key_num.c"	/* Sprite pattern for each key pad */
     21 #include "cursor.c"		/* cursor pattern */
     22 
     23 /*
     24 	usage of BG data
     25 	file name	number of BG	type of matrix	aount
     26 	-------------------------------------------------
     27 	frame_lcd.c 9				8 x 8			9
     28 	break_btn.c	9				8 x 8			9
     29 	press_btn.c 9				8 x 8			9
     30 	dtmf_lcd.c  25				8 x 16			50
     31 	------------------------------------------------
     32 	total										77
     33 
     34 
     35 	usage of OBJ data
     36 	file name	number of obj	type of matrix	amount
     37 	--------------------------------------------------
     38 	key_num.c	23				8 x 8			23
     39 	cursor.c	2				16 x 16			8
     40 	--------------------------------------------------
     41 	total										31
     42 */
     43 
     44 
     45 /* display */
     46 #define TITLE " GB-DTMF BY 05AMU "
     47 
     48 #define OFFSET 			27U
     49 #define KEY_STEP 		24U	/* Key matrix size as 24 x 24	*/
     50 #define START_CURSOR_X	24U	/* CURSOR position	*/
     51 #define START_CURSOR_Y	72U
     52 
     53 #define LCD_X 			1U	/* start position of X		*/
     54 #define LCD_Y			2U	/* start position of Y		*/
     55 #define LCD_WIDTH		18U	/* Horizontal size of LCD	*/
     56 #define LCD_HIGHT		2U	/* Vertical Size of LCD		*/
     57 
     58 
     59 #define ON	1
     60 #define OFF	0
     61 
     62 /* DTMF */
     63 #define DTMF_ON		100UL	/* Tone on time		*/
     64 #define DTMF_OFF	100UL	/* Tone off time	*/
     65 
     66 #define MAX_DTMF	30		/* Maximum length of DTMF strings	*/
     67 
     68 /*
     69 	Frequency setting
     70 */
     71 /*
     72 	We have to calculate the frequency as following formula
     73 
     74 	DTMF has two set frequency, we have to decide Row & Column
     75 	with each digit('0','1','2'...)
     76 */
     77 
     78 #define C1 0x94U /* 1209Hz, 1213Hz */
     79 #define C2 0x9EU /* 1336Hz, 1337Hz */
     80 #define C3 0xA7U /* 1477Hz, 1472Hz */
     81 #define C4 0xB0U /* 1633Hz, 1638Hz */
     82 
     83 #define R1 0x44U /*  697Hz,  697Hz */
     84 #define R2 0x56U /*  770Hz,  770Hz */
     85 #define R3 0x66U /*  852Hz,  851Hz */
     86 #define R4 0x75U /*  941Hz,  942Hz */
     87 
     88 const unsigned char row[4] = {R1,R2,R3,R4};	/* DTMF frequency strage of Row */
     89 const unsigned char col[4] = {C1,C2,C3,C4};	/* DTMF frequency strage of Col */
     90 
     91 /* It is possible to set up initial screen by each BG data. */
     92 const unsigned char dtmf_tile[] = {
     93 	 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
     94 
     95 	 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
     96 	 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
     97 	 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
     98 	 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8,
     99 
    100 	 4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,11, 9,10,11,
    101 	 4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,14,12,13,14,
    102 	 4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,17,15,16,17,
    103 
    104 	 4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,11, 9,10,11,
    105 	 4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,14,12,13,14,
    106 	 4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,17,15,16,17,
    107 
    108 	 4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,11, 9,10,11,
    109 	 4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,14,12,13,14,
    110 	 4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,17,15,16,17,
    111 
    112 	 4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,10,10,10,11,
    113 	 4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,13,13,13,14,
    114 	 4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,16,16,16,17,
    115 
    116 	 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
    117 };
    118 
    119 /*
    120 	Button image
    121 	Normal buttons are created by 3tiles x 3tiles(24pixels x 24pixels)
    122 	Dialing button is created by 6tiles x 3tiles(48pixels x 24pixels)
    123 */
    124 const unsigned char break_tile[] = {
    125 	 9,10,11,
    126 	12,13,14,
    127 	15,16,17
    128 };
    129 
    130 const unsigned char dialing_break[] = {
    131 	 9,10,10,10,10,11,
    132 	12,13,13,13,13,14,
    133 	15,16,16,16,16,17
    134 };
    135 
    136 const unsigned char press_tile[] = {
    137 	18,19,20,
    138 	21,22,23,
    139 	24,25,26
    140 };
    141 
    142 
    143 const unsigned char dialing_press[] = {
    144 	18,19,19,19,19,20,
    145 	21,22,22,22,22,23,
    146 	24,25,25,25,25,26
    147 };
    148 
    149 /*
    150 	LCD image at initial & AC
    151 */
    152 const unsigned char init_disp[] = {
    153 	59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
    154 	60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60
    155 };
    156 
    157 const char	pad[4][6] = {		/* DTMF Pad assign */
    158 	{'1','2','3','A','%','P'},
    159 	{'4','5','6','B','-','F'},
    160 	{'7','8','9','C',',','?'},
    161 	{'*','0','#','D','s','s'}
    162 };
    163 
    164 unsigned char disp_tile[MAX_DTMF * 2];
    165 
    166 /*
    167 	Initialize for sound registers
    168 	ch1, ch2 are used for this routine.
    169 */
    170 void init_dial(void)
    171 {
    172 
    173 	NR52_REG = 0x83U;
    174 	NR51_REG = 0x00U;
    175 	NR50_REG = 0x77U;
    176 
    177 	NR24_REG = 0x87U;
    178 	NR22_REG = 0xffU;
    179 	NR21_REG = 0xbfU;
    180 
    181 	NR14_REG = 0x87U;
    182 	NR12_REG = 0xffU;
    183 	NR11_REG = 0xbfU;
    184 	NR10_REG = 0x04U;
    185 }
    186 
    187 /* sound engine for DTMF */
    188 void dialtone(uint16_t dtmf_on, uint16_t dtmf_off, char str[20])
    189 {
    190 	uint8_t i = 0;
    191 
    192 	while(str[i]){
    193 		switch(str[i]){
    194 		    case '1':
    195 			  NR13_REG = R1;
    196 			  NR23_REG = C1;
    197 			  break;
    198 		    case '2':
    199 			  NR13_REG = R1;
    200 			  NR23_REG = C2;
    201 			  break;
    202 		    case '3':
    203 			  NR13_REG = R1;
    204 			  NR23_REG = C3;
    205 			  break;
    206 		    case 'A':
    207 		    case 'a':
    208 			  NR13_REG = R1;
    209 			  NR23_REG = C4;
    210 			  break;
    211 		    case '4':
    212 			  NR13_REG = R2;
    213 			  NR23_REG = C1;
    214 			  break;
    215 		    case '5':
    216 			  NR13_REG = R2;
    217 			  NR23_REG = C2;
    218 			  break;
    219 		    case '6':
    220 			  NR13_REG = R2;
    221 			  NR23_REG = C3;
    222 			  break;
    223 			case 'B':
    224 			case 'b':
    225 			  NR13_REG = R2;
    226 			  NR23_REG = C4;
    227 			  break;
    228 			case '7':
    229 			  NR13_REG = R3;
    230 			  NR23_REG = C1;
    231 			  break;
    232 			case '8':
    233 			  NR13_REG = R3;
    234 			  NR23_REG = C2;
    235 			  break;
    236 			case '9':
    237 			  NR13_REG = R3;
    238 			  NR23_REG = C3;
    239 			  break;
    240 			case 'C':
    241 			case 'c':
    242 			  NR13_REG = R3;
    243 			  NR23_REG = C4;
    244 			  break;
    245 			case '*':
    246 			  NR13_REG = R4;
    247 			  NR23_REG = C1;
    248 			  break;
    249 			case '0':
    250 			  NR13_REG = R4;
    251 			  NR23_REG = C2;
    252 			  break;
    253 			case '#':
    254 			  NR13_REG = R4;
    255 			  NR23_REG = C3;
    256 			  break;
    257 			case 'D':
    258 			case 'd':
    259 			  NR13_REG = R4;
    260 			  NR23_REG = C4;
    261 			  break;
    262 			case ',':
    263 			  delay(dtmf_on);	/* keep on */
    264 			  delay(dtmf_off);	/* keep off */
    265 
    266 			default:
    267 			  NR51_REG = 0x00U;	/* sound off */
    268 			  goto skip;
    269 
    270 		  }
    271 		NR24_REG = 0x87U;	/* ch2 tips */
    272 		NR51_REG = 0x33U;	/* sound on */
    273 		delay(dtmf_on);		/* keep on */
    274 
    275 		NR51_REG = 0x00U;	/* sound off */
    276 		delay(dtmf_off);	/* keep off */
    277 
    278 	  skip:
    279 		i++;
    280 	}
    281 }
    282 
    283 
    284 /* Display looks like 7-SEGMENT LED */
    285 void disp_lcd(uint8_t len, char str[MAX_DTMF])
    286 {
    287 	uint8_t i,j;
    288 
    289 	j = len;
    290 
    291 	i=0;
    292 	while(str[i]){
    293 		if(str[i] >= '0'||'9' <= str[i]){
    294 			disp_tile[i] = OFFSET + (str[i] - '0') * 2;
    295 			disp_tile[i+j] = OFFSET + (str[i] - '0') * 2 + 1;
    296 		}
    297 		switch(str[i]){
    298 			case 'A':
    299 				disp_tile[i] = OFFSET + 10 * 2;
    300 				disp_tile[i+j] = OFFSET + 10 * 2 + 1;
    301 			break;
    302 			case 'B':
    303 				disp_tile[i] = OFFSET + 11 * 2;
    304 				disp_tile[i+j] = OFFSET + 11 * 2 + 1;
    305 			break;
    306 			case 'C':
    307 				disp_tile[i] = OFFSET + 12 * 2;
    308 				disp_tile[i+j] = OFFSET + 12 * 2 + 1;
    309 			break;
    310 			case 'D':
    311 				disp_tile[i] = OFFSET + 13 * 2;
    312 				disp_tile[i+j] = OFFSET + 13 * 2 + 1;
    313 			break;
    314 			case '#':
    315 				disp_tile[i] = OFFSET + 14 * 2;
    316 				disp_tile[i+j] = OFFSET + 14 * 2 + 1;
    317 			break;
    318 			case '*':
    319 				disp_tile[i] = OFFSET + 15 * 2;
    320 				disp_tile[i+j] = OFFSET + 15 * 2 + 1;
    321 			break;
    322 			case ' ':
    323 				disp_tile[i] = OFFSET + 16 * 2;
    324 				disp_tile[i+j] = OFFSET + 16 * 2 + 1;
    325 			break;
    326 			case 'Y':
    327 				disp_tile[i] = OFFSET + 17 * 2;
    328 				disp_tile[i+j] = OFFSET + 17 * 2 + 1;
    329 			break;
    330 			case 'M':
    331 				disp_tile[i] = OFFSET + 18 * 2;
    332 				disp_tile[i+j] = OFFSET + 18 * 2 + 1;
    333 			break;
    334 			case 'U':
    335 				disp_tile[i] = OFFSET + 19 * 2;
    336 				disp_tile[i+j] = OFFSET + 19 * 2 + 1;
    337 			break;
    338 			case 'G':
    339 				disp_tile[i] = OFFSET + 20 * 2;
    340 				disp_tile[i+j] = OFFSET + 20 * 2 + 1;
    341 			break;
    342 			case '-':
    343 				disp_tile[i] = OFFSET + 21 * 2;
    344 				disp_tile[i+j] = OFFSET + 21 * 2 + 1;
    345 			break;
    346 			case 'T':
    347 				disp_tile[i] = OFFSET + 22 * 2;
    348 				disp_tile[i+j] = OFFSET + 22 * 2 + 1;
    349 			break;
    350 			case ',':
    351 				disp_tile[i] = OFFSET + 23 * 2;
    352 				disp_tile[i+j] = OFFSET + 23 * 2 + 1;
    353 			break;
    354 			case 'F':
    355 				disp_tile[i] = OFFSET + 24 * 2;
    356 				disp_tile[i+j] = OFFSET + 24 * 2 + 1;
    357 			break;
    358 			case 'S':
    359 				disp_tile[i] = OFFSET + ('5' - '0') * 2;
    360 				disp_tile[i+j] = OFFSET + ('5' - '0') * 2 + 1;
    361 			break;
    362 		}
    363 		i++;
    364 	}
    365 }
    366 
    367 /* clear display */
    368 void clr_disp(void)
    369 {
    370 	set_bkg_data(OFFSET, 50, dtmf_lcd);
    371 	set_bkg_tiles(LCD_X, LCD_Y, LCD_WIDTH, LCD_HIGHT, init_disp);
    372 }
    373 
    374 /*
    375 	CAUTION: Don't display the NULL code
    376 */
    377 void disp(const char *str)
    378 {
    379 	uint8_t no, left_pos;
    380 	uint8_t i, start_ch, end_ch;
    381 	char work[MAX_DTMF];
    382 
    383 	clr_disp();
    384 
    385 	no = 0;
    386 	while(str[no]){
    387 		no++;
    388 	}
    389 
    390 	if(no >= LCD_WIDTH){
    391 		start_ch = no - LCD_WIDTH;
    392 		end_ch = LCD_WIDTH;
    393 	}
    394 	else{
    395 		start_ch = 0;
    396 		end_ch = no;
    397 	}
    398 	for(i = 0;i < end_ch;i++){
    399 		work[i] = str[i+start_ch];
    400 	}
    401 	work[end_ch] = 0x00;
    402 
    403 	disp_lcd(end_ch, work);
    404 
    405 	left_pos = 19 - end_ch;
    406 	set_bkg_tiles(left_pos, 2, end_ch, LCD_HIGHT, disp_tile);
    407 }
    408 
    409 void press_button(uint8_t x, uint8_t y)
    410 {
    411 	if(x <= 3 && y <= 3){
    412 		set_bkg_tiles(x * 3 + 1, y * 3 + 5, 3, 3, press_tile);
    413 	}
    414 	if((x == 4 || x == 5) && (y <= 2)){
    415 		set_bkg_tiles(x * 3 + 2, y * 3 + 5, 3, 3, press_tile);
    416 	}
    417 	if((x == 4 || x == 5) && (y == 3)){
    418 		set_bkg_tiles(14, 14, 6, 3, dialing_press);
    419 	}
    420 }
    421 
    422 void break_button(uint8_t x, uint8_t y)
    423 {
    424 	if(x <= 3 && y <= 3){
    425 		set_bkg_tiles(x * 3 + 1, y * 3 + 5, 3, 3, break_tile);
    426 	}
    427 	if((x == 4 || x == 5) && (y <= 2)){
    428 		set_bkg_tiles(x * 3 + 2, y * 3 + 5, 3, 3, break_tile);
    429 	}
    430 	if((x == 4 || x == 5) && (y == 3)){
    431 		set_bkg_tiles(14, 14, 6, 3, dialing_break);
    432 	}
    433 }
    434 
    435 
    436 void init_key(void)
    437 {
    438 	uint8_t key_x, key_y, i;
    439 
    440 	/* To make numeric KeyPad */
    441 	set_sprite_data(0, 24, key_num);
    442 
    443 	/* key pad 1 - 3 */
    444 	key_y = KEY_STEP + 40;
    445 	for(i = 1;i <= 3;i++){
    446 		key_x = i * KEY_STEP;
    447 		set_sprite_tile(i, i);
    448 		move_sprite(i, key_x, key_y);
    449 	}
    450 
    451 	/* key pad 4 - 6 */
    452 	key_y = KEY_STEP * 2 + 40;
    453 	for(i = 4;i <= 6;i++){
    454 		key_x = (i - 3) * KEY_STEP;
    455 		set_sprite_tile(i, i);
    456 		move_sprite(i, key_x, key_y);
    457 	}
    458 
    459 	/* key pad 7 - 9 */
    460 	key_y = KEY_STEP * 3 + 40;
    461 		for(i = 7;i <= 9;i++){
    462 			key_x = (i - 6) * KEY_STEP;
    463 			set_sprite_tile(i, i);
    464 			move_sprite(i, key_x, key_y);
    465 		}
    466 
    467 	/* key pad 'A' - 'D' */
    468 	key_x = KEY_STEP * 4;
    469 	for(i = 0;i <= 3;i++){
    470 		key_y = (i+1) * KEY_STEP + 40;
    471 		set_sprite_tile(i+10, i+10);
    472 		move_sprite(i+10, key_x, key_y);
    473 	}
    474 
    475 	/* key pad '*', '0', '#' */
    476 	set_sprite_tile(15, 15);
    477 	move_sprite(15, KEY_STEP * 1, KEY_STEP * 4 + 40U);
    478 	set_sprite_tile(0, 0);
    479 	move_sprite(0, KEY_STEP * 2, KEY_STEP * 4 + 40U);
    480 	set_sprite_tile(14, 14);
    481 	move_sprite(14, KEY_STEP * 3, KEY_STEP * 4 + 40U);
    482 
    483 	/* func left */
    484 	key_x = KEY_STEP * 5 + 8U;
    485 	for(i = 0;i <= 2;i++){
    486 		key_y = (i+1) * KEY_STEP + 40;
    487 		set_sprite_tile(i+16, i+16);
    488 		move_sprite(i+16, key_x, key_y);
    489 	}
    490 
    491 	/* func right */
    492 	key_x = KEY_STEP * 6 + 8U;
    493 	for(i = 0;i <= 2;i++){
    494 		key_y = (i+1) * KEY_STEP + 40;
    495 		set_sprite_tile(i+19, i+19);
    496 		move_sprite(i+19, key_x, key_y);
    497 	}
    498 
    499 	/* dialing button */
    500 	key_x = KEY_STEP * 5 + 20U;
    501 	key_y = KEY_STEP * 4 + 40U;
    502 	set_sprite_tile(22, 22);
    503 	move_sprite(22, key_x, key_y);
    504 }
    505 
    506 void init_background(void)
    507 {
    508 	/* Initialize the background */
    509 	set_bkg_data( 0, 9, frame_lcd);
    510 	set_bkg_data( 9, 9, break_btn);
    511 	set_bkg_data(18, 9, press_btn);
    512 
    513 	set_bkg_tiles(0, 0, 20, 18, dtmf_tile);
    514 }
    515 
    516 void init_cursor(void)
    517 {
    518 	uint8_t i;
    519 
    520 	/* Setup the cursor data*/
    521 	set_sprite_data(23, 8, cursor_data);
    522 
    523 	for(i = 23;i <= 30;i++){
    524 		set_sprite_tile(i, i);
    525 	}
    526 }
    527 
    528 void move_cursor(uint8_t x, uint8_t y)
    529 {
    530 	move_sprite(23, x, y);
    531 	move_sprite(24, x, y+8);
    532 	move_sprite(25, x+8, y);
    533 	move_sprite(26, x+8, y+8);
    534 }
    535 
    536 void main(void)
    537 {
    538 	uint8_t key1, key2, i, j, pos_x, pos_y, ch_pos;
    539 	uint8_t non_flick = OFF;
    540 	uint16_t on_time, off_time;
    541 
    542 	char str[MAX_DTMF];
    543 	char str_ms[10];
    544 
    545         /* PENDING: sdcc is broken and needs this to be initalised. */
    546 	key2 = 0;
    547 
    548 	/* default dialling time setting */
    549 	on_time = DTMF_ON;
    550 	off_time = DTMF_OFF;
    551 
    552 	disable_interrupts();
    553 
    554 	SPRITES_8x8;   /* sprites are 8x8 */
    555 
    556 	init_dial();
    557 
    558 	init_background();
    559 
    560 	init_key();
    561 
    562 	init_cursor();
    563 
    564 	disp(TITLE);
    565 
    566 	SHOW_BKG;
    567 	SHOW_SPRITES;
    568 	DISPLAY_ON;
    569 
    570 	enable_interrupts();
    571 
    572 	i = j = 0;
    573 
    574 	ch_pos = 0;
    575 
    576 	while(1) {
    577 		vsync();
    578 		key1 = joypad();
    579 
    580 		if(key1 != key2){
    581 			pos_x = i * KEY_STEP + START_CURSOR_X;
    582 			pos_y = j * KEY_STEP + START_CURSOR_Y;
    583 			move_cursor(pos_x, pos_y);
    584 		}
    585 
    586 		if(key2 & J_A){
    587 			if(key1 & J_A){
    588 				/* value set for each sound reg only numeric key pad*/
    589 				if(i <= 3 && j <= 3){
    590 					/* frequncy register set up for DTMF */
    591 					NR13_REG = row[i];
    592 					NR23_REG = col[j];
    593 					NR24_REG = 0x87U;
    594 
    595 					/* sound output on */
    596 					NR51_REG = 0x33U;
    597 				}
    598 
    599 				/* '?' button */
    600 				/* appear the title during press A button */
    601 				if(i == 5 && j == 0 && !non_flick){
    602 					disp(TITLE);
    603 					non_flick = ON;
    604 				}
    605 
    606 				/* incremental button */
    607 				/* decremental button */
    608 				/* appear the delay during press A button */
    609 				if(i == 5 && (j == 1 || j == 2) && !non_flick){
    610 					sprintf(str_ms, "%u MS", on_time);
    611 					disp(str_ms);
    612 					non_flick = ON;
    613 				}
    614 			}
    615 			else{
    616 				/* sound output off */
    617 				NR51_REG = 0x00U;
    618 
    619 				break_button(i, j);
    620 
    621 				/* '?' button */
    622 				/* incremental button */
    623 				/* decremental button */
    624 				/* return to normal display at release the A button */
    625 				if(i == 5 && (j == 0 || j == 1 || j == 2)){
    626 					non_flick = OFF;
    627 					if(ch_pos == 0)
    628 						clr_disp();
    629 					else
    630 						disp(str);
    631 				}
    632 			}
    633 		}
    634 		else{
    635 			if(key1 & J_A){
    636 				/* button display handle */
    637 				press_button(i, j);
    638 
    639 				/* numeric key pad handling */
    640 				if(i <= 3 && j <= 3){
    641 					/* string length check */
    642 					if(ch_pos < MAX_DTMF-1){
    643 						str[ch_pos] = pad[j][i];
    644 						ch_pos++;
    645 						str[ch_pos] = 0x00;
    646 						disp(str);
    647 					}
    648 				}
    649 
    650 				/* ',' button */
    651 				if(i == 4 && j == 2){
    652 					/* string length check */
    653 					if(ch_pos < MAX_DTMF-1){
    654 						str[ch_pos] = pad[j][i];
    655 						ch_pos++;
    656 						str[ch_pos] = 0x00;
    657 						disp(str);
    658 					}
    659 				}
    660 
    661 				/* all clear button */
    662 				if(i == 4 && j == 0){
    663 					ch_pos = 0x00;
    664 					strcpy(str,"");
    665 					clr_disp();
    666 				}
    667 
    668 				/* delete button */
    669 				if(i == 4 && j == 1){
    670 					if(ch_pos > 0){
    671 						ch_pos--;
    672 						str[ch_pos] = 0x00;
    673 						if(ch_pos == 0)
    674 							clr_disp();
    675 						else
    676 							disp(str);
    677 					}
    678 				}
    679 
    680 				/* incremental button */
    681 				if(i == 5 && j == 1){
    682 					if(on_time >= DTMF_ON / 2){
    683 						on_time = on_time - 10;
    684 						off_time = off_time - 10;
    685 					}
    686 				}
    687 
    688 				/* decremental button */
    689 				if(i == 5 && j == 2){
    690 					if(on_time <= DTMF_ON * 2){
    691 						on_time = on_time + 10;
    692 						off_time = off_time + 10;
    693 					}
    694 				}
    695 
    696 				/* dialing button */
    697 				if((i==4 || i==5) && j==3){
    698 					dialtone(on_time, off_time, str);
    699 				}
    700 			}
    701 		}
    702 		if(!(key1 & J_A)){
    703 			if((key1 & J_UP) && !(key2 & J_UP) && j > 0)
    704 				j--;
    705 			else if((key1 & J_DOWN) && !(key2 & J_DOWN) && j < 3)
    706 				j++;
    707 
    708 			if((key1 & J_LEFT) && !(key2 & J_LEFT) && i > 0)
    709 				i--;
    710 			else if((key1 & J_RIGHT) && !(key2 & J_RIGHT) && i < 5)
    711 				i++;
    712 		}
    713 		key2 = key1;
    714 	}
    715 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.