Subversion Repositories NedoOS

Rev

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