home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / A / 28MAY87R.ARK / CXROM80.ASM < prev    next >
Assembly Source File  |  1989-09-27  |  28KB  |  1,679 lines

  1.  
  2. ;        13 May 85
  3.  
  4. ;**
  5. ;**        80 COLUMN FUNCTION CODE
  6. ;**
  7.  
  8. fixed$8563    equ    false
  9.  
  10. ;*
  11. ;*    Write character in D to current cursor address
  12. ;*    Advance cursor next position
  13. ;*
  14. wr$char$80:
  15.     lhld    char$adr
  16.     call    write$char$80
  17.     lda    char$col    ; get cursor column number
  18.     cpi    80-1
  19.     jrz    do$crlf
  20.     inr    a
  21.     sta    char$col    ; update column number
  22.     lhld    char$adr    ; get cursor address
  23.     inx    h
  24.     shld    char$adr    ; update cursor address
  25.  
  26. ;
  27. ;    input:
  28. ;        HL=current cursor address
  29. ;
  30. set$cursor:
  31.     mvi    a,14            ;
  32.     call    wait            ;
  33.     outp    h
  34.     mvi    a,15            ;
  35.     call    wait            ;
  36.     outp    l
  37.     ret
  38.  
  39.     page
  40.  
  41.  
  42. ;*
  43. ;*    Set current ROW and COL  (supplied in DE)
  44. ;*
  45. ;*
  46. crs$pos$80:
  47.     mov    a,d
  48.     cpi    25
  49.     rnc
  50.     mov    a,e
  51.     cpi    80
  52.     rnc
  53.     xchg                ; cursor row # in D,column # in C
  54.     shld    char$col
  55.  
  56. ;
  57. ;    returns with cursor set and current ROW, COLUMN in BC
  58. ;    and character screen address in HL 
  59. ;
  60. compute$adr:
  61.     lhld    char$col
  62.     call    cur$adr$hl        ; HL=cursor address on return
  63.     shld    char$adr
  64.     jr    set$cursor        ; call/ret
  65.  
  66.     page
  67. ;*
  68. ;*    Move cursor up one line; do nothing if on the 
  69. ;*    top line
  70. ;*
  71. crs$up$80:
  72.     lda    char$row
  73.     ora    a
  74.     rz
  75.     dcr    a
  76. set$row$80:
  77.     sta    char$row
  78.     jr    compute$adr
  79.  
  80.  
  81. do$crlf:
  82.     xra    a
  83.     sta    char$col
  84.  
  85. ;*
  86. ;*
  87. ;*
  88. ;*
  89. crs$down$80:
  90.     lda    char$row
  91.     cpi    lines-1            ; on bottom line ?
  92.     jrz    scroll$up        ; yes, scroll the screen
  93.     jrnc    set$24$80        ; past it, set it to line 24
  94.     inr    a
  95.     jr    set$row$80
  96.  
  97. ;*
  98. ;*
  99. ;*
  100. ;*
  101. crs$left$80:
  102.     lda    char$col
  103.     ora    a
  104.     rz
  105.     dcr    a
  106. set$col$80:
  107.     sta    char$col
  108.     jr    compute$adr
  109.  
  110.     page
  111. ;*
  112. ;*
  113. ;*
  114. ;*
  115. crs$rt$80:
  116.     lda    char$col
  117.     inr    a
  118.     cpi    80
  119.     jrnz    set$col$80
  120.     ret
  121.  
  122. ;*
  123. ;*
  124. ;*
  125. ;*
  126. crs$cr$80:
  127.     xra    a
  128.     jr    set$col$80
  129.  
  130.     page
  131. ;
  132. ;
  133. ;
  134. set$24$80:
  135.     mvi    a,lines-1
  136.     sta    char$row
  137. ;
  138. ;
  139. ;
  140. scroll$up:
  141.       lxi    h,80
  142.       lxi    d,0
  143.       lxi    b,80*(lines-1)
  144.       call    block$move$80
  145.  
  146. ;
  147. ;
  148. ;
  149. clear$bottom$line:
  150.     lxi    h,80*(lines-1)
  151.     lxi    b,80
  152.     call    block$fill$space$80
  153.     jr    compute$adr
  154.  
  155.     page
  156. ;*
  157. ;*    B= bit position to set or clear
  158. ;*    C= new bit value
  159. ;*
  160. ;*    attr byte def. (in B and C)
  161. ;*        bit 7-alternate char set (uper case set)
  162. ;*        bit 6-reverse video
  163. ;*        bit 5-underline
  164. ;*        bit 4-blink
  165. ;*        bit 0-full intensity
  166. ;*
  167. ;*
  168. set$attr$80:
  169.     lda    current$atr
  170.     cma                ; invert A
  171.     ora    b            ; force new bit to 1
  172.     cma                ; restore A
  173.     ora    c
  174.     sta    current$atr
  175.     ret
  176.  
  177.     page
  178. ;*
  179. ;*    ASCII codes(B)    20h to 2Fh set character color
  180. ;*            30h to 3Fh set background color
  181. ;*            50h to 5Fh set logical character color
  182. ;*            60h to 6Fh set logical background color
  183. ;*            all others code do nothing
  184. ;*
  185. ;*
  186. set$color$80:
  187.     mov    a,b            ; get color to A
  188.     sui    20h            ; remove the BIAS
  189.     cpi    20h            ; physical color ? (00h-1Fh)
  190.     jrc    ?col$80            ; yes, go set it
  191.     mvi    c,20h            ; max color value+1 (00h-1Fh)
  192.     call    lookup$color$1        ; convert char in A to color (ret in A)
  193.                     ; C=max color character
  194.     rc                ; return if error
  195.     mov    a,m            ; get color bytes
  196.     ani    0fh            ; LSB is 80 column color
  197.     add    b            ; Add color offset back
  198.                     ; 0-f set forground color
  199.                     ; 10-1f set background color
  200.  
  201.     page    
  202. ;
  203. ;    set color in A    (00-0F sets the character color)
  204. ;            (10-1F sets the background color)
  205. ;
  206. ;    This routine first calls lookup color to convert the 40 column
  207. ;    color (normal color) to the 80 column RGBI color 
  208. ;
  209. ?col$80:
  210.     sta    temp1
  211.     mvi    c,20h            ; max color value+1 (00h-1Fh)
  212.     adi    30h            ; restore a bias
  213.     lxi    h,color$convert$tbl    ; table to use
  214.     call    lookup$color$2        ; convert to same color as 40 Column
  215.     mov    a,m            ; get character color
  216.     add    b            ; add color offset back
  217.  
  218.     cpi    10h            ; character color? (0-f)
  219.     jrc    chr$col$80        ; yes, go do it
  220.                     ; no, fall thru and set background
  221. ;
  222. ;    set background color (10-1F)
  223. ;
  224.     ani    0Fh            ; get value of 0 to F
  225.     sta    bg$color$80
  226.     push    psw
  227.     mvi    a,26            ; color register
  228.     call    wait
  229.     pop    psw
  230.     outp    a    
  231.     ret
  232.  
  233. ;*
  234. ;*
  235. ;*
  236. rd$color$80:
  237.     lda    bg$color$80
  238.     mov    b,a
  239.     lda    current$atr
  240.     mov    d,a
  241.     lda    char$color$80
  242.     ret
  243.  
  244.     page
  245. ;
  246. ;    set character color
  247. ;
  248. chr$col$80:
  249.     mov    b,a
  250.     lda    current$atr
  251.     ani    0f0h        ; remove old color
  252.     ora    b        ; merge new color
  253.     sta    current$atr    ; save new attr
  254.     lda    temp1
  255.     sta    char$color$80
  256. ;
  257. ;    set current char position color to new color 
  258. ;
  259.     lhld    char$adr    ; get current cursor adr
  260.     lxi    d,800h        ; offset to attr
  261.     dad    d        ; pointing to current char attr
  262.     call    set$update$adr    ; point to attr byte
  263.     lda    current$atr
  264.     outp    a
  265.     ret
  266.  
  267.     page
  268. ;*
  269. ;*
  270. ;*
  271. ;*
  272. CEL$80:
  273.     call    cur$adr$80$hl$sz$a    ; HL=cur adr, DE=line start adr
  274.                     ; BC=count to move, A=BC+1
  275.     inx    b            ; 1 to 80 to fill
  276.     jr    cont$space$fill
  277.  
  278.  
  279. ;*
  280. ;*
  281. ;*
  282. ;*
  283. CES$80:
  284.     call    cur$adr$80$hl$sz$a    ; HL=cur adr, DE=line start adr
  285.                     ; BC=count to move, A=BC+1
  286.     xchg                ; cursor address in DE
  287.     lxi    h,lines*80
  288.     xra    a            ; clear the carry
  289.     dsbc    DE            ; count will be minus if on status line
  290.     rm                ; return if on status line
  291.     mov    b,h
  292.     mov    c,l            ; count to BC
  293.     xchg                ; cursor address back to HL
  294.  
  295. cont$space$fill:
  296.     jmp    block$fill$space$80
  297.  
  298.     page
  299. ;*
  300. ;*
  301. ;*
  302. char$ins$80:
  303.     call    cur$adr$80$hl$sz$a    ; HL=cur adr, DE=line start adr
  304.                     ; BC=count to move, A=BC+1 (1-80) 
  305.     lxi    h,80-1
  306.     dad    d            ; point to end of line
  307.     dcr    a            ; A=1 if at end of line
  308.     jrz    char$ins$80$end
  309.     mov    d,h
  310.     mov    e,l            ; HL=DE= end of line address
  311.     dcx    h            ; [HL--] -> [DE--] count BC
  312.  
  313.     push    b
  314.     push    h
  315.     push    d
  316.     call    insert$low
  317.     lxi    b,800h            ; attribute offset
  318.     pop    h
  319.     dad    b
  320.     xchg
  321.     pop    h
  322.     dad    b
  323.     pop    b
  324.  
  325. insert$low:
  326.     push    b
  327.     call    set$update$adr
  328.     inp    a
  329.     xchg
  330.     push    psw
  331.     call    set$update$adr
  332.     pop    psw
  333.     outp    a
  334.     xchg
  335.     pop    b
  336.     dcx    h
  337.     dcx    d
  338.     dcx    b
  339.     mov    a,b
  340.     ora    c
  341.     jrnz    insert$low
  342.  
  343.     lhld    char$adr
  344.  
  345. char$ins$80$end:
  346.     jmp    write$space$80
  347.  
  348.     page
  349. ;*
  350. ;*
  351. ;*
  352. ;*
  353. char$del$80:
  354.     call    cur$adr$80$hl$sz$a    ; HL=cur adr, DE=line start adr
  355.                     ; BC=count to move, A=BC+1
  356.     push    d            ; save line start address
  357.     mov    d,h
  358.     mov    e,l            ; DE=HL=cursor address
  359.     inx    h            ; [HL++]->[DE++] count BC
  360.     call    block$move$80        ; DE points to last position
  361.  
  362.     pop    h            ; recover line start address
  363.     lxi    d,80-1
  364.     dad    d            ; point to end of line
  365.     jmp    write$space$80
  366.  
  367.     page
  368. ;*
  369. ;*
  370. ;*    Moves one line at a time, down one line, starting with the next
  371. ;*    to the bottom line. Once the cursor line is moved down, the
  372. ;*    cursor line is cleared.
  373. ;*
  374. line$ins$80:
  375.     lxi    d,new$offset
  376.     mvi    a,lines-1        ; cursor on or past the last line ?
  377.     lhld    char$col
  378.     cmp    h
  379.     jz    clear$bottom$line    ; no bottom, clear bottom line
  380.     jrc    line$ins$cont        ; past,
  381.     lxi    h,(lines-2)*80
  382.     lxi    d,(lines-1)*80
  383.     mvi    b,lines
  384. move$next$down:
  385.     call    move$line$down
  386.     lda    char$row
  387.     cmp    b
  388.     jrnz    move$next$down
  389.  
  390.     call    cur$adr$80$hl$sz$a    ; HL=cur adr, DE=line start adr
  391.                     ; BC=count to move, A=BC+1
  392.     xchg                ; get line start adr
  393.     lxi    b,80
  394.     jr    block$fill$space$80
  395.  
  396. ;
  397. ;
  398. ;
  399. line$ins$cont:
  400.     inr    a
  401.     cmp    l
  402.     rnz
  403.     jmp    update$it
  404.  
  405.     page
  406. ;
  407. ;    INPUT:
  408. ;        HL=source
  409. ;        DE=dest
  410. ;         B=line number
  411. ;    OUTPUT:
  412. ;        HL=source-80
  413. ;        DE=dest-80
  414. ;         B=line number - 1
  415. ;
  416. move$line$down:
  417.     push    b
  418.     push    h
  419.     push    d
  420.     lxi    b,80
  421.     call    block$move$80
  422.     lxi    b,-80
  423.     pop    h
  424.     dad    b
  425.     xchg
  426.     pop    h
  427.     dad    b
  428.     pop    b
  429.     dcr    b
  430.     ret
  431.  
  432.     page
  433. ;*
  434. ;*
  435. ;*
  436. line$del$80:
  437.     lda    char$row
  438.     cpi    lines            ; is the cursor past the bottom line ?
  439.     rnc                ; yes, exit
  440.     call    cur$adr$80$hl$sz$a    ; HL=cur adr, DE=line start adr
  441.                     ; BC=count to move, A=BC+1
  442.     lxi    h,80            ; line length
  443.     dad    d            ; HL=start of next line
  444.     xchg                ; move from address in DE
  445.     push    h            ; save TO address
  446.     lxi    h,lines*80
  447.     xra    a            ; clear the carry
  448.     dsbc    DE
  449.     mov    b,h
  450.     mov    c,l            ; count to BC
  451.     pop    h            ; recover TO address 
  452.     xchg                ; move from address back to HL
  453.  
  454.     call    block$move$80        ; DE points to last position
  455.     jmp    clear$bottom$line
  456.  
  457.     page
  458. ;
  459. ;    user interface point
  460. ;
  461. blk$fill:
  462.     pop    h            ; get the return addres
  463.     xthl                ; get HL, ret adr to stack.
  464.     jr    block$fill$80
  465. ;
  466. ;    INPUT:
  467. ;        HL=start address
  468. ;        BC=count
  469. ;
  470. block$fill$space$80:
  471.     lda    current$atr
  472.     mov    e,a
  473.     mvi    d,' '
  474. ;
  475. ;    80 block fill
  476. ;
  477. ;    INPUT:
  478. ;        HL=start address
  479. ;        BC=count
  480. ;        D=fill character, E=attribute
  481. ;
  482. block$fill$80:
  483.     mov    a,b            ; get MSB of count to A
  484.     ana    a            ; is it zero
  485.     jrz    fill$less$256        ; yes, move less than 256 bytes
  486. block$fill$cont$80:
  487.     push    h
  488.     push    d
  489.     push    b
  490.     xra    a
  491.     call    fill$data$80
  492.     pop    b
  493.     pop    d
  494.     pop    h
  495.     inr    h
  496.     djnz    block$fill$cont$80
  497.  
  498.     page
  499. ;
  500. ;
  501. ;
  502. fill$less$256:
  503.     mov    a,c            ; get LSB of count to A
  504.     ana    a            ; is it zero ?
  505.     rz                ; yes, none left to fill, return 
  506. ;
  507. ;    count in A (1 to 256) (0=256)
  508. ;    HL=fill adr
  509. ;    DE=fill character, and attribute
  510. ;
  511. fill$data$80:
  512.     push    psw            ; save count
  513.     push    h            ; save adr
  514.     push    d            ; save fill character
  515.     call    fill$half$80
  516.     pop    d            ; recover fill character
  517.     lxi    b,800h            ; offset to attributes 
  518.     pop    h            ; recover adr
  519.     dad    b            ; HL=attr adr
  520.     call    do$twice?
  521.     pop    psw            ; recover count
  522.     mov    d,e            ; get the attr to D
  523.  
  524.     page
  525. ;
  526. ;
  527. fill$half$80:
  528.     push    psw            ; save the count
  529.     call    set$update$adr        ; write address to chip R18,R19
  530.     outp    d            ; write update data (R31)
  531.  
  532.     pop    psw
  533.     dcr    a            ; already wrote one above 
  534.     rz                ; return if only one required
  535.     push    psw
  536.     
  537.     mvi    a,24
  538.     call    wait
  539.     inp    a            ; get old value in reg 24
  540.     ani    7fh
  541.     outp    a            ; clear R24(7), enabling block writes
  542.  
  543.     mvi    a,30
  544.     call    wait
  545.     pop    psw            ; recover the count
  546.     outp    a            ; write count to R30
  547.     if    fixed$8563
  548.     ret
  549.     else
  550.     mvi    b,0    
  551.     mov    c,a
  552.     inx    b            ; add back the one removed above
  553.     dad    b
  554.     push    d            ; save fill char (in D)
  555.     push    h            ; HL=end address
  556.  
  557.     mvi    a,18
  558.     call    wait
  559.     inp    h
  560.     mvi    a,19
  561.     call    wait
  562.     inp    l            ; HL=current pointer
  563.  
  564.     pop    d            ; DE=end adr
  565.     pop    b            ; get fill char (to B)
  566. finish$fill:
  567.     call    cmp$HL$DE        ; compare dest with chip dest
  568.                     ; HL<DE carry is set
  569.     rnc                ; return if done
  570.  
  571.     push    b            ; save fill char
  572.     call    set$update$adr        ; HL&DE NOT changed (BC&A changed)
  573.     pop    b            ; recover fill char
  574.     outp    b
  575.     inx    h            ; add one to dest pointer
  576.     jr    finish$fill
  577.  
  578.     endif
  579.  
  580.     page
  581. ;
  582. ;    user entry point return adr on top of stack
  583. ;    and HL next
  584. ;
  585. blk$move:
  586.     pop    h            ; get return adr
  587.     xthl                ; get HL save ret adr
  588. ;
  589. ;    block move 80 column chip memory
  590. ;
  591. ;    INPUT:
  592. ;        HL=source
  593. ;        DE=dest
  594. ;        BC=count
  595. ;
  596. block$move$80:
  597.     mov    a,b            ; get MSB of count to A
  598.     ana    a            ; is it zero
  599.     jrz    move$less$256        ; yes, move less than 256 bytes
  600. block$move$cont$80:
  601.     push    h
  602.     push    d
  603.     push    b
  604.     xra    a
  605.     call    move$data$80
  606.     pop    b
  607.     pop    d
  608.     pop    h
  609.     inr    h
  610.     inr    d
  611.     djnz    block$move$cont$80
  612.  
  613. move$less$256:
  614.     mov    a,c            ; get LSB of count to A
  615.     ana    a            ; is it zero ?
  616.     rz                ; yes, none left to move, return 
  617.  
  618.     page
  619. ;
  620. ;    count in A (1 to 256) (0=256)
  621. ;    HL=source
  622. ;    DE=dest
  623. ;
  624. move$data$80:
  625.     xchg                ; HL=dest DE=source
  626.     push    psw            ; save count
  627.     push    h            ; save dest
  628.     push    d            ; save source
  629.     call    move$half$80
  630.     lxi    b,800h            ; offset to attributes 
  631.     pop    h            ; recover source addr
  632.     dad    b            ; make attr source
  633.     xchg                ; DE=attr source
  634.     pop    h            ; recover dest
  635.     dad    b            ; HL=attr dest
  636.     call    do$twice?
  637.     pop    psw            ; recover count
  638.  
  639. ;
  640. ;
  641. move$half$80:
  642.     push    psw            ; save the count
  643.     call    set$update$adr        ; write dest address to chip R18,R19
  644.  
  645.     mvi    a,24
  646.     call    wait
  647.     inp    a            ; get old value in reg 24
  648.     ori    80h
  649.     outp    a            ; set R24(7), enabling block copy
  650.  
  651. ; call    set$source$adr        ; write source address (R32,R33=DE)
  652. ;set$source$adr:
  653.     mvi    a,32
  654.     call    wait
  655.     outp    d
  656.     mvi    a,33
  657.     call    wait
  658.     outp    e
  659. ; ret
  660.  
  661.     mvi    a,30
  662.     call    wait
  663.     pop    psw            ; recover the count
  664.     outp    a            ; write count to R30
  665.     ret
  666.  
  667.     page
  668.  
  669. ;
  670. ;
  671. ;
  672. do$twice?:
  673.     mov    a,h            ; HL=video memory address
  674.     cpi    DS$char$def/256        ; Char def area?
  675.     rc                ; no, return, must be char, attr area
  676.     pop    psw            ; remove return adr
  677.     pop    psw            ; remove old A and psw
  678.     ret                ; return to org caller
  679.  
  680.     page
  681. ;
  682. ;
  683. ;
  684. write$space$80:
  685.     mvi    d,' '
  686. write$char$80:
  687.     lda    current$atr
  688.  
  689. ;
  690. ;    HL=cursor adr, D=char to write, A=attr to write
  691. ;
  692. write$memory:
  693.     push    h
  694.     push    d            ; save character
  695.     lxi    d,800h            ; offset to attribrute
  696.     dad    d
  697.     mov    d,a
  698.     call    wr$mem
  699.     pop    d
  700.     pop    h
  701.  
  702. wr$mem:
  703.     call    set$update$adr
  704.     outp    d
  705.     ret
  706.  
  707. ;*
  708. ;*    input:
  709. ;*        D=Char ROW, E=Char COLUMN
  710. ;*    output:
  711. ;*        B=Char, C=attribute (true RGBI color)    
  712. ;*
  713. rd$chr$80:
  714.     call    crs$pos$80
  715.     lhld    char$adr
  716.     call    read$memory
  717.     mov    c,a            ; attr was in A
  718.     ret
  719.  
  720. ;*
  721. ;*    input:
  722. ;*        D=Char ROW, E=Char COLUMN
  723. ;*        B=Char, C=attribute (true RGBI color)    
  724. ;*    output:
  725. ;*
  726. wr$chr$80:
  727.     push    b            ; save Char and attr
  728.     call    crs$pos$80
  729.     lhld    char$adr
  730.     pop    b            ; recover Char and attr
  731.     mov    d,b            ; char to D
  732.     mov    a,c            ; attr to A
  733.     jr    write$memory        ; write char and attr to memory
  734.  
  735. ;
  736. ;
  737. ;
  738. read$memory:
  739.     push    h
  740.     lxi    d,800h            ; offset to attribute
  741.     dad    d
  742.     call    rd$mem
  743.     mov    a,b
  744.     pop    h
  745. ;
  746. ;    
  747. rd$mem:
  748.     push    psw
  749.     call    set$update$adr
  750.     pop    psw
  751.     inp    b
  752.     ret
  753.  
  754.     page
  755. ;
  756. ;
  757. ;
  758. wait:
  759.     push    psw
  760.     lxi    b,0d600h        ; point to adr register
  761. wait$loop:
  762.     inp    a            ; check if chip is ready yet
  763.     ral                ; (MSB=1 when ready)
  764.     jrnc    wait$loop        ; not ready, loop
  765.     pop    psw
  766.     outp    a            ; set chip register
  767.     inr    c            ; point to data register
  768.     ret
  769.  
  770. ;
  771. ;
  772. ;
  773. set$update$adr:
  774.     mvi    a,18
  775.     call    wait
  776.     outp    h
  777.     mvi    a,19
  778.     call    wait
  779.     outp    l
  780.     mvi    a,31
  781.     call    wait
  782.     dcr    c
  783.     
  784. update$wait:
  785.     inp    a
  786.     ral
  787.     jrnc    update$wait
  788.     inr    c
  789.     ret
  790.  
  791.     page
  792. ;**
  793. ;**    40 COLUMN TERMINAL FUNCTION CODE 
  794. ;**
  795. ;**
  796.  
  797. ;*
  798. ;*
  799. ;*
  800. wr$char$40:
  801.     mov    b,d
  802.     call    ascii$to$petascii    ; convert to pet ASCII
  803.     lhld    char$adr$40
  804.     mov    b,a
  805.     lda    rev$40
  806.     ora    b
  807.     mov    m,a
  808.     inx    h
  809.     shld    char$adr$40
  810.     lxi    d,800h-1
  811.     dad    d            ; point to attribute byte
  812.     lda    attr$40            ; get current attribute
  813.     mov    m,a            ; set it
  814.  
  815.     lda    char$col$40
  816.     cpi    80-1            ; at end of line?
  817.     jrz    crlf$40            ; yes, do crlf
  818.     inr    a
  819.     sta    char$col$40        ; move cursor right
  820.     jmp    set$cursor$40        ; set cursor & paint the current ROW
  821.  
  822.     page
  823. ;*
  824. ;*    input:
  825. ;*        D=Char ROW, E=Char COLUMN
  826. ;*    output:
  827. ;*        H=Char ROW, L=Char COLUMN
  828. ;*        B=Char, C=attribute (40 col attr and color)    
  829. ;*
  830. rd$chr$40:
  831.     call    crs$pos$only$40
  832.     lhld    char$adr$40
  833.     mov    b,m
  834.     lxi    d,800h
  835.     dad    d
  836.     mov    c,m
  837.     ret
  838.  
  839. ;*
  840. ;*    input:
  841. ;*        D=Char ROW, E=Char COLUMN
  842. ;*        B=Char, C=attribute (40 col attr and color)    
  843. ;*    output:
  844. ;*        H=Char ROW, L=Char COLUMN
  845. ;*
  846. wr$chr$40:
  847.     push    b
  848.     call    crs$pos$only$40
  849.     pop    b
  850.     lhld    char$adr$40
  851.     mov    a,b
  852.     ani    7fh            ; remove reverse video bit
  853.     bit    6,c
  854.     jrz    not$rev$vid$bit
  855.     adi    80h            ; set reverse video
  856. not$rev$vid$bit:
  857.     mov    m,a
  858.     lxi    d,800h
  859.     dad    d
  860.     mov    m,c
  861.     jmp    set$cursor$40
  862.  
  863.  
  864. ;*
  865. ;*
  866. ;*
  867. crs$pos$40:
  868.     lxi    h,old$offset
  869.     setb    6,m            ; force page paint
  870. crs$pos$only$40:
  871.     mov    a,d
  872.     cpi    25
  873.     rnc
  874.     mov    a,e
  875.     cpi    80
  876.     rnc
  877.     xchg
  878.     shld    char$col$40
  879. ;
  880. ;
  881. ;
  882. compute$adr$40:
  883.     lhld    char$col$40
  884.     call    cur$adr$hl        ; HL=cursor adr relative to zero
  885.     lxi    d,screen$40        ; get screen offset
  886.     dad    d            ; true cursor address
  887.     shld    char$adr$40
  888.     jmp    set$cursor$40
  889.  
  890.     page
  891. ;*
  892. ;*
  893. ;*
  894. ;*
  895. crs$up$40:
  896.     lda    char$row$40
  897.     ora    a
  898.     rz
  899.  
  900.     dcr    a
  901. set$row$40:
  902.     sta    char$row$40
  903. cont$compute$adr$40:
  904.     lxi    h,old$offset
  905.     setb    6,m
  906.     jr    compute$adr$40
  907.  
  908. ;
  909. ;
  910. ;
  911. crlf$40:
  912.     xra    a
  913.     sta    char$col$40
  914. ;*
  915. ;*
  916. ;*
  917. ;*
  918. crs$down$40:
  919.     lda    char$row$40
  920.     cpi    lines-1
  921.     jrz    scroll$up$40
  922.     jrnc    set$24$40
  923.     inr    a
  924.     jr    set$row$40
  925.  
  926.     page
  927. ;
  928. ;
  929. ;
  930. set$24$40:
  931.     mvi    a,lines-1
  932.     sta    char$row$40
  933. ;
  934. ;
  935. ;
  936. scroll$up$40:
  937.     lxi    h,screen$40+80
  938.     lxi    d,screen$40
  939.     lxi    b,80*(24-1)
  940.     ldir                ; move characters up one line
  941.  
  942.     xchg                ; get start of last line in HL
  943.     lxi    d,screen$40+80*23+1
  944.     lxi    b,80-1
  945.     call    space$fill$40        ; clear the bottom line
  946.  
  947.     lxi    h,screen$40+800h+80
  948.     lxi    d,screen$40+800h
  949.     lxi    b,80*(lines-1)
  950.     ldir                ; move attributes up one line
  951.  
  952.     xchg                ; get start of last line in HL
  953.     lxi    d,screen$40+800h+80*23+1
  954.     lxi    b,80-1
  955.     lda    attr$40
  956.     mov    m,a
  957.     ldir                ; set color attribute 
  958.     jr    cont$compute$adr$40
  959.  
  960.     page
  961. ;*
  962. ;*
  963. ;*
  964. ;*
  965. crs$left$40
  966.     lda    char$col$40
  967.     ora    a
  968.     rz
  969.  
  970.     dcr    a
  971. set$col$40:
  972.     sta    char$col$40
  973.     jr    compute$adr$40
  974.  
  975. ;*
  976. ;*
  977. ;*
  978. ;*
  979. crs$rt$40:
  980.     lda    char$col$40
  981.     inr    a
  982.     cpi    80
  983.     jrnz    set$col$40
  984.     ret
  985.  
  986. ;*
  987. ;*
  988. ;*
  989. ;*
  990. crs$cr$40:
  991.     xra    a
  992.     jr    set$col$40
  993.  
  994.     page
  995. ;*
  996. ;*
  997. ;*
  998. ;*
  999. CEL$40:
  1000.     lxi    h,line$paint
  1001.     push    h
  1002.     call    cur$adr$40$hl$sz$a    ; HL=cursor adr, DE=start of line adr
  1003.                     ; BC=DE+80-HL-1, A=BC+1 (1-80)
  1004.     lxi    d,screen$40        ; get start of screen
  1005.     dad    d            ; HL=cursor position in memory
  1006.     call    write$space$40        ; place a space at the cursor adr
  1007.     mov    a,c
  1008.     ana    a
  1009.     rz
  1010.     push    b
  1011.     push    h
  1012.     mov    d,h
  1013.     mov    e,l            ; DE=HL=cursor pos 
  1014.     inx    d            ; point to next location
  1015.     ldir                ; BC=count (0-79)
  1016.     jr    clear$attr$also
  1017.  
  1018.     page
  1019. ;*
  1020. ;*
  1021. ;*
  1022. ;*
  1023. CES$40:
  1024.     lxi    h,screen$paint
  1025.     push    h
  1026.     lxi    d,screen$40+80*lines-1    ; DE=end of screen
  1027.     lhld    char$adr$40        ; clear from char$adr to DE
  1028.     xchg
  1029.     xra    a            ; clear the carry bit
  1030.     DSBC    DE            ; result is minus if on status line
  1031.     rm                ; return if on status line
  1032.  
  1033.     xchg
  1034.     jrz    write$space$40        ; at end, clear cursor position
  1035.  
  1036.     mov    b,d
  1037.     mov    c,e            ; count in BC
  1038.     mov    d,h
  1039.     mov    e,l            ; start adr in HL
  1040.     inx    d            ; start adr+1 in DE
  1041.     push    b            ; save number of bytes to move
  1042.     push    h            ; save start address
  1043.     call    space$fill$40        ; move space thru screen
  1044. ;
  1045. ;
  1046. ;
  1047. clear$attr$also:
  1048.     lxi    b,800h
  1049.     pop    h
  1050.     dad    b            ; 1st attribute
  1051.     pop    b            ; get the count
  1052.     mov    d,h
  1053.     mov    e,l
  1054.     inx    d            ; 2nd attribute
  1055.     lda    attr$40
  1056.     mov    m,a
  1057.     ldir                ; move current attribute to screen
  1058.     ret
  1059.  
  1060.     page
  1061. ;*
  1062. ;*
  1063. ;*
  1064. ;*
  1065. char$ins$40:
  1066.     lxi    h,line$paint
  1067.     push    h
  1068.     call    cur$adr$40$hl$sz$a    ; HL=cur adr, DE=line start adr
  1069.                     ; BC=count to move, A=BC+1 (1-80) 
  1070.     lxi    h,screen$40-1+80
  1071.     dad    d            ; point to end of current line
  1072.     dcr    a            ; at right end of screen ?
  1073.     jrz    write$space$40        ; yes, insert a space
  1074.     mov    d,h
  1075.     mov    e,l            ; HL=DE= end of line address
  1076.     dcx    h            ; [HL--] -> [DE--] count BC
  1077.     push    b
  1078.     push    d
  1079.     lddr                ; DE=cursor position
  1080.     xchg
  1081.     call    write$space$40        ; write a space at the cursor adr
  1082.     pop    h
  1083.     lxi    b,800h            ; now move the attributes
  1084.     dad    b
  1085.     pop    b
  1086.     mov    d,h
  1087.     mov    e,l            ; HL=DE= end of line address
  1088.     dcx    h            ; [HL--] -> [DE--] count BC
  1089.     lddr                ; DE=cursor position
  1090.     ret
  1091.  
  1092. ;
  1093. ;
  1094. ;
  1095. write$space$40:
  1096.     lda    rev$40
  1097.     adi    ' '            ; clear character, enable cursor
  1098.     mov    m,a
  1099.     ret
  1100.  
  1101.     page
  1102. ;*
  1103. ;*
  1104. ;*
  1105. ;*
  1106. char$del$40:
  1107.     lxi    h,line$paint
  1108.     push    h
  1109.     call    cur$adr$40$hl$sz$a    ; HL=cur adr, DE=line start adr
  1110.                     ; BC=count to move, A=BC+1
  1111.     lxi    d,screen$40
  1112.     dad    d            ; point to screen memory location
  1113.  
  1114.     dcr    a            ; at end of line ?
  1115.     jrz    write$space$40        ; yes, then just erase cursor pos
  1116.  
  1117.     mov    d,h
  1118.     mov    e,l            ; DE=HL=cursor address
  1119.     push    b
  1120.     push    h
  1121.     inx    h            ; [HL++]->[DE++] count BC
  1122.     ldir                ; DE points to last position
  1123.     xchg
  1124.     call    write$space$40        ; place a space at the end of line
  1125.     pop    h
  1126.     lxi    b,800h+1        ; now move the attributes
  1127.     dad    b
  1128.     pop    b
  1129.     mov    d,h
  1130.     mov    e,l            ; HL=DE= cursor attr address
  1131.     inx    h            ; [HL++] -> [DE++] count BC
  1132.     ldir                ;
  1133.     ret
  1134.  
  1135.     page
  1136. ;*
  1137. ;*
  1138. ;*
  1139. ;*
  1140. line$ins$40:
  1141.     lxi    h,screen$paint
  1142.     push    h
  1143.     lda    char$row$40
  1144.     cpi    lines-1
  1145.     jrz    clear$bottom$line$40
  1146.     rnc                ; return if on status line
  1147.     call    cur$adr$40$hl$sz$a    ; HL=cur adr, DE=line start adr
  1148.                     ; BC=count to move, A=BC+1
  1149.     lxi    h,screen$40
  1150.     dad    d            ; point to line start memory location
  1151.     push    h            ; save start address
  1152.     lxi    d,80
  1153.     dad    d            ; point to start of next line
  1154.  
  1155.     xchg                ; cursor line(+1) start address in DE
  1156.     lxi    h,screen$40+80*lines    ; end of screen address
  1157.     xra    a            ; clear the carry bit (and A)
  1158.     dsbc    DE            ; HL=HL-DE
  1159.     mov    b,h
  1160.     mov    c,l            ; count in
  1161.  
  1162.     lxi    h,screen$40+80*(lines-1)-1    ; HL=end of screen-80
  1163.     lxi    d,screen$40+80*lines-1        ; DE=end of screen
  1164.  
  1165.     push    b
  1166.     lddr
  1167.  
  1168.     page
  1169.  
  1170.     pop    b
  1171.     lxi    h,screen$40+80*(lines-1)-1+800h
  1172.     lxi    d,screen$40+80*lines-1+800h
  1173.     lddr                ; scroll the attributes
  1174.     pop    h            ; get cursor line start address
  1175.     mov    d,h
  1176.     mov    e,l
  1177.     inx    d
  1178.     lxi    b,80-1
  1179.     jr    space$fill$40
  1180.  
  1181. ;
  1182. ;
  1183. ;
  1184. clear$bottom$line$40:
  1185.     lxi    h,screen$40+(lines-1)*80
  1186.     lxi    d,screen$40+(lines-1)*80+1
  1187.     lxi    b,80-1
  1188. space$fill$40:
  1189.     lda    rev$40
  1190.     adi    ' '
  1191.     mov    m,a
  1192.     ldir
  1193.     ret
  1194.  
  1195.     page
  1196. ;*
  1197. ;*
  1198. ;*
  1199. ;*
  1200. line$del$40:
  1201.     lxi    h,screen$paint
  1202.     push    h
  1203.     lda    char$row$40
  1204.     cpi    lines-1            ; on or past last line ?
  1205.     jrz    clear$bottom$line$40    ; on, just clear it
  1206.     rnc                ; past it, return
  1207.  
  1208.     call    cur$adr$40$hl$sz$a    ; HL=cur adr, DE=line start adr
  1209.                     ; BC=count to move, A=BC+1
  1210.     lxi    h,screen$40
  1211.     dad    d            ; point to line start memory location
  1212.     push    h            ; save cursor line start adr
  1213.     lxi    d,80
  1214.     dad    d            ; point to start of next line
  1215.  
  1216.     xchg                ; cursor line(+1) start address in DE
  1217.     lxi    h,screen$40+80*lines    ; end of screen address
  1218.     xra    a            ; clear the carry bit (and A)
  1219.     dsbc    DE            ; HL=HL-DE
  1220.     mov    b,h
  1221.     mov    c,l            ; count in
  1222.  
  1223.     xchg                ; HL=start of line after cursor line
  1224.     pop    d            ; start of cursor line
  1225.  
  1226.     push    b            ; save count
  1227.     push    h            ; save source
  1228.     push    d            ; save dest
  1229.     ldir
  1230.  
  1231.     lxi    b,800h            ; get attribute offset
  1232.     pop    h            ; recover dest
  1233.     dad    b            ; attr dest
  1234.     xchg                ; dest belongs in DE
  1235.     pop    h            ; recover source
  1236.     dad    b            ; attr source
  1237.     pop    b            ; recover count
  1238.     ldir
  1239.     jr    clear$bottom$line$40    
  1240.  
  1241.     page
  1242. ;*
  1243. ;*    B=bits to set or clear
  1244. ;*    C=bits new value
  1245. ;* 
  1246. ;*    attr byte def. (in B)
  1247. ;*        bit 7-
  1248. ;*        bit 6-reverse video *
  1249. ;*        bit 5-underline
  1250. ;*        bit 4-blink
  1251. ;*        bit 0-full intensity (masked off)
  1252. ;*
  1253. ;*
  1254. set$attr$40:
  1255.     mov    a,b
  1256.     ani    070h
  1257.     mov    b,a
  1258.  
  1259.     mov    a,c
  1260.     ani    070h
  1261.     mov    c,a
  1262.  
  1263.     lda    attr$40
  1264.     cma
  1265.     ora    b
  1266.     cma                ; bits in B cleared A
  1267.     ora    c            ; add new value 
  1268.     sta    attr$40
  1269.     ral                ; get reverse attr in bit 7
  1270.     ani    80h
  1271.     sta    rev$40
  1272.     ret
  1273.  
  1274.     page
  1275. ;*
  1276. ;*    ASCII codes    20h to 2Fh set character color
  1277. ;*            30h to 3Fh set background color
  1278. ;*            40h to 4Fh set border color
  1279. ;*            50h to 5Fh set locical character color
  1280. ;*            60h to 6Fh set logical background color
  1281. ;*            70h to 7Fh set logical border color
  1282. ;*            all others code do nothing 
  1283. ;*
  1284. ;*    All colors are assigned from color lookup table
  1285. ;*
  1286. set$color$40:
  1287.     mov    a,b
  1288.     sui    20h
  1289.     cpi    30h
  1290.     jrc    ?col$40
  1291.     mvi    c,30h            ; max color value+1 (00h-2Fh)
  1292.     call    lookup$color$1        ; HL points to table entry on ret
  1293.     rc                ; exit if error
  1294.     mov    a,m            ; get table value again
  1295.     rrc
  1296.     rrc
  1297.     rrc
  1298.     rrc                ; get upper 4 bits to lower
  1299.     ani    0fh
  1300.     add    b            ; get old MSB
  1301.  
  1302. ?col$40:
  1303.     cpi    10h            ; character color? (0-f)
  1304.     jrc    char$color$40        ; yes, go do it
  1305.                     ; no, fall thru test background, border
  1306.     cpi    20h            ; background color? (10-1f) 
  1307.     jrc    back$color$40        ; yes, go do it
  1308.                     ; no, fall thru and set border color 
  1309. ;
  1310. ;    set border color
  1311. ;
  1312.     ani    0fh            ; color from 0-f
  1313.     sta    bd$color$40    
  1314.     lxi    b,VIC+32
  1315.     outp    a
  1316.     ret 
  1317.  
  1318.     page
  1319. ;
  1320. ;    set background color (10-1F)
  1321. ;
  1322. back$color$40:
  1323.     ani    0Fh            ; get value of 0 to F
  1324.     sta    bg$color$40
  1325.     lxi    b,VIC+33
  1326.     outp    a
  1327.     ret
  1328.  
  1329. ;*
  1330. ;*
  1331. ;*
  1332. rd$color$40:
  1333.     lda    bg$color$40
  1334.     mov    b,a
  1335.     lda    bd$color$40
  1336.     mov    c,a
  1337.     lda    attr$40
  1338.     mov    d,a
  1339.     ani    0fh
  1340.     ret
  1341.  
  1342. ;
  1343. ;    set character color
  1344. ;
  1345. char$color$40:
  1346.     mov    b,a
  1347.     lda    attr$40
  1348.     ani    0f0h
  1349.     ora    b
  1350.     sta    attr$40
  1351.  
  1352.     lhld    char$adr$40
  1353.     lxi    d,800h
  1354.     dad    d
  1355.     mov    m,a
  1356. ; jmp    line$paint
  1357.  
  1358.     page
  1359. ;
  1360. ;
  1361. ;
  1362. line$paint:
  1363.     lda    old$offset
  1364.     mov    b,a
  1365.     ora    a
  1366.     cm    trk$40
  1367.  
  1368.     lda    @off40            ; 
  1369.     cmp    b
  1370.     sta    old$offset
  1371.     jrnz    screen$paint
  1372.  
  1373.     call    cur$adr$40$hl$sz$a    ; DE=start of row adr (REL)
  1374.     lxi    h,screen$40        ; get start of screen
  1375.     dad    d            ; HL=row start address (ABS)
  1376.     xchg                ; save in DE
  1377.     lhld    @off40            ; get current screen offset (0-39)
  1378.     dad    d            ; screen source adr in HL
  1379.     push    h            ; save for later
  1380.  
  1381.     lda    char$row$40        ; get current row #
  1382.     mov    l,a            ; HL=row # (H=0)
  1383.     call    Lx40$plus$VIC
  1384.     xchg                ; place screen adr (25X40) in DE
  1385.     pop    h            ; recover logical screen adr (25X80)
  1386.  
  1387.     push    h            ; save for attr move
  1388.     push    d
  1389.  
  1390.     mvi    a,1            ; one line only
  1391.  
  1392.     call    update$window$fun
  1393.     pop    h            ; recover screen pointer (25X40)
  1394.     lxi    b,vic$color-vic$screen
  1395.     dad    b            ; point to Vic color memory
  1396.     xchg                ; DE=color memory pointer
  1397.     pop    h            ; recover screen pointer (25X80)
  1398.     lxi    b,800h            ; offset to attributes
  1399.     dad    b
  1400.     mvi    a,1            ; one line only
  1401.     jr    update$window$fun    ;
  1402.  
  1403.     page
  1404. ;
  1405. ;    hl=offset (0 to 39)
  1406. ;
  1407. screen$paint:
  1408.     lhld    @off40
  1409.     lda    paint$size        ; number of lines to move
  1410.     push    h
  1411.     push    psw            ; save the count
  1412.  
  1413.     lxi    d,screen$40
  1414.     dad    d            ; point to start of visible screen
  1415.     lxi    d,vic$screen        ; place to move it to
  1416.     call    update$window$fun
  1417.  
  1418.     pop    psw
  1419.     pop    h
  1420.     lxi    d,screen$40+800h
  1421.     dad    d            ; add the screen offset
  1422.     lxi    d,vic$color
  1423. ;
  1424. ;    Always called from bank 0, Placed in common so that IO
  1425. ;    will not overlay this code. Can go in ROM 
  1426. ;
  1427. update$window$fun:
  1428.     sta    io$0
  1429. update$window$loop:
  1430.     lxi    b,40            ; number of bytes to move
  1431.     ldir
  1432.     push    d
  1433.     lxi    d,80-40            ; advance pointer to next line
  1434.     dad    d
  1435.     pop    d
  1436.     dcr    a
  1437.     jrnz    update$window$loop
  1438.  
  1439.     sta    bank$0
  1440.     ret
  1441.  
  1442.  
  1443.     page
  1444. ;
  1445. ;
  1446. ;
  1447. trk$40:
  1448.     lda    char$col$40        ; get the current column number
  1449.     sui    40-8            ; remove 1st 32 columns
  1450.     jrnc    use$offset        ; if pass column 32, set an offset
  1451.     xra    a
  1452. use$offset:
  1453.     ani    0f8h            ; move 
  1454.     sta    @off40
  1455.     ret
  1456.  
  1457.     page
  1458. ;
  1459. ;
  1460. ;
  1461. set$cursor$40:
  1462.     call    no$cursor
  1463.     call    line$paint        ; will do a screen paint if required
  1464.  
  1465.     lda    @off40            ; get screen offset
  1466.     mov    b,a            ; save offset (0 to 39)
  1467.     lhld    char$col$40        ; H=row, L=col
  1468.     mov    a,l            ; get col # in A
  1469.     sub    b            ; remove offset
  1470.     jrc    no$cursor
  1471.     cpi    40
  1472.     jrnc    no$cursor
  1473.      mov    c,a
  1474.     mvi    b,0            ; BC=cursor column #
  1475.     mov    l,h            ; get row # in L
  1476.     call    Lx40$plus$VIC
  1477.     dad    b
  1478.     jr    set$flash
  1479. ;
  1480. no$cursor:
  1481.     lxi    h,0            ; if H=0 (L=xx) then cursor off
  1482. ;
  1483. set$flash:
  1484.     shld    flash$pos
  1485.     ret
  1486.  
  1487.     page
  1488. ;
  1489. ;
  1490. ;
  1491. Lx40$plus$VIC:
  1492.     mvi    h,0
  1493.     dad    h            ; 2X
  1494.     dad    h            ; 4X
  1495.     dad    h            ; 8X
  1496.     mov    d,h
  1497.     mov    e,l            ; DE=8X
  1498.     dad    h            ; 16X
  1499.     dad    h            ; 32X
  1500.     dad    d            ; 8X+32X=40X
  1501.     lxi    d,vic$screen
  1502.     dad    d            ; point to screen area
  1503.     ret
  1504.  
  1505.     page
  1506. ;
  1507. ;    input:
  1508. ;        range 20h to 7fh in B
  1509. ;    output:
  1510. ;        in A
  1511. ;
  1512. ascii$to$petascii:
  1513.     mov    a,b
  1514.     cpi    40h
  1515.     jrz    is40        ; get at sign
  1516.     rc            ; ret if code was 20h - 3fh
  1517.  
  1518.     cpi    'Z'+1        ; is it an upper case letter ?
  1519.     rc            ; yes, code was 41h - 5Ah
  1520.  
  1521.     sui    40h
  1522.     cpi    60h-40h
  1523.     jrz    was$60        ; 60h converted to 27h
  1524.  
  1525.     jrc    was$5b$to$5f
  1526.  
  1527.     sui    20h
  1528.     cpi    'z'+1-60h
  1529.     rc            ; code was 61h - 7Ah
  1530.  
  1531.     cpi    '{'-60h
  1532.     jrz    is$left$brace
  1533.     cpi    '|'-60h
  1534.     jrz    is$vert$bar
  1535.     cpi    '}'-60h
  1536.     jrz    isright$brace
  1537.     cpi    '~'-60h
  1538.     rnz
  1539.     mvi    a,64        ; commodore horz bar
  1540.     ret
  1541.  
  1542. was$60:
  1543.     mvi    a,126        ; solid upper left corner
  1544.     ret
  1545.  
  1546. is$left$brace:
  1547.     mvi    a,115        ;
  1548.     ret
  1549.  
  1550. is$vert$bar:
  1551.     mvi    a,93        ; commodore vertical bar
  1552.     ret
  1553.  
  1554. is$right$brace:
  1555.     mvi    a,107        ; 
  1556.     ret
  1557.  
  1558. was$5b$to$5f:
  1559.     cpi    '\'-40h
  1560.     jrz    is$back$slash
  1561.     cpi    '_'-40h
  1562.     rnz
  1563.     mvi    a,100            ; commodore under line
  1564.     ret
  1565.  
  1566. is$back$slash:
  1567.     mvi    a,127            ; upper left and lower right corners
  1568.     ret
  1569.  
  1570. is40:
  1571.     xra    a
  1572.     ret
  1573.  
  1574.     page
  1575. ;
  1576. ;
  1577. ;
  1578. cur$adr$40$hl$sz$a:
  1579.     lhld    char$col$40
  1580.     jr    cur$adr$hl$sz$a
  1581. ;
  1582. ;
  1583. ;
  1584. cur$adr$80$hl$sz$a:
  1585.     lhld    char$col
  1586.  
  1587. ;
  1588. ;    INPUT:
  1589. ;        H=row L=col
  1590. ;
  1591. ;    OUTPUT:
  1592. ;        HL=cursor address
  1593. ;        DE=cursor line start address
  1594. ;        BC=# character to end of line ( <80 )
  1595. ;            (not counting the cursor position) 
  1596. ;        A=BC+1
  1597. ;
  1598. cur$adr$hl$sz$a:
  1599.     mvi    a,80-1        ; get line length
  1600.     sub    l        ; A=
  1601.     mov    c,a
  1602.  
  1603. cur$adr$hl:
  1604.     mov    b,l        ; save column #
  1605.     mov    l,h
  1606.     mvi    h,0        ; HL=row #
  1607.     dad    h        ; 2x
  1608.     dad    h        ; 4x
  1609.     dad    h        ; 8x
  1610.     dad    h        ; 16x
  1611.     mov    d,h
  1612.     mov    e,l        ; save 16x
  1613.     dad    h        ; 32x
  1614.     dad    h        ; 64x
  1615.     dad    d        ; 64x+16x=80x
  1616.     xchg            ; DE=row start address
  1617.     mov    l,b        ; get saved column #
  1618.     mvi    h,0        ; HL=column #
  1619.     dad    d        ; HL=cursor address
  1620.  
  1621.     mvi    b,0        ; BC= count (if call to cur$adr$hl$sz$a:)
  1622.     inr    a        ; number of bytes to end of line (1-80)
  1623.     ret
  1624.  
  1625.     page    
  1626. ;
  1627. ;    destroys DE,HL,B,A
  1628. ;
  1629. lookup$color:
  1630.     mov    a,b            ; color supplied in B
  1631.  
  1632. lookup$color$1:
  1633.     lhld    color$tbl$ptr
  1634. ;
  1635. ;    HL=table adr
  1636. ;    A= color input
  1637. ;    C= max allowable color value
  1638. ;
  1639. lookup$color$2:
  1640.     sui    30h            ; remove bias
  1641.     rc
  1642.     cmp    c            ; above limit
  1643.     cmc
  1644.     rc                ; yes, return input out-of-range
  1645.     mov    b,a            ; save adjusted color #
  1646.     ani    0fh            ; get only the color #
  1647.  
  1648.     mov    e,a
  1649.     mvi    d,0
  1650.     dad    d            ; get converted color address
  1651.     mov    a,b            ; get the ASCII char back
  1652.     ani    30h            ; keep only char/background/borber bits
  1653.     mov    b,a            ; save char/background bit
  1654.     ret
  1655.  
  1656.     page
  1657. ;
  1658. ;
  1659. ;
  1660. bell:
  1661.     lxi    b,sid+24
  1662.     lhld    sound$1
  1663.     outp    h
  1664.     mvi    c,5
  1665.     outp    l
  1666.  
  1667.     lhld    sound$2
  1668.     inr    c
  1669.     outp    h
  1670.     mvi    c,1
  1671.     outp    l
  1672.  
  1673.     lhld    sound$3
  1674.     mvi    c,4
  1675.     outp    h
  1676.     outp    l
  1677.     ret
  1678.  
  1679.