?login_element?

Subversion Repositories NedoOS

Rev

Rev 1778 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.         jp fastprchar
  58.  
  59.         ds 0x0018-$
  60. ;setpg4000=0x0018
  61.         ld bc,memport4000
  62.         out (c),a
  63.         ret
  64.  
  65.         ds 0x0020-$
  66. ;setpg8000=0x0020
  67.         ld bc,memport8000
  68.         out (c),a
  69.         ret
  70.  
  71.         ds 0x0028-$
  72. ;setpgc000=0x0028
  73.         ld bc,memportc000
  74.         out (c),a
  75.         ret
  76.  
  77. sys_timer
  78.         ds 4
  79.  
  80.         ds 0x0030+4-$
  81.         jp sys_farcall
  82.  
  83.         ds 0x0038-$
  84.         jp sys_sysint
  85.  
  86.         ds 0x0038+7-$ -3
  87. sys_intq
  88. ;bc=memport0000
  89. ;d=pgmain
  90. ;a=screenpg
  91.        di ;на время до включения нужной pg0000, чтобы не запороть чужой стек
  92.         out (0xfd),a ;дальше попадаем в init_resident
  93. ;выход в конец юзерского обработчика прерываний
  94.  
  95. ;вход из начала юзерского обработчика прерываний
  96.         ;ds 0x0038+14-$ -4
  97.         ;TODO захватить мьютекс (прерывание внутри прерывания должно попасть в простой обработчик без шедулера)
  98.         jp sys_intgo ;нужно, чтобы можно было ставить точку останова на 0x0100
  99.  
  100. fastprchar
  101. ;e=char
  102.         if bdosstack_sz==0
  103.         ld (sys_prchar_sp),sp
  104.         ld sp,BDOSSTACK ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00)
  105.         else
  106.         exx
  107.         ld hl,0
  108.         add hl,sp
  109.         ld iy,(appaddr)
  110.         ;ld (iy+app.callbdos_sp),l
  111.         ;ld (iy+app.callbdos_sp+1),h
  112.         ld bc,app.bdosstack+bdosstack_sz
  113.         add iy,bc
  114.         ld sp,iy ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00)
  115.         exx
  116.         endif
  117.        
  118.         ld iy,(appaddr)
  119.         call BDOS_prchar ;портит только 0xc000+, но сама восстанавливает pgkillable
  120.         if bdosstack_sz==0
  121. sys_prchar_sp=$+1
  122.         ld sp,0
  123.         else
  124.         exx
  125.         ;ld iy,(appaddr)
  126.         ;ld l,(iy+app.callbdos_sp)
  127.         ;ld h,(iy+app.callbdos_sp+1)
  128.         ld sp,hl
  129.         exx
  130.         endif
  131.         jp endsys_result_a
  132.  
  133.         ds 0x0100-$ ;stack for CP/M programs
  134.        
  135. safestack_sz=16 +2 ;на запарывание прерыванием
  136.         STRUCT app
  137. flags           BYTE ;флаги (всегда в начале структуры)
  138. ;priority        BYTE ;TODO приоритет (0=конец списка)
  139. id              BYTE ;номер задачи (0=свободно)
  140. parentid        BYTE ;номер родительской задачи
  141. mainpg          BYTE ;главная страница задачи (там userkernel)
  142. ;callbdos_sp     WORD ;сюда сохраняется стек при вызове BDOS
  143. ;curmsg          WORD ;TODO адрес текущего сообщения этой задаче
  144. ;endmsg          WORD ;TODO адрес конца очереди сообщений этой задаче
  145. ;sp              WORD ;текущий адрес стека (лежит в mainpg:intsp)
  146. ;next            WORD ;TODO указатель на следущую задачу (следующая за выполняемой внутри того же приоритета)
  147. stdin           BYTE
  148. stdout          BYTE
  149. stderr          BYTE ;TODO не нужен?
  150. lasttime        BYTE
  151. border          BYTE ;текущий цвет бордера 0..15
  152. screen          BYTE ;текущий номер экрана ;fd_user + 8*screen
  153. gfxmode         BYTE ;текущий видеорежим ;значение для 0xbd77
  154. gfxkeep         BYTE ;b7 = keep gfx pages
  155. scr0low         BYTE ;pages
  156. scr0high        BYTE ;pages
  157. scr1low         BYTE ;pages
  158. scr1high        BYTE ;pages
  159. childresult     WORD ;filled by closed child
  160. textcuraddr     WORD ;адрес курсора на экране
  161. curcolor        BYTE ;текущий атрибут при печати
  162. dta             WORD ;data transfer address
  163. vol             BYTE ;текущий драйв (volume)
  164. dircluster      DWORD ;текущая директория
  165. dir             BLOCK DIR_sz ;временный буфер для чтения каталога
  166. bdosstack       BLOCK bdosstack_sz ;стек при вызове BDOS
  167. pal             BLOCK 32
  168. ;safestack       BLOCK safestack_sz ;de,hl,af',af,ix,hl',de',bc',iy
  169.         ENDS
  170.  
  171.         display "apps start=",/h,$
  172. safestack
  173.         ds safestack_sz
  174. app1    app
  175. app_sz=$-safestack
  176.  
  177.         ds (MAXAPPS-1)*app_sz
  178.         display "MAXAPPS=",/h,MAXAPPS
  179.  
  180. app_afterlast=$+safestack_sz
  181. app_last=app_afterlast-app_sz
  182.         display "app1=",/h,app1
  183.         display "app_last=",/h,app_last
  184.  
  185. sys_intgo
  186.         ex de,hl
  187.         ld hl,0
  188.         add hl,sp
  189. appaddr=$+1
  190.         ld sp,app1 ;safestack_end
  191.         push hl ;"sp"
  192.         push de ;"hl"
  193.         push iy
  194.         exx
  195.         push bc
  196.         push de
  197.         push hl
  198.         push ix
  199.         ex af,af' ;'
  200.         push af
  201.  
  202.         ld bc,memport4000
  203.         ld a,pgtrdosfs;pagexor-5
  204.         out (c),a ;там INTSTACK
  205.         ld sp,INTSTACK2
  206.         call setgfxpal_focus
  207.         call on_int ;тикает таймер
  208.         call schedule ;out: iy=app
  209.         ld a,pgkillable
  210.         ld bc,memport4000
  211.         ld (sys_curpg4000),a ;не надо? (если di)
  212.         out (c),a
  213.  
  214. sys_int_popregs ;только для выхода из yield
  215. ;iy=app
  216.         ld de,-(safestack_sz-2) ;2 на запарывание прерыванием
  217.         add iy,de
  218.         ld sp,iy ;di!!!
  219.  
  220.         pop af
  221.         ex af,af' ;'
  222.         pop ix
  223.         pop hl
  224.         pop de
  225.         pop bc
  226.         exx
  227.         ld d,(iy+app.mainpg+safestack_sz-2) ;2 на запарывание прерыванием
  228.         ld iy,(focusappaddr)
  229.         ld a,(iy+app.screen)
  230.         pop iy
  231.         pop bc ;"hl"
  232.         pop hl ;"sp"
  233.         ld sp,hl
  234.         ld h,b
  235.         ld l,c
  236.         ld bc,memport0000
  237.         ;TODO освободить мьютекс, можно включить прерывания
  238.         jp sys_intq ;out (0xfd),a ;дальше попадаем в init_resident
  239.  
  240. schedule
  241. ;find next app, set iy
  242. ;out: iy=app, ix=(focusappaddr)
  243.         ld iy,(appaddr)
  244.         ld bc,-app_last;app_afterlast
  245.         ld de,app_last+app_sz;app_sz
  246.          ld a,(sys_timer) ;ok
  247.         ld l,MAXAPPS
  248. findnextapp0
  249.         add iy,bc
  250.         jr nc,$+6
  251.         ld iy,app1 -(app_last+app_sz)
  252.         add iy,de
  253.          cp (iy+app.lasttime)
  254.          jr z,findnextappskip
  255.          ;bit fyield,(iy)
  256.          ;jr nz,findnextappq
  257.         bit factive,(iy)
  258.         jr nz,findnextappq
  259. findnextappskip
  260.         dec l
  261.         jr nz,findnextapp0
  262. ;no active apps (или каждая в данном фрейме уже вызывалась)
  263.         ld iy,app1 ;idle
  264. findnextappq
  265. ;TODO при fwaitfocus пропускать app, если у него нет фокуса
  266. ;или пусть term (хозяин пайпа) получает factive только после появления чего-то в пайпе или при нажатии клавиши (когда он в фокусе)
  267.         ld (appaddr),iy
  268.          ld (iy+app.lasttime),a
  269.           ;ld iy,(appaddr)
  270.           ld a,(iy+app.mainpg)
  271.           ld bc,memport4000
  272.           ld (sys_curpg4000),a ;нужно (могут вызвать из yield - в любой момент)
  273.           out (c),a
  274.           ld ix,(focusappaddr)
  275.           ld a,(ix+app.screen)
  276.           or fd_system
  277.           ;ld (user_fdvalue1+0x4000),a ;for QUIT, мешает делать многозадачность с 0xffff: jp nn
  278.           ld (user_fdvalue2+0x4000),a
  279.           ld (user_fdvalue3+0x4000),a
  280.           ld (user_fdvalue4+0x4000),a
  281.           ;ld (user_fdvalue5+0x4000),a ;not supported yet
  282.           ld (user_fdvalue6+0x4000),a
  283.           ld a,pgtrdosfs
  284.           ;ld (sys_curpg4000),a ;нужно (могут вызвать из yield - в любой момент - но там не важно, там стек в нулях, а потом само ввключает pgkillable)
  285.           out (c),a ;там INTSTACK
  286.         ;ld iy,(appaddr)
  287.         ret
  288.  
  289. setgfxpal_focus
  290. ;если в yield не поставить палитру второй задаче, то она никогда не поставится, если первая задача в цикле делает yield
  291. ;потому что все прерывания будут ставить первую задачу
  292. ;если же палитру ставить в самом yield, то могут быть проблемы с выставлением палитры, если yield вызывать в случайных местах или если все задачи неактивны
  293. ;поэтому обработчик прерываний должен выставлять палитру и видеорежим задачи, которая в фокусе, независимо от её активности
  294. ;менять палитру только после смены фокуса или записи палитры
  295.                 display "setgfxpal_focus ",setgfxpal_focus
  296. palettechanged=$
  297.         or a
  298.         jp c,focusappborder
  299.         ld a,55 ;"scf"
  300.         ld (palettechanged),a
  301.        ifndef NOPAL
  302.         ld hl,(focusappaddr)
  303.         ld bc,app.pal+31 ;-app.gfxmode
  304.         add hl,bc
  305.         if 0;atm==1
  306.                 ld bc,0x07ff
  307.                 dup 8
  308.                 ld a,b
  309.                 out (0xf6),a
  310.                 outd
  311.                 dec hl
  312.                 edup
  313.                 ld b,0x07
  314.                 dup 7
  315.                 ld a,b
  316.                 out (0xfe),a
  317.                 outd
  318.                 dec hl
  319.                 edup
  320.                 ld a,b
  321.                 out (0xfe),a
  322.                 outd
  323.         else
  324.  
  325.         ld c,0xff
  326.         ld a,7
  327.         dup 8
  328.         OUT (0xF6),A
  329.         ld d,(hl)
  330.         dec hl
  331.         ld b,(hl) ;DDp palette low bits
  332.         OUT (c),d;(0xFF),A
  333.         dec hl
  334.         dec a
  335.         edup
  336.         ld a,7
  337.         dup 7
  338.         OUT (0xFE),A
  339.         ld d,(hl)
  340.         dec hl
  341.         ld b,(hl) ;DDp palette low bits
  342.         OUT (c),d;(0xFF),A
  343.         dec hl
  344.         dec a
  345.         edup
  346.         OUT (0xFE),A ;0
  347.         ld d,(hl)
  348.         dec hl
  349.         ld b,(hl) ;DDp palette low bits
  350.         OUT (c),d;(0xFF),A
  351.         endif
  352.        endif
  353. focusappborder
  354.          ld ix,(focusappaddr)
  355.        ifndef NOPAL
  356.          ld a,(ix+app.border)
  357.          cp 8
  358.          res 3,a ;tapeout sound
  359.          out (0xfe),a
  360.          ret c
  361.          out (0xf6),a
  362.        endif
  363.         ret
  364.  
  365. sys_sysint
  366. ;TODO schedule (для RTOS), но тогда надо реентерабельность всех процедур BDOS (даже без этого шедулинга они всё равно не должны иметь состояния!)
  367. ;как шедулить, когда мы в kernelspace???
  368. ;TODO проверка критической секции (в обычном прерывании не нужно)
  369.         ex de,hl
  370.         ex (sp),hl ;восстановили стек из de
  371.         ld (sys_sysint_jp),hl
  372.         ld (sys_sysint_sp),sp
  373.         ld sp,INTSTACK1
  374.         push af
  375.         push bc
  376.         push de ;"hl"
  377.         ;push hl
  378.         exx
  379.         ex af,af' ;'
  380.         push af
  381.         push bc
  382.         push de
  383.         push hl
  384.         push ix
  385.         push iy
  386.         ld sp,INTSTACK2
  387.  
  388.         ld bc,memport4000
  389.         ld a,pgtrdosfs;pagexor-5 ;там INTSTACK
  390.         out (c),a
  391.  
  392.         call setgfxpal_focus
  393.  
  394.         call on_int
  395. sys_curpg4000=$+1
  396.         ld a,pgkillable
  397.         ld bc,memport4000
  398.         out (c),a
  399.  
  400.         ld sp,INTSTACK1-18
  401.         pop iy
  402.         pop ix
  403.         pop hl
  404.         pop de
  405.         pop bc
  406.         pop af
  407.         ex af,af' ;'
  408.         exx
  409.         pop hl ;"hl"
  410.         ;pop de
  411.         pop bc
  412.         pop af
  413. sys_sysint_sp=$+1
  414.         ld sp,0
  415.         pop de
  416.         ei
  417.         ;ret
  418. sys_sysint_jp=$+1
  419.         jp 0
  420.        
  421. on_int
  422. ;в 0x4000 сейчас pgtrdosfs;5, там стек
  423. focusappaddr=$+1
  424.         ld hl,app1
  425.         ld bc,app.gfxmode
  426.         add hl,bc
  427.         ld e,(hl)
  428. ;sys_curgfxmode=$+1
  429.         ;ld e,%10101000 ;320x200 mode
  430.                 if atm==1
  431.                         ld bc,0xfadf ;buttons
  432.                         in a,(c)
  433.                         ld (sys_mousebuttons),a
  434.                         inc b ;ld bc,0xfbdf ;x
  435.                         in l,(c)
  436.                         ld b,0xff ;y
  437.                         in h,(c)
  438.                          ld bc,0xff77   ;shadow ports and palette off
  439.                          out (c),e
  440.                         in a,(0x1f)
  441.                         ld (sys_kempstonbuttons),a
  442.                          ld bc,0x01bf
  443.                          out (c),b
  444.                          ld bc,0xbd77   ;shadow ports and palette remain on
  445.                          out (c),e
  446.                          ld a,32 ;xor a ;D5=444 palette
  447.                          out (0xbf),a
  448.                 else
  449.                         push de ;e=gfxmode
  450.                         ifdef NOMOUSE
  451.                         ld hl,0
  452.                         ld de,0x0f00
  453.                         else
  454.                         call readmouse ;resident >=0x4000
  455.                         endif
  456.                         ld a,d
  457.                         ld (sys_mousebuttons),a
  458.                         ld a,e
  459.                         ld (sys_kempstonbuttons),a
  460.                         pop de ;e=gfxmode
  461.                 endif
  462.         ld (sys_mousecoords),hl
  463. sys_settime_do=$
  464.                 or a ;/scf=set time
  465. sys_settime_time=$+1
  466.                 ld bc,0
  467. sys_settime_date=$+1
  468.                 ld hl,0
  469.                 call c,writetime ;keep de for atm != 1
  470.                 ld a,55+128
  471.                 ld (sys_settime_do),a
  472.  
  473.                 if atm != 1
  474.                         ld a,(sys_timer) ;ok
  475.                         and 7
  476.                         jr nz,on_int_noreadtime
  477.                         ifdef NOCMOS
  478.                         else
  479.                         call readtime ;in: e=gfxmode, out: hl=date, de=time
  480.                         ld (sys_time_date),de
  481.                         ld (sys_time_date+2),hl
  482.                         endif
  483. on_int_noreadtime
  484.                 endif
  485.         ld hl,sys_timer
  486.         inc (hl)
  487.         inc hl
  488.         jr nz,on_int_timerq
  489.         inc (hl)
  490.         inc hl
  491.         jr nz,on_int_timerq
  492.         inc (hl)
  493.         inc hl
  494.         jr nz,on_int_timerq
  495.         inc (hl)
  496. on_int_timerq
  497.        
  498.                 if PS2KBD==0
  499.                         ld a,pgtrdosfs
  500.                         ld bc,memport4000
  501.                         out (c),a ;don't keep in sys_curpg4000!
  502.                         call KEYSCAN
  503.                 else
  504. KEYSCAN
  505. .rep_wait=$+1
  506.                         ld a,0
  507.                         dec a
  508.                         jp m,.end_keyscan
  509.                         ld (.rep_wait),a
  510. .end_keyscan                   
  511.                 endif
  512. ;TODO при наличии клавиши или события мышки поставить factive для задачи в фокусе
  513. ;пока что просто ставим factive для задачи в фокусе, если у неё есть fgfx (т.е. это не idle) - этого достаточно для ускорения игр
  514.         ld iy,(focusappaddr)
  515.         bit fgfx,(iy+app.flags)
  516.         jr z,keyscan_nosetactive
  517.         set factive,(iy+app.flags)
  518. keyscan_nosetactive
  519.  
  520.         ;call PEEKKEY ;ld a,(curkey)
  521.         ;cp ssEnter
  522.        
  523.         ld a,0x7f
  524.         in a,(0xfe)
  525.         rra
  526.         ld c,a ;c0=ss
  527.         ld a,0xbf
  528.         in a,(0xfe)
  529.         or c
  530.         cpl
  531.         ld c,a
  532.         cpl
  533.         ;a0=c0=0: ssEnter pressed
  534. on_int_oldssEnter=$+1
  535.         or 0 ;=0: ssEnter was released
  536.         rra
  537.         ld a,c
  538.         ld (on_int_oldssEnter),a
  539.         jr c,sys_int_noselectapp
  540.          call KEY_PUTREDRAW
  541.  
  542.        ld a,(sys_curpg8000)
  543.        push af
  544.        ld a,(sys_curpgc000)
  545.        push af
  546.  
  547.         if 1==1
  548.         ld iy,(focusappaddr)
  549.         ;di
  550.         call disablescrpgs_setc000 ;портит sys_curpg8000, sys_curpgc000
  551.         ;ei
  552.         ld bc,-app_last;app_afterlast
  553.         ld de,app_last+app_sz;app_sz
  554.         ld l,MAXAPPS
  555. findnextgfxapp0
  556.         add iy,bc
  557.         jr nc,$+6
  558.         ld iy,app1 -(app_last+app_sz)
  559.         add iy,de
  560.         ld a,(iy+app.flags)
  561.         bit fgfx,a
  562.         jr z,findnextgfxappskip
  563.          bit fwaiting,a
  564.          jr z,findnextgfxappq
  565. findnextgfxappskip
  566.         dec l
  567.         jr nz,findnextgfxapp0
  568. ;no active apps (или каждая в данном фрейме уже вызывалась)
  569.         ld iy,app1 ;idle
  570. findnextgfxappq
  571.         ld (focusappaddr),iy
  572.         call setpalettechanged
  573.  
  574.         else
  575.        
  576.         ld hl,(focusappaddr)
  577.         ;отключить страницы экрана этой задаче и выключить их в памяти задачи
  578.         push hl
  579.         pop iy
  580.         call disablescrpgs_setc000 ;портит sys_curpg8000, sys_curpgc000
  581.         ld bc,-app_last;app_afterlast
  582.         ld de,app_last+app_sz;app_sz
  583.         ld a,MAXAPPS
  584. findnextgfxapp0
  585.         ;add hl,de
  586.         ;sbc hl,bc
  587.         ;add hl,bc
  588.         ;jr nz,$+5
  589.         ;ld hl,app1
  590.         add hl,bc
  591.         jr nc,$+5 ;hl < app_last
  592.         ld hl,app1 -(app_last+app_sz)
  593.         add hl,de
  594.         bit fgfx,(hl)
  595.         jr z,findnextgfxappskip
  596.          bit fwaiting,(hl)
  597.          jr z,findnextgfxappq
  598. findnextgfxappskip
  599.         dec a
  600.         jr nz,findnextgfxapp0
  601.         ld hl,app1
  602. findnextgfxappq
  603.         ld (focusappaddr),hl
  604.         call setpalettechanged
  605.         ;включить страницы экрана этой задаче
  606.         ;push iy
  607.         push hl
  608.         pop iy
  609.         endif
  610.        
  611.         call enablescreeninapp_setc000 ;портит sys_curpg8000, sys_curpgc000
  612.        
  613.         ;pop iy
  614.  
  615.        pop af
  616.        ld (sys_curpgc000),a
  617.        pop af
  618.        ld (sys_curpg8000),a
  619.        
  620. sys_int_noselectapp
  621. muzpg=$+1
  622.         ld a,pgkillable
  623.         ld bc,memport4000
  624.         out (c),a
  625. muzpg8000=$+1
  626.          ld a,pgkillable
  627.          ld b,memport8000_hi
  628.          out (c),a
  629. muzpgc000=$+1
  630.          ld a,pgkillable
  631.          ld b,memportc000_hi
  632.          out (c),a
  633.  
  634.         ;jr $
  635.         ld sp,INTMUZSTACK
  636.  
  637.          ld e,pgsys
  638.         ld ix,(focusappaddr)
  639.         ld a,(ix+app.gfxmode)
  640. muzcall=$+1
  641.         call sys_reter;pt3player.PLAY ;TODO call drivers
  642.        
  643.         ld sp,INTSTACK2-2
  644.  
  645.         ld ix,(focusappaddr)
  646.         ld a,(ix+app.gfxmode)
  647.         ld bc,0xbd77
  648.         out (c),a ;set gfx mode
  649.        
  650.         ld a,pgtrdosfs;pagexor-5
  651.         ;ld a,(sys_curpg4000)
  652.         ld bc,memport4000
  653.         out (c),a ;там INTSTACK
  654. sys_curpg8000=$+1
  655.          ld a,pgkillable
  656.          ld b,memport8000_hi
  657.          out (c),a
  658. sys_curpgc000=$+1
  659.          ld a,pgkillable
  660.          ld b,memportc000_hi
  661.          out (c),a
  662.         ret
  663.  
  664. copypage_a_to_e
  665.         call sys_setpg8000
  666.         ld a,e
  667.         call sys_setpgc000
  668.         ld hl,0x8000
  669.         ld de,0xc000
  670.         ld bc,0x4000
  671.         ldir
  672.         ret
  673.  
  674. disablescrpgs_setc000
  675.         bit 7,(iy+app.gfxkeep)
  676.         jr z,disablescrpgs_nokeep
  677.         ld a,pgscr0_0
  678.         ld e,(iy+app.scr0low)
  679.         call copypage_a_to_e
  680.         ld a,pgscr0_1
  681.         ld e,(iy+app.scr0high)
  682.         call copypage_a_to_e
  683.         ld a,pgscr1_0
  684.         ld e,(iy+app.scr1low)
  685.         call copypage_a_to_e
  686.         ld a,pgscr1_1
  687.         ld e,(iy+app.scr1high)
  688.         call copypage_a_to_e
  689.         call setmainpg_c000
  690.         if 1==0
  691.         ds 6*4
  692.         else
  693.        display "===",$
  694.         ld a,(iy+app.scr0low)
  695.         ld (0xc000+user_scr0_low),a
  696.         ld a,(iy+app.scr0high)
  697.         ld (0xc000+user_scr0_high),a
  698.         ld a,(iy+app.scr1low)
  699.         ld (0xc000+user_scr1_low),a
  700.         ld a,(iy+app.scr1high)
  701.         ld (0xc000+user_scr1_high),a
  702.         endif
  703.         jr disablescrpgs_keepok
  704. disablescrpgs_nokeep
  705.         call setmainpg_c000
  706.         call disablescreeninapp ;set user_scr0_low etc to pgkillable
  707. disablescrpgs_keepok
  708.         ld de,curpg16k+0xc000
  709.         call disablescrpg
  710.         ld  e,0xff&(curpg32klow+0xc000)
  711.         call disablescrpg
  712.         ld  e,0xff&(curpg32khigh+0xc000)
  713.         ;call disablescrpg
  714. disablescrpg
  715. ;de=page keeping addr
  716.         ld a,(de)
  717.         ;or 7&(pgscr0_0|pgscr0_1|pgscr1_0|pgscr1_1)
  718.         ;cp pgscr0_0
  719.         ;ret nz;jr z,disablescrpg_ok
  720. ;disablescrpg_ok
  721.         ;ld a,pgkillable
  722.         ld c,(iy+app.scr0low)
  723.         cp pgscr0_0
  724.         jr z,disablescrpg_ok
  725.         ld c,(iy+app.scr0high)
  726.         cp pgscr0_1
  727.         jr z,disablescrpg_ok
  728.         ld c,(iy+app.scr1low)
  729.         cp pgscr1_0
  730.         jr z,disablescrpg_ok
  731.         ld c,(iy+app.scr1high)
  732.         cp pgscr1_1
  733.         ret nz;jr z,disablescrpg_ok
  734. disablescrpg_ok
  735.         ld a,c
  736.         ld (de),a
  737.         ret
  738. enablescrpg
  739. ;de=page keeping addr
  740.         ld a,(de)
  741.         cp (iy+app.scr0high) ;this order for pg5 games not switching pages
  742.         ld c,pgscr0_1
  743.         jr z,disablescrpg_ok
  744.         cp (iy+app.scr0low)
  745.         ld c,pgscr0_0
  746.         jr z,disablescrpg_ok
  747.         cp (iy+app.scr1high)
  748.         ld c,pgscr1_1
  749.         ret nz;jr z,enablescrpg_ok
  750.         cp (iy+app.scr1low)
  751.         ld c,pgscr1_0
  752.         jr z,disablescrpg_ok
  753. enablescrpg_ok
  754.         ld a,c
  755.         ld (de),a
  756.         ret
  757.  
  758. sys_getchar
  759. ;out:
  760. ;de=mouse yx, l=buttons, A=key, H=high bits of key, bc=keynolang, lx=joystick 0bP2JFUDLR, nz=no focus (mouse position=0, ignore it!)
  761.         ;call checkfocus_getkbdmouse
  762. ;checkfocus_getkbdmouse
  763. ;out: nz=fail
  764.         ld de,(focusappaddr)
  765.         ld hl,(appaddr)
  766.         xor a
  767.         sbc hl,de
  768.         jr nz,sys_getchar_fail ;nz
  769. ;sys_oldmousecoords=$+1
  770. ;        ld de,0
  771. ;        ld (sys_oldmousecoords),hl
  772. ;        ld a,l
  773. ;        sub e ;a=dx
  774. ;        ld e,a ;e=dx
  775. ;        ld a,d
  776. ;        sub h ;a=dy
  777. ;        ld d,a ;d=dy
  778.                 if PS2KBD==1
  779.                         display "ps2_sp ",$
  780.                         ld (ps2_sp),sp
  781.                         ld sp,BDOSSTACK ;это может затереть стек возврата! поэтому возвращаемся через jp
  782.                         call BDOS_setpgtrdosfs
  783.                         call GETKEY ;A=key, H=high bits of key, BC=keynolang
  784.                         ld e,a
  785.                         push bc ;ld (ps2_bc),bc
  786.                         ld a,pgkillable
  787.                         ld bc,memport4000
  788.                         ld (sys_curpg4000),a
  789.                         out (c),a
  790.                         pop bc
  791. ps2_sp=$+1
  792.                         ld sp,0
  793. ;ps2_bc=$+1
  794. ;                       ld bc,0
  795.                         ld a,e
  796.                 else
  797.                         call GETKEY ;A=key, H=high bits of key, BC=keynolang
  798.                 endif
  799.         cp a ;z
  800. sys_mousecoords=$+1
  801.         ld de,0;hl,0
  802. sys_mousebuttons=$+1
  803.         ld l,0xff
  804. sys_kempstonbuttons=$+2
  805.         ld lx,0
  806.         ;ret ;z
  807.         ;jp endsys_result_a
  808. endsys_result_a
  809.          ld iy,(focusappaddr)
  810.         ex af,af' ;'
  811.         ld a,(iy+app.screen)
  812.         ;ld iy,(appaddr)
  813.         jp endsys_result_aq
  814.  
  815. ;TODO брать номер экрана у задачи с фокусом и при шедулинге ставить этот номер в userkernel новой задачи
  816.        
  817. sys_getchar_fail
  818. ;a=0, nz
  819.         ;ld a,NOKEY ;no key
  820.          ;ld h,a
  821.          ;ld b,a
  822.          ld c,a ;no keynolang
  823.         ld d,a;0
  824.         ld e,a;0 ;no mouse movement
  825.          ld lx,a ;no joystick buttons
  826.         ld l,0xff ;no buttons
  827.         jr endsys_result_a ;ret ;nz ;jp endsys_result_a
  828.  
  829. callbdos
  830. ;при вызове bdos надо включить:
  831. ;0x0000 - syscode (уже включено)
  832. ;[0x4000 - pgfatfs или bdospg2]
  833. ;защита от одновременного доступа двум задачам
  834. ;занято a,bc,de,hl
  835. ;свободно iy
  836.         if bdosstack_sz==0
  837.  
  838.         ld (callbdos_sp),sp
  839.         ld sp,BDOSSTACK ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00) ;это может затереть стек возврата! поэтому возвращаемся через jp
  840.  
  841.         else
  842.        
  843.         exx
  844. callbdos_lock        
  845.         ld hl,callbdos_mutex ;изначально 0xc0
  846.         sla (hl)
  847.         jr z,callbdos_lock ;был занят
  848.        
  849.         ld hl,0
  850.         add hl,sp
  851.         ld iy,(appaddr)
  852.         ;ld (iy+app.callbdos_sp),l
  853.         ;ld (iy+app.callbdos_sp+1),h
  854.         ld bc,app.bdosstack+bdosstack_sz
  855.         add iy,bc
  856.         ld sp,iy ;до этого момента прерывание может запороть любое место памяти (user sp >=0x3b00)
  857.         push hl
  858.         exx
  859.        
  860.         endif
  861.        
  862.             ;ld iy,(focusappaddr)
  863.             ;ld a,(iy+app.screen)
  864.             ;xor 0x10 ;fd_user^fd_system
  865.             ;out (0xfd),a
  866.         ld iy,(appaddr)
  867.        if 1
  868.         ;push hl
  869.         ;ld l,c
  870.         ;ld h,tbdoscmds/256
  871.         ;ld a,(hl)
  872.         ;inc h
  873.         ;ld h,(hl)
  874.         ;ld l,a
  875.         ;ex (sp),hl
  876.         ;ret ;73t+call ;TODO jp (hl)..pop hl..jp NN ;58t, no call
  877.         push hl
  878.         ld l,c
  879.         ld h,tbdoscmds/256
  880.         ld a,(hl)
  881.         inc h
  882.         ld h,(hl)
  883.         ld l,a
  884.         ld ($+3+1+1),hl
  885.         pop hl ;70t+call
  886.         call 0
  887.        else
  888.         call BDOShandler
  889.        endif
  890.          push af
  891.          push bc
  892.          call setpgs_killable
  893.         if bdosstack_sz !=0
  894.         ld a,0xc0
  895.         ld (callbdos_mutex),a ;то же самое делают те функции BDOS, которые не собираются возвращаться
  896.         endif
  897.          pop bc
  898.          pop af
  899.          
  900.         if bdosstack_sz==0
  901. callbdos_sp=$+1
  902.         ld sp,0
  903.         else
  904.         exx
  905.         pop hl
  906.         ld iy,(appaddr)
  907.         ;ld l,(iy+app.callbdos_sp)
  908.         ;ld h,(iy+app.callbdos_sp+1)
  909.         ld sp,hl
  910.         exx
  911.         endif
  912.         jp endsys_result_a
  913.  
  914.        if 0
  915. BDOShandler
  916.         push hl
  917.         ld a,c
  918.         ld hl,tbdoscmds
  919.         push bc
  920.         ld bc,nbdoscmds
  921.         cpir
  922.         jp nz,BDOS_pop2fail
  923. ;bc=nbdoscmds-(cmdnumber+1) = 0..(nbdoscmds-1)
  924.         add hl,bc
  925. ;hl=tbdoscmds+nbdoscmds
  926.         add hl,bc
  927.         add hl,bc
  928. ;hl=tbdoscmds+nbdoscmds+ 2*(nbdoscmds-(cmdnumber+1))
  929.         pop bc
  930.         ld a,(hl)
  931.         inc hl
  932.         ld h,(hl)
  933.         ld l,a
  934.         ;hl=jump addr
  935.         ex (sp),hl
  936.         ret
  937.        endif
  938.  
  939. sys_quit
  940. ;снять текущую задачу
  941. ;hl=result
  942.         ld sp,QUITSTACK ;если не сделать, то всё ещё стек задачи, и мы не вернёмся из schedule
  943.         ld iy,(appaddr)
  944.         ld e,(iy+app.id)
  945.        if 1==0
  946.         push de
  947.         push iy
  948.         call BDOS_freezeapp
  949.         pop iy
  950. ;если установлен muzcall в пространстве задачи, снимаем его
  951.         ld a,(muzpg)
  952.         call addrpage
  953.         pop de
  954.         ld a,(hl)
  955.         cp e
  956.         jr nz,sys_quit_nomuzcall
  957.        ld hl,sys_reter
  958.        ld (muzcall),hl ;есть в delapppages тоже!!! TODO выбросить?
  959. sys_quit_nomuzcall
  960.         call BDOS_delapppages ;глушит сокеты и музыку, удаляет страницы
  961.        endif
  962. ;hl=result
  963.        call BDOS_dropapp ;будит родителя, глушит сокеты и музыку, удаляет страницы
  964.         jp BDOS_yield_q ;переходим на какую-нибудь задачу (там же ставим pgkillable в 4000,8000,c000)
  965.        
  966. setkernelpages_go
  967. ;di!!!
  968. ;sp=0x3ffx
  969. ;сейчас включена 5-я страница
  970.         BDOSSETPGTRDOSFS
  971.         call makeidle
  972. ;setkernelpages_go_iy
  973.         ;ld sp,BDOSSTACK
  974.         call setpgs_killable
  975.         ld sp,-8
  976.  
  977.         ;ld iy,(appaddr)
  978.         ld d,(iy+app.mainpg)
  979. ;d=pgmain
  980. ;[e=значение для аккумулятора]
  981.         ld bc,memport0000
  982.         ld a,(iy+app.screen)
  983.         jp sys_intq ;там ei
  984.  
  985.  
  986. sys_findfreeappstruct
  987. ;out: nz=error, iy=free struct
  988.         ld iy,app1
  989.         ld de,app_sz
  990.         ld b,MAXAPPS
  991.         xor a
  992. sys_findfreeappstruct0
  993.         cp (iy+app.id)
  994.         ret z ;iy = free app struct
  995.         add iy,de
  996.         djnz sys_findfreeappstruct0
  997. ;too many apps!!!
  998.         ret ;nz
  999.        
  1000. sys_findfreeid
  1001.         xor a
  1002. sys_findfreeid_next
  1003.         inc a ;a!=0 (0 и 0xff нельзя - см. BDOS_newpage)
  1004.         ld iy,app1
  1005.         ld de,app_sz
  1006.         ld b,MAXAPPS
  1007. sys_findfreeid0
  1008.         cp (iy+app.id)
  1009.         jr z,sys_findfreeid_next
  1010.         add iy,de
  1011.         djnz sys_findfreeid0
  1012. ;a=free id
  1013.         ret
  1014.  
  1015. f_clos_curdrv_pp
  1016. ;de=fil !=0
  1017.         push de
  1018.         call BDOS_setpgstructs
  1019.         inc de
  1020.         inc de
  1021.         inc de
  1022.         inc de
  1023.         inc de
  1024.         xor a
  1025.         ld (de),a
  1026.         pop de
  1027.         ld hl,ffsfunc.f_close
  1028.         jp call_ffs_curvol
  1029.                
  1030.                 if atm==1
  1031. NVRAM_REG=0xde
  1032. NVRAM_VAL=0xbe
  1033. readtime
  1034. ;sp=0x7fxx
  1035. ;e=gfxmode
  1036. ;out: hl=date, de=time
  1037. ;TODO атомарно
  1038.                 ld bc,0xf7 + (NVRAM_REG<<8)
  1039.                 ld a,0x0b
  1040.                 out (c),a
  1041.                 ld b,NVRAM_VAL
  1042.                 in a,(c)
  1043.                 or 0x04
  1044.                 out (c),a
  1045.                 xor a           ;sec
  1046.                 call bcd2bin
  1047.                 srl a
  1048.                 ld l,a
  1049.                
  1050.                 ld a,2          ;min
  1051.                 call bcd2bin
  1052.                 call minmes
  1053.                 add a,l
  1054.                 ld (sys_time_date),a    ;ld e,a
  1055.                 ld l,h
  1056.                
  1057.                 ld a,4          ;h
  1058.                 call bcd2bin
  1059.                 add a,a
  1060.                 add a,a
  1061.                 add a,a
  1062.                 add a,l
  1063.                 ld (sys_time_date+1),a  ;ld d,a
  1064.                
  1065.                 ld a,7          ;day
  1066.                 call bcd2bin
  1067.                 ld l,a
  1068.                
  1069.                 ld a,8          ;mes
  1070.                 call bcd2bin
  1071.                 call minmes
  1072.                 add a,l
  1073.                 ld (sys_time_date+2),a  ;ld l,a
  1074.                
  1075.                 ld a,9          ;god
  1076.                 call bcd2bin
  1077.                 add a,20
  1078.                 add a,a
  1079.                 add a,h
  1080.                 ld (sys_time_date+3),a  ;ld h,a
  1081.                 ret
  1082. minmes
  1083.                 ld h,a
  1084.                 xor a
  1085.                 srl h
  1086.                 rra
  1087.                 srl h
  1088.                 rra
  1089.                 srl h
  1090.                 rra
  1091.                 ret
  1092.  
  1093. bcd2bin
  1094.                 ld b,NVRAM_REG
  1095.                 out (c),a
  1096.                 ld b,NVRAM_VAL
  1097.                 in a,(c)
  1098.                 ret
  1099.  
  1100. writetime ;keep de only needed for atm != 1
  1101.          ld d,b
  1102.          ld e,c
  1103.         ld a,e
  1104.         add a,a
  1105.         and 63
  1106.         ld b,0          ;sec
  1107.         call bin2cmos
  1108.  
  1109.         ld a,d
  1110.         rra
  1111.         rra
  1112.         rra
  1113.         and 31 ;h
  1114.         ld b,4
  1115.         call bin2cmos
  1116.  
  1117.         ex de,hl
  1118.         add hl,hl
  1119.         add hl,hl
  1120.         add hl,hl
  1121.         ex de,hl
  1122.         ld a,d
  1123.         and 63 ;m
  1124.         ld b,2
  1125.         call bin2cmos
  1126.  
  1127.         ld a,h
  1128.         srl a
  1129.         sub 20
  1130.         ld b,9          ;year
  1131.         call bin2cmos
  1132.  
  1133.         ld a,l
  1134.         and 31
  1135.         ld b,7          ;day
  1136.         call bin2cmos
  1137.    
  1138.         add hl,hl
  1139.         add hl,hl
  1140.         add hl,hl
  1141.         ld a,h
  1142.         and 15
  1143.         ld b,8          ;month
  1144.         ;call bin2cmos
  1145.         ;ret
  1146. bin2cmos ;a to cmos cell b (BCD)
  1147.         push af
  1148.         ld a,b
  1149.         ld bc,0xf7 + (NVRAM_REG<<8)
  1150.         out (c),a
  1151.         pop af
  1152.         ld b,NVRAM_VAL
  1153.         out (c),a ;BCD
  1154.         ret
  1155.    
  1156.                 endif
  1157.  
  1158.  
  1159.                 if PS2KBD==1
  1160. KEY_PUTREDRAW
  1161.                 ld bc,0xdef7
  1162.                 out (c),c
  1163.                 ld b,0xbe
  1164.         ld a,2
  1165.         out (c),a
  1166.                 in a,(c)
  1167.                 jr z,.buf_empty
  1168.                 inc a
  1169.                 jr nz,KEY_PUTREDRAW
  1170.                 ld b,0xde               ;переполнено
  1171.                 ld a,0x0c               ;сбросить буфер
  1172.                 out (c),a
  1173.                 ld b,0xbe
  1174.                 ld a,1
  1175.                 out (c),a
  1176. .buf_empty             
  1177.                 xor a
  1178.                 ld (KEYSCAN.rep_wait),a
  1179.                 ld b,a
  1180.                 ld c,a
  1181.                 ld (.rep_key),bc
  1182.                 ld bc,key_redraw
  1183.                 ld (.redrawkey),bc
  1184.                 ret
  1185. .rep_key
  1186.                 defw 0x0000
  1187. .redrawkey
  1188.                 defw 0x0000
  1189.                 else
  1190.                         include "syskey1.asm"
  1191.                 endif
  1192.                
  1193.         ds 50  
  1194. INTSTACK1;!=0x3f00 ;kernelspace (для входа в обработчик без порчи стека) (не пересекается с возможным стеком задачи!!!)
  1195.  
  1196.         include "fatfsdrv.asm"
  1197.         include "sysbdos.asm" ;в конце есть align 256
  1198. syskrnl_end=$
  1199.         ent
  1200.