conio: switch cursor get/set to BIOS calls, rename text-mode accessors
_get_cursor/_set_cursor now use BIOS GetCursor/SetCursor (RST 8, 08Eh/084h) instead of ESTEX CURSOR/LOCATE; cursor position packed into a two_bytes union. get_videotextmode/set_videotextmode renamed to gettextmode/settextmode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+136
-149
@@ -15,10 +15,18 @@
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/* Forward extern — definition is further down (after putch/cputs which
|
||||
* reference it from asm by linker-symbol name). */
|
||||
extern int16_t g_text_attr;
|
||||
static two_bytes g_text_attr = {0};
|
||||
static uint8_t pc_ch = 0;
|
||||
extern two_bytes pc_place = {0};
|
||||
static uint8_t pc_raw_mode = 0;
|
||||
|
||||
|
||||
// TODO - проверить - ф-ии 30h-33h (kbhit/getch/getche/getkey)
|
||||
// не должны менять IX и им можно не делать push ix / pop ix
|
||||
//
|
||||
char kbhit(void) __naked
|
||||
{
|
||||
__asm
|
||||
@@ -91,10 +99,6 @@ uint16_t getkey(void) __naked
|
||||
* caller to use "\r\n" explicitly. Stdio puts/putchar do translate.
|
||||
*/
|
||||
|
||||
static uint8_t pc_ch = 0;
|
||||
static uint8_t pc_attr = 0;
|
||||
static uint8_t pc_row = 0;
|
||||
static uint8_t pc_col = 0;
|
||||
|
||||
/* Controls how _raw_putch treats control characters (< 0x20):
|
||||
* 0 (default) — BS/TAB/LF/CR are interpreted (no glyph output);
|
||||
@@ -104,7 +108,6 @@ static uint8_t pc_col = 0;
|
||||
* Only takes effect on the WRCHAR (attr ≤ 0xFF) path. When
|
||||
* g_text_attr is KEEP_EXIST_ATTR, ESTEX's own PUTCHAR/PCHARS handle
|
||||
* cursor and control chars — pc_raw_mode is irrelevant. */
|
||||
static uint8_t pc_raw_mode = 0;
|
||||
|
||||
void set_putch_raw_mode(uint8_t mode) { pc_raw_mode = mode; }
|
||||
uint8_t get_putch_raw_mode(void) { return pc_raw_mode; }
|
||||
@@ -115,14 +118,11 @@ uint8_t get_putch_raw_mode(void) { return pc_raw_mode; }
|
||||
static void _get_cursor(void) __naked
|
||||
{
|
||||
__asm
|
||||
push ix
|
||||
ld c, #0x53 ; ESTEX CURSOR
|
||||
rst #0x10
|
||||
ld a, d
|
||||
ld (_pc_row), a
|
||||
ld a, e
|
||||
ld (_pc_col), a
|
||||
pop ix
|
||||
; push ix
|
||||
ld c, #0x8e ; BIOS GetCursor
|
||||
rst #0x08
|
||||
ld (_pc_place), de
|
||||
; pop ix
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
@@ -131,14 +131,11 @@ static void _get_cursor(void) __naked
|
||||
static void _set_cursor(void) __naked
|
||||
{
|
||||
__asm
|
||||
push ix
|
||||
ld a, (_pc_row)
|
||||
ld d, a
|
||||
ld a, (_pc_col)
|
||||
ld e, a
|
||||
ld c, #0x52 ; ESTEX LOCATE
|
||||
rst #0x10
|
||||
pop ix
|
||||
; push ix
|
||||
ld de, (_pc_place)
|
||||
ld c, #0x84 ; BIOS SetCursor
|
||||
rst #0x08
|
||||
; pop ix
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
@@ -183,7 +180,7 @@ static char _bios_putchar(char ch) __naked
|
||||
* once before a sequence of _raw_putch calls and write it back once
|
||||
* after, so we pay the BIOS overhead per OPERATION instead of per CHAR. */
|
||||
/* Mode-0 worker: interprets BS/TAB/LF/CR, outputs other chars as glyphs. */
|
||||
static void _raw_putch_raw0(char ch, uint8_t attr) __naked
|
||||
static void _putch_wrchar(char ch, uint8_t attr) __naked
|
||||
{
|
||||
(void)ch; (void)attr;
|
||||
__asm
|
||||
@@ -191,6 +188,12 @@ static void _raw_putch_raw0(char ch, uint8_t attr) __naked
|
||||
;; Dispatch on control chars while A still holds ch (cp does not
|
||||
;; modify A). B/C only get loaded on the output path so the
|
||||
;; ctrl-char paths are cheaper.
|
||||
|
||||
;; ld c, a
|
||||
;; ld a, (_pc_ch) ; A = ch (`ld a,(nn)` does not touch flags)
|
||||
;; jr nz, _rp0_pri
|
||||
|
||||
;; ld a, c
|
||||
cp #0x08
|
||||
jr z, _rp0_bs
|
||||
cp #0x09
|
||||
@@ -201,18 +204,21 @@ static void _raw_putch_raw0(char ch, uint8_t attr) __naked
|
||||
jr z, _rp0_cr
|
||||
;; Anything else (printable or unrecognised ctrl) → glyph.
|
||||
|
||||
_rp0_pri:
|
||||
|
||||
ld c, a ; C = ch (save before A is clobbered)
|
||||
ld a, (_pc_row)
|
||||
ld a, (_pc_place + 1)
|
||||
cp #32
|
||||
ret nc ; off-screen bottom — silently skip
|
||||
ld d, a ; D = row (ESTEX WRCHAR convention)
|
||||
ld a, (_pc_col)
|
||||
ld a, (_pc_place)
|
||||
cp #80
|
||||
ret nc ; off-screen right — silently skip
|
||||
ret nc ; off-screen right — silently skip
|
||||
ld e, a ; E = col
|
||||
inc a
|
||||
ld (_pc_col), a ; pc_col++
|
||||
ld (_pc_place), a ; pc_col++
|
||||
|
||||
_rp0_wr:
|
||||
ld b, l ; B = attr
|
||||
ld a, c ; A = ch
|
||||
push ix
|
||||
@@ -222,56 +228,61 @@ static void _raw_putch_raw0(char ch, uint8_t attr) __naked
|
||||
ret
|
||||
|
||||
_rp0_bs:
|
||||
ld a, (_pc_col)
|
||||
ld a, (_pc_place)
|
||||
or a, a
|
||||
ret z ; already at col 0 — no change
|
||||
dec a
|
||||
ld (_pc_col), a
|
||||
ret
|
||||
ld (_pc_place), a
|
||||
ld e, a ; E = col
|
||||
ld a, (_pc_place + 1)
|
||||
ld d, a ; D = row (ESTEX WRCHAR convention)
|
||||
ld c, #0x20
|
||||
jr _rp0_wr
|
||||
|
||||
_rp0_tab:
|
||||
ld a, (_pc_col)
|
||||
and #0xF8 ; floor to mult of 8
|
||||
add a, #8 ; → next mult of 8
|
||||
cp #80
|
||||
jr c, _rp0_tab_store
|
||||
ld a, #80 ; cap at off-screen right
|
||||
_rp0_tab_store:
|
||||
ld (_pc_col), a
|
||||
ld a, (_pc_place)
|
||||
or #0x07 ; floor to mult of 8
|
||||
inc a ; → next mult of 8
|
||||
cp #81 ; сравнить A с 81 (0x51)
|
||||
jr c, _rp0_tab_skip ; если A < 81 (т.е. A ≤ 80), пропустить загрузку
|
||||
ld a, #80 ; иначе A > 80 → установить A = 80
|
||||
_rp0_tab_skip:
|
||||
ld (_pc_place), a
|
||||
ret
|
||||
|
||||
_rp0_lf:
|
||||
ld a, (_pc_row)
|
||||
ld a, (_pc_place + 1)
|
||||
cp #32
|
||||
ret nc ; already at bottom edge
|
||||
inc a
|
||||
ld (_pc_row), a
|
||||
ld (_pc_place + 1), a
|
||||
ret
|
||||
|
||||
_rp0_cr:
|
||||
xor a, a
|
||||
ld (_pc_col), a
|
||||
ld (_pc_place), a
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
|
||||
/* Mode-1 worker: every byte goes through WRCHAR as a glyph. */
|
||||
static void _raw_putch_raw1(char ch, uint8_t attr) __naked
|
||||
static void _putch_wrchar_raw(char ch, uint8_t attr) __naked
|
||||
{
|
||||
(void)ch; (void)attr;
|
||||
__asm
|
||||
;; __sdcccall(1): ch in A, attr in L.
|
||||
ld c, a ; C = ch (save)
|
||||
ld a, (_pc_row)
|
||||
|
||||
ld a, (_pc_place + 1)
|
||||
cp #32
|
||||
ret nc ; off-screen bottom — silently skip
|
||||
ld d, a ; D = row
|
||||
ld a, (_pc_col)
|
||||
ld a, (_pc_place)
|
||||
cp #80
|
||||
ret nc ; off-screen right — silently skip
|
||||
ret nc ; off-screen right — silently skip
|
||||
ld e, a ; E = col
|
||||
inc a
|
||||
ld (_pc_col), a ; pc_col++
|
||||
ld (_pc_place), a ; pc_col++
|
||||
|
||||
ld b, l ; B = attr
|
||||
ld a, c ; A = ch
|
||||
@@ -283,18 +294,6 @@ static void _raw_putch_raw1(char ch, uint8_t attr) __naked
|
||||
__endasm;
|
||||
}
|
||||
|
||||
/* PCHARS (no attr) — used by cputs when KEEP_EXIST_ATTR is in effect. */
|
||||
static void _cputs_pchars(const char *s) __naked
|
||||
{
|
||||
(void)s;
|
||||
__asm
|
||||
push ix
|
||||
ld c, #0x5C ; ESTEX PCHARS
|
||||
rst #0x10
|
||||
pop ix
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
|
||||
/* ---- Public putch / cputs --------------------------------------- *
|
||||
*
|
||||
@@ -306,6 +305,7 @@ static void _cputs_pchars(const char *s) __naked
|
||||
* folds the per-char CURSOR/LOCATE pair from the old design into a
|
||||
* single pair per operation. */
|
||||
|
||||
|
||||
char putch(char ch) __naked
|
||||
{
|
||||
(void)ch;
|
||||
@@ -313,38 +313,26 @@ char putch(char ch) __naked
|
||||
;; A = ch on entry; char return → A.
|
||||
ld (_pc_ch), a ; stash c (for both return and re-load)
|
||||
|
||||
;; KEEP_EXIST_ATTR? high byte of g_text_attr != 0
|
||||
ld a, (_g_text_attr + 1)
|
||||
or a, a
|
||||
jr nz, _putch_fast
|
||||
|
||||
;; --- WRCHAR path: cursor → worker → cursor ---
|
||||
call __get_cursor
|
||||
|
||||
;; Worker ABI (2 char/uint8 args): ch in A, attr in L.
|
||||
ld a, (_g_text_attr) ; A = low byte = attr
|
||||
ld l, a ; L = attr
|
||||
|
||||
ld a, (_pc_raw_mode)
|
||||
or a, a ; Z = (mode == 0)
|
||||
ld a, (_pc_ch) ; A = ch (`ld a,(nn)` does not touch flags)
|
||||
jr nz, _putch_use_raw1
|
||||
call __raw_putch_raw0
|
||||
jr nz, _putch_use_raw
|
||||
call __putch_wrchar
|
||||
jr _putch_after_raw
|
||||
_putch_use_raw1:
|
||||
call __raw_putch_raw1
|
||||
_putch_use_raw:
|
||||
call __putch_wrchar_raw
|
||||
_putch_after_raw:
|
||||
call __set_cursor
|
||||
ld a, (_pc_ch) ; return value
|
||||
ret
|
||||
|
||||
_putch_fast:
|
||||
ld a, (_pc_ch)
|
||||
call __bios_putchar ; __bios_putchar keeps AF
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
|
||||
|
||||
char cputs(const char *s) __naked
|
||||
{
|
||||
(void)s;
|
||||
@@ -356,60 +344,48 @@ char cputs(const char *s) __naked
|
||||
or a, l
|
||||
ret z
|
||||
|
||||
;; IX is callee-saved under SDCC's z80 ABI. We use it as a
|
||||
;; function pointer below (ld ix, #__raw_putch_raw0/1) so save
|
||||
;; the caller's value up front and restore before every ret.
|
||||
push ix
|
||||
|
||||
call __get_cursor
|
||||
|
||||
;; KEEP_EXIST_ATTR? high byte of g_text_attr != 0
|
||||
ld a, (_g_text_attr + 1)
|
||||
or a, a
|
||||
jr nz, _cputs_fast
|
||||
|
||||
;; --- WRCHAR path: cursor → worker → cursor ---
|
||||
call __get_cursor
|
||||
|
||||
;; Worker walks the string via DE; HL is used to carry attr in L
|
||||
;; across iterations (RST 10 inside worker clobbers it, so we
|
||||
;; push/pop hl around each call).
|
||||
ex de, hl ; DE = s
|
||||
ld a, (_g_text_attr) ; A = attr (low byte)
|
||||
ld l, a ; L = attr (worker ABI: arg2 in L)
|
||||
|
||||
;; Pick worker once based on pc_raw_mode; IX = function pointer.
|
||||
ld a, (_pc_raw_mode)
|
||||
or a, a
|
||||
jr z, _cputs_use_raw0
|
||||
ld ix, #__raw_putch_raw1
|
||||
jr _cputs_loop
|
||||
_cputs_use_raw0:
|
||||
ld ix, #__raw_putch_raw0
|
||||
jr nz, _cputs_bios
|
||||
|
||||
_cputs_loop:
|
||||
ld a, (de)
|
||||
or a, a
|
||||
jr z, _cputs_loop_end
|
||||
inc de
|
||||
;; Z80 has no "call (ix)" — emulate via push-of-ret + jp (ix).
|
||||
push de ; save string pointer
|
||||
push hl ; save attr (in L)
|
||||
ld de, #_cputs_after_worker
|
||||
push de ; push return address
|
||||
jp (ix) ; "call" worker
|
||||
_cputs_after_worker:
|
||||
pop hl
|
||||
push hl
|
||||
pop de
|
||||
jr _cputs_loop
|
||||
_cputs_loop_end:
|
||||
|
||||
_cputs_wrloop:
|
||||
ld a, (_g_text_attr)
|
||||
ld l, a
|
||||
ld a, (de) ; загрузить байт
|
||||
or a ; установить флаг Z, если A == 0
|
||||
jr z, _cputs_ex ; завершить подпрограмму (конец строки)
|
||||
push de
|
||||
call __putch_wrchar ; вывести символ (A передаётся как аргумент)
|
||||
pop de
|
||||
inc de ; перейти к следующему байту
|
||||
jr _cputs_wrloop ; повторить
|
||||
|
||||
_cputs_bios:
|
||||
ld a, (_g_text_attr)
|
||||
ld b, #0xFF
|
||||
ld d, #0x0
|
||||
ld e, a
|
||||
ld c, #0x8B ; BIOS LP_PRINT_LN5
|
||||
rst #0x08
|
||||
jr _cputs_ex
|
||||
_cputs_fast:
|
||||
ld c, #0x5C ; ESTEX PCHARS
|
||||
rst #0x10
|
||||
_cputs_ex:
|
||||
call __set_cursor
|
||||
pop ix ; restore caller's IX
|
||||
xor a, a ; return 0
|
||||
ret
|
||||
|
||||
_cputs_fast:
|
||||
call __cputs_pchars
|
||||
pop ix ; restore caller's IX
|
||||
pop ix ; restore callers IX
|
||||
xor a, a ; return 0
|
||||
ret
|
||||
__endasm;
|
||||
@@ -446,12 +422,15 @@ void gotoxy(uint8_t x, uint8_t y) __naked
|
||||
__asm
|
||||
;; __sdcccall(1) 2 uint8 args: x in A, y in L.
|
||||
;; ESTEX LOCATE ($52) wants: D = row, E = col.
|
||||
push ix
|
||||
ld d, l ; D = row (y)
|
||||
ld e, a ; E = col (x)
|
||||
ld c, #0x52
|
||||
rst #0x10
|
||||
pop ix
|
||||
;; push ix
|
||||
ld d, l ; D = row (y)
|
||||
ld e, a ; E = col (x)
|
||||
ld (_pc_place), de
|
||||
ld c, #0x84 ; BIOS SetCursor
|
||||
rst #0x08
|
||||
;; ld c, #0x52
|
||||
;; rst #0x10
|
||||
;; pop ix
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
@@ -460,11 +439,14 @@ uint8_t wherex(void) __naked
|
||||
{
|
||||
__asm
|
||||
;; ESTEX CURSOR ($53): D = row, E = col. Return col in DE.
|
||||
push ix
|
||||
ld c, #0x53
|
||||
rst #0x10
|
||||
pop ix
|
||||
ld a, e
|
||||
;; push ix
|
||||
ld c, #0x8e ; BIOS GetCursor
|
||||
rst #0x08
|
||||
;; ld c, #0x53
|
||||
;; rst #0x10
|
||||
;; pop ix
|
||||
ld a, e
|
||||
ld (_pc_place), de
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
@@ -472,11 +454,14 @@ uint8_t wherex(void) __naked
|
||||
uint8_t wherey(void) __naked
|
||||
{
|
||||
__asm
|
||||
push ix
|
||||
ld c, #0x53
|
||||
rst #0x10
|
||||
pop ix
|
||||
ld a, d
|
||||
;; push ix
|
||||
ld c, #0x8e ; BIOS GetCursor
|
||||
rst #0x08
|
||||
;; ld c, #0x53
|
||||
;; rst #0x10
|
||||
;; pop ix
|
||||
ld a, d
|
||||
ld (_pc_place), de
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
@@ -485,10 +470,13 @@ uint16_t wherexy(void) __naked
|
||||
{
|
||||
__asm
|
||||
;; ESTEX CURSOR ($53): D = row, E = col. Return col in DE.
|
||||
push ix
|
||||
ld c, #0x53
|
||||
rst #0x10
|
||||
pop ix
|
||||
;; push ix
|
||||
ld c, #0x8e ; BIOS GetCursor
|
||||
rst #0x08
|
||||
;; ld c, #0x53
|
||||
;; rst #0x10
|
||||
;; pop ix
|
||||
ld (_pc_place), de
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
@@ -577,12 +565,12 @@ uint16_t rdchar(uint8_t x, uint8_t y) __naked
|
||||
extern uint8_t _videomode_raw_get(void);
|
||||
extern int _videomode_raw_set(uint8_t mode);
|
||||
|
||||
uint8_t get_videotextmode(void)
|
||||
uint8_t gettextmode(void)
|
||||
{
|
||||
return _videomode_raw_get();
|
||||
}
|
||||
|
||||
int set_videotextmode(uint8_t mode)
|
||||
int settextmode(uint8_t mode)
|
||||
{
|
||||
/* Refuse anything that isn't a known text mode — otherwise a stray
|
||||
* GFX_MODE_* value could swap the screen out from under text I/O. */
|
||||
@@ -600,18 +588,17 @@ int set_videotextmode(uint8_t mode)
|
||||
*
|
||||
* 0x00..0xFF — real attribute (4-bit FG | 3-bit BG | 1-bit blink)
|
||||
* KEEP_EXIST_ATTR (0xFFFF) — putch/cputs fall back to fast no-attr path */
|
||||
int16_t g_text_attr = 0x0F;
|
||||
|
||||
int16_t set_text_attr(int16_t attr)
|
||||
{
|
||||
int16_t prev = g_text_attr;
|
||||
g_text_attr = attr;
|
||||
int16_t prev = g_text_attr.value;
|
||||
g_text_attr.value = attr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
int16_t get_text_attr(void)
|
||||
{
|
||||
return g_text_attr;
|
||||
return g_text_attr.value;
|
||||
}
|
||||
|
||||
/* ---- Turbo-C-style palette helpers --------------------------------
|
||||
@@ -620,21 +607,21 @@ int16_t get_text_attr(void)
|
||||
|
||||
void textcolor(uint8_t fg)
|
||||
{
|
||||
/* If we were KEEP_EXIST_ATTR, switch to a real attr first. */
|
||||
uint8_t cur = ((uint16_t)g_text_attr > 0xFF) ? 0x00 : (uint8_t)g_text_attr;
|
||||
g_text_attr = (int16_t)((cur & 0xF0) | (fg & 0x0F));
|
||||
fg = (fg & 0x07);
|
||||
g_text_attr.value = (g_text_attr.byte.low & 0xF0) | fg;
|
||||
// g_text_attr.byte.high = 0;
|
||||
}
|
||||
|
||||
void textbackground(uint8_t bg)
|
||||
{
|
||||
uint8_t cur = ((uint16_t)g_text_attr > 0xFF) ? 0x00 : (uint8_t)g_text_attr;
|
||||
/* Background uses 3 bits (4..6); preserve blink (bit 7) too. */
|
||||
g_text_attr = (int16_t)((cur & 0x8F) | ((bg & 0x07) << 4));
|
||||
bg = (bg & 0x07) << 4;
|
||||
g_text_attr.value = (g_text_attr.byte.low & 0x0F) | bg;
|
||||
// g_text_attr.byte.high = 0;
|
||||
}
|
||||
|
||||
void textattr(uint8_t attr)
|
||||
{
|
||||
g_text_attr = (int16_t)attr;
|
||||
g_text_attr.value = (uint16_t)attr;
|
||||
}
|
||||
|
||||
/* ---- Solid-C compatibility ---------------------------------------- */
|
||||
|
||||
+14
-2
@@ -74,12 +74,24 @@ uint16_t getkey(void);
|
||||
#define KEY_PGUP 0x59
|
||||
#define KEY_INS 0x50 /* numpad 0; not verified */
|
||||
#define KEY_DEL 0x55 /* numpad 5/.; not verified */
|
||||
|
||||
typedef union {
|
||||
uint16_t value;
|
||||
struct {
|
||||
uint8_t low;
|
||||
uint8_t high;
|
||||
} byte;
|
||||
} two_bytes;
|
||||
|
||||
|
||||
|
||||
char putch (char c);
|
||||
char cputs (const char *s);
|
||||
int cprintf(const char *fmt, ...);
|
||||
void clrscr(void);
|
||||
void gotoxy(uint8_t x, uint8_t y);
|
||||
|
||||
|
||||
/* Solid-C compatibility helpers. */
|
||||
#define home() gotoxy(0, 0)
|
||||
#define inp(port) z80_inp(port)
|
||||
@@ -124,8 +136,8 @@ void clrscr_attr(uint8_t attr);
|
||||
#define TEXT_MODE_40x32 0x02
|
||||
#define TEXT_MODE_80x32 0x03
|
||||
|
||||
uint8_t get_videotextmode(void);
|
||||
int set_videotextmode(uint8_t mode); /* 0 OK, -1 + errno on bad mode */
|
||||
uint8_t gettextmode(void);
|
||||
int settextmode(uint8_t mode); /* 0 OK, -1 + errno on bad mode */
|
||||
|
||||
/* ------------------------------------------------------------------ *
|
||||
* Text-output attribute (used by the conio set: putch / cputs / cprintf).
|
||||
|
||||
+27
-5
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <unistd.h> /* sleep */
|
||||
#include <sprinter_exit.h>
|
||||
|
||||
/*
|
||||
* Exercises every conio function:
|
||||
@@ -16,6 +17,8 @@
|
||||
* (0,0), (79,0), (0,31), (79,31).
|
||||
*/
|
||||
|
||||
extern two_bytes pc_place;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* 1. clrscr + diagnostic probes + a centered banner.
|
||||
@@ -27,9 +30,16 @@ int main(void)
|
||||
*/
|
||||
clrscr();
|
||||
|
||||
gotoxy(0, 0); putch('0');
|
||||
gotoxy(1, 0);
|
||||
textattr(0x07);
|
||||
putch('0');
|
||||
textattr(0x70);
|
||||
gotoxy(1, 0); putch('1');
|
||||
putch('1');
|
||||
// gotoxy(10, 20);
|
||||
printf("X = %u, Y = %u\n", pc_place.byte.low, pc_place.byte.high);
|
||||
uint8_t x = wherex();
|
||||
uint8_t y = wherey();
|
||||
printf("X = %u, Y = %u\n", x, y);
|
||||
|
||||
set_putch_raw_mode(1);
|
||||
|
||||
@@ -51,11 +61,23 @@ int main(void)
|
||||
}
|
||||
}
|
||||
|
||||
set_text_attr(0x011D);
|
||||
set_putch_raw_mode(0);
|
||||
gotoxy(0,22);
|
||||
set_text_attr(0x000E);
|
||||
// cputs("Test message line");
|
||||
cputs("Test message line 1\nTest message line2\rline3\n\r\n\r1234\t5678\b90");
|
||||
cputs("Test message line 1\nTest message line2\rline3\n\r1234\t5678\b90\n\r");
|
||||
|
||||
set_putch_raw_mode(1);
|
||||
gotoxy(0,25);
|
||||
cputs("Test message line 1\nTest message line2\rline3\n\r1234\t5678\b90\n\r");
|
||||
|
||||
set_text_attr(0x001D);
|
||||
set_putch_raw_mode(0);
|
||||
gotoxy(0,28);
|
||||
cputs("Test message line 1\nTest message line2\rline3\n\r1234\t5678\b90\n\r");
|
||||
|
||||
set_putch_raw_mode(1);
|
||||
gotoxy(0,31);
|
||||
cputs("Test message line 1\nTest message line2\rline3\n\r1234\t5678\b90\n\r");
|
||||
|
||||
(void)getch();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user