First commit

This commit is contained in:
Juhani Krekelä 2021-08-14 10:22:53 +03:00
commit b434e826fe
5 changed files with 544 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.bin

116
CC0 Normal file
View File

@ -0,0 +1,116 @@
CC0 1.0 Universal
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.
For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate,
and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness
depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data in
a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties
of any kind concerning the Work, express, implied, statutory or otherwise,
including without limitation warranties of title, merchantability, fitness
for a particular purpose, non infringement, or the absence of latent or
other defects, accuracy, or the present or absence of errors, whether or not
discoverable, all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without limitation
any person's Copyright and Related Rights in the Work. Further, Affirmer
disclaims responsibility for obtaining any necessary consents, permissions
or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to this
CC0 or use of the Work.
For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>

15
Makefile Normal file
View File

@ -0,0 +1,15 @@
.SUFFIXES:
.SUFFIXES: .asm .bin
all: anattos.bin
.asm.bin:
nasm -fbin -o $@ $<
clean:
rm -f *.bin
run: anattos.bin
qemu-system-i386 -fda $<
.PHONY: all clean run

24
README.md Normal file
View File

@ -0,0 +1,24 @@
AnattOS
=======
AnattOS is a 512 byte memory editor with convenience features for hand
programming machine code.
Interface
---------
256 bytes of memory are show in a 16 by 16 grid. Each line of 16 bytes is
checksummed with Fletcher-16, and the checksum is displayed after the line.
The address under the cursor is displayed below the memory dump.
If the byte under the cursor begins an instruction where the opcode and
mod-r/m bytes' fields have the standard meanings, the fields' meanings are
decoded and shown below the address. Note that the case of mod=0 r/m=6 is
not special cased, and will display `bp` for the r/m field.
Arrow keys can be used to navigate the memory, and `r` to call into the
address under the cursor. When returning to AnattOS the code should restore
segment registers, direction flag, and stack pointer to the values they had
upon entry.
Limitations
-----------
AnattOS is only able to examine first 64KiB of RAM.

388
anattos.asm Normal file
View File

