first (crude) implementation for Radeon console output
This commit is contained in:
@@ -893,3 +893,5 @@ tos/Makefile
|
|||||||
radeon/radeon_i2c.c
|
radeon/radeon_i2c.c
|
||||||
basflash.lk.in
|
basflash.lk.in
|
||||||
radeon/i2c-algo-bit.c
|
radeon/i2c-algo-bit.c
|
||||||
|
util/conout.c
|
||||||
|
include/conout.h
|
||||||
|
|||||||
@@ -1,55 +1,55 @@
|
|||||||
include
|
include
|
||||||
tos/jtagwait/include
|
tos/jtagwait/include
|
||||||
tos/pci_test/include
|
tos/pci_test/include
|
||||||
/usr/m68k-atari-mint/include
|
/usr/m68k-atari-mint/include
|
||||||
/opt/cross-mint/m68k-atari-mint/include
|
/opt/cross-mint/m68k-atari-mint/include
|
||||||
/opt/gygwin/opt/cross-mint/m68k-atari-mint/include
|
/opt/gygwin/opt/cross-mint/m68k-atari-mint/include
|
||||||
/opt/m68k-elf/include
|
/opt/m68k-elf/include
|
||||||
/opt/cygwin/opt/m68k-elf/include
|
/opt/cygwin/opt/m68k-elf/include
|
||||||
/opt/cygwin/opt/m68k-elf/lib/gcc/m68k-elf/4.6.4/include
|
/opt/cygwin/opt/m68k-elf/lib/gcc/m68k-elf/4.6.4/include
|
||||||
dma
|
dma
|
||||||
m54455
|
m54455
|
||||||
sys
|
sys
|
||||||
pci
|
pci
|
||||||
tos/pci_test
|
tos/pci_test
|
||||||
tos/jtagwait/m5475/mshort
|
tos/jtagwait/m5475/mshort
|
||||||
m5484lite
|
m5484lite
|
||||||
tos/pci_test/include
|
tos/pci_test/include
|
||||||
tos/bascook
|
tos/bascook
|
||||||
tos/vmem_test/m5475/mshort
|
tos/vmem_test/m5475/mshort
|
||||||
i2c
|
i2c
|
||||||
fs
|
fs
|
||||||
tos/vmem_test/m5475
|
tos/vmem_test/m5475
|
||||||
tos/pci_test/m5475
|
tos/pci_test/m5475
|
||||||
spi
|
spi
|
||||||
if
|
if
|
||||||
tos/jtagwait/m5475
|
tos/jtagwait/m5475
|
||||||
util
|
util
|
||||||
kbd
|
kbd
|
||||||
flash_scripts
|
flash_scripts
|
||||||
video
|
video
|
||||||
usb
|
usb
|
||||||
exe
|
exe
|
||||||
tos/vmem_test/sources
|
tos/vmem_test/sources
|
||||||
tos
|
tos
|
||||||
nutil
|
nutil
|
||||||
tos/jtagwait/sources
|
tos/jtagwait/sources
|
||||||
x86emu
|
x86emu
|
||||||
flash
|
flash
|
||||||
tos/vmem_test/include
|
tos/vmem_test/include
|
||||||
tos/bascook/sources
|
tos/bascook/sources
|
||||||
tos/pci_test/m5475/mshort
|
tos/pci_test/m5475/mshort
|
||||||
.
|
.
|
||||||
radeon
|
radeon
|
||||||
net
|
net
|
||||||
xhdi
|
xhdi
|
||||||
tos/vmem_test
|
tos/vmem_test
|
||||||
tos/pci_test/sources
|
tos/pci_test/sources
|
||||||
firebee
|
firebee
|
||||||
tos/jtagwait
|
tos/jtagwait
|
||||||
tos/fpga_test/include
|
tos/fpga_test/include
|
||||||
tos/fpga_test
|
tos/fpga_test
|
||||||
tos/fpga_test/sources
|
tos/fpga_test/sources
|
||||||
tos/pci_mem
|
tos/pci_mem
|
||||||
tos/pci_mem/include
|
tos/pci_mem/include
|
||||||
tos/pci_mem/sources
|
tos/pci_mem/sources
|
||||||
|
|||||||
@@ -87,8 +87,11 @@ CSRCS= \
|
|||||||
init_fpga.c \
|
init_fpga.c \
|
||||||
fault_vectors.c \
|
fault_vectors.c \
|
||||||
interrupts.c \
|
interrupts.c \
|
||||||
|
\
|
||||||
bas_printf.c \
|
bas_printf.c \
|
||||||
bas_string.c \
|
bas_string.c \
|
||||||
|
conout.c \
|
||||||
|
\
|
||||||
BaS.c \
|
BaS.c \
|
||||||
cache.c \
|
cache.c \
|
||||||
mmu.c \
|
mmu.c \
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ SECTIONS
|
|||||||
OBJDIR/s19reader.o(.text)
|
OBJDIR/s19reader.o(.text)
|
||||||
OBJDIR/bas_printf.o(.text)
|
OBJDIR/bas_printf.o(.text)
|
||||||
OBJDIR/bas_string.o(.text)
|
OBJDIR/bas_string.o(.text)
|
||||||
|
OBJDIR/conout.o(.text)
|
||||||
#if (FORMAT_ELF == 1)
|
#if (FORMAT_ELF == 1)
|
||||||
OBJDIR/libgcc_helper.o(.text)
|
OBJDIR/libgcc_helper.o(.text)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
63
BaS_gcc/include/conout.h
Executable file
63
BaS_gcc/include/conout.h
Executable file
@@ -0,0 +1,63 @@
|
|||||||
|
#ifndef __CONOUT_H__
|
||||||
|
#define __CONOUT_H__
|
||||||
|
|
||||||
|
#include "bas_types.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* conout.h - lowlevel color model dependent screen handling routines
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2016 by Authors:
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* MAD Martin Doering
|
||||||
|
*
|
||||||
|
* This file is distributed under the GPL, version 2 or at your
|
||||||
|
* option any later version. See doc/license.txt for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Defines for cursor */
|
||||||
|
#define M_CFLASH 0x0001 /* cursor flash 0:disabled 1:enabled */
|
||||||
|
#define M_CSTATE 0x0002 /* cursor flash state 0:off 1:on */
|
||||||
|
#define M_CVIS 0x0004 /* cursor visibility 0:invisible 1:visible */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The visibility flag is also used as a semaphore to prevent
|
||||||
|
* the interrupt-driven cursor blink logic from colliding with
|
||||||
|
* escape function/sequence cursor drawing activity.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define M_CEOL 0x0008 /* end of line handling 0:overwrite 1:wrap */
|
||||||
|
#define M_REVID 0x0010 /* reverse video 0:on 1:off */
|
||||||
|
#define M_SVPOS 0x0020 /* position saved flag. 0:false, 1:true */
|
||||||
|
#define M_CRIT 0x0040 /* reverse video 0:on 1:off */
|
||||||
|
|
||||||
|
/* Color related linea variables */
|
||||||
|
|
||||||
|
extern int16_t v_col_bg; /* current background color */
|
||||||
|
extern int16_t v_col_fg; /* current foreground color */
|
||||||
|
|
||||||
|
/* Cursor related linea variables */
|
||||||
|
|
||||||
|
extern uint8_t *v_cur_ad; /* current cursor address */
|
||||||
|
extern int16_t v_cur_of; /* cursor offset */
|
||||||
|
extern int8_t v_cur_tim; /* cursor blink timer */
|
||||||
|
|
||||||
|
extern int8_t v_period;
|
||||||
|
extern int16_t disab_cnt; /* disable depth count. (>0 means disabled) */
|
||||||
|
extern int8_t v_stat_0; /* video cell system status */
|
||||||
|
extern int16_t sav_cur_x; /* saved cursor cell x */
|
||||||
|
extern int16_t sav_cur_y; /* saved cursor cell y */
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
|
||||||
|
extern void ascii_out(int);
|
||||||
|
extern void move_cursor(int, int);
|
||||||
|
extern void blank_out (int, int, int, int);
|
||||||
|
extern void invert_cell(int, int);
|
||||||
|
extern void scroll_up(int);
|
||||||
|
extern void scroll_down(int);
|
||||||
|
|
||||||
|
#endif /* __CONOUT_H__ */
|
||||||
@@ -95,4 +95,6 @@ struct font_head {
|
|||||||
void font_init(void); /* initialize BIOS font ring */
|
void font_init(void); /* initialize BIOS font ring */
|
||||||
void font_set_default(void); /* choose the default font */
|
void font_set_default(void); /* choose the default font */
|
||||||
|
|
||||||
|
extern const struct font_head *fnt_st_8x16;
|
||||||
|
|
||||||
#endif /* FONT_H */
|
#endif /* FONT_H */
|
||||||
|
|||||||
561
BaS_gcc/util/conout.c
Executable file
561
BaS_gcc/util/conout.c
Executable file
@@ -0,0 +1,561 @@
|
|||||||
|
/*
|
||||||
|
* conout.c - lowlevel color model dependent screen handling routines
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 by Authors (see below)
|
||||||
|
* Copyright (C) 2016 The EmuTOS development team
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* MAD Martin Doering
|
||||||
|
*
|
||||||
|
* This file is distributed under the GPL, version 2 or at your
|
||||||
|
* option any later version. See doc/license.txt for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "conout.h"
|
||||||
|
#include "video.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "fb.h"
|
||||||
|
|
||||||
|
#define plane_offset 2 /* interleaved planes */
|
||||||
|
|
||||||
|
#define v_fnt_st fnt_st_8x16->first_ade
|
||||||
|
#define v_fnt_nd fnt_st_8x16->last_ade
|
||||||
|
#define v_off_ad fnt_st_8x16->off_table
|
||||||
|
#define v_bas_ad info_fb->screen_base
|
||||||
|
|
||||||
|
uint8_t *v_cur_ad; /* cursor address */
|
||||||
|
int8_t v_stat_0; /* console status byte */
|
||||||
|
uint16_t v_cur_cx;
|
||||||
|
uint16_t v_cur_cy;
|
||||||
|
const int16_t v_planes = 8;
|
||||||
|
extern struct fb_info *info_fb;
|
||||||
|
#define v_lin_wr (info_fb->var.width / 2) /* length of a screen line in words */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* internal prototypes
|
||||||
|
*/
|
||||||
|
static void neg_cell(uint8_t *);
|
||||||
|
static uint8_t * cell_addr(int, int);
|
||||||
|
static void cell_xfer(uint8_t *, uint8_t *);
|
||||||
|
static bool next_cell(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* char_addr - retrieve the address of the source cell
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Given an offset value.
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
* ch - source cell code
|
||||||
|
*
|
||||||
|
* out:
|
||||||
|
* pointer to first byte of source cell if code was valid
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint8_t *char_addr(int16_t ch)
|
||||||
|
{
|
||||||
|
uint16_t offs;
|
||||||
|
|
||||||
|
/* test against limits */
|
||||||
|
if (ch >= v_fnt_st)
|
||||||
|
{
|
||||||
|
if (ch <= v_fnt_nd)
|
||||||
|
{
|
||||||
|
/* getch offset from offset table */
|
||||||
|
offs = v_off_ad[ch];
|
||||||
|
offs >>= 3; /* convert from pixels to bytes. */
|
||||||
|
|
||||||
|
/* return valid address */
|
||||||
|
return (uint8_t*) v_fnt_ad + offs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invalid code. no address returned */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ascii_out - prints an ascii character on the screen
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
*
|
||||||
|
* ch.w ascii code for character
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ascii_out(int ch)
|
||||||
|
{
|
||||||
|
uint8_t * src, * dst;
|
||||||
|
bool visible; /* was the cursor visible? */
|
||||||
|
|
||||||
|
src = char_addr(ch); /* a0 -> get character source */
|
||||||
|
if (src == NULL)
|
||||||
|
return; /* no valid character */
|
||||||
|
|
||||||
|
dst = v_cur_ad; /* a1 -> get destination */
|
||||||
|
|
||||||
|
visible = v_stat_0 & M_CVIS; /* test visibility bit */
|
||||||
|
if ( visible ) {
|
||||||
|
neg_cell(v_cur_ad); /* delete cursor. */
|
||||||
|
v_stat_0 &= ~M_CVIS; /* start of critical section */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put the cell out (this covers the cursor) */
|
||||||
|
cell_xfer(src, dst);
|
||||||
|
|
||||||
|
/* advance the cursor and update cursor address and coordinates */
|
||||||
|
if (next_cell())
|
||||||
|
{
|
||||||
|
uint8_t * cell;
|
||||||
|
|
||||||
|
int y = v_cur_cy;
|
||||||
|
|
||||||
|
/* perform cell carriage return. */
|
||||||
|
cell = v_bas_ad + (uint32_t) v_cel_wr * y;
|
||||||
|
v_cur_cx = 0; /* set X to first cell in line */
|
||||||
|
|
||||||
|
/* perform cell line feed. */
|
||||||
|
if ( y < v_cel_my )
|
||||||
|
{
|
||||||
|
cell += v_cel_wr; /* move down one cell */
|
||||||
|
v_cur_cy = y + 1; /* update cursor's y coordinate */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scroll_up(0); /* scroll from top of screen */
|
||||||
|
}
|
||||||
|
v_cur_ad = cell; /* update cursor address */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if visible */
|
||||||
|
if ( visible ) {
|
||||||
|
neg_cell(v_cur_ad); /* display cursor. */
|
||||||
|
v_stat_0 |= M_CSTATE; /* set state flag (cursor on). */
|
||||||
|
v_stat_0 |= M_CVIS; /* end of critical section. */
|
||||||
|
|
||||||
|
/* do not flash the cursor when it moves */
|
||||||
|
if (v_stat_0 & M_CFLASH) {
|
||||||
|
v_cur_tim = v_period; /* reset the timer. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* blank_out - Fills region with the background color.
|
||||||
|
*
|
||||||
|
* Fills a cell-word aligned region with the background color.
|
||||||
|
*
|
||||||
|
* The rectangular region is specified by a top/left cell x,y and a
|
||||||
|
* bottom/right cell x,y, inclusive. Routine assumes top/left x is
|
||||||
|
* even and bottom/right x is odd for cell-word alignment. This is,
|
||||||
|
* because this routine is heavily optimized for speed, by always
|
||||||
|
* blanking as much space as possible in one go.
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
* topx - top/left cell x position (must be even)
|
||||||
|
* topy - top/left cell y position
|
||||||
|
* botx - bottom/right cell x position (must be odd)
|
||||||
|
* boty - bottom/right cell y position
|
||||||
|
*/
|
||||||
|
|
||||||
|
void blank_out(int topx, int topy, int botx, int boty)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cell_addr - convert cell X,Y to a screen address.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* convert cell X,Y to a screen address. also clip cartesian coordinates
|
||||||
|
* to the limits of the current screen.
|
||||||
|
*
|
||||||
|
* latest update:
|
||||||
|
*
|
||||||
|
* 18-sep-84
|
||||||
|
* in:
|
||||||
|
*
|
||||||
|
* d0.w cell X
|
||||||
|
* d1.w cell Y
|
||||||
|
*
|
||||||
|
* out:
|
||||||
|
* a1 points to first byte of cell
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint8_t *cell_addr(int x, int y)
|
||||||
|
{
|
||||||
|
int32_t disx, disy;
|
||||||
|
|
||||||
|
/* check bounds against screen limits */
|
||||||
|
if ( x >= v_cel_mx )
|
||||||
|
x = v_cel_mx; /* clipped x */
|
||||||
|
|
||||||
|
if ( y >= v_cel_my )
|
||||||
|
y = v_cel_my; /* clipped y */
|
||||||
|
|
||||||
|
/* X displacement = even(X) * v_planes + Xmod2 */
|
||||||
|
disx = (int32_t)v_planes * (x & ~1);
|
||||||
|
if ( x & 1 ) { /* Xmod2 = 0 ? */
|
||||||
|
disx++; /* Xmod2 = 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Y displacement = Y // cell conversion factor */
|
||||||
|
disy = (int32_t)v_cel_wr * y;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cell address = screen base address + Y displacement
|
||||||
|
* + X displacement + offset from screen-begin (fix)
|
||||||
|
*/
|
||||||
|
return v_bas_ad + disy + disx + v_cur_of;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cell_xfer - Performs a byte aligned block transfer.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This routine performs a byte aligned block transfer for the purpose of
|
||||||
|
* manipulating monospaced byte-wide text. the routine maps a single-plane,
|
||||||
|
* arbitrarily-long byte-wide image to a multi-plane bit map.
|
||||||
|
* all transfers are byte aligned.
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
* a0.l points to contiguous source block (1 byte wide)
|
||||||
|
* a1.l points to destination (1st plane, top of block)
|
||||||
|
*
|
||||||
|
* out:
|
||||||
|
* a4 points to byte below this cell's bottom
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void cell_xfer(uint8_t * src, uint8_t * dst)
|
||||||
|
{
|
||||||
|
uint8_t * src_sav, * dst_sav;
|
||||||
|
uint16_t fg;
|
||||||
|
uint16_t bg;
|
||||||
|
int fnt_wr, line_wr;
|
||||||
|
int plane;
|
||||||
|
|
||||||
|
fnt_wr = v_fnt_wr;
|
||||||
|
line_wr = v_lin_wr;
|
||||||
|
|
||||||
|
/* check for reversed foreground and background colors */
|
||||||
|
if ( v_stat_0 & M_REVID)
|
||||||
|
{
|
||||||
|
fg = v_col_bg;
|
||||||
|
bg = v_col_fg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fg = v_col_fg;
|
||||||
|
bg = v_col_bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_sav = src;
|
||||||
|
dst_sav = dst;
|
||||||
|
|
||||||
|
for (plane = v_planes; plane--;)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
src = src_sav; /* reload src */
|
||||||
|
dst = dst_sav; /* reload dst */
|
||||||
|
|
||||||
|
if (bg & 0x0001)
|
||||||
|
{
|
||||||
|
if (fg & 0x0001)
|
||||||
|
{
|
||||||
|
/* back:1 fore:1 => all ones */
|
||||||
|
for (i = v_cel_ht; i--;)
|
||||||
|
{
|
||||||
|
*dst = 0xff; /* inject a block */
|
||||||
|
dst += line_wr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* back:1 fore:0 => invert block */
|
||||||
|
for (i = v_cel_ht; i--; )
|
||||||
|
{
|
||||||
|
/* inject the inverted source block */
|
||||||
|
*dst = ~*src;
|
||||||
|
dst += line_wr;
|
||||||
|
src += fnt_wr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (fg & 0x0001)
|
||||||
|
{
|
||||||
|
/* back:0 fore:1 => direct substitution */
|
||||||
|
for (i = v_cel_ht; i--;)
|
||||||
|
{
|
||||||
|
*dst = *src;
|
||||||
|
dst += line_wr;
|
||||||
|
src += fnt_wr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* back:0 fore:0 => all zeros */
|
||||||
|
for (i = v_cel_ht; i--; )
|
||||||
|
{
|
||||||
|
*dst = 0x00; /* inject a block */
|
||||||
|
dst += line_wr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bg >>= 1; /* next background color bit */
|
||||||
|
fg >>= 1; /* next foreground color bit */
|
||||||
|
dst_sav += plane_offset; /* top of block in next plane */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* move_cursor - move the cursor.
|
||||||
|
*
|
||||||
|
* move the cursor and update global parameters
|
||||||
|
* erase the old cursor (if necessary) and draw new cursor (if necessary)
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
* d0.w new cell X coordinate
|
||||||
|
* d1.w new cell Y coordinate
|
||||||
|
*/
|
||||||
|
|
||||||
|
void move_cursor(int x, int y)
|
||||||
|
{
|
||||||
|
/* update cell position */
|
||||||
|
|
||||||
|
/* clamp x,y to valid ranges */
|
||||||
|
if (x < 0)
|
||||||
|
x = 0;
|
||||||
|
else if (x > v_cel_mx)
|
||||||
|
x = v_cel_mx;
|
||||||
|
|
||||||
|
if (y < 0)
|
||||||
|
y = 0;
|
||||||
|
else if (y > v_cel_my)
|
||||||
|
y = v_cel_my;
|
||||||
|
|
||||||
|
v_cur_cx = x;
|
||||||
|
v_cur_cy = y;
|
||||||
|
|
||||||
|
/* is cursor visible? */
|
||||||
|
if ( !(v_stat_0 & M_CVIS) ) {
|
||||||
|
/* not visible */
|
||||||
|
v_cur_ad = cell_addr(x, y); /* just set new coordinates */
|
||||||
|
return; /* and quit */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is cursor flashing? */
|
||||||
|
if ( v_stat_0 & M_CFLASH ) {
|
||||||
|
v_stat_0 &= ~M_CVIS; /* yes, make invisible...semaphore. */
|
||||||
|
|
||||||
|
/* is cursor presently displayed ? */
|
||||||
|
if ( !(v_stat_0 & M_CSTATE )) {
|
||||||
|
/* not displayed */
|
||||||
|
v_cur_ad = cell_addr(x, y); /* just set new coordinates */
|
||||||
|
|
||||||
|
/* show the cursor when it moves */
|
||||||
|
neg_cell(v_cur_ad); /* complement cursor. */
|
||||||
|
v_stat_0 |= M_CSTATE;
|
||||||
|
v_cur_tim = v_period; /* reset the timer. */
|
||||||
|
|
||||||
|
v_stat_0 |= M_CVIS; /* end of critical section. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move the cursor after all special checks failed */
|
||||||
|
neg_cell(v_cur_ad); /* erase present cursor */
|
||||||
|
|
||||||
|
v_cur_ad = cell_addr(x, y); /* fetch x and y coords. */
|
||||||
|
neg_cell(v_cur_ad); /* complement cursor. */
|
||||||
|
|
||||||
|
/* do not flash the cursor when it moves */
|
||||||
|
v_cur_tim = v_period; /* reset the timer. */
|
||||||
|
|
||||||
|
v_stat_0 |= M_CVIS; /* end of critical section. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* neg_cell - negates
|
||||||
|
*
|
||||||
|
* This routine negates the contents of an arbitrarily-tall byte-wide cell
|
||||||
|
* composed of an arbitrary number of (Atari-style) bit-planes.
|
||||||
|
* Cursor display can be accomplished via this procedure. Since a second
|
||||||
|
* negation restores the original cell condition, there is no need to save
|
||||||
|
* the contents beneath the cursor block.
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
* a1.l points to destination (1st plane, top of block)
|
||||||
|
*
|
||||||
|
* out:
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void neg_cell(uint8_t * cell)
|
||||||
|
{
|
||||||
|
int plane, len;
|
||||||
|
int cell_len = v_cel_ht;
|
||||||
|
|
||||||
|
v_stat_0 |= M_CRIT; /* start of critical section. */
|
||||||
|
|
||||||
|
for (plane = v_planes; plane--; ) {
|
||||||
|
uint8_t * addr = cell; /* top of current dest plane */
|
||||||
|
|
||||||
|
/* reset cell length counter */
|
||||||
|
for (len = cell_len; len--; ) {
|
||||||
|
*addr = ~*addr;
|
||||||
|
addr += v_lin_wr;
|
||||||
|
}
|
||||||
|
cell += plane_offset; /* a1 -> top of block in next plane */
|
||||||
|
}
|
||||||
|
v_stat_0 &= ~M_CRIT; /* end of critical section. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* invert_cell - negates the cells bits
|
||||||
|
*
|
||||||
|
* This routine negates the contents of an arbitrarily-tall byte-wide cell
|
||||||
|
* composed of an arbitrary number of (Atari-style) bit-planes.
|
||||||
|
*
|
||||||
|
* Wrapper for neg_cell().
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
* x - cell X coordinate
|
||||||
|
* y - cell Y coordinate
|
||||||
|
*/
|
||||||
|
|
||||||
|
void invert_cell(int x, int y)
|
||||||
|
{
|
||||||
|
/* fetch x and y coords and invert cursor. */
|
||||||
|
neg_cell(cell_addr(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* next_cell - Return the next cell address.
|
||||||
|
*
|
||||||
|
* sets next cell address given the current position and screen constraints
|
||||||
|
*
|
||||||
|
* returns:
|
||||||
|
* false - no wrap condition exists
|
||||||
|
* true - CR LF required (position has not been updated)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool next_cell(void)
|
||||||
|
{
|
||||||
|
/* check bounds against screen limits */
|
||||||
|
if (v_cur_cx == v_cel_mx)
|
||||||
|
{
|
||||||
|
/* increment cell ptr */
|
||||||
|
if (!(v_stat_0 & M_CEOL))
|
||||||
|
{
|
||||||
|
/* overwrite in effect */
|
||||||
|
return 0; /* no wrap condition exists */
|
||||||
|
/* don't change cell parameters */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call carriage return routine */
|
||||||
|
/* call line feed routine */
|
||||||
|
return 1; /* indicate that CR LF is required */
|
||||||
|
}
|
||||||
|
|
||||||
|
v_cur_cx += 1; /* next cell to right */
|
||||||
|
|
||||||
|
/* if X is even, move to next word in the plane */
|
||||||
|
if (v_cur_cx & 1)
|
||||||
|
{
|
||||||
|
/* x is odd */
|
||||||
|
v_cur_ad += 1; /* a1 -> new cell */
|
||||||
|
return 0; /* indicate no wrap needed */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* new cell (1st plane), added offset to next word in plane */
|
||||||
|
v_cur_ad += (v_planes << 1) - 1;
|
||||||
|
|
||||||
|
return 0; /* indicate no wrap needed */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scroll_up - Scroll upwards
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Scroll copies a source region as wide as the screen to an overlapping
|
||||||
|
* destination region on a one cell-height offset basis. Two entry points
|
||||||
|
* are provided: Partial-lower scroll-up, partial-lower scroll-down.
|
||||||
|
* Partial-lower screen operations require the cell y # indicating the
|
||||||
|
* top line where scrolling will take place.
|
||||||
|
*
|
||||||
|
* After the copy is performed, any non-overlapping area of the previous
|
||||||
|
* source region is "erased" by calling blank_out which fills the area
|
||||||
|
* with the background color.
|
||||||
|
*
|
||||||
|
* in:
|
||||||
|
* top_line - cell y of cell line to be used as top line in scroll
|
||||||
|
*/
|
||||||
|
|
||||||
|
void scroll_up(int top_line)
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
uint8_t * src, * dst;
|
||||||
|
|
||||||
|
/* screen base addr + cell y nbr * cell wrap */
|
||||||
|
dst = v_bas_ad + (uint32_t) top_line * v_cel_wr;
|
||||||
|
|
||||||
|
/* form source address from cell wrap + base address */
|
||||||
|
src = dst + v_cel_wr;
|
||||||
|
|
||||||
|
/* form # of bytes to move */
|
||||||
|
count = (uint32_t) v_cel_wr * (v_cel_my - top_line);
|
||||||
|
|
||||||
|
/* move BYTEs of memory*/
|
||||||
|
memmove(dst, src, count);
|
||||||
|
|
||||||
|
/* exit thru blank out, bottom line cell address y to top/left cell */
|
||||||
|
blank_out(0, v_cel_my , v_cel_mx, v_cel_my );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scroll_down - Scroll (partially) downwards
|
||||||
|
*/
|
||||||
|
|
||||||
|
void scroll_down(int start_line)
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
uint8_t * src, * dst;
|
||||||
|
|
||||||
|
/* screen base addr + offset of start line */
|
||||||
|
src = v_bas_ad + (uint32_t) start_line * v_cel_wr;
|
||||||
|
|
||||||
|
/* form destination from source + cell wrap */
|
||||||
|
dst = src + v_cel_wr;
|
||||||
|
|
||||||
|
/* form # of bytes to move */
|
||||||
|
count = (uint32_t) v_cel_wr * (v_cel_my - start_line);
|
||||||
|
|
||||||
|
/* move BYTEs of memory*/
|
||||||
|
memmove(dst, src, count);
|
||||||
|
|
||||||
|
/* exit thru blank out */
|
||||||
|
blank_out(0, start_line , v_cel_mx, start_line);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user