flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Mini machine code monitor

Author
Thread Post new topic Reply to topic
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
MiniMON - a mini machine code "monitor" for your PC

- like a simple microprocessor development board ROM

- all squeezed into a bootable single 512-byte bootsector!

- You can view all conventional RAM and ROM contents 256 bytes at a time

- You can change all RAM contents with a hex editor

- So you can enter your program machine code in hex (almost) anywhere you like

- and then run it using the e(X)ecute key.

Code starts executing from the nearest lowest paragraph boundary (XXXX0H)
so best to always enter code starting from the left-most screen column
i.e. when you press the X key code starts executing from the left-most byte on that row.

- code CD 05 for normal program termination, or in emergencies press the PrtSc key (INT 05H)



- No room for any on-screen instructions, but the (messy) source code says it all!

- Hex numeric keys A - F and X key are not case-sensitive

- Navigation of 64K offset addresses using cursor keys and PgDn/PgUp keys

- Navigation of segment address using End key

- Memory addresses displayed in 20-bit linear format 0SXXXX (not S000:XXXX)



Of course once MiniMON has booted it knows nothing about disks, including the device it just booted from. In effect it's about the smallest possible memory operating system, but at the same time it is sufficient to hand-code and test anything you like. Limited only by the imagination!


Scroll down to page 7D00 and move the cursor around - watch the changing MEMADDR and CURLOC (CursorLocation) variables stored at word[7DF1] and word[7DF3] in the bottom row.



Now every monitor program should have some support for breakpoints but unfortunately there wasn't room in the bootsector Smile

So here's a 20-byte breakpoint handler for the single-byte opcode CCH (INT 3) which can be entered almost anywhere in RAM:

B8 03 00 CD 10 90 B8 42 0E CD 10 B4 00 CD 16 EA 00 7C 00 00


OK, as a breakpoint handler it could be improved on - displaying register contents would be nice - but hey, what do you expect in 20 bytes?


Let's say you put the breakpoint routine at address 07E00 (the page following the bootsector).
Now enter the Interrupt vector address straight into the Interrupt Vector Table:
Scroll up (down?) to address 000000 then cursor along to 0000C - 0000F (address for INT 3) and enter

00 7E 00 00


Done! Now you can code breakpoints anywhere you like, with a 90 (NOP) byte that you change to a CC (INT 3) byte when you want a breakpoint.



Now to test the breakpoint routine:

Write a test program into RAM, lets say at address 012340:

B8 DB 0E CD 10 CD 16 CC EB FE

This program will hack the screen display by printing a big white block character at the cursor, and then waiting for a keystroke before hitting the breakpoint.
After you press any key, the breakpoint routine should clear the screen and print a B in the top left corner and wait for another key. It then returns to the monitor, not your program code. Which is just as well, because after the breakpoint is the dreaded dead loop JMP $, code EB FE

So change the breakpoint CC to 90 (NOP) and execute it again. Yep, gets kinda cold - a big freeze. But don't panic! You still don't need that boot device because the PrtSc key is your saviour and will take you back to the monitor, no questions asked Smile So long as PrtSc is one of the first 8 keys you press - because the keyboard buffer isn't being flushed, so when its full its full ...


Notice there's also provision for a breakpoint in the breakpoint routine, 6th byte. Right after setting the video mode which clears the screen. Find out what happens when the breakpoint routine calls itself... You might need the PrtSc key again!



Enjoy!



BTW:

- Even this simple little program exhibits some of the features of a memory OS, like variables retaining values in memory if desired.


- I've written MiniMON into the bootsector of a pendrive (using USBIT - thanks for the tip Mike Gonta), and until I finish hand-coding my USB host controller driver in MiniMON I'm unplugging the pendrive as soon as it boots. Saves wear and tear on the pendrive for the next 25 years until I finish the hcd Smile


- The code is based on MEMED, the Memory Editor I wrote for my MiniMOS os a while ago, which in turn is a vastly cut-down version of the 32-bit flat real FAMOS Memory Editor, FAME.


Description: Mini Monitor Ver 1.0
Download
Filename: minimon.asm
Filesize: 11.05 KB
Downloaded: 156 Time(s)


_________________
FAMOS - the first memory operating system
Post 14 Jan 2011, 03:19
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
Here's the bootsector image too, all 512 bytes of it Smile


