Справочник функций

Ваш аккаунт

Логин:
Пароль:
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:
Убрать блок ВКонтакте навсегда

Последние темы форума

Показать новые сообщения »

Почтовая рассылка



Подписчиков: 19017
Последний выпуск: 23.04.2012

Модуль commands.asm

; Выход ######################################################################
PROC            doQuit
                mov     [QuitFLG],1
                ret
ENDP            doQuit
; Страничка помощи ###########################################################
PROC            doHELP
                lea     di,[ctable]
doHelp0:        mov     si,di
                push    di
                mov     al,[di]
                or      al,al
                je      doHelp3
                call    write
                lea     si,[plots]
                call    write
                pop     di
doHelp1:        inc     di
                cmp     [Byte Ptr di],0
                jne     doHelp1
                inc     di
                push    di
                mov     si,di
                call    write
                lea     si,[null]
                call    writeln
                pop     di
doHelp2:        inc     di
                cmp     [Byte Ptr di],0
                jne     doHelp2
                inc     di
                inc     di
                inc     di
                jmp     doHelp0
doHelp3:        pop     di
                ret
ENDP            doHELP
; Очистка экрана #############################################################
PROC            doCLS
                mov     ch,[windowy]             ;¬
                mov     cl,[windowx]             ;¦
                dec     cl                       ;¦
                mov     dh,[windowHx]            ;¦
                inc     dh                       ;¦
                mov     dl,[windowWx]            ;¦ Сдвиг окна вверх
                inc     dl                       ;¦      (или очистка)
                inc     dl                       ;¦
                mov     ax,0600h                 ;¦
                mov     bh,[color]               ;¦
                int     10h                      ;-
                mov     [Byte Ptr mainx],0
                mov     [Byte Ptr mainy],0
                ret
ENDP            doCLS
; Загрузка задачи (из корня) #################################################
doStartData0    DB      "Enter Task name: ",0
doStartData1    DB      " ¦ Error: Task not found.",0
doStartData2    DB      " ¦ Error: Absent task name.",0
doStartData3    DB      " ¦ Loading task. Please wait...",0
doStartData4    DB      " ¦ Error: No memory.",0
doStartData5    DB      " ¦ Error: No free task descriptors.",0
doStartName     DB      "FILENAMEEXT"
PROC            doStart
                lea     si,[doStartData0]
                call    write
                call    input
                lea     si,[null]
                call    writeln
                ; Не пустая-ли строка
                mov     al,[command]
                or      al,al
                je      doStart2
                lea     di,[command]
                call    UpperString
                ; Копируем строку из command в doCDSubStr1
                lea     di,[doCDSubStr1]
                lea     si,[command]
DoStart2_0:     mov     al,[cs:si]
                or      al,al
                je      DoStart2_1
                mov     [cs:di],al
                inc     si
                inc     di
                jmp     DoStart2_0
DoStart2_1:     mov     [Byte Ptr cs:di],0
                call    doCDNormaliseName           ; Нормализуем имя файла
                ; Поиск файла в каталоге
                call    _di
                call    FindFirst
                or      ax,ax
                jne     doStart3_0
DoStart2_2:     lea     di,[find_FileName]
                lea     si,[doCDFileName]
                mov     cx,11
DoStart2_4:     mov     al,[di]
                cmp     al,[si]
                jne     DoStart2_3
                inc     di
                inc     si
                loop    DoStart2_4
                ; Найден файл
                call    _ei
                jmp     doStart5
DoStart2_3:     call    FindNext
                or      ax,ax
                jne     doStart3_0
                jmp     DoStart2_2
doStart3_0:     lea     si,[doStartData1]
doStart3:       call    writeln
                call    _ei
                ret
doStart2:       pop     dx
                lea     si,[doStartData2]
                jmp     doStart3
doStart6:       pop     di dx
                lea     si,[doStartData4]
                jmp     doStart3
                ; Найдено название файла в секторе
                ;      (надо узнать начальный кластер)
doStart5:       mov     dx,[cs:find_ClustNo]
                push    dx
                push    di
                call    GetMemory
                or      dx,dx
                je      doStart6
                push    dx
                lea     si,[doStartData3]
                call    writeln
                pop     dx
                pop     di
                mov     es,dx
                pop     dx

                call    _di
                add     dx,33-2         ; 33 - первый сектор данных
                mov     cx,127
                mov     di,100h
