Subversion Repositories NedoOS

Rev

Rev 661 | Rev 746 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; KERNEL (system side) ;;;;;;;;;;;;;;;;;;;;;;;        
  2. ;при вызове 0x0005 в системе включены страницы: pgsystem, pgkillable, pgkillable, pgkillable (на случай порчи стеком)
  3.  
  4. MAXAPPS=16
  5. bdosstack_sz=0;150 ;80 мало для загрузки файла, 110 мало для fopen (даже с INTSTACK2), 140 мало для чтения каталога (даже с INTSTACK2) ;0=отключить мьютекс BDOS
  6.  
  7. QUITSTACK=0x4000 ;<=0x4000
  8.  
  9.         macro BDOSSETPGSSCR
  10.         call sys_setpgsscr
  11.         endm
  12.  
  13.         macro BDOSSETPGFATFS
  14.         call BDOS_setpgfatfs
  15.         endm
  16.  
  17.         macro BDOSSETPGTRDOSFS
  18.         call BDOS_setpgtrdosfs
  19.         endm
  20.  
  21.         macro BDOSSETPGW5300
  22.         call BDOS_setpgtrdosfs
  23.         endm
  24.  
  25.  
  26. fatfs.tabl=0x4000
  27.         include "fatfs_h.asm"
  28.        
  29. wassyscode
  30.         disp 0x0000
  31. syscode
  32. sys_time_date
  33.         ds 4
  34.  
  35.         ds 0x0000+4-$
  36.         jp sys_quit
  37.  
  38. sys_reter
  39.         ret
  40.  
  41. callbdos_mutex
  42.         db 0xc0
  43.         ds 0x0005+4-$
  44.         jp callbdos
  45.  
  46.         ds 0x0009+4-$
  47.         jp sys_getchar
  48.  
  49. sys_farcall
  50.         jp endsys_result_a
  51.  
  52.         ds 0x0015-2-$
  53. endsys_result_aq
  54.         out (0xfd),a
  55.         display "kernel_result_a=",$
  56.         ds 0x0010+5-$
  57. ;e=char
  58.         if bdosstack_sz==0
  59.         ld (sys_prchar_sp),sp
  60.         ld sp,BDOSSTACK ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00)
  61.         else
  62.         exx
  63.         ld hl,0
  64.         add hl,sp
  65.         ld iy,(appaddr)
  66.         ;ld (iy+app.callbdos_sp),l
  67.         ;ld (iy+app.callbdos_sp+1),h
  68.         ld bc,app.bdosstack+bdosstack_sz
  69.         add iy,bc
  70.         ld sp,iy ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00)
  71.         exx
  72.         endif
  73.        
  74.         ld iy,(appaddr)
  75.         call BDOS_prchar ;портит только 0xc000+, но сама восстанавливает pgkillable
  76.         if bdosstack_sz==0
  77. sys_prchar_sp=$+1
  78.         ld sp,0
  79.         else
  80.         exx
  81.         ;ld iy,(appaddr)
  82.         ;ld l,(iy+app.callbdos_sp)
  83.         ;ld h,(iy+app.callbdos_sp+1)
  84.         ld sp,hl
  85.         exx
  86.         endif
  87.         jp endsys_result_a
  88.  
  89. sys_timer
  90.         ds 4
  91.  
  92.         ds 0x0030+4-$
  93.         jp sys_farcall
  94.  
  95.         ds 0x0038-$
  96.         jp sys_sysint
  97.  
  98.         ds 0x0038+7-$ -2
  99. sys_intq
  100. ;[di]
  101. ;bc=memport0000
  102. ;d=pgmain
  103. ;[e=значение для аккумулятора]
  104. ;a=screenpg
  105. ;iy="iy"
  106.         ;ld sp,INTMICROSTACK
  107.         out (0xfd),a ;дальше попадаем в init_resident
  108. ;sp=INTMICROSTACK
  109. ;bc=memport0000
  110. ;d=pgmain
  111. ;[e=значение для аккумулятора]
  112. ;[di]
  113. ;выход в конец юзерского обработчика прерываний
  114.  
  115. ;вход из начала юзерского обработчика прерываний
  116.         ;ds 0x0038+14-$ -4
  117.         ;TODO захватить мьютекс (прерывание внутри прерывания должно попасть в простой обработчик без шедулера)
  118.         jp sys_intgo ;нужно, чтобы можно было ставить точку останова на 0x0100
  119.  
  120.         ds 0x0100-$ ;stack for CP/M programs
  121.        
  122. safestack_sz=16;18
  123.         STRUCT app
  124. flags           BYTE ;флаги (всегда в начале структуры)
  125. ;priority        BYTE ;TODO приоритет (0=конец списка)
  126. id              BYTE ;номер задачи (0=свободно)
  127. parentid        BYTE ;номер родительской задачи
  128. mainpg          BYTE ;главная страница задачи (там userkernel)
  129. ;callbdos_sp     WORD ;сюда сохраняется стек при вызове BDOS
  130. ;curmsg          WORD ;TODO адрес текущего сообщения этой задаче
  131. ;endmsg          WORD ;TODO адрес конца очереди сообщений этой задаче
  132. ;sp              WORD ;текущий адрес стека (лежит в mainpg:intsp)
  133. ;next            WORD ;TODO указатель на следущую задачу (следующая за выполняемой внутри того же приоритета)
  134. stdin           BYTE
  135. stdout          BYTE
  136. stderr          BYTE ;TODO не нужен?
  137. lasttime        BYTE
  138. border          BYTE ;текущий цвет бордера 0..15
  139. screen          BYTE ;текущий номер экрана ;fd_user + 8*screen
  140. gfxmode         BYTE ;текущий видеорежим ;значение для 0xbd77
  141. textcuraddr     WORD ;адрес курсора на экране
  142. curcolor        BYTE ;текущий атрибут при печати
  143. dta             WORD ;data transfer address
  144. vol             BYTE ;текущий драйв (volume)
  145. dircluster      DWORD ;текущая директория
  146. dir             BLOCK DIR_sz ;временный буфер для чтения каталога
  147. bdosstack       BLOCK bdosstack_sz ;стек при вызове BDOS
  148. pal             BLOCK 32
  149. ;safestack       BLOCK safestack_sz ;de,hl,af',af,ix,hl',de',bc',iy
  150.         ENDS
  151.  
  152.         display "apps start=",/h,$
  153. safestack
  154.         ds safestack_sz
  155. app1    app
  156. app_sz=$-safestack
  157.  
  158.         ds (MAXAPPS-1)*app_sz
  159.         display "MAXAPPS=",/h,MAXAPPS
  160.  
  161. app_afterlast=$+safestack_sz
  162. app_last=app_afterlast-app_sz
  163.         display "app1=",/h,app1
  164.         display "app_last=",/h,app_last
  165.  
  166. sys_intgo
  167.         ex de,hl
  168.         ld hl,0
  169.         add hl,sp
  170. appaddr=$+1
  171.         ld sp,app1 ;safestack_end
  172.         push hl ;"sp"
  173.         push de ;"hl"
  174.         push iy
  175.         exx
  176.         push bc
  177.         push de
  178.         push hl
  179.         push ix
  180.         ex af,af'
  181.        push af
  182.  
  183.        ld bc,memport4000
  184.        ld a,pgtrdosfs;pagexor-5
  185.        out (c),a ;там INTSTACK
  186.        ld sp,INTSTACK2
  187.        call setgfxpal_focus
  188.        call on_int ;тикает таймер
  189.        call schedule ;out: iy=app
  190.        ld a,pgkillable
  191.        ld bc,memport4000
  192.        ld (sys_curpg4000),a ;не надо? (если di)
  193.        out (c),a
  194.  
  195. sys_int_popregs ;только для выхода из yield
  196. ;iy=app
  197.        ld de,-safestack_sz
  198.        add iy,de
  199.        ld sp,iy ;di!!!
  200.  
  201.        pop af
  202.        ex af,af'
  203.         pop ix
  204.         pop hl
  205.         pop de
  206.         pop bc
  207.         exx
  208.         ld d,(iy+app.mainpg+safestack_sz)
  209.         ld iy,(focusappaddr)
  210.         ld a,(iy+app.screen)
  211.         pop iy
  212.         pop bc ;"hl"
  213.         pop hl ;"sp"
  214.         ld sp,hl
  215.         ld h,b
  216.         ld l,c
  217.         ld bc,memport0000
  218.         ;TODO освободить мьютекс, можно включить прерывания
  219.         jp sys_intq ;out (0xfd),a ;дальше попадаем в init_resident
  220.  
  221. schedule
  222. ;find next app, set iy
  223. ;out: iy=app, ix=(focusappaddr)
  224.         ld iy,(appaddr)
  225.         ld bc,-app_last;app_afterlast
  226.         ld de,app_last+app_sz;app_sz
  227.          ld a,(sys_timer) ;ok
  228.         ld l,MAXAPPS
  229. findnextapp0
  230.         add iy,bc
  231.         jr nc,$+6
  232.         ld iy,app1 -(app_last+app_sz)
  233.         add iy,de
  234.          cp (iy+app.lasttime)
  235.          jr z,findnextappskip
  236.          ;bit fyield,(iy)
  237.          ;jr nz,findnextappq
  238.         bit factive,(iy)
  239.         jr nz,findnextappq
  240. findnextappskip
  241.         dec l
  242.         jr nz,findnextapp0
  243. ;no active apps (или каждая в данном фрейме уже вызывалась)
  244.         ld iy,app1 ;idle
  245. findnextappq
  246.         ld (appaddr),iy
  247.          ld (iy+app.lasttime),a
  248.           ;ld iy,(appaddr)
  249.           ld a,(iy+app.mainpg)
  250.           ld bc,memport4000
  251.           ld (sys_curpg4000),a ;нужно (могут вызвать из yield - в любой момент)
  252.           out (c),a
  253.           ld ix,(focusappaddr)
  254.           ld a,(ix+app.screen)
  255.           or fd_system
  256.           ;ld (user_fdvalue1+0x4000),a ;for QUIT, мешает делать многозадачность с 0xffff: jp nn
  257.           ld (user_fdvalue2+0x4000),a
  258.           ld (user_fdvalue3+0x4000),a
  259.           ld (user_fdvalue4+0x4000),a
  260.           ;ld (user_fdvalue5+0x4000),a ;not supported yet
  261.           ld (user_fdvalue6+0x4000),a
  262.           ld a,pgtrdosfs
  263.           ;ld (sys_curpg4000),a ;нужно (могут вызвать из yield - в любой момент - но там не важно, там стек в нулях, а потом само ввключает pgkillable)
  264.           out (c),a ;там INTSTACK
  265.         ;ld iy,(appaddr)
  266.         ret
  267.  
  268. setgfxpal_focus
  269. ;если в yield не поставить палитру второй задаче, то она никогда не поставится, если первая задача в цикле делает yield
  270. ;потому что все прерывания будут ставить первую задачу
  271. ;если же палитру ставить в самом yield, то могут быть проблемы с выставлением палитры, если yield вызывать в случайных местах или если все задачи неактивны
  272. ;поэтому обработчик прерываний должен выставлять палитру и видеорежим задачи, которая в фокусе, независимо от её активности
  273. ;менять палитру только после смены фокуса или записи палитры
  274. palettechanged=$
  275.         or a
  276.         jp c,focusappborder
  277.         ld a,55 ;"scf"
  278.         ld (palettechanged),a
  279.  
  280.         ld hl,(focusappaddr)
  281.         ld bc,app.pal+31 ;-app.gfxmode
  282.         add hl,bc
  283.  
  284.         ld c,0xff
  285.         ld a,7
  286.         dup 8
  287.         OUT (0xF6),A
  288.         ld d,(hl)
  289.         dec hl
  290.         ld b,(hl) ;DDp palette low bits
  291.         OUT (c),d;(0xFF),A
  292.         dec hl
  293.         dec a
  294.         edup
  295.         ld a,7
  296.         dup 7
  297.         OUT (0xFE),A
  298.         ld d,(hl)
  299.         dec hl
  300.         ld b,(hl) ;DDp palette low bits
  301.         OUT (c),d;(0xFF),A
  302.         dec hl
  303.         dec a
  304.         edup
  305.         OUT (0xFE),A ;0
  306.         ld d,(hl)
  307.         dec hl
  308.         ld b,(hl) ;DDp palette low bits
  309.         OUT (c),d;(0xFF),A
  310. focusappborder
  311.          ld ix,(focusappaddr)
  312.          ld a,(ix+app.border)
  313.          cp 8
  314.          res 3,a ;tapeout sound
  315.          out (0xfe),a
  316.          ret c
  317.          out (0xf6),a
  318.         ret
  319.  
  320. sys_sysint
  321. ;TODO schedule (для RTOS), но тогда надо реентерабельность всех процедур BDOS (даже без этого шедулинга они всё равно не должны иметь состояния!)
  322. ;как шедулить, когда мы в kernelspace???
  323. ;TODO проверка критической секции (в обычном прерывании не нужно)
  324.         ex de,hl
  325.         ex (sp),hl ;восстановили стек из de
  326.         ld (sys_sysint_jp),hl
  327.         ld (sys_sysint_sp),sp
  328.         ld sp,INTSTACK1
  329.         push af
  330.         push bc
  331.         push de ;"hl"
  332.         ;push hl
  333.         exx
  334.         ex af,af'
  335.        push af
  336.        push bc
  337.        push de
  338.        push hl
  339.        push ix
  340.        push iy
  341.        ld sp,INTSTACK2
  342.  
  343.        ld bc,memport4000
  344.        ld a,pgtrdosfs;pagexor-5 ;там INTSTACK
  345.        out (c),a
  346.  
  347.        call setgfxpal_focus
  348.  
  349.        call on_int
  350. sys_curpg4000=$+1
  351.        ld a,pgkillable
  352.        ld bc,memport4000
  353.        out (c),a
  354.  
  355.        ld sp,INTSTACK1-18
  356.        pop iy
  357.        pop ix
  358.        pop hl
  359.        pop de
  360.        pop bc
  361.        pop af
  362.        ex af,af'
  363.         exx
  364.         pop hl ;"hl"
  365.         ;pop de
  366.         pop bc
  367.         pop af
  368. sys_sysint_sp=$+1
  369.         ld sp,0
  370.         pop de
  371.         ei
  372.         ;ret
  373. sys_sysint_jp=$+1
  374.         jp 0
  375.        
  376. on_int
  377. ;в 0x4000 сейчас pg5, там стек
  378. focusappaddr=$+1
  379.         ld hl,app1
  380.         ld bc,app.gfxmode
  381.         add hl,bc
  382.         ld e,(hl)
  383. ;sys_curgfxmode=$+1
  384.         ;ld e,%10101000 ;320x200 mode
  385.                 if atm==1
  386.                         ld bc,0xfadf ;buttons
  387.                         in d,(c)
  388.                         inc b ;ld bc,0xfbdf ;x
  389.                         in l,(c)
  390.                         ld b,0xff ;y
  391.                         in h,(c)
  392.                 else
  393.                         call readmouse ;resident >=0x4000
  394.                 endif
  395.         ld (sys_mousecoords),hl
  396.         ld a,d
  397.                 ld (sys_mousebuttons),a
  398.                 if atm != 1
  399.                         ld a,(sys_timer) ;ok
  400.                         and 7
  401.                         jr nz,on_int_noreadtime
  402.                         call readtime ;hl=date, de=time
  403.                         ld (sys_time_date),de
  404.                         ld (sys_time_date+2),hl
  405. on_int_noreadtime
  406.                 endif
  407.         ld hl,sys_timer
  408.         inc (hl)
  409.         inc hl
  410.         jr nz,on_int_timerq
  411.         inc (hl)
  412.         inc hl
  413.         jr nz,on_int_timerq
  414.         inc (hl)
  415.         inc hl
  416.         jr nz,on_int_timerq
  417.         inc (hl)
  418. on_int_timerq
  419.        
  420.                 if PS2KBD==0
  421.                         ld a,pgtrdosfs
  422.                         ld bc,memport4000
  423.                         out (c),a ;don't keep in sys_curpg4000!
  424.                         call KEYSCAN
  425.                 else
  426. KEYSCAN
  427. .rep_wait=$+1
  428.                         ld a,0
  429.                         dec a
  430.                         jp m,.end_keyscan
  431.                         ld (.rep_wait),a
  432. .end_keyscan                   
  433.                 endif
  434.  
  435.         ;call PEEKKEY ;ld a,(curkey)
  436.         ;cp ssEnter
  437.        
  438.         ld a,0x7f
  439.         in a,(0xfe)
  440.         rra
  441.         ld c,a ;c0=ss
  442.         ld a,0xbf
  443.         in a,(0xfe)
  444.         or c
  445.         cpl
  446.         ld c,a
  447.         cpl
  448.         ;a0=c0=0: ssEnter pressed
  449. on_int_oldssEnter=$+1
  450.         or 0 ;=0: ssEnter was released
  451.         rra
  452.         ld a,c
  453.         ld (on_int_oldssEnter),a
  454.         jr c,sys_int_noselectapp
  455.          call KEY_PUTREDRAW
  456.  
  457.         ld hl,(focusappaddr)
  458.         ;отключить страницы экрана этой задаче и выключить их в памяти задачи
  459.         push hl
  460.         pop iy
  461.         call disablescrpgs_setc000
  462.        
  463.         ld bc,-app_last;app_afterlast
  464.         ld de,app_last+app_sz;app_sz
  465.         ld a,MAXAPPS
  466. findnextgfxapp0
  467.         ;add hl,de
  468.         ;sbc hl,bc
  469.         ;add hl,bc
  470.         ;jr nz,$+5
  471.         ;ld hl,app1
  472.         add hl,bc
  473.         jr nc,$+5 ;hl < app_last
  474.         ld hl,app1 -(app_last+app_sz)
  475.         add hl,de
  476.         bit fgfx,(hl)
  477.         jr z,findnextgfxappskip
  478.          bit fwaiting,(hl)
  479.          jr z,findnextgfxappq
  480. findnextgfxappskip
  481.         dec a
  482.         jr nz,findnextgfxapp0
  483.         ld hl,app1
  484. findnextgfxappq
  485.         ld (focusappaddr),hl
  486.         call setpalettechanged
  487.         ;включить страницы экрана этой задаче
  488.         ;push iy
  489.         push hl
  490.         pop iy
  491.         call enablescreeninapp_setc000
  492.        
  493.         ;pop iy
  494.        
  495. sys_int_noselectapp
  496. muzpg=$+1
  497.         ld a,pgkillable
  498.         ld bc,memport4000
  499.         out (c),a
  500. muzpg8000=$+1
  501.          ld a,pgkillable
  502.          ld b,memport8000_hi
  503.          out (c),a
  504. muzpgc000=$+1
  505.          ld a,pgkillable
  506.          ld b,memportc000_hi
  507.          out (c),a
  508.  
  509.         ;jr $
  510.         ld sp,INTMUZSTACK
  511.  
  512.         ld ix,(focusappaddr)
  513.         ld a,(ix+app.gfxmode)
  514. muzcall=$+1
  515.         call sys_reter;pt3player.PLAY ;TODO call drivers
  516.        
  517.         ld sp,INTSTACK2-2
  518.  
  519.         ld ix,(focusappaddr)
  520.         ld a,(ix+app.gfxmode)
  521.         ld bc,0xbd77
  522.         out (c),a ;set gfx mode
  523.        
  524.         ld a,pgtrdosfs;pagexor-5
  525.         ld bc,memport4000
  526.         out (c),a ;там INTSTACK
  527. sys_curpg8000=$+1
  528.          ld a,pgkillable
  529.          ld b,memport8000_hi
  530.          out (c),a
  531. sys_curpgc000=$+1
  532.          ld a,pgkillable
  533.          ld b,memportc000_hi
  534.          out (c),a
  535.         ret
  536.        
  537. disablescrpgs_setc000
  538.         call disablescreeninapp_setc000
  539.         ld de,curpg16k+0xc000
  540.         call disablescrpg
  541.         ld  e,0xff&(curpg32klow+0xc000)
  542.         call disablescrpg
  543.         ld  e,0xff&(curpg32khigh+0xc000)
  544.         ;call disablescrpg
  545. disablescrpg
  546. ;de=page keeping addr
  547.         ld a,(de)
  548.         or 7&(pgscr0_0|pgscr0_1|pgscr1_0|pgscr1_1)
  549.         cp pgscr0_0
  550.         ret nz;jr z,disablescrpg_ok
  551. disablescrpg_ok        
  552.         ld a,pgkillable
  553.         ld (de),a
  554.         ret
  555.  
  556. sys_getchar
  557. ;out: de=mouse yx, l=buttons, A=key, H=high bits of key, nz=no focus (mouse position=0, ignore it!)
  558.         ;call checkfocus_getkbdmouse
  559. ;checkfocus_getkbdmouse
  560. ;out: nz=fail
  561.         ld de,(focusappaddr)
  562.         ld hl,(appaddr)
  563.         xor a
  564.         sbc hl,de
  565.         jr nz,sys_getchar_fail ;nz
  566. ;sys_oldmousecoords=$+1
  567. ;        ld de,0
  568. ;        ld (sys_oldmousecoords),hl
  569. ;        ld a,l
  570. ;        sub e ;a=dx
  571. ;        ld e,a ;e=dx
  572. ;        ld a,d
  573. ;        sub h ;a=dy
  574. ;        ld d,a ;d=dy
  575.                 if PS2KBD==1
  576.                         display "ps2_sp ",$
  577.                         ld (ps2_sp),sp
  578.                         ld sp,BDOSSTACK ;это может затереть стек возврата! поэтому возвращаемся через jp
  579.                         call BDOS_setpgtrdosfs
  580.                         call GETKEY ;A=key, H=high bits of key, BC=keynolang
  581.                         ld e,a
  582.                         push bc ;ld (ps2_bc),bc
  583.                         ld a,pgkillable
  584.                         ld bc,memport4000
  585.                         ld (sys_curpg4000),a
  586.                         out (c),a
  587.                         pop bc
  588. ps2_sp=$+1
  589.                         ld sp,0
  590. ;ps2_bc=$+1
  591. ;                       ld bc,0
  592.                         ld a,e
  593.                 else
  594.                         call GETKEY ;A=key, H=high bits of key, BC=keynolang
  595.                 endif
  596.         cp a ;z
  597. sys_mousecoords=$+1
  598.         ld de,0;hl,0
  599. sys_mousebuttons=$+1
  600.         ld l,0xff
  601.         ;ret ;z
  602.         ;jp endsys_result_a
  603. endsys_result_a
  604.          ld iy,(focusappaddr)
  605.         ex af,af'
  606.        ld a,(iy+app.screen)
  607.        ;ld iy,(appaddr)
  608.        jp endsys_result_aq
  609.  
  610. ;TODO брать номер экрана у задачи с фокусом и при шедулинге ставить этот номер в userkernel новой задачи
  611.        
  612. sys_getchar_fail
  613. ;a=0, nz
  614.        ;ld a,NOKEY ;no key
  615.         ;ld h,a
  616.         ;ld b,a
  617.         ld c,a ;no keynolang
  618.        ld d,a;0
  619.        ld e,a;0 ;no mouse movement
  620.        ld l,0xff ;no buttons
  621.        jr endsys_result_a ;ret ;nz ;jp endsys_result_a
  622.  
  623. callbdos
  624. ;при вызове bdos надо включить:
  625. ;0x0000 - syscode (уже включено)
  626. ;[0x4000 - pgfatfs или bdospg2]
  627. ;защита от одновременного доступа двум задачам
  628. ;занято a,bc,de,hl
  629. ;свободно iy
  630.        if bdosstack_sz==0
  631.  
  632.        ld (callbdos_sp),sp
  633.        ld sp,BDOSSTACK ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00) ;это может затереть стек возврата! поэтому возвращаемся через jp
  634.  
  635.        else
  636.        
  637.        exx
  638. callbdos_lock        
  639.        ld hl,callbdos_mutex ;изначально 0xc0
  640.        sla (hl)
  641.        jr z,callbdos_lock ;был занят
  642.        
  643.        ld hl,0
  644.        add hl,sp
  645.        ld iy,(appaddr)
  646.        ;ld (iy+app.callbdos_sp),l
  647.        ;ld (iy+app.callbdos_sp+1),h
  648.        ld bc,app.bdosstack+bdosstack_sz
  649.        add iy,bc
  650.        ld sp,iy ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00)
  651.        push hl
  652.        exx
  653.        
  654.        endif
  655.        
  656.            ;ld iy,(focusappaddr)
  657.            ;ld a,(iy+app.screen)
  658.            ;xor 0x10 ;fd_user^fd_system
  659.            ;out (0xfd),a
  660.        ld iy,(appaddr)
  661.        call BDOShandler
  662.         push af
  663.         push bc
  664.         call setpgs_killable
  665.        if bdosstack_sz !=0
  666.        ld a,0xc0
  667.        ld (callbdos_mutex),a ;то же самое делают те функции BDOS, которые не собираются возвращаться
  668.        endif
  669.         pop bc
  670.         pop af
  671.        
  672.        if bdosstack_sz==0
  673. callbdos_sp=$+1
  674.        ld sp,0
  675.        else
  676.        exx
  677.        pop hl
  678.        ld iy,(appaddr)
  679.        ;ld l,(iy+app.callbdos_sp)
  680.        ;ld h,(iy+app.callbdos_sp+1)
  681.        ld sp,hl
  682.        exx
  683.        endif
  684.        jp endsys_result_a
  685.  
  686. sys_quit
  687. ;снять текущую задачу
  688.        ld sp,QUITSTACK ;если не сделать, то всё ещё стек задачи, и мы не вернёмся из schedule
  689.        ld iy,(appaddr)
  690.        ld e,(iy+app.id)
  691.        push de
  692.        push iy
  693.        call BDOS_freezeapp
  694.        pop iy
  695. ;если установлен muzcall в пространстве задачи, снимаем его
  696.        ld a,(muzpg)
  697.        call addrpage
  698.        pop de
  699.        ld a,(hl)
  700.        cp e
  701.        jr nz,sys_quit_nomuzcall
  702.       ld hl,sys_reter
  703.       ld (muzcall),hl ;есть в delapppages тоже!!! TODO выбросить?
  704. sys_quit_nomuzcall
  705.        call BDOS_delapppages
  706.        jp BDOS_yield_q ;переходим на какую-нибудь задачу
  707.        
  708. setkernelpages_go
  709. ;di!!!
  710. ;sp=0x3ffx
  711. ;сейчас включена 5-я страница
  712.        BDOSSETPGTRDOSFS
  713.        call makeidle
  714. ;setkernelpages_go_iy
  715.        ;ld sp,BDOSSTACK
  716.        call setpgs_killable
  717.        ld sp,-8
  718.  
  719.        ;ld iy,(appaddr)
  720.        ld d,(iy+app.mainpg)
  721. ;d=pgmain
  722. ;[e=значение для аккумулятора]
  723.        ld bc,memport0000
  724.        ld a,(iy+app.screen)
  725.        jp sys_intq ;там ei
  726.  
  727.  
  728. sys_findfreeappstruct
  729. ;out: nz=error, iy=free struct
  730.        ld iy,app1
  731.        ld de,app_sz
  732.        ld b,MAXAPPS
  733.        xor a
  734. sys_findfreeappstruct0
  735.        cp (iy+app.id)
  736.        ret z ;iy = free app struct
  737.        add iy,de
  738.        djnz sys_findfreeappstruct0
  739. ;too many apps!!!
  740.        ret ;nz
  741.        
  742. sys_findfreeid
  743.        xor a
  744. sys_findfreeid_next
  745.        inc a ;a!=0 (0 и 0xff нельзя - см. BDOS_newpage)
  746.        ld iy,app1
  747.        ld de,app_sz
  748.        ld b,MAXAPPS
  749. sys_findfreeid0
  750.        cp (iy+app.id)
  751.        jr z,sys_findfreeid_next
  752.        add iy,de
  753.        djnz sys_findfreeid0
  754. ;a=free id
  755.        ret
  756.                
  757.                 if atm==1
  758. NVRAM_REG=0xde
  759. NVRAM_VAL=0xbe
  760. readtime
  761. ;sp=0x7fxx
  762. ;e=gfxmode
  763. ;out: hl=date, de=time
  764. ;TODO атомарно
  765.                 ld bc,0xf7 + (NVRAM_REG<<8)
  766.                 ld a,0x0b
  767.                 out (c),a
  768.                 ld b,NVRAM_VAL
  769.                 in a,(c)
  770.                 or 0x04
  771.                 out (c),a
  772.                 xor a           ;sec
  773.                 call bcd2bin
  774.                 srl a
  775.                 ld l,a
  776.                
  777.                 ld a,2          ;min
  778.                 call bcd2bin
  779.                 call minmes
  780.                 add a,l
  781.                 ld (sys_time_date),a    ;ld e,a
  782.                 ld l,h
  783.                
  784.                 ld a,4          ;h
  785.                 call bcd2bin
  786.                 add a,a
  787.                 add a,a
  788.                 add a,a
  789.                 add a,l
  790.                 ld (sys_time_date+1),a  ;ld d,a
  791.                
  792.                 ld a,7          ;day
  793.                 call bcd2bin
  794.                 ld l,a
  795.                
  796.                 ld a,8          ;mes
  797.                 call bcd2bin
  798.                 call minmes
  799.                 add a,l
  800.                 ld (sys_time_date+2),a  ;ld l,a
  801.                
  802.                 ld a,9          ;god
  803.                 call bcd2bin
  804.                 add a,20
  805.                 add a,a
  806.                 add a,h
  807.                 ld (sys_time_date+3),a  ;ld h,a
  808.                 ret
  809. minmes
  810.                 ld h,a
  811.                 xor a
  812.                 srl h
  813.                 rra
  814.                 srl h
  815.                 rra
  816.                 srl h
  817.                 rra
  818.                 ret
  819.  
  820. bcd2bin
  821.                 ld b,NVRAM_REG
  822.                 out (c),a
  823.                 ld b,NVRAM_VAL
  824.                 in a,(c)
  825.                 ret
  826.    
  827.                 endif
  828.  
  829.  
  830.                 if PS2KBD==1
  831. KEY_PUTREDRAW
  832.                 ld bc,0xdef7
  833.                 out (c),c
  834.                 ld b,0xbe
  835.                 in a,(c)
  836.                 jr nz,KEY_PUTREDRAW
  837.                 xor a
  838.                 ld (KEYSCAN.rep_wait),a
  839.                 ld b,a
  840.                 ld c,a
  841.                 ld (.rep_key),bc
  842.                 ld bc,key_redraw
  843.                 ld (.redrawkey),bc
  844.                 ret
  845. .rep_key
  846.                 defw 0x0000
  847. .redrawkey
  848.                 defw 0x0000
  849.                 else
  850.                         include "syskey1.asm"
  851.                 endif
  852.        
  853.        include "fatfsdrv.asm"
  854.        include "sysbdos.asm" ;в конце есть align 256
  855.        ent
  856. syscodesz=$-wassyscode
  857.        display "syscodesz=",/h,syscodesz," < minstack=",/h,SYSMINSTACK
  858.