mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
Use uint32 for console coordinates and fix dimension bug
This commit is contained in:
parent
d804b17ed8
commit
fd3ca91138
@ -15,7 +15,7 @@ const (
|
|||||||
// consoles.
|
// consoles.
|
||||||
type Device interface {
|
type Device interface {
|
||||||
// Dimensions returns the width and height of the console in characters.
|
// Dimensions returns the width and height of the console in characters.
|
||||||
Dimensions() (uint16, uint16)
|
Dimensions() (uint32, uint32)
|
||||||
|
|
||||||
// DefaultColors returns the default foreground and background colors
|
// DefaultColors returns the default foreground and background colors
|
||||||
// used by this console.
|
// used by this console.
|
||||||
@ -24,16 +24,16 @@ type Device interface {
|
|||||||
// Fill sets the contents of the specified rectangular region to the
|
// Fill sets the contents of the specified rectangular region to the
|
||||||
// requested color. Both x and y coordinates are 1-based (top-left
|
// requested color. Both x and y coordinates are 1-based (top-left
|
||||||
// corner has coordinates 1,1).
|
// corner has coordinates 1,1).
|
||||||
Fill(x, y, width, height uint16, fg, bg uint8)
|
Fill(x, y, width, height uint32, fg, bg uint8)
|
||||||
|
|
||||||
// Scroll the console contents to the specified direction. The caller
|
// Scroll the console contents to the specified direction. The caller
|
||||||
// is responsible for updating (e.g. clear or replace) the contents of
|
// is responsible for updating (e.g. clear or replace) the contents of
|
||||||
// the region that was scrolled.
|
// the region that was scrolled.
|
||||||
Scroll(dir ScrollDir, lines uint16)
|
Scroll(dir ScrollDir, lines uint32)
|
||||||
|
|
||||||
// Write a char to the specified location. Both x and y coordinates are
|
// Write a char to the specified location. Both x and y coordinates are
|
||||||
// 1-based (top-left corner has coordinates 1,1).
|
// 1-based (top-left corner has coordinates 1,1).
|
||||||
Write(ch byte, fg, bg uint8, x, y uint16)
|
Write(ch byte, fg, bg uint8, x, y uint32)
|
||||||
|
|
||||||
// Palette returns the active color palette for this console.
|
// Palette returns the active color palette for this console.
|
||||||
Palette() color.Palette
|
Palette() color.Palette
|
||||||
|
@ -24,8 +24,8 @@ var portWriteByteFn = cpu.PortWriteByte
|
|||||||
// - light gray text (color 7) on black background (color 0).
|
// - light gray text (color 7) on black background (color 0).
|
||||||
// - space as the clear character
|
// - space as the clear character
|
||||||
type VgaTextConsole struct {
|
type VgaTextConsole struct {
|
||||||
width uint16
|
width uint32
|
||||||
height uint16
|
height uint32
|
||||||
|
|
||||||
fb []uint16
|
fb []uint16
|
||||||
|
|
||||||
@ -37,15 +37,15 @@ type VgaTextConsole struct {
|
|||||||
|
|
||||||
// NewVgaTextConsole creates an new vga text console with its
|
// NewVgaTextConsole creates an new vga text console with its
|
||||||
// framebuffer mapped to fbPhysAddr.
|
// framebuffer mapped to fbPhysAddr.
|
||||||
func NewVgaTextConsole(columns, rows uint16, fbPhysAddr uintptr) *VgaTextConsole {
|
func NewVgaTextConsole(columns, rows uint32, fbPhysAddr uintptr) *VgaTextConsole {
|
||||||
return &VgaTextConsole{
|
return &VgaTextConsole{
|
||||||
width: columns,
|
width: columns,
|
||||||
height: rows,
|
height: rows,
|
||||||
clearChar: uint16(' '),
|
clearChar: uint16(' '),
|
||||||
// overlay a 16bit slice over the fbPhysAddr
|
// overlay a 16bit slice over the fbPhysAddr
|
||||||
fb: *(*[]uint16)(unsafe.Pointer(&reflect.SliceHeader{
|
fb: *(*[]uint16)(unsafe.Pointer(&reflect.SliceHeader{
|
||||||
Len: 80 * 25,
|
Len: int(columns * rows),
|
||||||
Cap: 80 * 25,
|
Cap: int(columns * rows),
|
||||||
Data: fbPhysAddr,
|
Data: fbPhysAddr,
|
||||||
})),
|
})),
|
||||||
palette: color.Palette{
|
palette: color.Palette{
|
||||||
@ -73,7 +73,7 @@ func NewVgaTextConsole(columns, rows uint16, fbPhysAddr uintptr) *VgaTextConsole
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dimensions returns the console width and height in characters.
|
// Dimensions returns the console width and height in characters.
|
||||||
func (cons *VgaTextConsole) Dimensions() (uint16, uint16) {
|
func (cons *VgaTextConsole) Dimensions() (uint32, uint32) {
|
||||||
return cons.width, cons.height
|
return cons.width, cons.height
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,10 +85,10 @@ func (cons *VgaTextConsole) DefaultColors() (fg uint8, bg uint8) {
|
|||||||
|
|
||||||
// Fill sets the contents of the specified rectangular region to the requested
|
// Fill sets the contents of the specified rectangular region to the requested
|
||||||
// color. Both x and y coordinates are 1-based.
|
// color. Both x and y coordinates are 1-based.
|
||||||
func (cons *VgaTextConsole) Fill(x, y, width, height uint16, fg, bg uint8) {
|
func (cons *VgaTextConsole) Fill(x, y, width, height uint32, fg, bg uint8) {
|
||||||
var (
|
var (
|
||||||
clr = (((uint16(bg) << 4) | uint16(fg)) << 8) | cons.clearChar
|
clr = (((uint16(bg) << 4) | uint16(fg)) << 8) | cons.clearChar
|
||||||
rowOffset, colOffset uint16
|
rowOffset, colOffset uint32
|
||||||
)
|
)
|
||||||
|
|
||||||
// clip rectangle
|
// clip rectangle
|
||||||
@ -104,12 +104,12 @@ func (cons *VgaTextConsole) Fill(x, y, width, height uint16, fg, bg uint8) {
|
|||||||
y = cons.height
|
y = cons.height
|
||||||
}
|
}
|
||||||
|
|
||||||
if x+width > cons.width {
|
if x+width-1 > cons.width {
|
||||||
width = cons.width - x
|
width = cons.width - x + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if y+height > cons.height {
|
if y+height-1 > cons.height {
|
||||||
height = cons.height - y
|
height = cons.height - y + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
rowOffset = ((y - 1) * cons.width) + (x - 1)
|
rowOffset = ((y - 1) * cons.width) + (x - 1)
|
||||||
@ -123,12 +123,12 @@ func (cons *VgaTextConsole) Fill(x, y, width, height uint16, fg, bg uint8) {
|
|||||||
// Scroll the console contents to the specified direction. The caller
|
// Scroll the console contents to the specified direction. The caller
|
||||||
// is responsible for updating (e.g. clear or replace) the contents of
|
// is responsible for updating (e.g. clear or replace) the contents of
|
||||||
// the region that was scrolled.
|
// the region that was scrolled.
|
||||||
func (cons *VgaTextConsole) Scroll(dir ScrollDir, lines uint16) {
|
func (cons *VgaTextConsole) Scroll(dir ScrollDir, lines uint32) {
|
||||||
if lines == 0 || lines > cons.height {
|
if lines == 0 || lines > cons.height {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var i uint16
|
var i uint32
|
||||||
offset := lines * cons.width
|
offset := lines * cons.width
|
||||||
|
|
||||||
switch dir {
|
switch dir {
|
||||||
@ -146,7 +146,7 @@ func (cons *VgaTextConsole) Scroll(dir ScrollDir, lines uint16) {
|
|||||||
// Write a char to the specified location. If fg or bg exceed the supported
|
// Write a char to the specified location. If fg or bg exceed the supported
|
||||||
// colors for this console, they will be set to their default value. Both x and
|
// colors for this console, they will be set to their default value. Both x and
|
||||||
// y coordinates are 1-based
|
// y coordinates are 1-based
|
||||||
func (cons *VgaTextConsole) Write(ch byte, fg, bg uint8, x, y uint16) {
|
func (cons *VgaTextConsole) Write(ch byte, fg, bg uint8, x, y uint32) {
|
||||||
if x < 1 || x > cons.width || y < 1 || y > cons.height {
|
if x < 1 || x > cons.width || y < 1 || y > cons.height {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -205,7 +205,7 @@ func probeForVgaTextConsole() device.Driver {
|
|||||||
|
|
||||||
fbInfo := getFramebufferInfoFn()
|
fbInfo := getFramebufferInfoFn()
|
||||||
if fbInfo.Type == multiboot.FramebufferTypeEGA {
|
if fbInfo.Type == multiboot.FramebufferTypeEGA {
|
||||||
drv = NewVgaTextConsole(uint16(fbInfo.Width), uint16(fbInfo.Height), uintptr(fbInfo.PhysAddr))
|
drv = NewVgaTextConsole(fbInfo.Width, fbInfo.Height, uintptr(fbInfo.PhysAddr))
|
||||||
}
|
}
|
||||||
|
|
||||||
return drv
|
return drv
|
||||||
|
@ -11,8 +11,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestVgaTextDimensions(t *testing.T) {
|
func TestVgaTextDimensions(t *testing.T) {
|
||||||
cons := NewVgaTextConsole(80, 25, 0)
|
var cons Device = NewVgaTextConsole(40, 50, 0)
|
||||||
if w, h := cons.Dimensions(); w != 80 || h != 25 {
|
if w, h := cons.Dimensions(); w != 40 || h != 50 {
|
||||||
t.Fatalf("expected console dimensions to be 80x25; got %dx%d", w, h)
|
t.Fatalf("expected console dimensions to be 80x25; got %dx%d", w, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,34 +27,38 @@ func TestVgaTextDefaultColors(t *testing.T) {
|
|||||||
func TestVgaTextFill(t *testing.T) {
|
func TestVgaTextFill(t *testing.T) {
|
||||||
specs := []struct {
|
specs := []struct {
|
||||||
// Input rect
|
// Input rect
|
||||||
x, y, w, h uint16
|
x, y, w, h uint32
|
||||||
|
|
||||||
// Expected area to be cleared
|
// Expected area to be cleared
|
||||||
expX, expY, expW, expH uint16
|
expStartX, expStartY, expEndX, expEndY uint32
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
0, 0, 500, 500,
|
0, 0, 500, 500,
|
||||||
0, 0, 80, 25,
|
1, 1, 80, 25,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
10, 10, 11, 50,
|
10, 10, 11, 50,
|
||||||
10, 10, 11, 15,
|
10, 10, 20, 25,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
10, 10, 110, 1,
|
10, 10, 110, 1,
|
||||||
10, 10, 70, 1,
|
10, 10, 80, 10,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
70, 20, 20, 20,
|
70, 20, 20, 20,
|
||||||
70, 20, 10, 5,
|
70, 20, 80, 39,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
90, 25, 20, 20,
|
90, 25, 20, 20,
|
||||||
0, 0, 0, 0,
|
80, 25, 80, 25,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
12, 12, 5, 6,
|
12, 12, 5, 6,
|
||||||
12, 12, 5, 6,
|
12, 12, 16, 17,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
80, 25, 1, 1,
|
||||||
|
80, 25, 80, 25,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,12 +78,12 @@ nextSpec:
|
|||||||
|
|
||||||
cons.Fill(spec.x, spec.y, spec.w, spec.h, 0, 0)
|
cons.Fill(spec.x, spec.y, spec.w, spec.h, 0, 0)
|
||||||
|
|
||||||
var x, y uint16
|
var x, y uint32
|
||||||
for y = 1; y <= ch; y++ {
|
for y = 1; y <= ch; y++ {
|
||||||
for x = 1; x <= cw; x++ {
|
for x = 1; x <= cw; x++ {
|
||||||
fbVal := fb[((y-1)*cw)+(x-1)]
|
fbVal := fb[((y-1)*cw)+(x-1)]
|
||||||
|
|
||||||
if x < spec.expX || y < spec.expY || x >= spec.expX+spec.expW || y >= spec.expY+spec.expH {
|
if x < spec.expStartX || y < spec.expStartY || x > spec.expEndX || y > spec.expEndY {
|
||||||
if fbVal != testPat {
|
if fbVal != testPat {
|
||||||
t.Errorf("[spec %d] expected char at (%d, %d) not to be cleared", specIndex, x, y)
|
t.Errorf("[spec %d] expected char at (%d, %d) not to be cleared", specIndex, x, y)
|
||||||
continue nextSpec
|
continue nextSpec
|
||||||
@ -101,7 +105,7 @@ func TestVgaTextScroll(t *testing.T) {
|
|||||||
cw, ch := cons.Dimensions()
|
cw, ch := cons.Dimensions()
|
||||||
|
|
||||||
t.Run("up", func(t *testing.T) {
|
t.Run("up", func(t *testing.T) {
|
||||||
specs := []uint16{
|
specs := []uint32{
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
@ -109,10 +113,10 @@ func TestVgaTextScroll(t *testing.T) {
|
|||||||
nextSpec:
|
nextSpec:
|
||||||
for specIndex, lines := range specs {
|
for specIndex, lines := range specs {
|
||||||
// Fill buffer with test pattern
|
// Fill buffer with test pattern
|
||||||
var x, y, index uint16
|
var x, y, index uint32
|
||||||
for y = 0; y < ch; y++ {
|
for y = 0; y < ch; y++ {
|
||||||
for x = 0; x < cw; x++ {
|
for x = 0; x < cw; x++ {
|
||||||
fb[index] = (y << 8) | x
|
fb[index] = uint16((y << 8) | x)
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,7 +127,7 @@ func TestVgaTextScroll(t *testing.T) {
|
|||||||
index = 0
|
index = 0
|
||||||
for y = 0; y < ch-lines; y++ {
|
for y = 0; y < ch-lines; y++ {
|
||||||
for x = 0; x < cw; x++ {
|
for x = 0; x < cw; x++ {
|
||||||
expVal := ((y + lines) << 8) | x
|
expVal := uint16(((y + lines) << 8) | x)
|
||||||
if fb[index] != expVal {
|
if fb[index] != expVal {
|
||||||
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, fb[index])
|
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, fb[index])
|
||||||
continue nextSpec
|
continue nextSpec
|
||||||
@ -135,7 +139,7 @@ func TestVgaTextScroll(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("down", func(t *testing.T) {
|
t.Run("down", func(t *testing.T) {
|
||||||
specs := []uint16{
|
specs := []uint32{
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
@ -144,10 +148,10 @@ func TestVgaTextScroll(t *testing.T) {
|
|||||||
nextSpec:
|
nextSpec:
|
||||||
for specIndex, lines := range specs {
|
for specIndex, lines := range specs {
|
||||||
// Fill buffer with test pattern
|
// Fill buffer with test pattern
|
||||||
var x, y, index uint16
|
var x, y, index uint32
|
||||||
for y = 0; y < ch; y++ {
|
for y = 0; y < ch; y++ {
|
||||||
for x = 0; x < cw; x++ {
|
for x = 0; x < cw; x++ {
|
||||||
fb[index] = (y << 8) | x
|
fb[index] = uint16((y << 8) | x)
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,7 +162,7 @@ func TestVgaTextScroll(t *testing.T) {
|
|||||||
index = lines * cw
|
index = lines * cw
|
||||||
for y = lines; y < ch-lines; y++ {
|
for y = lines; y < ch-lines; y++ {
|
||||||
for x = 0; x < cw; x++ {
|
for x = 0; x < cw; x++ {
|
||||||
expVal := ((y - lines) << 8) | x
|
expVal := uint16(((y - lines) << 8) | x)
|
||||||
if fb[index] != expVal {
|
if fb[index] != expVal {
|
||||||
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, fb[index])
|
t.Errorf("[spec %d] expected value at (%d, %d) to be %d; got %d", specIndex, x, y, expVal, fb[index])
|
||||||
continue nextSpec
|
continue nextSpec
|
||||||
@ -177,7 +181,7 @@ func TestVgaTextWrite(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("off-screen", func(t *testing.T) {
|
t.Run("off-screen", func(t *testing.T) {
|
||||||
specs := []struct {
|
specs := []struct {
|
||||||
x, y uint16
|
x, y uint32
|
||||||
}{
|
}{
|
||||||
{81, 26},
|
{81, 26},
|
||||||
{90, 24},
|
{90, 24},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user