doStart7:       push    es dx di cx
                call    ReadSect
                pop     cx di dx es
                inc     dx
                add     di,512
                loop    doStart7
                mov     [Word Ptr ES:0000h],020CDh   ; int 20h
                ; Теперь в ES:0000 имеем задачу (точка входа ES:0100h)
                ; Инициализируем задачу
                ; Ищем первый свободный дескриптор задачи
                lea    di,[tasks]
                mov    cx,8
doStart9:       cmp    [Byte Ptr cs:di],255
                je     doStart8
                add    di,515
                loop   doStart9
                ; Нет свободных дескрипторв (такого быть не может, но ладно)
                lea     si,[doStartData5]
                jmp     doStart3
                ; В DI имеем адрес свободного дескриптора
doStart8:       mov     al,[tasknum]
                inc     al
                mov     [tasknum],al
                mov     [cs:di],al
               ; Сохраним точку входа в дескрипторе задач
                mov     [Word Ptr cs:di+1],100h
                mov     [cs:di+3],es
               ; Подготовим оба стека
                mov     [Word Ptr es:0FFFEh],00000h  ; 0 - если программа
               ; закончится RET'ом, то CS:IP=CS:0000, а там int 20h
                mov     [Word Ptr es:0FFFCh],00232h  ; FLAGS
                mov     [Word Ptr es:0FFFAh],es      ; CS    PSP
                mov     [Word Ptr es:0FFF8h],00100h  ; IP    100h
                mov     [Word Ptr es:0FFF6h],00111h  ; DI    0000
                mov     [Word Ptr es:0FFF4h],00222h  ; BX    0000
                mov     [Word Ptr es:0FFF2h],00333h  ; AX    0000
                mov     [Word Ptr es:0FFF0h],es      ; ES    PSP
                mov     [Word Ptr es:0FFEEh],es      ; DS    PSP
                mov     [Word Ptr es:0FFECh],00000h  ; SI    0000

                mov     [Word Ptr cs:di+513],0FFECh  ; SS    FFEC
                mov     [Word Ptr cs:di+511],ES      ; SP    seg
                mov     [Word Ptr cs:di+509],00000h  ; CX    0000
                mov     [Word Ptr cs:di+507],00000h  ; DX    0000
                mov     [Word Ptr cs:di+505],00000h  ; BP    0000
                mov     [Word Ptr cs:di+9],1         ; Задаем приоритет задачи
                mov     [Word Ptr cs:di+11],1        ; Задаем приоритет задачи
                call    _ei
                ret
ENDP            doStart
; Выдает список задач ########################################################
doListData1     DB      "Task list:",0
doListData3     DB      "  ",0
doListData4     DB      ":",0
doListData5     DB      "Task not loaded.",0
doListData6     DB      "Task stoped.",0
PROC            doList
                lea     si,[doListData1]
                call    writeln

                lea     di,[tasks]
                mov     bx,1
doList1:        push    bx di
                lea     si,[doListData3]
                call    write
                mov     ax,bx
                xor     ah,ah
                call    writeAX
                lea     si,[doListData3]
                call    write
                pop     di
                push    di
                mov     al,[cs:di]
                cmp     al,255
                je      doList2
                cmp     al,254
                je      doList4
                mov     ax,[cs:di+3]
                call    writeAX
                lea     si,[doListData4]
                call    write
                pop     di
                push    di
                mov     ax,[cs:di+1]
                call    writeAX
                lea     si,[doListData3]
                call    write
                pop     di
                push    di
                mov     ax,[cs:di+11]
                call    writeAX
                lea     si,[doListData3]
                call    write
                lea     si,[null]
                call    writeln
doList3:        pop     di bx
                inc     bx
                add     di,515
                cmp     bx,9
                jne     doList1
                ret
doList2:        lea     si,[doListData5]
                call    writeln
                jmp     doList3
doList4:        lea     si,[doListData6]
                call    writeln
                jmp     doList3
