aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTianhao Wang <shrik3@riseup.net>2023-03-14 03:16:54 +0100
committerTianhao Wang <shrik3@riseup.net>2023-03-14 03:16:54 +0100
commit4eae38a6ce9110a155715575adcf12bdf45703cb (patch)
tree407cc8f97eabca6d67cd6e83801d83b3a1542beb
parentb6a2fe46752ce5198122bd427a36fdd8878fd05a (diff)
CGA cursor location
-rw-r--r--Makefile21
-rw-r--r--src/arch/x86_64/asm/io_port.s16
-rw-r--r--src/arch/x86_64/io_port.rs41
-rw-r--r--src/lib.rs4
-rw-r--r--src/machine/cgascr.rs51
5 files changed, 96 insertions, 37 deletions
diff --git a/Makefile b/Makefile
index b11b2db..c0165f6 100644
--- a/Makefile
+++ b/Makefile
@@ -10,29 +10,34 @@
# TODO replace hardcoded values with variables
# TODO there can be more options of grub-mkrescue
# TODO put the startup.s elsewhere (I don't like it in the root dir)
+# TODO maybe put the bootdisk.iso in the build dir too ..
# verbose for testing; VERBOSE=@ to turn off..
VERBOSE=@
BUILD = build
ARCH = x86_64
-ASM_SOURCES = $(shell find ./src -name "*.s")
-ASM_OBJECTS = $(patsubst %.s,_%.o, $(notdir $(ASM_SOURCES)))
ASM = nasm
ASMOBJFORMAT = elf64
+LINKER_SCRIPT = ./src/arch/$(ARCH)/linker.ld
+CARGO_XBUILD_FLAGS =
+
+# ---------- No need to edit below this line --------------
+# ---------- If you have to, something is wrong -----------
+ASM_SOURCES = $(shell find ./src -name "*.s")
+ASM_OBJECTS = $(patsubst %.s,_%.o, $(notdir $(ASM_SOURCES)))
# I don't like this style... but what can I do?
ASMOBJ_PREFIXED = $(addprefix $(BUILD)/,$(ASM_OBJECTS))
# Setting directories to look for missing source files
VPATH = $(sort $(dir $(ASM_SOURCES)))
-LINKER_SCRIPT = ./src/arch/$(ARCH)/linker.ld
-# include --release flag to build optimized code
-CARGO_XBUILD_FLAG =
-ifneq ($(CARGO_XBUILD_FLAG), --release)
- RUST_BUILD = debug
-else
+
+# the logic here is so cursed
+ifeq (--release, $(findstring NT-5.1,$(CARGO_XBUILD_FLAGS)))
RUST_BUILD = release
+else
+ RUST_BUILD = debug
endif
RUST_OBJECT = target/$(ARCH)-rustubs/$(RUST_BUILD)/librustubs.a
diff --git a/src/arch/x86_64/asm/io_port.s b/src/arch/x86_64/asm/io_port.s
index 9ddc4e6..3aec69d 100644
--- a/src/arch/x86_64/asm/io_port.s
+++ b/src/arch/x86_64/asm/io_port.s
@@ -11,10 +11,10 @@
; EXPORTED FUNCTIONS
-[GLOBAL outb]
-[GLOBAL outw]
-[GLOBAL inb]
-[GLOBAL inw]
+[GLOBAL _outb]
+[GLOBAL _outw]
+[GLOBAL _inb]
+[GLOBAL _inw]
; FUNCTION IMPLEMENTATIONS
@@ -24,7 +24,7 @@
;
; C prototype: void outb (int port, int value);
-outb:
+_outb:
push rbp
mov rbp, rsp
mov rdx, rdi
@@ -37,7 +37,7 @@ outb:
;
; C prototype: void outw (int port, int value);
-outw:
+_outw:
push rbp
mov rbp, rsp
mov rdx, rdi
@@ -50,7 +50,7 @@ outw:
;
; C prototype: unsigned char inb (int port);
-inb:
+_inb:
push rbp
mov rbp, rsp
mov rdx, rdi
@@ -62,7 +62,7 @@ inb:
;
; C prototype: unsigned short inw (int port);
-inw:
+_inw:
push rbp
mov rbp, rsp
mov rdx, rdi
diff --git a/src/arch/x86_64/io_port.rs b/src/arch/x86_64/io_port.rs
index 9c24c98..4f629b8 100644
--- a/src/arch/x86_64/io_port.rs
+++ b/src/arch/x86_64/io_port.rs
@@ -1,13 +1,36 @@
-
extern "C" {
- fn inb(port:u32) -> u32;
- fn inw(port:u32) -> u32;
- fn outb(port:u32, val:u32);
- fn outw(port:u32, val:u32);
+ fn _inb(port:u16) -> u8;
+ fn _inw(port:u16) -> u16;
+ fn _outb(port:u16, val:u8);
+ fn _outw(port:u16, val:u16);
+}
+
+// The port addr is 16-bit wide.
+// wrappers for in/out[b,w]
+// Also I don't feel necessary to have a IO_Port Class give how
+// trivial it is
+// TODO perhaps use inline asm, because the code is short
+
+pub fn inw(p:u16) -> u16 {
+ unsafe{
+ _inw(p)
+ }
}
-// TODO
-// pub struct IO_Port {
-// addr: u32,
-// }
+pub fn inb(p:u16) -> u8 {
+ unsafe{
+ _inb(p)
+ }
+}
+pub fn outb(p:u16, val:u8){
+ unsafe{
+ _outb(p,val);
+ }
+}
+
+pub fn outw(p:u16, val:u16){
+ unsafe{
+ _outw(p,val)
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 6544781..0f005ae 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,7 +3,6 @@
mod arch;
mod machine;
use core::panic::PanicInfo;
-use core::{mem, ptr};
use machine::cgascr::CGAScreen;
#[panic_handler]
@@ -18,6 +17,7 @@ pub extern "C" fn _entry() -> ! {
// scr.show(0,79,'X',0x0f);
// scr.show(24,0,'X',0x0f);
// scr.show(24,79,'X',0x0f);
- scr.test();
+ // scr.test();
+ scr.setpos(10, 10);
loop {}
}
diff --git a/src/machine/cgascr.rs b/src/machine/cgascr.rs
index 091c50d..2748e67 100644
--- a/src/machine/cgascr.rs
+++ b/src/machine/cgascr.rs
@@ -1,4 +1,8 @@
-const vga_buffer:*mut u8 = 0xb8000 as *mut u8;
+use crate::arch::x86_64::io_port::*;
+
+const CGA_BUFFER_START:*mut u8 = 0xb8000 as *mut u8;
+const IR_PORT:u16 = 0x3d4;
+const DR_PORT:u16 = 0x3d5;
#[allow(dead_code)]
pub struct CGAScreen{
@@ -13,7 +17,7 @@ impl CGAScreen{
}
- fn get_index(&self,row:u32, col:u32) -> u32{
+ fn cal_offset(&self,row:u32, col:u32) -> u32{
col + row*self.max_cows
}
@@ -21,21 +25,48 @@ impl CGAScreen{
// the memory by address.
// and since it's unsafe, it shouldn't be public
pub fn show(&self, row:u32, col:u32, c:char, attr:u8){
- let index = self.get_index(row, col);
+ let index = self.cal_offset(row, col);
unsafe{
- *vga_buffer.offset(index as isize * 2) = c as u8;
- *vga_buffer.offset(index as isize * 2 + 1) = attr;
+ *CGA_BUFFER_START.offset(index as isize * 2) = c as u8;
+ *CGA_BUFFER_START.offset(index as isize * 2 + 1) = attr;
}
}
- pub fn putchar(&self, ch:char){
-
- }
+ // pub fn putchar(&self, ch:char){
+ //
+ // }
- pub fn setpos(){}
- pub fn getpos(){}
+ pub fn setpos(&self, row:u32, col:u32){
+ // io ports for instruction register and data register
+ let offset = self.cal_offset(row,col);
+
+ // set lower byte
+ outb(IR_PORT, 15 as u8);
+ outb(DR_PORT, offset as u8);
+ // set higher byte
+ outb(IR_PORT, 14 as u8);
+ outb(DR_PORT, (offset >> 8) as u8);
+
+ }
+
+ pub fn getoffset() -> u32 {
+ // read higher byte
+ outb(IR_PORT, 14 as u8);
+ let mut offset = inb(DR_PORT);
+ offset = offset << 8;
+ // read lower byte
+ outb(IR_PORT, 15 as u8);
+ offset += inb(DR_PORT);
+ offset as u32
+ }
+
+ pub fn getpos(&self, row:& mut u32, cow:& mut u32){
+ let offset = Self::getoffset();
+ *row = offset % self.max_cows;
+ *cow = offset / self.max_cows;
+ }
// Sanity Check of the cgascreen