home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / hd64180a.lbr / EXCPM.AZM / EXCPM.ASM
Encoding:
Assembly Source File  |  1991-08-04  |  12.6 KB  |  606 lines

  1.     title    'Executive Processor For CP/M'
  2. ;
  3. ;----------------------------------------------------------------
  4. ; This module contains the Console I/O Drivers for CP/M as well
  5. ; as printer and AUX drivers, initialization code and the
  6. ; I/O pocessor code.
  7. ;
  8. ; These are meant to be run in conjunction with the EXEC
  9. ; module.
  10. ;
  11. ;
  12. ;    Written     By  Richard Holmes    04-02-86
  13. ;       Last Update By  Richard Holmes    11-12-87
  14. ;----------------------------------------------------------------
  15. ;
  16.     public    sys$ini
  17.     public    con$ini,con$inp,con$out,con$ost,con$ist,con$cmd
  18.     public    aux$ini,aux$inp,aux$out,aux$ost,aux$ist,aux$cmd
  19.     public    prn$ini,prn$out,prn$ost
  20.     public    lcd$ini,lcd$out,lcd$ost,lcd$cmd
  21. ;
  22.     public    set$led,clr$led,tog$led,zro$led
  23.     public    set$bel,clr$bel
  24.     public    clk$rd,clk$wr
  25.     public    ms$delay
  26. ;
  27.  
  28.     public    clrwdt
  29.     public    hrs, min, sec
  30. ;
  31.     maclib    z80
  32.     maclib    iocmd
  33. ;
  34. ; CP/M equates 
  35. ;
  36. bdos    equ    5        ;; Operating system entry
  37. dirio    equ    6
  38. numatt    equ    6            ; 6 attributes
  39. cr    equ    0dh            ; Simple video definitions
  40. lf    equ    0ah
  41. ;
  42. clrwdt:
  43. set$led:
  44. clr$led:
  45. tog$led:
  46. zro$led:
  47. set$bel:
  48. clr$bel:
  49. clk$rd:
  50. clk$wr:
  51.     ret
  52. sys$ini:
  53.     xra    a
  54.     sta    hrs
  55.     sta    min
  56.     sta    sec
  57.     ret
  58. ;
  59. lcd$ini:
  60. lcd$out:
  61. lcd$ost:
  62. lcd$cmd:
  63.     xra    a
  64.     ora    a
  65.     ret
  66. ;
  67. ms$delay:
  68.     mov    a,e
  69.     ora    d
  70.     rz
  71. ;
  72.     push    d            ; save it
  73. delay2:
  74.     call    clr$wdt
  75.     call    delay3
  76.     dcx    d            ; one less millisecond less overhead
  77.     mov    a,d
  78.     ora    e
  79.     jrnz    delay2            ; keep on till DE = 0
  80.     pop    d            ; restore users initial value
  81.     ret                ; back to user
  82. ;
  83. ; Delay 1 millisecond less the overhead involved in the above code.
  84. ;
  85. ; This routine must delay 3957 t-states
  86. ;
  87. delay3:
  88.     push    b            ; 11
  89.     mvi    b,224            ;  7
  90. delay4:    ; This loop does (4 + 13) * 230 - 5 = 3905 t
  91.     nop                ; 4
  92.     nop
  93.     djnz    delay4            ; 13
  94. ; Fudge 14 machine cycles
  95.     lxi    b,0            ; 10
  96.     nop                ;  4
  97.     pop    b            ; 10
  98.     ret
  99. ;
  100. ;----------------------------------------------------------------
  101. ; This is the console command processor. The channel routines call
  102. ; it with a function number in C and these are then performed.
  103. ;----------------------------------------------------------------
  104. ;
  105. con$cmd:
  106.     push    h
  107.     push    b
  108.     push    d
  109.     mvi    b,0        ; Top offset = 0
  110.     lxi    h,con$cmd$tbl    ; -> table of routine addresses
  111.     dad    b
  112.     dad    b        ; Add twice for 2 byte offsets
  113.     mov    e,m        ; Low address
  114.     inx    h        ; -> High address
  115.     mov    d,m
  116.     xchg            ; HL -> routine
  117.     pop    d        ; Restore DE, it may be a parameter
  118.     pop    b        ;         BC could be someones counter
  119.     xthl            ; top of stack = routine, HL restored also.
  120.     ret
  121. ;
  122. con$cmd$tbl:
  123.     dw    0
  124.     dw    clear
  125.     dw    cleop
  126.     dw    cleol
  127.     dw    cursor
  128.     dw    setatt
  129.  
  130.  
  131.  
  132. aux$cmd:
  133.     xra    a
  134.     ora    a
  135.     ret
  136. ;
  137. ;================================================================
  138. ;
  139. ;         ---- Console Output ----
  140. ;
  141. ; On Entry
  142. ;    A = character to send
  143. ;================================================================
  144. ;
  145. con$out:
  146.     push    h
  147.     push    b
  148.     push    d
  149.     mov    e,a            ; Load the ascii character
  150.     mvi    c,dirio            ; Direct console output
  151.     call    bdos
  152.     pop    d            ; Restore output
  153.     pop    b
  154.     pop    h
  155.     ora    a
  156.     ret
  157. ;
  158. ;================================================================
  159. ;
  160. ;     Get a console character into A
  161. ;
  162. ;================================================================
  163. ;
  164. con$inp:
  165.     push    h
  166.     push    b
  167.     push    d
  168. cie$wait:
  169.     call    con$ist
  170.     jrz    cie$wait
  171. ;
  172.     mvi    e,0fdh            ; Wait and fetch
  173.     mvi    c,dirio
  174.     call    bdos
  175.     pop    d
  176.     pop    b
  177.     pop    h
  178.     ret
  179. ;
  180. ;================================================================
  181. ;
  182. ; Get the console status. 
  183. ;
  184. ; On Exit
  185. ;  A = 0 if not ready, 
  186. ;      1 if got a character 
  187. ;================================================================
  188. ;
  189. con$ist:
  190.     push    h
  191.     push    b
  192.     push    d
  193.     mvi    e,0feh            ; Status only code
  194.     mvi    c,dirio            ; Direct console I/O
  195.     call    bdos
  196.     pop    d
  197.     pop    b
  198.     pop    h
  199.     ora    a
  200.     ret
  201. ;
  202. con$ini:
  203. con$ost:
  204.     xra    a
  205.     ora    a
  206.     ret
  207. ;
  208. ;----------------------------------------------------------------
  209. ; Read a character into A and return it to the user. Wait for it
  210. ; for ever if needed. Not a smart routine at all.
  211. ;
  212. ; On Entry
  213. ;
  214. ; On Exit
  215. ;   A = character read from AUX port
  216. ;   All other registers preserved
  217. ;----------------------------------------------------------------
  218. ;
  219. aux$inp:
  220.     push    h
  221.     push    b
  222.     push    d
  223. ;
  224.     mvi    c,3            ; AUX Input code
  225.     call    bdos
  226. ;
  227.     pop    d
  228.     pop    b
  229.     pop    h
  230.     ret
  231. ;
  232. ;----------------------------------------------------------------
  233. ; Write the character in A to the AUX port.
  234. ;
  235. ; On Entry
  236. ;   A = character to write
  237. ;
  238. ; On Exit
  239. ;   All other registers preserved
  240. ;----------------------------------------------------------------
  241. ;
  242. aux$out:
  243.     push    psw
  244.     push    h
  245.     push    b
  246.     push    d
  247. ;
  248.     mvi    c,4            ; Aux out code
  249.     mov    e,a            ; Load data
  250.     call    bdos
  251. ;
  252.     pop    d
  253.     pop    b
  254.     pop    h
  255.     pop    psw
  256.     ret
  257. ;
  258. ;----------------------------------------------------------------
  259. ; Return the input status.
  260. ;
  261. ; On Exit
  262. ;  A = FF if a character ready
  263. ;  A = 00 if no character ready
  264. ;----------------------------------------------------------------
  265. ;
  266. aux$ist:
  267.     push    h
  268.     push    b
  269.     push    d
  270. ;
  271.     mvi    c,07
  272.     call    bdos
  273. ;
  274.     pop    d
  275.     pop    b
  276.     pop    h
  277.     ora    a            ; Set the zero flags
  278.     ret
  279. ;
  280. ;----------------------------------------------------------------
  281. ; Return the output status of the console port.
  282. ;
  283. ; On Exit
  284. ;   A = FF if port ready for character output
  285. ;   A = 00 for device busy
  286. ;----------------------------------------------------------------
  287. ;
  288. aux$ost:
  289.     push    h
  290.     push    b
  291.     push    d
  292. ;
  293.     mvi    c,8
  294.     call    bdos
  295. ;
  296.     pop    d
  297.     pop    b
  298.     pop    h
  299.     ret
  300. ;
  301. aux$ini:
  302.     xra    a
  303.     ora    a
  304.     ret
  305. ;
  306. ;----------------------------------------------------------------
  307. ;        Printer Drivers.
  308. ;----------------------------------------------------------------
  309. ;
  310. prn$out:
  311.     push    h
  312.     push    b
  313.     push    d
  314. ;
  315.     mov    e,a            ; Load character
  316.     mvi    c,5            ; Printer output
  317.     call    bdos
  318. ;
  319.     pop    d
  320.     pop    b
  321.     pop    h
  322.     ret
  323. ;
  324. prn$ost:
  325. prn$ini:
  326.     xra    a
  327.     ora    a
  328.     ret
  329. ;
  330. ; Initializations.
  331. ;
  332. ini$vid:
  333.     xra    a
  334.     sta    curatt            ; Select attribute 0
  335.     sta    curvid
  336.     ret
  337. ;
  338. ;================================================================
  339. ;        Terminal Function Codes
  340. ;================================================================
  341. ;
  342. ; General purpose function codes
  343. ;
  344. xyfn:    db    02,01bh,'=',00,00    ; xy addressing
  345. ;
  346. rowcol:    db    00            ; 00 means row first
  347. xoff:    db    32            ; X offset
  348. yoff:    db    32            ; Y offset
  349. cdly:    db    01            ; Cursor positioning delay qty
  350. ;
  351. cpfn    db    02,01bh,'*',00,00    ; erase whole page
  352. clfn    db    02,01bh,'T',00,00    ; erase to end of line
  353. epfn    db    02,01bh,'Y',00,00    ; erase to end of page
  354. ecfn    db    03,01bh,'.','1',0    ; enable cursor function
  355. dcfn    db    03,01bh,'.','0',0    ; disable cursor function
  356. ;
  357. attset:
  358.     db    2,01bh,029h,00,00    ; Start half intensity
  359.     db    2,01bh,05eh,00,00    ; Start blinking
  360.     db    2,01bh,06ah,00,00    ; Start reverse video
  361.     db    2,01bh,06ch,00,00    ; Start underline
  362.     db    4,01bh,029h,01bh,05eh    ; Start half-blinking
  363.     db    4,01bh,06ah,01bh,05eh    ; Start reverse-blinking
  364.     db    0,00,00,00,00        ; Start underline
  365. ;
  366. attclr:
  367.     db    02,01bh,028h,00,00    ; End half intensity
  368.     db    02,01bh,071h,00,00    ; End blinking
  369.     db    02,01bh,06bh,00,00    ; End reverse video
  370.     db    02,01bh,06dh,00,00    ; End underline
  371.     db    4,01bh,071h,01bh,028h    ; End half-blinking
  372.     db    4,01bh,071h,01bh,06bh    ; End reverse-blinking
  373.     db    0,00,00,00,00        ; end
  374. ;
  375. ;
  376. ;-----------------
  377. ; Clear the screen
  378. ;-----------------
  379. ;
  380. clear:
  381.     push    b
  382.     push    h            ; save
  383.     push    psw
  384.     lxi    h,cpfn            ; clear page function
  385.     jmp    do$fn            ; send the function and return
  386. ;
  387. ;----------------------------------------------------------------
  388. ; Clear the screen till the end of the line. This is highly
  389. ; terminal dependant and is table driven to suit.
  390. ;----------------------------------------------------------------
  391. ;
  392. cleol:
  393.     push    b
  394.     push    h            ; save
  395.     push    psw
  396.     lxi    h,clfn            ; clear page function
  397.     jr    do$fn            ; send the function and return
  398. ;
  399. ;----------------------------------------------------------------
  400. ; Clear to the end of the page. Same comments as the above fn.
  401. ;----------------------------------------------------------------
  402. ;
  403. cleop:
  404.     push    b
  405.     push    h            ; save
  406.     push    psw
  407.     lxi    h,epfn            ; clear page function
  408.     jr    do$fn            ; end of job
  409. ;
  410. ;-----------------------------------------------
  411. ; Set a visual attribute onto the video terminal
  412. ;         Attribute in register A
  413. ;-----------------------------------------------
  414. ;
  415. setatt:
  416.     cpi    numatt + 1    ; In range ??
  417.     rnc            ; Return tail B/N legs if too big
  418.     push    d
  419.     push    b
  420.     push    h
  421.     push    psw        ; Save the users attribute
  422.     mov    c,a        ; Save locally also
  423.     lda    curatt        ; Get the current attribute
  424.     cmp    c
  425.     jz    set$fin        ; Terminate if THE SAME
  426.     ora    a
  427.     jrz    doatt        ; If 00, no need to clear old one, already 0
  428. ;
  429. ; See if the current attribute is an illegal value. This may be because of
  430. ; rom based software first time through and a silly ram value. 
  431. ;
  432.     cpi    numatt + 1
  433.     jrnc    doatt        ; Silly old attribute, then set new one now.
  434. ;
  435. ; Here we must clear the old attribute before proceeding.
  436. ;
  437. clr$start:
  438.     dcr    a        ; Make the attribute in range
  439.     lxi    h,attclr    ; Point to the table of clear atts.
  440.     call    index
  441.     call    att$send    ; Send the attributes -> by HL
  442. doatt:
  443.     pop    psw        ; Get users attribute
  444.     sta    curatt        ; Save in ram.
  445.     ora    a        ; Is it attribute 00 ?
  446.     jrz    set$end        ; Ignore if so
  447.     dcr    a        ; Make in the correct range then
  448. ; Now index into the table of attribute setting bytes to get the req'd code.
  449.     lxi    h,attset    ; Point to start
  450.     call    index        ; Get hl -> start
  451.     call    att$send    ; Send attributes -> by HL
  452. ;
  453. ; Re-load registers and return.
  454. ;
  455. set$end:
  456.     pop    h
  457.     pop    b
  458.     pop    d
  459.     ret
  460. ;
  461. ; Restore registers when terminated
  462. ;
  463. set$fin:
  464.     pop    psw
  465.     jr    set$end
  466. ;
  467. ; This routine must use HL -> a counter byte to send
  468. ; the proceeeding bytes to the console.
  469. ;
  470. att$send:    
  471.     mov    a,m
  472.     ora    a        ; See if a null length ?
  473.     rz            ; Return if a null string
  474.     mov    b,a        ; Else load the length
  475. sloop:
  476.     inx    h        ; Point to next character
  477.     mov    a,m
  478.     call    con$out        ; Send
  479.     djnz    sloop
  480.     ret
  481. ;
  482. ;----------------------------------------------------------------
  483. ; This routine that follows simply indexes into the table 
  484. ; of bytes. Each table entry is assumed to be 5 bytes long.
  485. ;
  486. ; On entry hl -> start of table, on exit hl -> first element 
  487. ; in line (a)
  488. ;----------------------------------------------------------------
  489. ;
  490. index:    
  491.     ora    a
  492.     rz            ; Return if no loops needed
  493.     mvi    d,0        ; Clear upper register
  494.     mov    e,a        ; Load counter
  495. ; Multiply A by 5 then add to HL
  496.     add    a        ; * 2 (double original)
  497.     add    a        ; * 4
  498.     add    e        ; * 5 (add original)
  499.     mov    e,a        ; load into indexing register
  500.     dad    d        ; now HL -> start of this entry
  501.     ret            ; hl -> start of a line
  502. ;
  503. ; This routine uses HL to send the function to the screen.
  504. ;
  505. send$fn:
  506.     mov    a,m            ; test if this is not supported
  507.     ora    a
  508.     rz                ; not supported if no bytes to send
  509.     mov    b,a            ; load a counter
  510. send$fn2:
  511.     inx    h            ; get next byte
  512.     mov    a,m
  513.     call    con$out
  514.     djnz    send$fn2
  515.     ret
  516. ;
  517. ;----------------------------------------------------------------
  518. ; Send the function pointed to by HL to the terminal then exit
  519. ;----------------------------------------------------------------
  520. ;
  521. do$fn:
  522.     call    send$fn            ; send it.
  523. ; Fall through to the exit routine
  524. end$fn:
  525.     pop    psw
  526.     pop    h
  527.     pop    b
  528.     ret
  529. ;
  530. ;----------------------------------------------------------------
  531. ; Position the cursor to the value in DE. D = X, E = Y.
  532. ;----------------------------------------------------------------
  533. ;
  534. cursor:
  535.     push    b
  536.     push    h
  537.     push    psw            ; save registers
  538.     push    d            ; save the original
  539. ; Send the lead in string
  540.     lxi    h,xyfn            ; XY addressing lead in string
  541.     call    send$fn
  542. ; Now we must add the offsets to be applied to the X and Y values
  543.     lda    xoff
  544.     add    e            ; Y value
  545.     mov    e,a            ; save it
  546. ;
  547.     lda    yoff
  548.     add    d            ; X value
  549.     mov    d,a            ; save it also
  550. ; Now decode the row or column sent first decision
  551.     lda    rowcol            ; 00 = row first
  552.     ora    a
  553.     jrz    row$first
  554. ; Here and we are sending the column first (X value first)
  555.     mov    a,d            ; X value
  556.     call    con$out
  557.     mov    a,e            ; Y next
  558.     jr    row$first2
  559. ; Here and we send the row first for cursor addressing
  560. row$first:
  561.     mov    a,e            ; Y value
  562.     call    con$out
  563.     mov    a,d            ; X value next
  564. row$first2:
  565.     call    con$out
  566.     pop    d            ; restore original cursor address
  567. ; Now do any delays required
  568.     lda    cdly
  569. cursor$delay:
  570.     ora    a
  571.     jrz    end$fn            ; End of job
  572.     push    psw
  573.     mvi    a,0ffh            ; Loop counter
  574. cd$loop:
  575.     nop                ; Extra waits
  576.     dcr    a
  577.     jrnz    cd$loop            ; Loop till A = 0
  578.     pop    psw
  579.     dcr    a            ; One done.
  580.     jr    cursor$delay
  581. ;
  582. ;----------------------------------------------------------------
  583. ;            Write bytes at mDE till a null
  584. ;----------------------------------------------------------------
  585. ;
  586. wrt$vid:
  587.     ldax    d
  588.     ora    a
  589.     rz
  590.     call    con$out
  591.     inx    d
  592.     jr    wrt$vid
  593. ;
  594.     dseg
  595. ;
  596. hrs    ds    1
  597. min    ds    1
  598. sec    ds    1
  599. ;
  600. curatt    db    00
  601. curvid    db    00
  602.     end
  603. ;
  604. ;
  605. ;
  606.