Description: MiniMON binary V1.0
(change name to minimon.img)

Download
Filename: minimon.doc
Filesize: 512 Bytes
Downloaded: 135 Time(s)


_________________
FAMOS - the first memory operating system
Post 14 Jan 2011, 03:27
View user's profile Send private message Visit poster's website Reply with quote
Coty



Joined: 17 May 2010
Posts: 554
Location: ␀
Coty
Cool! It took me a while but I was eventually able to make a jump loop Very Happy

... Crashing QEmu with it was easier Laughing

Anyway nice Smile

_________________
http://codercat.org/
Post 15 Jan 2011, 13:42
View user's profile Send private message Send e-mail Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2140
Location: Estonia
Madis731
I don't fully understand the magic behind this, but wouldn't it be more optimal (speed and size wise) to reduce the following three lines:
Code:
                MOV     AL,CH           ;retrieve binary MSD
                SHL     AL,4            ;shift to bits 4-7
                OR      AL,CL           ;merge with bits 0-3  
    

to this:
Code:
shl cl,4
shr cx,4
    

First it will reduce the source footprint, then it will be 1 byte shorter and finally it will fix (what seems to be) a bug when unknown bits from high nibble of the CL will creep into the result when ORing.

Now you just have to modify the MOV [BX],AL line to use the CL.

Another thought. Why do you move the value in SI to BX when you could move into [SI] just as well? By a quick look I couldn't spot any reusing of that register.
Post 17 Jan 2011, 12:59
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
Thanks for your thoughts.

My coding style is that, unless there is good reason otherwise, I generally write for readability and future maintainability rather than optimisation, and I've certainly never worried about "source footprints". In fact, the bigger the source the better because it's probably got more comments and is generally more readable Wink

As mentioned this code was originally written for FAMOS using 32-bit registers, and the binary was about 3kb. Chopping out all the screen text reduced it to under 1kb, and then it was just a matter of getting it under 512 bytes which turned out to be quite easy.

As you can see, here I am always deriving the required bits in AL, which is easy to read and understand. There is no "magic" Smile Your method might work, but imo it is less obvious and less readable Razz BTW, your perceived "bug" can not occur because the high nybble of AL returned by GETNYBL is always 0.

My use of the SI register does look a bit strange, but I did that in the MiniMOS code to avoid a couple of memory accesses (with segment overrides) which was actually just an easy way of saving quite a few bytes of code. Yes, it could certainly be further optimised.

If I'm optimising it's usually for speed rather than code size but of course every byte saved here means more functions could potentially be squeezed into the boot sector....

_________________
FAMOS - the first memory operating system
Post 19 Jan 2011, 02:26
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 619
cod3b453
Thank you for sharing this neville! This is a very slick way to see what's where at boot time so I know I'm not trashing stuff with my boot loader Laughing
Post 20 Jan 2011, 23:27
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
You are welcome cod3b453 Smile

I've just used MiniMON to see what my BIOS thinks my 2Gb pendrive is when it boots.

Interestingly, it reports the parameters as 1023 cyls, 16 heads and 32 sectors per track.

I would never have guessed 32 SPT !!

So the size is only 1023*16*32*512 = 268,173,312 bytes, about 1/8 of its actual size.

BTW this was using INT13h/AH=08 which returned CX=FFE0h, DX=0F02h

I should be able to access the full 2GB from MiniMON using EDD services though.

_________________
FAMOS - the first memory operating system
Post 23 Jan 2011, 21:35
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2140
Location: Estonia
Madis731
I tried to code this one from scratch and I had fun. Actually I discovered something new about 16-bit mode. Even if it doesn't support more than 16 bits it still can use 32-wide registers in a funny way. For example when ecx=-1 and I increase cx, the upper half of ecx will not wrap around and point to a different address in memory when addressed with [ecx].

Here are all the 389 bytes of it Very Happy

PS. Additional feature: character representation of binary data right next to the dump.

EDIT (just to be clear about the implementation/functionality):
-Code starts executing from the selected byte (not the paragraph like in the original)
-PrtSc key (INT 05H) is not implemented


Description: minimalistic monitor (debugger)
Download
Filename: MiniMON2.asm
Filesize: 3.13 KB
Downloaded: 123 Time(s)


_________________
My updated idol Very Happy http://www.agner.org/optimize/
Post 24 Jan 2011, 07:24
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.