Compare commits
10 Commits
2d9d72e162
...
5ae907ca5a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ae907ca5a | ||
|
|
e4575605aa | ||
|
|
c72d1a8677 | ||
|
|
d4f5a4780c | ||
|
|
7670ffdf42 | ||
|
|
30638e0b29 | ||
|
|
2fea91b6cf | ||
|
|
0cfcfe5fcb | ||
|
|
adbe5934fa | ||
|
|
f03e33928b |
@@ -1,18 +1,23 @@
|
|||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
#include "ioport.h"
|
||||||
|
|
||||||
Serial::Serial(ComPort port, BaudRate baud_rate, DataBits data_bits,
|
Serial::Serial(ComPort port, BaudRate baud_rate, DataBits data_bits,
|
||||||
StopBits stop_bits, Parity parity)
|
StopBits stop_bits, Parity parity)
|
||||||
: port(port) {
|
: port(port) {
|
||||||
// initialize FIFO mode, no irqs for sending, irq if first byte was received
|
// initialize FIFO mode, no irqs for sending, irq if first byte was received
|
||||||
|
writeReg(INTERRUPT_ENABLE_REGISTER, RECEIVED_DATA_AVAILABLE);
|
||||||
|
|
||||||
// line control, select r/w of divisor latch register
|
// line control, select r/w of divisor latch register
|
||||||
writeReg(LINE_CONTROL_REGISTER, DIVISOR_LATCH_ACCESS_BIT);
|
writeReg(LINE_CONTROL_REGISTER, DIVISOR_LATCH_ACCESS_BIT);
|
||||||
|
|
||||||
// TODO: Implement here the correct handling of input arguments
|
writeReg(DIVISOR_LOW_REGISTER, baud_rate & 0xFF);
|
||||||
(void)baud_rate;
|
writeReg(DIVISOR_HIGH_REGISTER, (baud_rate>>8) & 0xFF);
|
||||||
(void)data_bits;
|
|
||||||
(void)stop_bits;
|
// also turns DLAB off
|
||||||
(void)parity;
|
uint8_t val = parity;
|
||||||
|
val |= stop_bits;
|
||||||
|
val |= data_bits;
|
||||||
|
writeReg(LINE_CONTROL_REGISTER, val);
|
||||||
|
|
||||||
// FIFO: Enable & clear buffers
|
// FIFO: Enable & clear buffers
|
||||||
writeReg(FIFO_CONTROL_REGISTER,
|
writeReg(FIFO_CONTROL_REGISTER,
|
||||||
@@ -23,19 +28,22 @@ Serial::Serial(ComPort port, BaudRate baud_rate, DataBits data_bits,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Serial::writeReg(RegisterIndex reg, char out) {
|
void Serial::writeReg(RegisterIndex reg, char out) {
|
||||||
// TODO: Implement
|
uint16_t addr = port;
|
||||||
(void)reg;
|
IOPort iop = IOPort(addr += reg);
|
||||||
(void)out;
|
iop.outb(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
char Serial::readReg(RegisterIndex reg) {
|
char Serial::readReg(RegisterIndex reg) {
|
||||||
// TODO: Implement
|
uint16_t addr = port;
|
||||||
(void)reg;
|
IOPort iop = IOPort(addr += reg);
|
||||||
return '\0';
|
return iop.inb();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Serial::write(char out) {
|
int Serial::write(char out) {
|
||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
(void)out;
|
if(readReg(LINE_STATUS_REGISTER) & TRANSMITTER_EMPTY){
|
||||||
return 0;
|
writeReg(TRANSMIT_BUFFER_REGISTER, out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,15 @@ void TextWindow::setPos(unsigned rel_x, unsigned rel_y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextWindow::getPos(unsigned& rel_x, unsigned& rel_y) const {
|
void TextWindow::getPos(unsigned& rel_x, unsigned& rel_y) const {
|
||||||
|
if(use_cursor){
|
||||||
CGA::getCursor(rel_x, rel_y);
|
CGA::getCursor(rel_x, rel_y);
|
||||||
rel_x -= from_col;
|
rel_x -= from_col;
|
||||||
rel_y -= from_row;
|
rel_y -= from_row;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rel_x = pos_x - from_col;
|
||||||
|
rel_y = pos_y - from_row;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextWindow::setPos(int rel_x, int rel_y) {
|
void TextWindow::setPos(int rel_x, int rel_y) {
|
||||||
@@ -35,8 +41,10 @@ void TextWindow::setPos(int rel_x, int rel_y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextWindow::getPos(int& rel_x, int& rel_y) const {
|
void TextWindow::getPos(int& rel_x, int& rel_y) const {
|
||||||
(void)rel_x;
|
unsigned x, y;
|
||||||
(void)rel_y;
|
getPos(x,y);
|
||||||
|
rel_x = x;
|
||||||
|
rel_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextWindow::print(const char* str, size_t length, CGA::Attribute attrib) {
|
void TextWindow::print(const char* str, size_t length, CGA::Attribute attrib) {
|
||||||
@@ -47,7 +55,7 @@ void TextWindow::print(const char* str, size_t length, CGA::Attribute attrib) {
|
|||||||
if(from_col+x_now >= to_col-1){
|
if(from_col+x_now >= to_col-1){
|
||||||
x_now = 0;
|
x_now = 0;
|
||||||
if(from_row + y_now >= to_row-1){
|
if(from_row + y_now >= to_row-1){
|
||||||
//scrollUp()
|
//TODO scrollUp()
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
y_now++;
|
y_now++;
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ class TextWindow {
|
|||||||
* software cursor/variable (`false`) should be used to
|
* software cursor/variable (`false`) should be used to
|
||||||
* store the current position
|
* store the current position
|
||||||
*
|
*
|
||||||
* \todo(11) Implement constructor
|
|
||||||
*/
|
*/
|
||||||
TextWindow(unsigned from_col, unsigned to_col, unsigned from_row,
|
TextWindow(unsigned from_col, unsigned to_col, unsigned from_row,
|
||||||
unsigned to_row, bool use_cursor = false);
|
unsigned to_row, bool use_cursor = false);
|
||||||
@@ -71,8 +70,6 @@ class TextWindow {
|
|||||||
*
|
*
|
||||||
* \param rel_x Column in window
|
* \param rel_x Column in window
|
||||||
* \param rel_y Row in window
|
* \param rel_y Row in window
|
||||||
* \todo(11) Implement method, use \ref CGA::setCursor() for the hardware
|
|
||||||
* cursor
|
|
||||||
*/
|
*/
|
||||||
void setPos(unsigned rel_x, unsigned rel_y);
|
void setPos(unsigned rel_x, unsigned rel_y);
|
||||||
|
|
||||||
@@ -87,8 +84,6 @@ class TextWindow {
|
|||||||
* Negative coordinates are interpreted relative to the right and bottom
|
* Negative coordinates are interpreted relative to the right and bottom
|
||||||
* border of the window.
|
* border of the window.
|
||||||
*
|
*
|
||||||
* \todo(11) Implement this method (it can either use or replace
|
|
||||||
* \ref setPos(unsigned, unsigned))
|
|
||||||
*/
|
*/
|
||||||
void setPos(int rel_x, int rel_y);
|
void setPos(int rel_x, int rel_y);
|
||||||
|
|
||||||
@@ -100,8 +95,6 @@ class TextWindow {
|
|||||||
*
|
*
|
||||||
* \param rel_x Column in window
|
* \param rel_x Column in window
|
||||||
* \param rel_y Row in window
|
* \param rel_y Row in window
|
||||||
* \todo(11) Implement Method, use \ref CGA::getCursor() for the hardware
|
|
||||||
* cursor
|
|
||||||
*/
|
*/
|
||||||
void getPos(unsigned& rel_x, unsigned& rel_y) const;
|
void getPos(unsigned& rel_x, unsigned& rel_y) const;
|
||||||
|
|
||||||
@@ -128,7 +121,6 @@ class TextWindow {
|
|||||||
* \param string Text to be printed
|
* \param string Text to be printed
|
||||||
* \param length Length of text
|
* \param length Length of text
|
||||||
* \param attrib Attribute for text
|
* \param attrib Attribute for text
|
||||||
* \todo(11) Implement Method
|
|
||||||
*/
|
*/
|
||||||
void print(const char* string, size_t length,
|
void print(const char* string, size_t length,
|
||||||
CGA::Attribute attrib = CGA::Attribute()); // NOLINT
|
CGA::Attribute attrib = CGA::Attribute()); // NOLINT
|
||||||
@@ -137,7 +129,6 @@ class TextWindow {
|
|||||||
*
|
*
|
||||||
* \param character Fill character
|
* \param character Fill character
|
||||||
* \param attrib Attribute for fill character
|
* \param attrib Attribute for fill character
|
||||||
* \todo(11) Implement Method
|
|
||||||
*/
|
*/
|
||||||
void reset(char character = ' ', CGA::Attribute attrib = CGA::Attribute());
|
void reset(char character = ' ', CGA::Attribute attrib = CGA::Attribute());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,30 +1,95 @@
|
|||||||
#include "serialstream.h"
|
#include "serialstream.h"
|
||||||
|
#include "../utils/string.h"
|
||||||
|
|
||||||
SerialStream::SerialStream(ComPort port, BaudRate baud_rate, DataBits data_bits,
|
SerialStream::SerialStream(ComPort port, BaudRate baud_rate, DataBits data_bits,
|
||||||
StopBits stop_bits, Parity parity) {
|
StopBits stop_bits, Parity parity)
|
||||||
(void)port;
|
:Serial(port, baud_rate, data_bits, stop_bits, parity) {}
|
||||||
(void)baud_rate;
|
|
||||||
(void)data_bits;
|
void SerialStream::flush() {
|
||||||
(void)stop_bits;
|
print(buffer, strlen(buffer));
|
||||||
(void)parity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialStream::flush() {}
|
// https://stackoverflow.com/questions/3440726/what-is-the-proper-way-of-implementing-a-good-itoa-function
|
||||||
|
// Yet, another good itoa implementation
|
||||||
|
// returns: the length of the number string
|
||||||
|
int itoa(int value, char *sp, int radix)
|
||||||
|
{
|
||||||
|
char tmp[16];// be careful with the length of the buffer
|
||||||
|
char *tp = tmp;
|
||||||
|
int i;
|
||||||
|
unsigned v;
|
||||||
|
|
||||||
void SerialStream::setForeground(Color c) { (void)c; }
|
int sign = (radix == 10 && value < 0);
|
||||||
|
if (sign)
|
||||||
|
v = -value;
|
||||||
|
else
|
||||||
|
v = (unsigned)value;
|
||||||
|
|
||||||
void SerialStream::setBackground(Color c) { (void)c; }
|
while (v || tp == tmp)
|
||||||
|
{
|
||||||
|
i = v % radix;
|
||||||
|
v /= radix;
|
||||||
|
if (i < 10)
|
||||||
|
*tp++ = i+'0';
|
||||||
|
else
|
||||||
|
*tp++ = i + 'a' - 10;
|
||||||
|
}
|
||||||
|
|
||||||
void SerialStream::setAttribute(Attrib a) { (void)a; }
|
int len = tp - tmp;
|
||||||
|
|
||||||
void SerialStream::reset() {}
|
if (sign)
|
||||||
|
{
|
||||||
|
*sp++ = '-';
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (tp > tmp)
|
||||||
|
*sp++ = *--tp;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialStream::setForeground(Color c) {
|
||||||
|
write(0x1b);
|
||||||
|
write('[');
|
||||||
|
write('3');
|
||||||
|
write(c + 0x30);
|
||||||
|
write('m');
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialStream::setBackground(Color c) {
|
||||||
|
write(0x1b);
|
||||||
|
write('[');
|
||||||
|
write('4');
|
||||||
|
write(c + 0x30);
|
||||||
|
write('m');
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialStream::setAttribute(Attrib a) {
|
||||||
|
write(0x1b);
|
||||||
|
write('[');
|
||||||
|
write(a + 0x30);
|
||||||
|
write('m');
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialStream::reset() {
|
||||||
|
write(0x1b);
|
||||||
|
write('c');
|
||||||
|
}
|
||||||
|
|
||||||
void SerialStream::setPos(int x, int y) {
|
void SerialStream::setPos(int x, int y) {
|
||||||
(void)x;
|
//char out[] = {0x1b, '[', 0, 0, ';', 0, 0, 'H', 0};
|
||||||
(void)y;
|
*this << 0x1b;
|
||||||
|
*this << '[';
|
||||||
|
*this << dec << x;
|
||||||
|
*this << ';' << y << 'H' << endl;
|
||||||
|
flush();
|
||||||
|
//itoa(x, &out[2], 10);
|
||||||
|
//itoa(y, &out[5], 10);
|
||||||
|
//print( out , strlen(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialStream::print(char* str, int length) {
|
void SerialStream::print(char* str, int length) {
|
||||||
(void)str;
|
for(int i=0; i < length; i++)
|
||||||
(void)length;
|
write(str[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
#include "textstream.h"
|
#include "textstream.h"
|
||||||
|
|
||||||
TextStream::TextStream(unsigned from_col, unsigned to_col, unsigned from_row,
|
TextStream::TextStream(unsigned from_col,
|
||||||
unsigned to_row, bool use_cursor) {
|
unsigned to_col,
|
||||||
(void)from_col;
|
unsigned from_row,
|
||||||
(void)to_col;
|
unsigned to_row,
|
||||||
(void)from_row;
|
bool use_cursor)
|
||||||
(void)to_row;
|
: TextWindow(from_col,
|
||||||
(void)use_cursor;
|
to_col,
|
||||||
}
|
from_row,
|
||||||
|
to_row,
|
||||||
|
use_cursor){}
|
||||||
|
|
||||||
void TextStream::flush() {}
|
|
||||||
|
void TextStream::flush() {
|
||||||
|
print(buffer,pos);
|
||||||
|
pos = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
#include "../object/outputstream.h"
|
||||||
|
#include "../arch/textwindow.h"
|
||||||
/*! \brief Output text (form different data type sources) on screen in text
|
/*! \brief Output text (form different data type sources) on screen in text
|
||||||
* mode
|
* mode
|
||||||
* \ingroup io
|
* \ingroup io
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
* \ref TextWindow and only implements the method \ref TextStream::flush().
|
* \ref TextWindow and only implements the method \ref TextStream::flush().
|
||||||
* Further formatting or special effects are implemented in \ref TextWindow.
|
* Further formatting or special effects are implemented in \ref TextWindow.
|
||||||
*/
|
*/
|
||||||
class TextStream {
|
class TextStream: public OutputStream, protected TextWindow {
|
||||||
// Prevent copies and assignments
|
// Prevent copies and assignments
|
||||||
TextStream(const TextStream&) = delete;
|
TextStream(const TextStream&) = delete;
|
||||||
TextStream& operator=(const TextStream&) = delete;
|
TextStream& operator=(const TextStream&) = delete;
|
||||||
@@ -38,4 +39,11 @@ class TextStream {
|
|||||||
* \todo(11) Implement method
|
* \todo(11) Implement method
|
||||||
*/
|
*/
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned from_col;
|
||||||
|
unsigned to_col;
|
||||||
|
unsigned from_row;
|
||||||
|
unsigned to_row;
|
||||||
|
bool use_cursor;
|
||||||
};
|
};
|
||||||
|
|||||||
37
main.cc
37
main.cc
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "arch/cga.h"
|
#include "arch/cga.h"
|
||||||
#include "arch/textwindow.h"
|
#include "arch/textwindow.h"
|
||||||
|
#include "arch/serial.h"
|
||||||
|
#include "device/serialstream.h"
|
||||||
|
|
||||||
// Main function
|
// Main function
|
||||||
// (the bootstrap processor starts here)}
|
// (the bootstrap processor starts here)}
|
||||||
@@ -19,14 +21,35 @@ extern "C" int main() {
|
|||||||
//for(uint8_t i = 0; i < 10; i++)
|
//for(uint8_t i = 0; i < 10; i++)
|
||||||
// CGA::show(i, i, i+0x30, CGA::Attribute());
|
// CGA::show(i, i, i+0x30, CGA::Attribute());
|
||||||
|
|
||||||
//test textwindow implemantation
|
////test textwindow implemantation
|
||||||
TextWindow tw_global = TextWindow(0, 80, 0, 25, true);
|
//TextWindow tw_global = TextWindow(0, 80, 0, 25, true);
|
||||||
tw_global.reset(' ', CGA::Attribute(CGA::LIGHT_GREEN, CGA::BLUE, false));
|
//tw_global.reset(' ', CGA::Attribute(CGA::LIGHT_GREEN, CGA::BLUE, false));
|
||||||
|
//TextWindow tw = TextWindow(0, 10, 0, 10, true);
|
||||||
|
//tw.reset();
|
||||||
|
//tw.setPos(0,0);
|
||||||
|
//tw.print("lorem ipsum dolor sit amit", 26);
|
||||||
|
//tw.setPos(0,-1);
|
||||||
|
//tw.print("test", 4, CGA::Attribute(CGA::BLACK, CGA::BLUE));
|
||||||
|
//int x,y;
|
||||||
|
//tw.getPos(x,y);
|
||||||
|
//tw.setPos(x+1,y);
|
||||||
|
|
||||||
TextWindow tw = TextWindow(0, 10, 0, 10, true);
|
////test Serial
|
||||||
tw.reset();
|
//Serial s = Serial();
|
||||||
tw.setPos(0,0);
|
//s.write('a');
|
||||||
tw.print("lorem ipsum dolor sit amit", 26);
|
|
||||||
|
// test SerialStream
|
||||||
|
SerialStream ss = SerialStream();
|
||||||
|
ss.print("test", 4);
|
||||||
|
ss.setAttribute(SerialStream::UNDERSCORE);
|
||||||
|
ss.print("test", 4);
|
||||||
|
ss.setAttribute(SerialStream::RESET);
|
||||||
|
ss.setForeground(SerialStream::MAGENTA);
|
||||||
|
ss.print("test", 4);
|
||||||
|
ss.setBackground(SerialStream::CYAN);
|
||||||
|
ss.print("test", 4);
|
||||||
|
ss.setPos(10, 10);
|
||||||
|
ss.print("test", 4);
|
||||||
|
|
||||||
/* Start application processors
|
/* Start application processors
|
||||||
* To avoid unexpected behaviour, make sure that interrupts are not
|
* To avoid unexpected behaviour, make sure that interrupts are not
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class Stringbuffer {
|
|||||||
protected:
|
protected:
|
||||||
/*! \brief Constructor; Marks the buffer as empty
|
/*! \brief Constructor; Marks the buffer as empty
|
||||||
*/
|
*/
|
||||||
Stringbuffer() {}
|
Stringbuffer() : pos(0){}
|
||||||
|
|
||||||
/*! \brief Inserts a character into the buffer.
|
/*! \brief Inserts a character into the buffer.
|
||||||
*
|
*
|
||||||
@@ -63,7 +63,9 @@ class Stringbuffer {
|
|||||||
* flush() is required to reset the position pos.
|
* flush() is required to reset the position pos.
|
||||||
*/
|
*/
|
||||||
virtual void flush() = 0;
|
virtual void flush() = 0;
|
||||||
|
|
||||||
|
unsigned pos;
|
||||||
|
char buffer[80+1];
|
||||||
public:
|
public:
|
||||||
/*! \brief Destructor (nothing to do here)
|
/*! \brief Destructor (nothing to do here)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ kvm: all
|
|||||||
|
|
||||||
# Execute Qemu with activated GDB stub and directly connect GDB to the spawned Qemu.
|
# Execute Qemu with activated GDB stub and directly connect GDB to the spawned Qemu.
|
||||||
gdb: all
|
gdb: all
|
||||||
${VERBOSE} cgdb -d $(GDB) "$(DBGKERNEL)" \
|
${VERBOSE} $(GDB) "$(DBGKERNEL)" \
|
||||||
-ex "set arch $(DBGARCH)" \
|
-ex "set arch $(DBGARCH)" \
|
||||||
-ex "target remote | exec $(QEMU) -gdb stdio $(QEMUKERNEL) -smp $(QEMUCPUS) -S $(QEMUFLAGS) $(DBGFLAGS)"
|
-ex "target remote | exec $(QEMU) -gdb stdio $(QEMUKERNEL) -smp $(QEMUCPUS) -S $(QEMUFLAGS) $(DBGFLAGS)"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user