ENDP            doList
; Выгружает задачу ###########################################################
doKillData0     DB      "Enter task number (1-8): ",0
doKillData1     DB      " ¦ Parametrs error.",0
doKillData2     DB      " ¦ This task not loaded.",0
PROC            doKill
                lea     si,[doKillData0]
                call    write
                call    input
                lea     si,[null]
                call    writeln
                lea     si,[command]
                cmp     [Byte Ptr cs:si+1],0
                jne     doKill1
                mov     al,[Byte Ptr cs:si]
                cmp     al,'1'
                jl      doKill1
                cmp     al,'8'
                ja      doKill1
                sub     al,'1'
                xor     ah,ah
                push    ax
                lea     di,[tasks]
                mov     cx,515
                imul    cx
                add     di,ax
                mov     al,[cs:di]
                cmp     al,255
                pop     ax
                je      doKill2
                inc     al
                cmp     [cs:LastLineFlag],al
                jne     doKill3
                mov     [Byte Ptr cs:LastLineFlag],0
doKill3:        call    _di
                mov     al,255
                mov     [cs:di],al
                mov     dx,[cs:di+3]
                call    FreeMemory
                call    _ei
                ret
doKill1:        lea     si,[doKillData1]
                call    writeln
                ret
doKill2:        lea     si,[doKillData2]
                call    writeln
                ret
ENDP            doKill
; Вывод каталога #############################################################
doDirData1      DB "------",0
doDirData2      DB "   ",0
doDirEnd:       pop     bx
                ret
PROC            doDir
                xor     bx,bx
                push    bx
                call    ReadFAT
                mov     [Word Ptr RSSData],0
                call    FindFirst
                or      ax,ax
                jne     doDirEnd
                test    [Byte Ptr find_Attr],08h
                je      doDirFFileName
                pop     bx
                jmp     Dodirnext
doDirFFileName: call    doDirPrintFind
                pop     bx
                inc     bx
Dodirnext:      mov     dl,[cs:windowhx]
                dec     dl
                cmp     bl,dl
                jne     doDir1
                xor     ax,ax
                int     16h
                xor     bx,bx
doDir1:         push    bx
                call    FindNext
                or      ax,ax
                jne     doDirEnd
                test    [Byte Ptr find_Attr],08h
                je      doDirFileName
                pop     bx
                jmp     doDirNext
doDirFileName:  call    doDirPrintFind
                pop     bx
                inc     bx
                jmp     doDirNext
ENDP            doDir
; Вывод структуры find
PROC            doDirPrintFind
                ; Вывод имени файла с расширением
                lea     si,[find_FileName]
                mov     cx,8
                call    writeCX
                cmp     [Word Ptr find_Ext],2020h
                jne     doDirFileName1
                cmp     [Byte Ptr find_Ext+2],20h
                jne     doDirFileName1
                lea     si,[space]
                call    write
                lea     si,[space]
                call    write
                lea     si,[space]
                call    write
                lea     si,[space]
                call    write
                jmp     doDirSp1
doDirFileName1: lea     si,[Plot]
                call    write
                lea     si,[find_Ext]
                mov     cx,3
                call    writeCX
                ; Два пробела
doDirSp1:       lea     si,[space]
                call    write
                lea     si,[space]
                call    write
                ; Вывод размера
                test    [Byte Ptr find_Attr],10h
                je      doDirSize1
                lea     si,[doDirData2]
                call    write
                jmp     doDirSize2
doDirSize1:     mov     ax,[cs:find_SizeH]
                call    writeAX
                mov     ax,[cs:find_SizeL]
                call    writeAX
                ; Два пробела
