Development with NedoOS
Alone Coder
Under NedoOS can be developed on AC─
assembler, C, Pascal and Nedolang, but in this
In this article I will tell you specifically about assembler. On
there are most examples, and it will be with him
It is more clear how the system works.
In addition to examples,NedoOSprovides ra─
The employee has a large set of functions that
usually too lazy to write from scratch, as well as the environment
for automatic assembly.
First acquaintance
First acquaintance with the system for development─
The bot looks like this (if you have Windows):
1. download everything from http://nedoos.ru/svn/
to a directory that does not contain spaces in the path
2. enter this directory, or rather, in
subdirectorysrc/
3.runmkevo.bat.
In this case, the entire system is rebuilt (to
at the time of writing this article - 70 packs─
Comrade), an SD card image is createdsd_nedo.vhd
(if it was not there), and it is written to
everything that is in release/.The image is in
us/ - emulator directories.
How it works internally:
1. mkevo.bat writes settings files
for ZX Evo configuration to filesrc/_sdk/
syssets.asm
2. mkevo.bat runs make.bat with steam─
meter noneedtrd (that is, we don’t do trd-
floppy disk image, we don't need it)
3. make.bat creates if necessary
directoryrelease/
4. make.bat assembles the package fatfs4os (fa─
File system FAT)
5. make.bat builds the package kernel (kernel
OS), is creatednedoos.$c
6. make.bat collects all packages in a loop
by calling build.bat for each of them, and
after building the package, copies it to release/
received *.com, *.ext, *.txt,*.new and
subdirectory of the same name as the directory
package
7. make.bat if there is no parameter
noneedtrd (and we have it) created─
it and fills test.trd
8. mkevo.bat renamesnedoos.$c to
sd_boot.$c (so you can run from
Evo Reset Servicewith one button 5)
9. mkevo.bat launches chkimg.bat with pa─
meter sd (if there washdd,then they would work
with a hard disk imagehdd_nedo.vhd )
10. chkimg.bat creates if necessary
image (using images.exe )
11. chkimg.bat writes everything to the image
what is inrelease/ (using dmimg.exe )
12. mkevo.bat launches the configured emu─
lator.
The collectors for the rest work similarly─
line configurations:
mkevsd-g.bat - ZX Evo without SD card in NeoGS
mkatm3.bat - ATM3 on a floppy disk
mkatm3hd.bat - ATM3 on HDD (Nemo IDE, possible
fix in the batch file)
mkatm3sd.bat - ATM3 onSD card
mkpe26.bat - Pentagon 2.666LE on floppy disk
mkpe26sd.bat - Pentagon 2.666LE on SD card
mkatm2.bat - ATM2 on a floppy disk
mkatm2hd.bat - ATM2 on HDD (ATM IDE)
They are all the same type, so everyone can
create your own collector or fix an existing one─
howling.
makeall.bat calls everything mk*.bat. It
must be run before committing to the reposito─
riy.
Batch file
From all this (especially from the point about
build.bat ) it is clear that the program is user─
it is better to write the body according to the existing ones
programs. The easiest way is to take the directory
emptyapp (or if your program is similar
to some existing directory
toy), copy it entirely andcorrect.
What does the simplest one look like build.bat:
1. Setting up paths:
if "%settedpath%"=="" call ../_sdk/
setpath.bat
2. Compilation (can be many lines, with
calling the necessary resource conversion utilities and
etc.):
sjasmplus --nologo --msg=war emptyapp.asm
This is where you can fix for
your program, but if its main module
is called emptyapp.asm - don't correct it :)
And the rest will most likely be corrected
You won't have to do that.
3. If build.bat is called separately (from me─
nya this is the F9 button in Notepad++ ), thenкопиро─
вать в release/ и на образ SD-карты:
if "%currentdir%"=="" (
FOR %%j IN (*.com) DO (
copy /Y %%j "../../release/bin/" > nul
"../../tools/dmimg.exe" ../../us/
sd_nedo.vhd put %%j /bin/%%j
)
if "%makeall%"=="" ....usemul.exe
)
Вариант для игр с кучей файлов в одно─
имённой поддиректории:
SET releasedir2=../../../release/
if "%currentdir%"=="" (
FOR %%j IN (*.com) DO (
"../../../tools/dmimg.exe" ../../../us/
sd_nedo.vhd put %%j /nedogame/%%j
move "*.com" "%releasedir2%nedogame">nul
IF EXIST %%~nj xcopy /Y "%%~nj"
"%releasedir2%nedogame%%~nj">nul
)
cd../../../src/
call ..toolschkimg.bat sd
if "%makeall%"=="" ..usemul.exe
)
Maybe someone can do it everywhere
the same? But for now we live like this.
There is also a batch file option runcurl.bat,
which, after assembly, tries to transmit co─
abusive *.com via HTTP to an already running one
emulator, and then launch it remotely.
To do this, the emulator must be running
NedoOS, and it has a web server 3ws.
Main module of the program
Let's assume that you are writing a game. Its source─
the days are in src/games/somegame/. Her eyes─
The main module is called main.asm. Its com-
the file is called somegame.com, and add─
Line files are generated in src/games/
somegame/somegame/ (during assembly they will end up in
release/nedogame/somegame/somegame/ ). How
looks main.asm:
DEVICE ZXSPECTRUM128
include "../../_sdk/sys_h.asm"
;all system constants and macros are there
STACK=0x4000 ;this is most convenient for games
org PROGSTART ;all programs start─
;can be found from this address
begin
ld sp,STACK ;otherwise it will be sp=0
;Our program does not work through stdio, but
; she picks around the screen herself, so:
OS_HIDEFROMPARENT ;wake up the rod─
;program body (usually a navigator)
ld e,0+128 ;e=0: EGA, e=2:MC,
;e=3: 6912, e=6: text
;+8=noturbo;+128=keep screen
;e=-1: disable gfx
OS_SETGFX ;включаем граф.режим и
;получаем фокус (out:e=old gfxmode)
ld de,path
OS_CHDIR ;входим в поддиректорию
;...грузим файлы...
mainloop
;...играем...
jr mainloop
ld hl,0 ;результат
QUIT ;выход
path
db "somegame",0
;...всякие процедурки, таблицы, инклюды...
end
savebin "somegame.com",begin,end-begin
LABELSLIST "../../../us/user.l" ;сохраним
;метки,смотреть их дебагере Unreal Speccy
If your program code compiles
several pages, then use direct─
tivu PAGE and several savebin (you can under─
see in the projectbr,how this is done).
Debugging
So if you wrote the above
example main.asm and ran build.bat (not
forget to specify there main.asm ), then just
you will find yourself inUnreal Speccy.
Click the button "5" you will find yourself in NedoOS,
run your game from there nedogame/
(you can automate this using
autoexec.bat).PressShift+F1,to─
fall into the debugger. Press Ctrl+L,to
see the marks (and to unsee them - againCtrl+L ).
Make sure the current task is
your game: Tab (to the dump window), Ctrl+G,0080
- you should see somegame.com in the dump.
If it's not, then go back to the window
disassembler (Shift+Tab), Ctrl+G, 0057
(end of interrupt handler), and then
press F4 (execute to the cursor) until
you will seesomegame.comin the dump. Bottom right
currently enabled pages are visible in all
four quarters.
Step through the program - F7. Step through the program─
starting calls - F8. Step to the exit along
stack - F11. You can rearrange the current
execution address -Z.
During program execution, you can manually─
correct registers (go to them -
Shift+Tab,mouse also works).You can even
correct the program.
If other tasks (especially term.com )
interfere with tracing your program, they can─
but close: once in this task, rearrange
execution address on0.
View screen - F9.
Save a piece of memory - Alt+W (save─
appears in src/ ). Load -Alt+R.
Exit the debugger - Shift+F1. Current─
For some reason this version of the emulator is awesome─
dit to sticking Shift, so you need to poke
again Shift. When exiting the debugger that─
Also turns off Kempston mouse, it is necessary
capture by clicking on the emulator window.
Loading and saving files from the program
If you only need to read some
something small, like shipping, you can just
sketch:
ld de,filename ;"name.ext",0
OS_OPENHANDLE ;opened the file
or a
jr nz, error ;could not open
push bc ;b=open file handle
ld de,SAVEDATA ;address where to ship
ld hl,SAVEDATAsz ;how many bytes
OS_READHANDLE ;loaded
pop bc ;b=open file handle
OS_CLOSEHANDLE ;closed
Saving is similar, only instead of
OPENHANDLE write CREATEHANDLE, and instead
READHANDLE - WRITEHANDLE. Sample can
look inuntangle.
But usually the data must be loaded in the country─
Tsy, these pages need to be highlighted!
Initially, the OS allocates to each program
4 pages, the numbers of which can be found out─
res OS_GETMAINPAGES (get dehl=pages
in 0000, 4000, 8000, c000 ). Best
recognize them at the very beginning and remember them on─
example, like this:
OS_GETMAINPAGES ;dehl=pages in
;0000,4000,8000,c000
ld a,e
ld (pgmain4000),a
ld a,h
ld (pgmain8000),a
ld a,l
ld (pgmainc000),a
;and then there will be loading
And at the end of the program write convenient
procedures for including these pages:
setpgmain4000
pgmain4000=$+1
ld a,0
SETPG4000
ret
setpgmain8000
pgmain8000=$+1
ld a,0
SETPG8000
ret
setpgmainc000
pgmainc000=$+1
ld a,0
SETPGC000
ret
If your program always includes
screen at 4000 and 8000, then volume makes sense─
combine setpgmain4000 and setpgmain8000 into
one procedure setpgsmain40008000. And now─
turn on the current screen through the procedure
setpgsscr40008000.You don’t have to write this with
zero, and borrow the entire module src/
games/sprexamp/mem.asm.
So, we need to load some fa─
ylov into pages. Let's take a universal pro─
procedure for loading one page from the same
sprexamp:
loadpage
;orders a page and uploads a file there
;(nameфайла в hl)
;out: hl=после имени файла, a=pg
push hl
OS_NEWPAGE
pop hl
ld a,e
push af ;pg
SETPGC000
push hl
ex de,hl
OS_OPENHANDLE
push bc
ld de,0xc000 ;addr
ld hl,0x4000 ;size
OS_READHANDLE
pop bc
OS_CLOSEHANDLE
pop hl
ld b,1
xor a
cpir ;after 0
pop af ;pg
ret
И будем её вызывать так:
ld hl,texfilename
call loadpage
ld (pg0),a
call loadpage
ld (pg1),a
call loadpage
ld (pgsfx),a
call loadpage
ld (pgmusic),a
etc.
Inbr this is generally done in a loop, but─
A measure of pages are placed in the table.
texfilename
db "pg0.bin",0
db "pg1.bin",0
db "sfx.bin",0
db "music.bin",0
It's easy to convertloadpageto loading from
arbitrary address, which can also be
take from texfilename (for example, before the name─
file).
Drawing on the screen
There are two ways to draw - in visible
screen or with double buffering (one
we update the screen, another one is visible).
For dynamic games it is best to use─
call the second option, otherwise it’s possible
Problems with flickering and disappearing sprites.
The main loop of a game running on two computers─
wounds, looks something like this (example from
loadscr ):
ld a,(timer)
ld (oldtimer),a
;main loop
mainloop
;display background/restore it under sprites
;... I recommend taking it from sprexamp!
;sprite output
call setpgsscr40008000 ;enabled
;screen pages
ld iy,spaceship0
ld e,50 ;e=x = -(sprmaxwid-1)..159
;(encoded as x+(sprmaxwid-1))
ld c,50 ;c=y = -(sprmaxhgt-1)..199
;(encoded as is)
call prspr
call setpgsmain40008000 ;enabled
;program pages in 4000,8000, as it was
;finisheddraw
ld a,(timer)
push af
call changescrpg ;from now on
;(more precisely, with INT) we will see what we drew
;logic
;called as many times as elapsed
;interrupts!
mainloop_uvwaittimer0
ld a,(timer)
oldtimer=$+1
ld b,0
ld (oldtimer),a
sub b
ld b,a
jr z,mainloop_uvwaittimer0 ;if
;there have been no interruptions yet, let's spin here
;b=how many interrupts have passed
mainloop_uvlogic0
push bc
call logic ;write your logic here
pop bc
djnzmainloop_uvlogic0
;waiting for the screen to physically switch!
;we can start a new rendering only if
;at least one time has passed since changescrpg
;interrupt (possibly inside logic)
pop bc ;b=timer during changescrpg
waitchangescr0
ld a,(timer)
cp b
jr z,waitchangescr0
ld a,(curkey)
cp key_esc
jp nz,mainloop ;exit via esc/break
To make the timer work,connect the module
sprexamp/int.asm and use swapimer
(enable/disable custom
interrupt handler) before and after va─
of our main loop. Please note
music is not played in this handler, for
there is a systemiccallOS_SETMUSIC,
which guarantees smooth playback,
even if your task is superseded by others
tasks!
Procedure prspr take from sprexamp/
prspr.asm.If you have compiled sprites─
not in pages, but in separate files
then you can define them prsprqwid=0x100,
and before the first call prspr write to
0x100 command jp prsprqwid. Generally possible
start writing a game with a fix about─
ekta sprexamp. There are even two ready-made
engine - with background scrolling along two axes
(without scrolling the background is not reprinted) and with
scrolling vertically (background reprinting─
always happens). And by the first engine already
screwed controls and logic in style
platformer.
Worth reading nedoos.txt,api_base.txt
andsys_h.asm, to get an idea
about other system functions.
Share your thoughts about the article