2018-01-30 22:30:49 +01:00
|
|
|
; This is the minimal startup & I/O needed to run a basic RETRO
|
|
|
|
; instance on x86 hardware.
|
|
|
|
; =============================================================
|
|
|
|
|
2018-01-31 16:56:30 +01:00
|
|
|
MODULEALIGN equ 1<<0
|
|
|
|
MEMINFO equ 1<<1
|
|
|
|
FLAGS equ MODULEALIGN | MEMINFO
|
|
|
|
MAGIC equ 0x1BADB002
|
|
|
|
CHECKSUM equ -(MAGIC + FLAGS)
|
2018-01-30 18:25:44 +01:00
|
|
|
|
2018-01-31 16:56:30 +01:00
|
|
|
section .mbheader
|
|
|
|
align 4
|
|
|
|
MultiBootHeader:
|
|
|
|
dd MAGIC
|
|
|
|
dd FLAGS
|
|
|
|
dd CHECKSUM
|
2018-01-30 18:25:44 +01:00
|
|
|
|
2018-01-30 22:44:44 +01:00
|
|
|
section .data
|
|
|
|
gdt:
|
|
|
|
dw (.end-.dummy)
|
|
|
|
dd .dummy
|
|
|
|
dw 0
|
|
|
|
.dummy: dw 0,0,0,0
|
|
|
|
dw 0xffff,0x0000
|
|
|
|
db 0x00,0x9a,0xcf,0x00
|
|
|
|
dw 0xffff,0x0000
|
|
|
|
db 0x00,0x92,0xcf,0x00
|
|
|
|
.end:
|
|
|
|
|
|
|
|
|
2018-01-30 18:25:44 +01:00
|
|
|
section .text
|
|
|
|
extern main
|
2018-01-31 16:56:30 +01:00
|
|
|
global loader
|
2018-01-30 18:25:44 +01:00
|
|
|
global _start
|
|
|
|
global getchar
|
|
|
|
|
2018-01-31 16:56:30 +01:00
|
|
|
STACKSIZE equ 0x4000
|
|
|
|
|
2018-01-30 18:25:44 +01:00
|
|
|
align 4
|
2018-01-31 16:56:30 +01:00
|
|
|
loader:
|
2018-01-30 18:25:44 +01:00
|
|
|
_start:
|
2018-01-31 19:42:42 +01:00
|
|
|
lgdt [gdt]
|
2018-01-31 18:31:52 +01:00
|
|
|
mov esp, stack+STACKSIZE
|
2018-01-31 18:50:19 +01:00
|
|
|
push dword 0
|
|
|
|
push dword 0
|
2018-01-31 18:31:52 +01:00
|
|
|
jmp main
|
|
|
|
jmp $
|
2018-01-30 18:25:44 +01:00
|
|
|
|
|
|
|
align 4
|
|
|
|
getchar:
|
2018-01-31 18:31:52 +01:00
|
|
|
xor eax, eax ; clear eax
|
|
|
|
.a: in al, 64h ; Is any data waiting?
|
|
|
|
test al, 1 ; Is character = ASCII 0?
|
|
|
|
jz .a ; Yes? Try again
|
|
|
|
in al, 60h ; Otherwise, read scancode
|
|
|
|
xor edx, edx ; edx: 0=make, 1=break
|
|
|
|
test al, 80h ; Is character = HEX 80h?
|
|
|
|
jz .b ; Skip the next line
|
|
|
|
inc edx ; Update edx
|
|
|
|
.b: and al, 7Fh ; Filters to handle
|
|
|
|
cmp al, 39h ; the ignored keys
|
|
|
|
ja .a ; We just try another key
|
|
|
|
mov ecx, [board] ; Load the keymap
|
|
|
|
mov al, [ecx+eax] ; Get the key ASCII char
|
|
|
|
or al, al ; Is is = 0?
|
|
|
|
js .shift ; No, use CAPITALS
|
|
|
|
jz .a ; Ignore 0's
|
|
|
|
or dl, dl ; Filter for break code
|
|
|
|
jnz .a ; Ignore break code
|
|
|
|
jmp .done ; Skip to end
|
|
|
|
.shift: mov ecx, [edx*4 + .shifts] ; Load the CAPITAL keymap
|
|
|
|
mov [board], ecx ; Store into BOARD pointer
|
|
|
|
jmp .a ; And try again
|
|
|
|
.done: ret
|
2018-01-30 22:34:03 +01:00
|
|
|
|
2019-02-19 14:28:54 +01:00
|
|
|
|
2018-01-30 22:34:03 +01:00
|
|
|
section .data
|
2019-02-19 14:28:54 +01:00
|
|
|
|
2018-01-31 18:31:52 +01:00
|
|
|
.shifts dd shift, alpha
|
2019-02-19 14:28:54 +01:00
|
|
|
|
2018-01-30 22:34:03 +01:00
|
|
|
board dd alpha
|
2019-02-19 14:28:54 +01:00
|
|
|
|
2018-01-30 22:34:03 +01:00
|
|
|
alpha:
|
|
|
|
db 0,27,"1234567890-=",8 ;00-0E
|
|
|
|
db 9,"qwertyuiop[]",10 ;0F-1C
|
|
|
|
db 0,"asdfghjkl;'`" ;1D-29
|
|
|
|
db -1,"\zxcvbnm,./",-1,"*",0,32,-2 ;2A-3A
|
2019-02-19 14:28:54 +01:00
|
|
|
|
2018-01-30 22:34:03 +01:00
|
|
|
shift:
|
|
|
|
db 0,27,"!@#$%^&*()_+",8 ;00-0E
|
|
|
|
db 9,"QWERTYUIOP{}",10 ;0F-1C
|
|
|
|
db 0,'ASDFGHJKL:"~' ;1D-29
|
|
|
|
db -1,"|ZXCVBNM<>?",-1,"*",0,32,-2 ;2A-3A
|
|
|
|
|
2018-01-30 22:30:49 +01:00
|
|
|
|
2018-01-31 16:56:30 +01:00
|
|
|
section .bss
|
|
|
|
align 4
|
|
|
|
stack:
|
|
|
|
resb STACKSIZE
|
|
|
|
stack_ptr:
|