@ -0,0 +1,388 @@
; CC0 2021 nortti
org 0x7c00
jmp 0:start
start:
cld
cli
xor dx, dx
mov ds, dx
mov ss, dx
mov sp, $$
sti
; VGA video memory
mov ax, 0xb800
mov es, ax
; Start at bootloader
mov bx, $$
init_screen:
; Set 80x25 text mode
mov ax, 3
int 0x10
; Clear screen
xor di, di
xor ax, ax
mov cx, 80 * 25
rep stosw
mainloop:
; Align dump display to 256 byte page
mov si, 0xff00
and si, bx
; Display RAM contents
xor di, di
mov bp, 256
.dump:
cmp si, bx
jne .not_cursor
; Set cursor
pusha
shr di, 1 ; Cursor position is in char cells
mov dx, 0x3d4
mov al, 0x0f ; Lower 8 bits of position
out dx, al
inc dx
mov ax, di
out dx, al
mov dx, 0x3d4
mov al, 0x0e ; Higher 8 bits of position
out dx, al
inc dx
mov ax, di
mov al, ah
out dx, al
popa
.not_cursor:
lodsb
call hexprint8
; Fletcher-16
add dl, al
adc dl, 0
add dh, dl
adc dh, 0
inc di
inc di
dec bp
test bp, 0x0f
jnz .dump
inc di
inc di
mov ax, dx
call hexprint16
xor dx, dx
add di, (80 - 16*3 - 5)*2
test bp, bp
jnz .dump
.end_dump:
; Display address
mov di, 17 * 80 * 2
mov ax, bx
call hexprint16
xor ax, ax
call disasm
; Read user input
int 0x16
.left:
cmp ah, 0x4b
jne .right
dec bx
.right:
cmp ah, 0x4d
jne .up
inc bx
.up:
cmp ah, 0x48
jne .down
sub bx, 16
.down:
cmp ah, 0x50
jne .digit09
add bx, 16
.digit09:
cmp al, '0'
jb .digitaf
cmp al, '9'
ja .digitaf
sub al, '0'
jmp digit
.digitaf:
cmp al, 'a'
jb .r
cmp al, 'f'
ja .r
sub al, 'a' - 10
jmp digit
.r:
cmp al, 'r'
mov al, 0xff
jne digit.update_nybble
pusha
call bx
popa
jmp init_screen
digit:
; 00 … 0f are stored nybbles, other values are sentinels
test byte [high_nybble], 0xf0
jnz .update_nybble
mov cl, [high_nybble]
shl cl, 4
or al, cl
mov [bx], al
inc bx
mov al, 0xff
.update_nybble:
mov [high_nybble], al
jmp mainloop
; IN:
; ah = 0
; bx = offset
disasm:
pusha
mov si, bx
mov di, 19 * 80 * 2
mov cx, 2 * 80
push di
rep stosw
pop di
; Opcode byte
lodsb
mov dl, al
shr al, 1
cmp al, 0x7f ; fe ff
jz .do_disasm
test al, 0x62 ; add, or, adc, sbb, and, sub, xor, cmp
jz .do_disasm
cmp al, 0x40
jb .no_disasm
cmp al, 0x45 ; 80 81 82 83, test, mov
jbe .do_disasm
cmp al, 0x60 ; c0 c1
je .do_disasm
jb .no_disasm
cmp al, 0x62 ; c4 c5
je .do_disasm
test al, 0x16 ; d0 d1 d2 d3
jnz .no_disasm
.do_disasm:
; Opcode
shr al, 1
call hexprint8
inc di
inc di
; Direction / extend
mov ax, 0x0700 + ' '
test dl, 2
jz .print_direction
mov al, 's'
.print_direction:
stosw
inc di
inc di
; Width
mov al, 'b'
test dl, 1
jz .print_width
mov al, 'w'
.print_width:
stosw
add di, (80 - 6) * 2
; Mod-reg-r/m byte
lodsb
mov dh, al
; Mode
shr al, 6
call hexprint4
inc di
inc di
; Reg or opcode extension
mov al, 0x38
and al, dh
shr al, 3
cmp dl, 0x80
jb .not_op_ext
cmp dl, 0x83 ; 80 81 82 83
jbe .op_ext
cmp dl, 0x8b ; test mov
jbe .not_op_ext
.op_ext:
call hexprint4
jmp .skip_print_reg
.not_op_ext:
call .reg
.skip_print_reg:
inc di
inc di
; R/m
mov al, 0x07
and al, dh
cmp dh, 0xc0 ; Hacky way to check if top two bits are both set
jb .base
call .reg
.no_disasm:
popa
ret
.reg:
xor bx, bx
mov bl, al
test dl, 1
jz .reg8
mov al, byte [bx + register_first]
stosw
shr bx, 1
mov al, byte [bx + register_second]
stosw
ret
.reg8:
mov cl, al
shr cl, 2
and bl, 3
mov al, byte [bx + register_first]
stosw
mov bl, cl
mov al, byte [bx + register_halves]
stosw
ret
.base:
mov cl, al
test al, 4
jnz .base47
mov al, 'b'
stosw
mov bx, 2
and bl, cl
shr bl, 1
mov al, byte [bx + base_first]
stosw
mov al, '+'
stosw
.si_di:
mov bl, 1
and bl, cl
mov al, byte [bx + base_second]
stosw
mov al, 'i'
stosw
popa
ret
.base47:
test al, 2
jz .si_di
mov al, 'b'
stosw
mov bx, 7
sub bl, cl
mov al, byte [bx + base_first]
stosw
popa
ret
register_first db 'acdbsb'
base_second db 'sd'
register_second db 'x'
base_first db 'xp'
db 'i'
register_halves db 'lh'
; IN: ax/al/al = number
; UPDATE: di = index into video memory
hexprint16:
xchg al, ah
call hexprint8
xchg al, ah
hexprint8:
rol al, 4
call hexprint4
rol al, 4
hexprint4:
push ax
and al, 0xf
cmp al, 10
jb .below_10
add al, 'a' - '0' - 10
.below_10:
add al, '0'
; 07 = white on black
mov ah, 0x07
stosw
pop ax
ret
times 510 - ($ - $$) db 0
high_nybble db 0x55, 0xaa