?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;
  4. ctype:  defb    0       ;CALL type of current call operation (0/1/2/3)
  5. ;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7. ;
  8. var_ops:        ;VAR:0         1         2      3        4       5      6    7
  9.         defw    call_fv, zstorew, zstoreb,zpprop,  zread, prchar, prnum,z_rand
  10.         defw    zput,    zpull,   split_w, sel_w,call_fv, erase_w,erase_l,setcur
  11.         defw    getcpos, style,   sbfmde,  ostrm,  istrm, sfx,    rchr, scantbl
  12.         defw    znot,    call_pv, call_pv, ztok, zencode, cpytab, prtbl,ck_arg
  13. ;
  14. call_pv:
  15.         ld      a,1
  16.         jr      call_gen
  17. ;
  18. callfv2:
  19.         ld      b,8
  20.         ld      hl,v_arg1
  21. lp2:    ld      e,(hl)
  22.         inc     hl
  23.         ld      d,(hl)
  24.         inc     hl
  25.         inc     hl
  26.         inc     hl
  27.         djnz    lp2
  28.  
  29. call_fv:
  30.         xor     a
  31. call_gen:
  32.         ld      (ctype),a
  33.         ld      hl,(v_arg1)     ;Packed routine address
  34.  
  35.         ld      a,h
  36.         or      l               ;<< v0.04 Return false if HL = 0
  37.         jr      nz,call_g1
  38.         scf
  39.         jp      ret_hl
  40.  
  41. call_g1:                        ;>> v0.04
  42.  
  43.         call    upack_addr      ;Unpack it
  44.         call    ipeek
  45.         ld      b,a             ;B = no. of local variables
  46.         ld      a,(v_argc)
  47.         dec     a
  48.         ld      c,a             ;C = no. of parameters
  49.         cp      b               ;IF C <= B, ok
  50.         jr      c,cfv1
  51.         jr      z,cfv1
  52.         ld      c,b             ;Ignore surplus parameters
  53. cfv1:   push    hl
  54.         push    de              ;EHL -> start of routine
  55.         call    mkframe
  56.         jp      nc,spfail2
  57.         push    hl
  58.         pop     ix              ;IX -> new frame
  59.         ld      hl,(zpc)
  60.         ld      (ix+0),l
  61.         ld      (ix+1),h
  62.         ld      hl,(zpc+2)
  63.         ld      (ix+2),l
  64.         ld      (ix+3),h        ;Old ZPC into frame
  65.         ld      (ix+35),c       ;No. of parameters
  66.         ld      a,c
  67.         or      a
  68.         jr      z,noarg
  69.         push    ix
  70.         ld      hl,v_arg2
  71. arglp:  ld      a,(hl)          ;Args copied into frame
  72.         ld      (ix+4),a
  73.         inc     hl
  74.         inc     ix
  75.         ld      a,(hl)
  76.         ld      (ix+4),a
  77.         inc     ix
  78.         inc     hl
  79.         inc     hl
  80.         inc     hl
  81.         dec     c
  82.         jr      nz,arglp
  83.         pop     ix
  84. noarg:  ld      hl,(rsp)
  85.         ld      a,(ctype)
  86.         ld      (ix+34),a       ;Procedure, function or interrupt?
  87.         ld      (ix+36),l
  88.         ld      (ix+37),h       ;Routine stack pointer
  89.         pop     hl
  90.         ld      (zpc+2),hl
  91.         pop     hl              ;New ZPC
  92.         ld      (zpc),hl
  93.         ld      a,(zver)        ;<< v0.04 support for v3-style calls
  94.         cp      5               ;<< v1.10 v4 uses v3-style calls >>
  95.         ccf
  96.         ret     c               ;v1-v4: SET up the initial values of locals
  97.         ld      hl,(v_arg1)     ;Packed routine address
  98.         call    upack_addr      ;Unpack it
  99.         call    ipeek
  100.         or      a
  101.         scf
  102.         ret     z               ;No locals
  103.         ld      b,a             ;B = no. of local variables
  104.         ld      hl,(zsp)
  105.         ld      de,4
  106.         add     hl,de           ;HL->local vars
  107.         ld      a,(v_argc)      ;A = no. of parameters (which override the
  108.                                 ;initial values)
  109.         ld      d,a             ;D = no. of parameters
  110. argl:   push    bc
  111.         call    zpcipeek        ;Get default parameter into BC
  112.         ld      b,a
  113.         call    zpcipeek
  114.         ld      c,a
  115.         ld      a,d
  116.         dec     d
  117.         jr      z,argl1         ;Argument was provided. Skip.
  118.         inc     hl
  119.         inc     hl
  120.         jr      argl2
  121. ;
  122. argl1:  inc     d               ;To counterbalance the dec d above, so that
  123.         ld      (hl),c          ;the test works the next time round
  124.         inc     hl              ;Copy in the initial values, flipping them
  125.         ld      (hl),b          ;to little-endian as we go
  126.         inc     hl
  127. argl2:  pop     bc
  128.         djnz    argl
  129.         scf
  130.         ret                     ;>> v0.04
  131. ;
  132. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  133. ;
  134. ck_arg: ld      ix,(zsp)
  135.         ld      a,(v_arg1)      ;Argument number to check
  136.         cp      (ix+35)         ;No. of arguments
  137.         jp      z,branch
  138.         jp      c,branch        ;IF A <= no. of args, it is provided.
  139.         jp      nbranch         ;Not provided.
  140. ;
  141. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  142. ;
  143. ;PUSH and pop...
  144. ;
  145. zput:   ld      hl,(v_arg1)
  146.         call    zpush
  147.         scf
  148.         ret
  149. ;
  150. zpull:  call    zpop            ;HL = value
  151.         ld      a,(v_arg1)      ;A = variable number
  152.         scf
  153.         jp      put_var
  154. ;
  155. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  156. ;
  157. zstorew:
  158.         ld      hl,(v_arg1)
  159.         ld      de,(v_arg2)
  160.         add     hl,de
  161.         add     hl,de
  162.         ld      bc,(v_arg3)
  163.         ld      a,b
  164.         call    trap_poke       ; << v0.03 >> trap writes to location 11h
  165.         inc     hl
  166.         ld      a,c
  167.         jr      trap_poke       ; << v0.03 >> trap writes to location 11h
  168. ;
  169. zstoreb:
  170.         ld      hl,(v_arg1)
  171.         ld      de,(v_arg2)
  172.         add     hl,de
  173.         ld      a,(v_arg3)
  174. ;
  175. ;<< v0.03 IF there's a write to Flags 2 (at address 11h) then flush buffers
  176. ;
  177. trap_poke:
  178.         push    af
  179.         ld      a,h
  180.         or      a
  181.         jr      nz,trap1
  182.         ld      a,l
  183.         cp      11h
  184.         jr      nz,trap1
  185.         push    hl
  186.         call    flush_buf
  187.         call    ZXUSCR
  188.         pop     hl
  189. trap1:  pop     af
  190.         call    ZXPOKE
  191.         scf
  192.         ret
  193. ;
  194. ; >> v0.03
  195. ;
  196. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  197. ;
  198. zpprop: ld      de,(v_arg1)     ;DE = object no.
  199.         ld      a,d             ;<< v1.01
  200.         or      e
  201.         scf
  202.         ret     z               ;>> v1.01 Object 0 errors
  203.         ld      bc,(v_arg2)     ;C  = property no.
  204.         ld      hl,(v_arg3)     ;HL = value
  205.         jp      putprop
  206. ;
  207. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  208. ;
  209. ;Screen operations. These mostly map directly to ZXIO functions
  210. ;
  211. erase_w:
  212.         call    flush_buf
  213.         ld      a,(v_arg1)
  214.         jp      ZXERAW
  215. ;
  216. erase_l:
  217.         ld      a,(v_arg1)
  218.         dec     a
  219.         scf
  220.         ret     nz
  221.         call    flush_buf
  222.         jp      ZXERAL
  223. ;
  224. split_w:
  225.         call    flush_buf
  226.         ld      a,(v_arg1)
  227.         jp      ZXSWND
  228.  
  229. sel_w:  call    flush_buf
  230.         ld      a,(v_arg1)
  231.         xor     1
  232.         ld      (cwin),a
  233.         xor     1
  234.         jp      ZXUWND
  235. ;
  236. getcpos:
  237.         call    flush_buf
  238.         call    ZXGETX
  239.         push    hl
  240.         call    ZXGETY
  241.         ex      de,hl
  242.         pop     bc
  243.         ld      d,0     ;DE = Y
  244.         ld      b,0     ;BC = X
  245.         ld      hl,(v_arg1)
  246.         ld      a,b
  247.         call    ZXPOKE
  248.         inc     hl
  249.         ld      a,c
  250.         call    ZXPOKE
  251.         inc     hl
  252.         ld      a,d
  253.         call    ZXPOKE
  254.         inc     hl
  255.         ld      a,e
  256.         call    ZXPOKE
  257.         scf
  258.         ret
  259. ;
  260. style:  call    flush_buf
  261.         ld      a,(v_arg1)
  262.         jp      ZXSTYL
  263. ;
  264. setcur: call    flush_buf
  265.         ld      a,(v_arg1)
  266.         ld      b,a
  267.         ld      a,(v_arg2)
  268.         ld      c,a
  269.         jp      ZXSCUR
  270. ;
  271. prchar: ld      hl,(v_arg1)
  272.         call    ll_zchr
  273.         scf
  274.         ret
  275. ;
  276. sbfmde: ld      a,(v_arg1)      ;SET buffer mode
  277.         ld      (bufmde),a
  278.         or      a
  279.         call    z,flush_buf
  280.         scf
  281.         ret
  282. ;
  283. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  284. ;
  285. prnum:
  286.         ld      de,numbuf
  287.         ld      hl,(v_arg1)
  288.         bit     7,h     ;Negative?
  289.         jr      z,prnum1
  290.         ld      a,'-'
  291.         ld      (de),a
  292.         inc     de
  293.         call    neghl
  294. prnum1: call    spdec
  295.         ld      a,'$'
  296.         ld      (de),a
  297.         ld      de,numbuf
  298. opbuf:  ld      a,(de)
  299.         cp      '$'
  300.         scf
  301.         ret     z
  302.         ld      l,a
  303.         ld      h,0
  304.         push    de
  305.         call    ll_zchr
  306.         pop     de
  307.         inc     de
  308.         jr      opbuf
  309.  
  310. numbuf:
  311.         defb    '-00000$'
  312. ;
  313. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  314. ;
  315. ;Text entry interrupt...
  316. ;
  317. tr_a1:  defw    0
  318. tr_a2:  defw    0
  319. tr_a3:  defw    0
  320. tr_a4:  defw    0       ;Arguments
  321. ;
  322. timer:  defb    0       ;IN the timer already?
  323. ;
  324. rch_timer:
  325.         ld      c,3     ;Timer called from read_char
  326.         ld      de,(v_arg3)
  327.         ld      (tr_a3),de
  328.         ld      hl,(v_arg4)
  329.         ld      (tr_a4),hl
  330.         ld      a,(timer)
  331.         or      a
  332.         ret     nz
  333.         inc     a
  334.         ld      (timer),a
  335.         jr      rch_t1
  336. ;
  337. timer_int:
  338.         ld      c,2     ;Timer called from read_line
  339.         ld      a,(timer)
  340.         or      a
  341.         ret     nz
  342.         inc     a
  343.         ld      (timer),a
  344. ;
  345. ;DE = routine, HL = time
  346. ;
  347.         ld      (tr_a3),hl
  348.         ld      (tr_a4),de
  349. rch_t1: ld      hl,(v_arg1)
  350.         ld      (tr_a1),hl
  351.         ld      hl,(v_arg2)
  352.         ld      (tr_a2),hl
  353.         ld      (v_arg1),de     ;Routine address
  354.         ld      a,1
  355.         ld      (v_argc),a
  356.         pop     hl              ;Return address, we don't use this.
  357.         ld      a,c
  358.         jp      call_gen
  359. ;
  360. rchr_iret:
  361.         ld      hl,(tr_a1)
  362.         ld      (v_arg1),hl
  363.         ld      hl,(tr_a2)
  364.         ld      (v_arg2),hl
  365.         ld      hl,(tr_a3)
  366.         ld      (v_arg3),hl
  367.         ld      a,3
  368.         ld      (v_argc),a
  369.         ld      a,(timer)
  370.         dec     a
  371.         ld      (timer),a
  372.         ld      a,d
  373.         or      e
  374.         jp      z,rchr
  375.         ld      hl,0
  376.         scf
  377.         jp      ret_hl
  378. ;
  379. timer_iret:
  380.         ld      hl,(tr_a1)
  381.         ld      (v_arg1),hl
  382.         ld      hl,(tr_a2)
  383.         ld      (v_arg2),hl
  384.         ld      hl,(tr_a3)
  385.         ld      (v_arg3),hl
  386.         ld      hl,(tr_a4)
  387.         ld      (v_arg4),hl
  388.         ld      a,4
  389.         ld      (v_argc),a
  390.         ld      a,(timer)
  391.         dec     a
  392.         ld      (timer),a
  393.         ld      a,d
  394.         or      e
  395.         jr      nz,iterm
  396. ;
  397. ;The input routine wants the z-program to have printed its data for it again
  398. ;after a return from a timer interrupt...
  399. ;
  400.         ld      hl,(v_arg1)
  401.         inc     hl
  402.         call    peek64  ;Length of line
  403.         or      a
  404.         jr      z,zread
  405.         ld      b,a
  406.         ld      a,(zver)
  407.         cp      5
  408.         jr      nc,iplp1
  409. iplp4:  call    peek64  ;<< v1.10 reprint input line in the v4 model
  410.         or      a
  411.         jp      z,sreadt        ;Reprint the line
  412.         inc     hl
  413.         push    hl
  414.         push    bc
  415.         ld      l,a
  416.         ld      h,0
  417.         call    ll_zchr
  418.         pop     bc
  419.         pop     hl
  420.         jr      iplp4   ;>> v1.10 end reprint input line
  421.  
  422. iplp1:  inc     hl
  423.         call    peek64  ;Print it
  424.         push    hl
  425.         push    bc
  426.         ld      l,a
  427.         ld      h,0
  428.         call    ll_zchr
  429.         pop     bc
  430.         pop     hl
  431.         djnz    iplp1
  432.         jr      zread
  433. ;
  434. ;Terminate input at once...
  435. ;
  436. iterm:  ld      hl,(v_arg1)     ;Input buffer
  437.         call    peek64
  438.         ld      b,a             ;B = no. of bytes
  439.         inc     b               ;+1 for length
  440.         xor     a
  441. ztlp:   inc     hl
  442.         call    ZXPOKE          ;Zap the buffer
  443.         djnz    ztlp
  444.         jr      aread2
  445. ;
  446. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  447. ;
  448. ;Reading text
  449. ;
  450. zread:  ld      a,(zver)
  451.         cp      5
  452.         jr      c,sread
  453. aread:  ld      hl,(v_arg1)
  454.         ld      a,(v_argc)
  455.         ld      de,0
  456.         cp      3
  457.         jr      c,aread1
  458.         ld      de,(v_arg3)
  459. aread1: call    flush_buf
  460.         call    ZXINP   ;Input line
  461.         ld      a,b
  462.         or      a       ;Timeout
  463.         jr      nz,aread2
  464.         ld      hl,(v_arg3)     ;Timeout
  465.         ld      a,h
  466.         or      l
  467.         jr      z,aread2
  468.         ld      de,(v_arg4)
  469.         ld      a,d
  470.         or      e
  471.         call    nz,timer_int    ;This function only returns if unsuccessful.
  472. aread2:
  473.         ld      hl,(v_arg1)     ;<< v0.04 remove invalid characters
  474.         inc     hl              ;Length
  475.         call    ZXPK64          ;A = actual length
  476.         or      a
  477.         jr      z,areadw        ;No length?
  478.         ld      b,a
  479. areadv: inc     hl
  480.         call    ZXPK64          ;Character
  481.         call    valid_char
  482.         call    ZXPOKE
  483.         djnz    areadv          ;>> v0.04
  484. areadw: ld      hl,0dh
  485.         call    ll_zchr
  486.         ld      hl,(v_arg2)
  487.         ld      a,h
  488.         or      l
  489.         jr      z,nopse
  490. ;
  491. ;Tokenise?
  492. ;
  493.         push    bc
  494.         ld      bc,0
  495.         ld      a,c
  496.         ld      hl,(v_arg1)
  497.         ld      de,(v_arg2)
  498.         call    tokenise
  499.         pop     bc
  500.  
  501. nopse:  ld      l,b
  502.         ld      h,0
  503.         scf
  504.         jp      ret_hl
  505. ;
  506. ;<< v0.04 read for v3
  507. ;
  508. ;I'm going to do v3 input by converting the input format to v5-style before,
  509. ;and back afterwards. There's enough room, because the 1 byte for length
  510. ;matches the 1-byte terminator.
  511. ;
  512. sreadt: call    sstatus         ;<< v1.10 rewritten for timer events in v4
  513.         call    line_from_v5
  514.         ld      hl,(v_arg1)
  515.         jr      sreads
  516.  
  517. sread:  call    sstatus
  518.         ld      hl,(v_arg1)
  519.         inc     hl
  520.         xor     a
  521.         call    ZXPOKE          ;Write current length = 0 (no passed data)
  522.         dec     hl
  523. sreads: ld      de,0
  524.         ld      a,(zver)
  525.         cp      4
  526.         jr      c,sreadu
  527.         ld      a,(v_argc)
  528.         ld      de,0
  529.         cp      3
  530.         jr      c,sreadu
  531.         ld      de,(v_arg3)     ;>> v1.10
  532.  
  533. sreadu: call    flush_buf       ;
  534.         call    ZXINP           ;Input line
  535.  
  536.         push    bc              ;<< v1.10
  537.         call    line_to_v5
  538.         pop     bc              ;>> v1.10
  539.  
  540.         ld      a,b             ;<< v1.10 Handle timeouts in v4 input
  541.         or      a               ;Timeout
  542.         jr      nz,sreadr
  543.         ld      hl,(v_arg3)     ;Timeout
  544.         ld      a,h
  545.         or      l
  546.         jr      z,sreadr
  547.         ld      de,(v_arg4)
  548.         ld      a,d
  549.         or      e
  550.         call    nz,timer_int    ;This function only returns if unsuccessful.
  551.                                 ;>> v1.10
  552.  
  553. sreadr: ld      hl,0dh
  554.         call    ll_zchr
  555. ;
  556. ; << v1.10 >> v5 -> v4 line converter was here
  557. ;
  558. sread1: ld      hl,(v_arg2)
  559.         ld      a,h
  560.         or      l
  561.         scf
  562.         ret     z
  563. ;
  564. ;Tokenise?
  565. ;
  566.         push    bc
  567.         ld      bc,0
  568.         ld      a,c
  569.         ld      hl,(v_arg1)
  570.         ld      de,(v_arg2)
  571.         call    tokenise
  572.         pop     bc
  573.         scf
  574.         ret
  575. ;>> v0.04
  576. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  577. ;
  578. ;Read a character
  579. ;
  580. rchr:   ld      a,(v_argc)
  581.         cp      2
  582.         ld      de,0
  583.         jr      c,rchr1
  584.         ld      de,(v_arg2)
  585. rchr1:  call    flush_buf
  586.         call    ZXRCHR
  587.         or      a
  588.         call    z,rch_timer
  589.         call    valid_char
  590.         ld      l,a
  591.         ld      h,0
  592.         scf
  593.         jp      ret_hl
  594. ;
  595. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  596. ;
  597. ;Output and input streams
  598. ;
  599. ostrm:  ld      a,(v_arg1)
  600.         ld      hl,(v_arg2)
  601.         jp      ll_strm
  602. ;
  603. istrm:  ld      a,(v_arg1)
  604.         ld      hl,(v_arg2)
  605.         scf             ;Instruction has no effect
  606.         ret
  607. ;
  608. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  609. ;
  610. sfx:    ld      hl,(v_arg1)
  611.         ld      de,(v_arg2)
  612.         ld      bc,(v_arg3)
  613.         call    ZXSND
  614.         scf
  615.         ret
  616. ;
  617. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  618. ;
  619. z_rand: ld      hl,(v_arg1)
  620.         call    random
  621.         scf
  622.         jp      ret_hl
  623. ;
  624. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  625. ;
  626. znot:   ld      hl,(v_arg1)
  627.         ld      a,h
  628.         cpl
  629.         ld      h,a
  630.         ld      a,l
  631.         cpl
  632.         ld      l,a
  633.         scf
  634.         jp      ret_hl
  635. ;
  636. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  637. ;
  638. ;Tokenise & encode text
  639. ;
  640. ztok:   ld      a,(v_arg4)
  641.         ld      hl,(v_arg1)
  642.         ld      de,(v_arg2)
  643.         ld      bc,(v_arg3)
  644.         jp      tokenise
  645. ;
  646. zencode:
  647.         ld      hl,(v_arg1)     ;Text in
  648.         ld      de,(v_arg3)     ;offset
  649.         add     hl,de
  650.         ld      a,(v_arg2)
  651.         ld      b,a
  652.         call    encode
  653.         ld      a,(encptr)
  654.         ld      hl,(v_arg4)     ;Destination
  655.         ld      de,encbuf
  656. zenc1:  or      a
  657.         scf
  658.         ret     z
  659.         push    af              ;Transfer 3 Z-characters
  660.         ld      a,(de)
  661.         ld      b,a
  662.         call    ZXPOKE
  663.         inc     hl
  664.         inc     de
  665.         ld      a,(de)
  666.         ld      c,a
  667.         call    ZXPOKE
  668.         inc     hl
  669.         inc     de
  670.         pop     af
  671.         sub     3               ;3 characters moved
  672.         ret     c
  673.         jr      zenc1
  674. ;
  675. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  676. ;
  677. ;Scan table for byte or word pattern
  678. ;
  679. scantbl:
  680.         ld      a,(v_argc)
  681.         cp      4
  682.         ld      a,82h
  683.         jr      c,scant1
  684.         ld      a,(v_arg4)
  685. scant1: bit     7,a
  686.         jr      z,scanbyt
  687.         and     7Fh     ;<< v1.10: Only bits 0-7 are entry size >>
  688.         ld      e,a
  689.         ld      d,0     ;DE = step between table entries
  690.         ld      bc,(v_arg3)
  691.         ld      hl,(v_arg2)
  692. scanw1:
  693.         push    de
  694.         call    peek64
  695.         ld      d,a
  696.         inc     hl
  697.         call    peek64
  698.         ld      e,a     ;DE = word from table
  699.         dec     hl
  700.         push    hl
  701.         ld      hl,(v_arg1)
  702.         call    cphlde
  703.         pop     hl
  704.         pop     de
  705.         jr      z,tmatch
  706.         add     hl,de
  707.         dec     bc
  708.         ld      a,b
  709.         or      c
  710.         jr      nz,scanw1
  711.         jr      tnmatch
  712. ;
  713. scanbyt:
  714.         ld      e,a
  715.         ld      d,0             ;DE = step between table entries
  716.         ld      bc,(v_arg3)     ;Table length
  717.         ld      hl,(v_arg2)
  718. scanb1: push    de
  719.         call    peek64
  720.         ld      e,a
  721.         ld      a,(v_arg1)
  722.         cp      e       ;Byte to find
  723.         pop     de
  724.         jr      z,tmatch
  725.         add     hl,de
  726.         dec     bc
  727.         ld      a,b
  728.         or      c
  729.         jr      nz,scanb1
  730. tnmatch:
  731.         ld      hl,0
  732.         call    ret_hl
  733.         jp      nbranch
  734. ;
  735. tmatch: call    ret_hl
  736.         jp      branch
  737. ;
  738. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  739. ;
  740. ;Copy_table
  741. ;
  742. cpytab: ld      hl,(v_arg2)     ;Destination
  743.         ld      a,l
  744.         or      h
  745.         jr      z,zerotab
  746.         ld      de,(v_arg1)     ;Source
  747.         ld      bc,(v_arg3)     ;Count
  748.         bit     7,b
  749.         jr      nz,fwdcpy
  750. ;
  751. ;IF source < dest, use backward copy
  752. ;
  753.         call    cphlde
  754.         jr      c,fwdcpy
  755. bwdcpy: add     hl,bc
  756.         ex      de,hl
  757.         add     hl,bc
  758.         ex      de,hl
  759. bcpylp: dec     de
  760.         dec     hl
  761.         ex      de,hl
  762.         call    peek64
  763.         ex      de,hl
  764.         call    ZXPOKE
  765.         dec     bc
  766.         ld      a,b
  767.         or      c
  768.         jr      nz,bcpylp
  769.         scf
  770.         ret
  771. ;
  772. fwdcpy: call    absbc
  773. fcpylp: ex      de,hl
  774.         call    peek64  ;Read from source
  775.         ex      de,hl
  776.         call    ZXPOKE  ;Write to dest
  777.         inc     hl
  778.         inc     de
  779.         dec     bc
  780.         ld      a,b
  781.         or      c
  782.         jr      nz,fcpylp
  783.         scf
  784.         ret
  785. ;
  786. zerotab:
  787.         ld      hl,(v_arg1)
  788.         ld      bc,(v_arg3)     ;Size
  789.         call    absbc
  790. zerot1: xor     a
  791.         call    ZXPOKE
  792.         inc     hl
  793.         dec     bc
  794.         ld      a,b
  795.         or      c
  796.         jr      nz,zerot1
  797.         scf
  798.         ret
  799. ;
  800. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  801. ;
  802. prtbl:  call    flush_buf       ;<< v0.04 >> Ensure the screen is up to date
  803.  
  804.         ld      a,(v_argc)
  805.         cp      3
  806.         jr      nc,prtbl0       ;<< v0.04 >> IF there is 1 line, initialise
  807.         ld      a,1             ;            properly
  808.         ld      (v_arg3),a
  809. prtbl0: ld      hl,(v_arg3)     ;<< v1.04 deal with degenerate case
  810.         ld      a,h             ;        when height is 0
  811.         or      l
  812.         scf
  813.         ret     z               ;>> v1.04
  814.         call    ZXGETX
  815.         ld      e,l
  816.         call    ZXGETY
  817.         ld      d,l     ;D=Y E=X
  818.         ld      bc,(v_arg2)     ;<< v1.02 rewritten for lines
  819.         ld      hl,(v_arg1)     ;        longer than 256 chars
  820.         xor     a
  821.         ld      a,b             ;<< v1.04 deal with degenerate case
  822.         or      c               ;        when width is 0
  823.         scf
  824.         ret     z               ;>> v1.04
  825. prtbl1: call    doline
  826.         push    de
  827.         ld      de,(v_arg4)
  828.         add     hl,de
  829.         pop     de
  830.         inc     a
  831.         inc     d       ;Next line
  832.         push    hl
  833.         ld      hl,v_arg3
  834.         dec     (hl)
  835.         pop     hl
  836.         jr      nz,prtbl1       ;>> v1.02
  837.         scf
  838.         ret
  839. ;
  840. doline: push    de      ;<< v1.02 rewritten for lines >256 chars
  841.         push    bc
  842.         or      a       ;<< v0.04  Don't position the cursor if on 1st line
  843.         jr      z,doln1 ;>> v0.04
  844.         ld      b,d
  845.         ld      c,e
  846.         inc     b
  847.         inc     c       ;1-based
  848.         call    ZXSCUR
  849.         pop     bc
  850.         push    bc
  851. doln1:  push    bc
  852.         call    peek64  ;ZSCII character
  853.         push    hl
  854.         ld      l,a
  855.         ld      h,0
  856.         call    ll_zchr
  857.         pop     hl
  858.         inc     hl      ;HL = address of character to read
  859.         pop     bc
  860.         dec     bc
  861.         ld      a,b
  862.         or      c
  863.         jr      nz,doln1
  864.  
  865.         pop     bc
  866.         pop     de      ;>> v1.02
  867.         ret
  868. ;
  869. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  870. ;
  871. ; << v1.10: New line conversion functions
  872. ;
  873. ; Convert line from v3 format to v5.
  874. ;
  875. line_to_v5:
  876.         ld      hl,(v_arg1)     ;input buffer
  877.         inc     hl              ;Length
  878.         call    ZXPK64          ;A = actual length
  879.         or      a
  880.         ret     z               ;No input; the 0 becomes a terminating null
  881.         ld      b,a
  882. sreadv: inc     hl
  883.         call    ZXPK64          ;Character
  884.         call    valid_char      ;Ensure it's valid
  885.         dec     hl
  886.         call    ZXPOKE          ;Write it to previous slot
  887.         inc     hl
  888.         djnz    sreadv
  889. sreadw:
  890.         xor     a
  891.         jp      ZXPOKE          ;Terminating 0
  892. ;
  893. ; Convert line from v5 format to v3. Only used when recovering from a
  894. ; timeout.
  895. ;
  896. line_from_v5:
  897.         ld      hl,(v_arg1)
  898.         inc     hl
  899.         ld      bc,0            ;B = length, C = character being moved up
  900. lv501:  call    ZXPK64
  901.         or      a
  902.         jr      z,l5eol
  903.         ld      e,a             ;E = character just read
  904.         ld      a,c
  905.         call    ZXPOKE          ;Write character from previous slot
  906.         ld      c,e             ;C = next character to write back
  907.         inc     hl
  908.         inc     b
  909.         jr      lv501
  910. ;
  911. l5eol:  ld      a,c
  912.         call    ZXPOKE          ;Write back the last character
  913.         ld      hl,(v_arg1)
  914.         inc     hl
  915.         ld      a,b             ;A = count
  916.         jp      ZXPOKE
  917. ;
  918.