doDirSize2:     lea     si,[space]
                call    write
                lea     si,[space]
                call    write
                ; Вывод время создания
                mov     ax,[find_Time]  
                push    ax              
                and     ax,0F800h       
                shr     ax,11           
                call    writeDEC2       
                lea     si,[dvoet]      
                call    write           
                pop     ax
                push    ax
                and     ax,07E0h        ;               (t & 001fH)
                shr     ax,5            ;        ((t & 07e0H) >> 5)
                call    writeDEC2       ;      ((t & 0f800H) >> 11)
                lea     si,[dvoet]
                call    write
                pop     ax
                and     ax,001Fh
                shl     ax,1
                call    writeDEC2
                ; Два пробела
                lea     si,[space]
                call    write
                lea     si,[space]
                call    write
                ; Вывод даты создания
                mov     ax,[find_Date] 
                push    ax             
                and     ax,001Fh       
                call    writeDEC2      
                lea     si,[plot]      
                call    write          
                pop     ax             
                push    ax
                and     ax,01E0h        ;           (d & 001fH)
                shr     ax,5            ;    ((d & 01e0H) >> 5)
                call    writeDEC2       ;    ((d & f800H) >> 9)
                lea     si,[plot]
                call    write
                pop     ax
                and     ax,0F800h
                shr     ax,9
                add     ax,1980
                call    writeDEC4
                ; Два пробела
                lea     si,[space]
                call    write
                lea     si,[space]
                call    write
                ; Вывод аттрибутов
                lea     si,[doDirData1]
                mov     [Word Ptr cs:si],2D2Dh
                mov     [Word Ptr cs:si+2],2D2Dh
                mov     [Byte Ptr cs:si+4],2Dh
                mov     al,[find_Attr]
                test    al,001h
                je      doDirAttr1
                mov     [cs:doDirData1+0],'R'
doDirAttr1:     test    al,002h
                je      doDirAttr2
                mov     [cs:doDirData1+1],'H'
doDirAttr2:     test    al,004h
                je      doDirAttr3
                mov     [cs:doDirData1+2],'S'
doDirAttr3:     test    al,008h
                je      doDirAttr4
                mov     [cs:doDirData1+3],'V'
doDirAttr4:     test    al,010h
                je      doDirAttr5
                mov     [cs:doDirData1+4],'D'
doDirAttr5:     test    al,020h
                je      doDirAttr6
                mov     [cs:doDirData1+5],'A'
doDirAttr6:
                lea     si,[doDirData1]
                call    write
                ; Перенос строки
                lea     si,[null]
                call    writeln
                ret
ENDP            doDirPrintFind
; Смена текущего каталога ####################################################
doCDData1       DB      "    Curent dir: ",0
doCDData2       DB      "New Curent dir: ",0
doCDData3       DB      " ¦ Specified directory not found.",0
doCDSubStr1     DB      "dir_name.ext",0
doCDFileName    DB      "dir_name"
doCDExt         DB      "ext"
doCDError       DW      0
; Внешний цикл - разбивает строку типа DIR1\DIR2\DIR3. И передает во
; внутренний параметры DIR1, DIR2, DIR3 и т.д.
PROC            doCD
                ; Вывод старого каталога
                lea     si,[doCDData1]
                call    write
                lea     si,[dos_CurDir]
                call    writeln
                lea     si,[doCDData2]
                call    write
                call    input
                call    ReadFAT
                mov     [Word Ptr RSSData],0
                lea     di,[command]
                push    di
                call    Upperstring
                pop     di
                mov     [Word Ptr cs:doCDError],0
                ; Если ввели '\', то меняем на корень
                mov     ax,[di]
                cmp     ax,005Ch
                jne     doCDnRoot
                mov     [Word Ptr cs:dos_CurDir+3],0
                lea     si,[null]
                call    writeln
                ret
                ; Разбиваем строку на подстроки
doCDnRoot:      lea     si,[command]
doCDnRoot0:     lea     di,[doCDSubStr1]
                xor     cx,cx
doCDnRoot2:     mov     al,[cs:si]
                or      al,al
                je      doCDnRoot3
                cmp     al,'\'
                jne     doCDnRoot1
doCDnRoot3:     mov     [Byte Ptr cs:di],0
                push    ax si
                call    doCDNormaliseName
                call    doCDInner
                pop     si ax
                inc     si
                or      al,al
                je      CDEnd
                jmp     doCDnRoot0
doCDnRoot1:     mov     [cs:di],al
                inc     si
                inc     di
                inc     cx
                cmp     cx,13
                jne     doCDnRoot2
                mov     [Word Ptr cs:doCDError],1
                jmp     doCDnRoot3
CDEnd:          mov     ax,[cs:doCDError]
                or      ax,ax
                je      CDEnd1
                lea     si,[null]
                call    writeln
                lea     si,[doCDData3]
                call    writeln
CDEnd1:         lea     si,[null]
                call    writeln
                push    cs
                pop     ds
                xor     ah,ah
                lea     di,[dos_CurDir]
                mov     ah,1                ; Задать строку статуса
                int     0FFh
                ret
