Subversion Repositories NedoOS

Rev

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

  1.         DEVICE ZXSPECTRUM128
  2.         include "../_sdk/sys_h.asm"
  3.  
  4. STDINBUF_SZ=256
  5. NETINBUF_SZ=256
  6.  
  7. STACK=0x4000
  8.  
  9. PORT=2323
  10.  
  11. SHUT_RDWR               EQU 2
  12. ERR_EAGAIN              EQU 35          ;/* Try again */
  13. ERR_EWOULDBLOCK EQU ERR_EAGAIN  ;/* Operation would block */
  14. ERR_INTR                EQU 4
  15. ERR_NFILE               EQU 23
  16. ERR_ALREADY     EQU 37
  17. ERR_NOTSOCK     EQU 38
  18. ERR_EMSGSIZE    EQU 40    ;/* Message too long */
  19. ERR_PROTOTYPE   EQU 41
  20. ERR_AFNOSUPPORT EQU 47
  21. ERR_HOSTUNREACH EQU 65
  22. ERR_ECONNABORTED EQU    53      ;/* Software caused connection abort */
  23. ERR_CONNRESET   EQU 54
  24. ERR_NOTCONN     EQU 57
  25.  
  26. ;************************* Протоколы соединений *************************
  27. SOCK_STREAM EQU 0x01            ;tcp/ip
  28. SOCK_ICMP       EQU 0x02                ;icmp
  29. SOCK_DGRAM      EQU 0x03                ;udp/ip
  30.  
  31. AF_INET EQU 2
  32.  
  33.         org PROGSTART
  34. begin
  35.         ld sp,STACK
  36.         OS_HIDEFROMPARENT
  37.         ;ld e,6 ;textmode
  38.         ;OS_SETGFX
  39.         OS_GETMAINPAGES ;dehl
  40.         push de
  41.         push hl
  42.         ld e,l
  43.         OS_DELPAGE
  44.         pop hl
  45.         ld e,h
  46.         OS_DELPAGE
  47.         pop de
  48.         OS_DELPAGE
  49.  
  50.         ld de,tpipename
  51.         push de
  52.         OS_OPENHANDLE
  53.         ld a,b
  54.         ld (stdinhandle),a
  55.         pop de
  56.         OS_OPENHANDLE
  57.         ld a,b
  58.         ld (stdouthandle),a
  59.  
  60.         OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
  61.         ld a,(stdinhandle)
  62.         ld e,a
  63.         ld a,(stdouthandle)
  64.         ld d,a
  65.         ld h,0xff ;rnd
  66. ;b=id, e=stdin, d=stdout, h=stderr        
  67.         OS_SETSTDINOUT
  68.  
  69. ;TODO запускать файл, указанный в параметре (по умолчанию cmd, искать в bin)
  70. ;TODO здесь не надо запускать CMD, запускать надо после коннекта клиента
  71.                 ld a,(waitpid_id)
  72.                 inc a
  73.                 jr z,nul_id
  74.                 ;TODO тут надо закрыть cmd
  75. nul_id
  76.         ld de,cmd_filename
  77.         OS_OPENHANDLE
  78.         or a
  79.         jr nz,execcmd_error
  80.        
  81.         call readapp ;делает CLOSE
  82.        
  83.         push af
  84.         ld b,a
  85.         ld a,(stdinhandle)
  86.         ld d,a
  87.         ld a,(stdouthandle)
  88.         ld e,a
  89.         ld h,0xff ;rnd
  90. ;b=id, e=stdin, d=stdout, h=stderr        
  91.         OS_SETSTDINOUT
  92.        
  93.         pop af ;id
  94.  
  95.         ld e,a ;id
  96.         ld (waitpid_id),a
  97.         OS_RUNAPP
  98.  
  99. execcmd_error
  100.         display $
  101. gotostart
  102.         ld sp,STACK
  103.         ld a,(soc)
  104.         or a
  105.         jr z,nul_soc
  106.         ld e,0
  107.         OS_NETSHUTDOWN
  108.         xor a
  109.         ld (soc),a
  110. nul_soc
  111.         ld a,(soc_client)
  112.         or a
  113.         jr z,nul_soc_client
  114.         ld e,0
  115.         OS_NETSHUTDOWN
  116.         xor a
  117.         ld (soc_client),a
  118. nul_soc_client
  119. ;1. s = OS_NETSOCKET
  120.         LD D,AF_INET
  121.         LD E,SOCK_STREAM
  122.         OS_NETSOCKET
  123.         BIT 7,L
  124.         JP NZ,inet_exiterr      ;обработка ошибки
  125.         LD A,L
  126.         ld (soc),a
  127. ;2. OS_BIND(s)
  128.         ld a,(soc)
  129.         LD DE,destination_host
  130.         OS_BIND
  131.         BIT 7,L
  132.         JP NZ,inet_exiterr
  133. ;3. OS_LISTEN(s)
  134.         ld a,(soc)
  135.         OS_LISTEN
  136.         bit 7,l
  137.         JP NZ,inet_exiterr
  138. ;4. s1 = OS_ACCEPT(s)
  139. ;5. если s1<0 гото 4
  140. WAIT_CLIENTS
  141.         LD A,(soc)
  142.         OS_ACCEPT
  143.         BIT 7,L
  144.         JR Z,ESTABLISHED
  145.         CP ERR_EAGAIN
  146.         JP NZ,inet_exiterr      ;обработка ошибки
  147.         YIELD   ;не обязательно. Если время реагирования на подключение не критично,
  148.                                 ;то отдадим квант времени системе.
  149.         JR WAIT_CLIENTS ;никто не подключился, ждём
  150. ESTABLISHED
  151.         LD A,L                          ;удачно
  152.         LD (soc_client),A       ;сохраняем дескриптор сокета.
  153. ;6. OS_NETSHUTDOWN(s)
  154. ;close_wait:
  155.         LD A,(soc)
  156.         LD E,0 ;0 - закрыть немедленно, 1 - закрыть только если буфер отправки пуст
  157.         OS_NETSHUTDOWN
  158.         xor a
  159.         ld (soc),a
  160.         ;BIT 7,L
  161.         ;jp z,close_ok       ;сокет закрылся
  162.         ;CP ERR_EAGAIN
  163.         ;JP NZ,inet_exiterr             ;обработка ошибки не связанной с ожиданием отправки.
  164.         ;YIELD          ;не обязательно. Если время не критично,
  165.                                         ;то отдадим квант времени системе.
  166.         ;JR close_wait ;ожидаем отправки данных
  167. close_ok
  168.         ;TODO тут надо запустить CMD
  169. ;7. если надо то OS_WIZNETWRITE(s1)
  170. ;8. hl = OS_WIZNETREAD(s1)          
  171. ;9. if hl > 0 then обработаем и goto 7
  172. ;10. if A == ERR_EAGAIN goto 7
  173. ;11. OS_NETSHUTDOWN(s1)
  174. ;12. goto 1
  175.  
  176. mainloop
  177.         YIELD
  178.         call checkquit
  179.        
  180.         call send_stdin ;stdin to internet client
  181.        
  182. mainloop_afterkey
  183.         call readsocket_key ;GET_KEY
  184.         or a ;cp NOKEY ;keylang==0?
  185.         ;jr nz,$+3
  186.         ;cp c ;keynolang==0?
  187.         jr z,mainloop
  188.        
  189.          ;push af
  190.          ;call prhex ;debug
  191.          ;pop af
  192.        
  193.          cp 240 ;telnet codes
  194.          jr nc,parsetelnetcodes
  195. will_do_flag=$
  196.         or a
  197.         jr c,will_do_off ;skip one byte
  198. subnegotiation_flag=$
  199.         or a
  200.         jr c,mainloop_afterkey
  201.         call sendchar
  202.         jr mainloop_afterkey
  203.  
  204. parsetelnetcodes
  205.          ;cp 240
  206.          jr z,subnegotiation_off
  207.          cp 250
  208.          jr z,subnegotiation_on
  209.          cp 251 ;do
  210.          jr z,will_do_on ;skip next byte
  211.          cp 253 ;will
  212.          jr z,will_do_on ;skip next byte
  213.          jr mainloop
  214.        
  215. will_do_off
  216. ;will_do_off_once_flag=$+1
  217. ;        ld a,2
  218. ;        dec a
  219. ;        jp z,will_do_off_once_skip
  220. ;        ld (will_do_off_once_flag),a
  221.         if 1==0
  222.         ld a,255
  223.         call term_prfsm_prchar
  224.         ld a,253 ;will
  225.         call term_prfsm_prchar
  226.         ld a,34 ;??? не воспринимается putty, пишет символ 34
  227.         call term_prfsm_prchar
  228.         endif
  229.        
  230.         ;ld a,255
  231.         ;call term_prfsm_prchar
  232.         ;ld a,251 ;do
  233.         ;call term_prfsm_prchar
  234.         ;ld a,0x2d ;??? не воспринимается putty, пишет символ 2d
  235.         ;call term_prfsm_prchar ;disable local echo
  236.        
  237.         if 1==0
  238.         ld a,255
  239.         call term_prfsm_prchar
  240.         ;ld a,254 ;don't
  241.         ld a,251 ;do
  242.         call term_prfsm_prchar
  243.         ld a,1 ;echo
  244.         call term_prfsm_prchar ;если делать IAC IAC_DO IAC_Echo, то клиент посылает кнопки только по ентеру, но процесс редактирования не отображает
  245.         endif
  246.  
  247.         if 1==0
  248.         ld a,255
  249.         call term_prfsm_prchar
  250.         ld a,254 ;don't
  251.         ;ld a,251 ;do
  252.         call term_prfsm_prchar
  253.         ld a,7 ;Remote Controlled Trans and Echo
  254.         call term_prfsm_prchar ;ни на что не влияет
  255.         endif
  256.        
  257.         if 1==0
  258.         ld a,255
  259.         call term_prfsm_prchar
  260.         ld a,250 ;Начало субопции
  261.         call term_prfsm_prchar
  262.         ld a,34
  263.         call term_prfsm_prchar
  264.         ld a,1
  265.         call term_prfsm_prchar
  266.         ld a,1;0
  267.         call term_prfsm_prchar
  268.         ld a,255
  269.         call term_prfsm_prchar
  270.         ld a,240 ;Завершение согласования параметров (конец субопции)
  271.         call term_prfsm_prchar ;disable local line editing
  272.         endif
  273.  
  274.         ld a,255
  275.         call term_prfsm_prchar
  276.         ld a,251
  277.         call term_prfsm_prchar
  278.         ld a,1
  279.         call term_prfsm_prchar
  280.  
  281.         ld a,255
  282.         call term_prfsm_prchar
  283.         ld a,251
  284.         call term_prfsm_prchar
  285.         ld a,3
  286.         call term_prfsm_prchar
  287. will_do_off_once_skip
  288.         ld a,55+128 ;or a
  289.         jr will_do_onoff
  290. will_do_on
  291.         ld a,55 ;scf
  292. will_do_onoff
  293.         ld (will_do_flag),a
  294.         jp mainloop_afterkey
  295.  
  296. subnegotiation_off      
  297.         ld a,55+128 ;or a
  298.         jr subnegotiation_onoff
  299. subnegotiation_on
  300.         ld a,55 ;scf
  301. subnegotiation_onoff
  302.         ld (subnegotiation_flag),a
  303.         jp mainloop_afterkey
  304.  
  305.  
  306. checkquit
  307. waitpid_id=$+1
  308.         ld e,0xff
  309.         OS_WAITPID
  310.         or a
  311.         ret nz ;jp z,quit
  312.         ;ret
  313.                 dec a
  314.                 ld (waitpid_id),a
  315. quit
  316. ;cmd closed!!!
  317.         LD A,(soc_client)
  318.         LD E,0 ;0 - закрыть немедленно, 1 - закрыть только если буфер отправки пуст
  319.         OS_NETSHUTDOWN
  320.  
  321.         dup 2 ;close twice - as stdin and as stdout! на случай, если клиент не закрыл у себя
  322.         ld a,(stdinhandle)
  323.         ld b,a
  324.         OS_CLOSEHANDLE
  325.         ld a,(stdouthandle)
  326.         ld b,a
  327.         OS_CLOSEHANDLE
  328.         edup
  329. inet_exiterr
  330.         jp gotostart
  331.  
  332.         QUIT
  333.  
  334.         if 1==0
  335. prhex
  336.         push af
  337.         ld a,'#'
  338.         PRCHAR
  339.         pop af
  340.         call prhexdigit
  341. prhexdigit
  342.         rrca
  343.         rrca
  344.         rrca
  345.         rrca
  346.         push af
  347.         or 0xf0
  348.         daa
  349.         add a,0xa0
  350.         adc a,0x40
  351.         PRCHAR
  352.         pop af
  353.         ret
  354.         endif
  355.  
  356. readsocket_key
  357. datain_size=$+1
  358.         ld hl,0
  359.         ld a,h
  360.         or l
  361.         jr z,WAIT_DATA
  362. datain_addr=$+1
  363.         ld hl,netinbuf
  364.         ld a,(hl)
  365.         inc hl
  366.         ld (datain_addr),hl
  367.         ld hl,(datain_size)
  368.         dec hl
  369.         ld (datain_size),hl
  370.         ret
  371. WAIT_DATA
  372. ;out:hl=datain_size
  373.         ld hl,netinbuf
  374.         ld (datain_addr),hl
  375. wait_data0
  376.         LD A,(soc_client)
  377.         LD DE,netinbuf
  378.         LD HL,NETINBUF_SZ
  379.         OS_WIZNETREAD
  380.         BIT 7,H
  381.         JR Z,RECEIVED   ;ошибок нет
  382.         CP ERR_EAGAIN
  383.         JP NZ,inet_exiterr      ;обработка ошибки
  384.         YIELD           ;не обязательно. Если время реагирования на пришедшие данные не критично,
  385.                                                 ;то отдадим квант времени системе.
  386.         call checkquit
  387.         call send_stdin
  388.         JR wait_data0   ;данных нет, ждём
  389. RECEIVED
  390.         ld (datain_size),HL     ;удачно. если требуется, то сохраняем количество принятых данных.
  391.         ;push hl
  392.         ;call term_print
  393.         ;pop hl
  394.         jr readsocket_key
  395.  
  396. sendchar
  397. ;to stdout
  398.         ;cp 0x80
  399.         ;jr nc,sendchar_rustoutf8
  400.         ;cp 0x08 ;backspace
  401.         ;cp 0x0d ;enter
  402. ;        ld c,a
  403. ;sendchar_byte
  404. ;        ld a,c
  405. sendchar_byte_a
  406.         ld (stdoutbuf),a
  407. sendchar_repeat
  408.         ld hl,1
  409.         ld de,stdoutbuf
  410. stdouthandle=$+1
  411.         ld b,0
  412.         OS_WRITEHANDLE
  413.         ld a,h
  414.         or l
  415.         ret nz
  416.         YIELDKEEP
  417.         call checkquit
  418.         jr sendchar_repeat
  419.  
  420. send_stdin
  421. ;stdin to internet client
  422.         ld de,stdinbuf
  423.         ld hl,STDINBUF_SZ
  424. stdinhandle=$+1
  425.         ld b,0
  426.         ;ld b,0xff
  427.         OS_READHANDLE
  428. ;hl=size
  429.         ld a,h
  430.         or l
  431.         ret z;jr z,mainloop_afterkey
  432.         ld de,stdinbuf
  433.         jr term_prfsm_prchars
  434.         if 1==0
  435.         ld b,h
  436.         ld c,l
  437.         ld hl,stdinbuf
  438. term_print0
  439.         push bc
  440.         push hl
  441.         ld a,(hl)
  442.         call term_prfsm_prchar ;to internet client
  443.         pop hl
  444.         pop bc
  445.         cpi
  446.         jp pe,term_print0
  447.         ret
  448.         endif
  449.  
  450. term_prfsm_prchar
  451. ;to internet client
  452. ;a=char
  453.         ld (netoutbuf),a        
  454. ;send_data_addr=$+1
  455.         LD DE,netoutbuf
  456. ;send_data_size=$+1
  457.         LD HL,1
  458. term_prfsm_prchars
  459. send_data0
  460.         push de
  461.         push hl
  462.         LD A,(soc_client)
  463.         OS_WIZNETWRITE
  464.         BIT 7,H
  465.         pop hl
  466.         pop de
  467.         JR Z,send_ok    ;ошибок нет
  468.         CP ERR_EMSGSIZE
  469.         JP NZ,inet_exiterr      ;обработка ошибки
  470.         push de
  471.         push hl
  472.         YIELD           ;не обязательно. Если время не критично,
  473.                                                 ;то отдадим квант времени системе.
  474.         call checkquit
  475.         pop hl
  476.         pop de
  477.         JR send_data0   ;буфер отправки переполнен, ждём освобождения
  478. send_ok
  479.         ;LD (DATA_SIZE),HL      ;удачно. если требуется, то сохраняем количество отправленных данных.
  480.         ;ld bc,(send_data_size)
  481.         ;or a
  482.         ;sbc hl,bc        
  483.         ret
  484.  
  485. readapp
  486.         ld a,b
  487.         ld (curhandle),a
  488.        
  489.         OS_NEWAPP ;для первой создаваемой задачи будут созданы первые два пайпа и подключены
  490. ;dehl=номера страниц в 0000,4000,8000,c000 нового приложения, b=id, a=error
  491.         push bc ;b=id
  492.  
  493.         ld a,d
  494.         SETPG32KHIGH
  495.         push de
  496.         push hl
  497.         ld hl,COMMANDLINE ;command line
  498.         call skipword
  499.         call skipspaces ;пропустили первое слово (там было term.com, а дальше, например, cmd.com autoexec.bat)
  500.         ld de,0xc080
  501.         ld bc,128  
  502.         ldir ;command line
  503.         pop hl
  504.         pop de
  505.  
  506.         call readfile_pages_dehl
  507.  
  508.         ld a,(curhandle)
  509.         ld b,a
  510.         OS_CLOSEHANDLE
  511.  
  512.         pop af ;id
  513.         ret
  514.  
  515. readfile_pages_dehl
  516.         ld a,d
  517.         SETPG32KHIGH
  518.         ld a,0xc100/256
  519.         call cmd_loadpage
  520.         or a
  521.         ret nz
  522.        
  523.         ld a,e
  524.         SETPG32KHIGH
  525.         ld a,0xc000/256
  526.         call cmd_loadpage
  527.         or a
  528.         ret nz
  529.        
  530.         ld a,h
  531.         SETPG32KHIGH
  532.         ld a,0xc000/256
  533.         call cmd_loadpage
  534.         or a
  535.         ret nz
  536.        
  537.         ld a,l
  538.         SETPG32KHIGH
  539.         ld a,0xc000/256
  540.  
  541. cmd_loadpage
  542. ;out: a=error
  543. ;keeps hl,de
  544.         push de
  545.         push hl
  546.         ld d,a
  547.         xor a
  548.         ld l,a
  549.         ld e,a
  550.         sub d
  551.         ld h,a ;de=buffer, hl=size
  552. curhandle=$+1
  553.         ld b,0
  554.         OS_READHANDLE
  555.         pop hl
  556.         pop de
  557.         ret
  558.  
  559. skipword
  560. ;hl=string
  561. ;out: hl=terminator/space addr
  562. skipword0
  563.         ld a,(hl)
  564.         or a
  565.         ret z
  566.         sub ' '
  567.         ret z
  568.         inc hl
  569.         jp skipword0
  570.  
  571. skipspaces
  572. ;hl=string
  573. ;out: hl=after last space
  574.         ld a,(hl)
  575.         cp ' '
  576.         ret nz
  577.         inc hl
  578.         jr skipspaces
  579.  
  580. cmd_filename
  581.         db "cmd.com",0
  582.  
  583. tpipename
  584.         db "z:",0
  585.  
  586. stdoutbuf
  587.         db 0
  588.  
  589. netoutbuf
  590.         db 0
  591.  
  592. stdinbuf
  593.         ds STDINBUF_SZ
  594.  
  595. netinbuf
  596.         ds NETINBUF_SZ
  597.  
  598. soc
  599.         db 0
  600. soc_client
  601.         db 0
  602.  
  603. ;struct sockaddr_in {unsigned char sin_family;unsigned short sin_port;
  604. ;       struct in_addr sin_addr;char sin_zero[8];};
  605. destination_host               
  606.         DEFB AF_INET
  607.         DEFB PORT/256,PORT&0xff ;port (big endian)
  608.         DEFB 0,0,0,0                    ;исходящий IP адрес (не используется в текущей реализации)
  609.         DEFB 0,0,0,0,0,0,0,0    ;резерв
  610.        
  611. end
  612.         savebin "netterm.com",begin,end-begin
  613.        
  614.         LABELSLIST "..\..\us\user.l"
  615.