ENDP            doCD
; Нормализация имени файла ###################################################
PROC            doCDNormaliseName
                push    si
                lea     di,[doCDFileName]
                mov     cx,11
                mov     ax,20h
                rep     stosb
                xor     cx,cx
                lea     di,[doCDSubStr1]
                lea     si,[doCDFileName]
                cmp     [Word Ptr cs:di],02E2Eh  ;  '..'
                je      doCDNUp
doCDN1:         mov     al,[di]
                or      al,al
                je      doCDNEnd
                cmp     al,'.'
                je      doCDNExt
                mov     [si],al
                inc     si
                inc     di
                inc     cx
                cmp     cx,9
                je      doCDNEnd1
                jmp     doCDN1
doCDNExt:       lea     si,[doCDExt]
                inc     di
                xor     cx,cx
doCDN2:         mov     al,[di]
                or      al,al
                je      doCDNEnd
                mov     [si],al
                inc     si
                inc     di
                inc     cx
                cmp     cx,4
                je      doCDNEnd1
                jmp     doCDN2
doCDNEnd1:      mov     [Word Ptr cs:doCDError],1
doCDNEnd:       pop     si
                ret
doCDNUp:        mov     [Word Ptr cs:si],02E2Eh   ; '..'
                pop     si
                ret
ENDP            doCDNormaliseName
; Внутренний цикл ############################################################
PROC            doCDInner
                call    FindFirst
                or      ax,ax
                jne     doCDInnerEnd
doCDInner0:     lea     di,[find_FileName]
                lea     si,[doCDFileName]
                mov     cx,11
doCDInner2:     mov     al,[di]
                cmp     al,[si]
                jne     doCDInner1
                inc     di
                inc     si
                loop    doCDInner2
                ; Найден каталог
                lea     si,[doCDFileName]
                cmp     [Word Ptr cs:si],02E2Eh     ; Если .. ,то на каталог
                                                    ; выше.
                je      doCDUp
                lea     si,[dos_CurDir]
                xor     cx,cx
doCDChange2:    cmp     [Byte Ptr cs:si],0
                je      doCDChange1
                inc     si
                inc     cx
                jmp     doCDChange2
doCDChange1:    lea     di,[doCDSubStr1]
doCDChange4:    mov     al,[cs:di]
                or      al,al
                je      doCDChange3
                mov     [cs:si],al
                inc     si
                inc     di
                inc     cx
                cmp     cx,128
                jne     doCDChange4
                mov     [Word Ptr cs:doCDError],1
                jmp     doCDChange5
doCDChange3:    mov     [Word Ptr cs:si],005Ch
doCDChange5:    ret
                ; На каталог выше
doCDUp:         lea     si,[dos_CurDir]
doCDUp0:        cmp     [Byte Ptr cs:si],0
                je      doCDUp1
                inc     si
                jmp     doCDUp0
doCDUp1:        dec     si
doCDUp2:        dec     si
                cmp     [Byte Ptr cs:si],':'
                je      doCDUp3
                cmp     [Byte Ptr cs:si],'\'
                jne     doCDUp2
                inc     si
                mov     [Byte Ptr cs:si],0
                ret
doCDUp3:        ;mov     [Word Ptr cs:doCDError],1
                ret
doCDInner1:     call    FindNext
                or      ax,ax
                jne     doCDInnerEnd
                jmp     doCDInner0
doCDInnerEnd:   mov     [Word Ptr cs:doCDError],1
                ret
ENDP            doCDInner
; Вывод текущего каталога ####################################################
PROC            doCDir
                lea     si,[dos_CurDir]
                jmp     WriteLn
ENDP            doCDir
; Приостановка задачи ########################################################
doStopData0     DB      "Enter task number (1-8): ",0
doStopData1     DB      " ¦ Parametrs error.",0
doStopData2     DB      " ¦ This task not loaded.",0
PROC            doStop
                lea     si,[doStopData0]
                call    write
                call    input
                lea     si,[null]
                call    writeln
                lea     si,[command]
                cmp     [Byte Ptr cs:si+1],0
                jne     doStop1
                mov     al,[Byte Ptr cs:si]
                cmp     al,'1'
                jl      doStop1
                cmp     al,'8'
                ja      doStop1
                sub     al,'1'
                xor     ah,ah
                push    ax
                lea     di,[tasks]
                mov     cx,515
                imul    cx
                add     di,ax
                mov     al,[cs:di]
                cmp     al,255
                pop     ax
                je      doStop2
                inc     al
                cmp     [cs:LastLineFlag],al
                jne     doStop3
                mov     [Byte Ptr cs:LastLineFlag],0
doStop3:        call    _di
                mov     al,254
                mov     [cs:di],al
                mov     dx,[cs:di+3]
                call    _ei
                ret
doStop1:        lea     si,[doStopData1]
                call    writeln
                ret
doStop2:        lea     si,[doStopData2]
                call    writeln
                ret
ENDP            doStop
; Перезапуск задачи ##########################################################
doReStartData0  DB      "Enter task number (1-8): ",0
doReStartData1  DB      " ¦ Parametrs error.",0
doReStartData2  DB      " ¦ This task not stoped.",0
PROC            doReStart
                lea     si,[doReStartData0]
                call    write
                call    input
                lea     si,[null]
                call    writeln
                lea     si,[command]
                cmp     [Byte Ptr cs:si+1],0
                jne     doReStart1
                mov     al,[Byte Ptr cs:si]
                cmp     al,'1'
                jl      doReStart1
                cmp     al,'8'
                ja      doReStart1
                sub     al,'1'
                xor     ah,ah
                lea     di,[tasks]
                mov     cx,515
                imul    cx
                add     di,ax
                cmp     [Byte PTr cs:di],254
                jne     doReStart2
                call    _di
                mov     al,1
                mov     [cs:di],al
                call    _ei
                ret
doReStart1:     lea     si,[doReStartData1]
                jmp     writeln
doReStart2:     lea     si,[doReStartData2]
                jmp     writeln
ENDP            doReStart
; Задать приоритет ###########################################################
doPrioritetD0   DB      "Enter task number (1-8): ",0
doPrioritetD1   DB      " ¦ Parametrs error.",0
doPrioritetD2   DB      " ¦ This task not loaded.",0
doPrioritetD3   DB      "Enter new prioritet (1-9): ",0
PROC            doSetPrioritet
                lea     si,[doPrioritetD0]
                call    write
                call    input
                lea     si,[null]
                call    writeln
                lea     si,[command]
                cmp     [Byte Ptr cs:si+1],0
                jne     doPrioritet1
                mov     al,[Byte Ptr cs:si]
                cmp     al,'1'
                jl      doPrioritet1
                cmp     al,'8'
                ja      doPrioritet1
                sub     al,'1'
                xor     ah,ah
                lea     di,[tasks]
                mov     cx,515
                imul    cx
                add     di,ax
                cmp     [Byte PTr cs:di],255
                je      doPrioritet2
                push    di
                lea     si,[doPrioritetD3]
                call    write
                call    input
                lea     si,[command]
                cmp     [Byte Ptr cs:si+1],0
                jne     doPrioritet1
                mov     al,[Byte Ptr cs:si]
                cmp     al,'1'
                jl      doPrioritet1
                cmp     al,'9'
                ja      doPrioritet1
                sub     al,'0'
                xor     ah,ah
                pop     di
                call    _di
                mov     [cs:di+11],ax
                mov     [cs:di+9],ax
                call    _ei
                lea     si,[null]
                jmp     writeln
doPrioritet1:   lea     si,[doPrioritetD1]
                jmp     writeln
doPrioritet2:   lea     si,[doPrioritetD2]
                jmp     writeln
ENDP            doSetPrioritet
; Запуск программы ###########################################################
doRunData1      DB      "Not yet implimented.",0
PROC            doRun
                lea     si,[doRunData1]
                call    WriteLn
                ret
ENDP            doRun

Оставить комментарий

Оставлять комментарии могут только зарегистрированные пользователи.

Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.

Комментарии

1. qwe123 / 23 ноября 2004, 20:39:27
Мне нравитсяМне не нравится

На первый взгляд все нормально, но это тока на первый!!!!!!!
Я нашел 5 ошибок после того как изучил код. И это тока за полчаса.
Вы учите ОС писать или очередное детище от мелко-мягких.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог