home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol049 / modem.asm < prev    next >
Assembly Source File  |  1984-04-29  |  11KB  |  500 lines

  1.     TITLE    'MODEM - PL/1 DC HAYES MODEM SUBROUTINES'
  2. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  3. ;
  4. ;    MODEM I/O AND CONTROL SUBROUTINES FOR DC HAYES MODEM
  5. ;    (ADAPTED FROM MICROMODEM 100 PROGRAM)
  6. ;    (ADAPTED AGAIN TO RUN WITH PL/1 ON AUGUST 30, 1980)
  7. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  8.  
  9. ;      ASSEMBLER STUFF
  10.     NAME    'MODEM'
  11. MODEM:    CSEG
  12. FALSE:    EQU    0        ;TRUE/FALSE SUBSTITUTIONS
  13. TRUE:    EQU    NOT FALSE
  14.  
  15. ;         PORT ASSIGNMENTS
  16.  
  17. DATA    EQU    80H        ;DATA I/O PORT
  18. STAT    EQU    DATA+1        ;STATUS PORT
  19. MODE    EQU    DATA+2        ;MODE CONTROL PORT
  20. CR1    EQU    DATA+1        ;CONTROL REG 1
  21. CR2    EQU    DATA+2        ;CONTROL REG 2
  22. CR3    EQU    DATA+3        ;CONTROL REG 3
  23.  
  24.  
  25. ;      BIT FUNCTIONS
  26.  
  27. ;STATUS REGISTER
  28. RRF    EQU    001H        ;RECEIVE REGISTER FULL
  29. TRE    EQU    002H        ;TRANSMITTER HOLDING REGISTER EMPTY
  30. PE    EQU    004H        ;PARITY ERROR
  31. FE    EQU    008H        ;FRAMING ERROR
  32. OE    EQU    010H        ;DATA OVERRUN ERROR
  33. TMR    EQU    020H        ;TIMER STATUS
  34. CD    EQU    040H        ;CARRIER PRESENT
  35. RI    EQU    080H        ;NOT RING INDICATOR (LOW TRUE)
  36.  
  37. ;CONTROL REGISTER 1 (CR1)
  38. EPE    EQU    001H        ;EVEN PARITY ENABLE
  39. LS1    EQU    002H        ;WORD LENGTH SELECT BIT 1
  40. LS2    EQU    004H        ;WORD LENGTH SELECT BIT 2
  41. SBS    EQU    008H        ;STOP BITS
  42. PI    EQU    010H        ;PARITY INHIBIT
  43. TMIE    EQU    020H        ;TIMER INTERRUPTS ENABLE
  44.  
  45. ;CONTROL REGISTER 2 (CR2)
  46. BRS    EQU    001H        ;BAUD RATE CONTROL
  47. TXE    EQU    002H        ;TRANSMIT CARRIER ENABLE
  48. MS    EQU    004H        ;MODE (0=ANSWER 1=ORIGINATE)
  49. BRK    EQU    008H        ;SEND BREAK
  50. ST    EQU    010H        ;SELF TEST
  51. TIE    EQU    020H        ;TRANSMITTER INTERRUPT ENABLE
  52. RIE    EQU    040H        ;RECEIVER INTERRUPT ENABLE
  53. OH    EQU    080H        ;OFF-HOOK
  54.  
  55.  
  56. ;        * * *  RESET MODEM  * * *
  57. MDMRST:
  58.     PUBLIC    MDMRST
  59.     XRA    A    ;ZERO CONTROL REGS.
  60.     OUT    CR1
  61.     OUT    CR2
  62.     STA    MICR1    ;  AND MEMORY IMAGES OF REGISTERS.
  63.     STA    MICR2
  64.     RET
  65.  
  66. ;        * * *  TRANSMIT CHAR  * * *
  67. ;    THIS ROUTINE SENDS A BYTE IN REGISTER C TO THE MODEM
  68. ;    TRANSMITTER.  ONLY REGISTER A IS DISTURBED.
  69. MDMTXC:
  70.     PUBLIC    MDMTXC
  71.     CALL    PLICHR    ;GET THE CHAR TO OUTPUT.
  72. MDMTXC$DIR:
  73.     IN    STAT    ;GET MODEM STATUS.
  74.     ANI    TXE    ;XMIT BUFFER EMPTY?
  75.     JZ    MDMTXC$DIR ;...YES, LOOP.
  76.     MOV    A,C    ;...NO, SEND THE BYTE.
  77.     OUT    DATA
  78.     RET
  79.  
  80. ;        * * *  RECEIVE CHAR  * * *
  81. ;    THIS ROUTINE RECEIVES A BYTE FROM THE MODEM RECEIVER
  82. ;    IN REGISTER A.
  83. MDMRXC:
  84.     PUBLIC    MDMRXC
  85.     IN    STAT    ;GET MODEM STATUS.
  86.     ANI    RRF    ;RECV BUFFER EMPTY?
  87.     JZ    MDMRXC    ;...YES, LOOP.
  88.     IN    DATA    ;...NO, GET DATA.
  89.     ANI    07FH    ;STRIP PARITY.
  90.     RET
  91.  
  92. ;        * * *  GET RECV STATUS  * * *
  93. ;    THIS ROUTINE RETURNS A=TRUE IF A RECEIVED CHARACTER
  94. ;    IS WAITING OR A=FALSE IF NOT.
  95. MDMRXS:
  96.     PUBLIC    MDMRXS
  97.     IN    STAT    ;GET MODEM STATUS.
  98.     ANI    RRF    ;RECV BUFFER EMPTY?
  99.     MVI    A,FALSE
  100.     RZ        ;...YES, RETURN A=FALSE.
  101.     MVI    A,TRUE    ;...NO, RETURN A=TRUE
  102.     RET
  103.  
  104. ;        * * *  CHECK CARRIER STATUS  * * *
  105. ;    THIS ROUTINE RETURNS TRUE IF CARRIER IS PRESENT.
  106. MDMCDS:
  107.     PUBLIC    MDMCDS
  108.     IN    STAT    ;GET MODEM STATUS.
  109.     ANI    CD    ;CARRIER DETECTED?
  110.     MVI    A,FALSE
  111.     RZ        ;...NO.
  112.     MVI    A,TRUE    ;...YES.
  113.     RET
  114.  
  115. ;        * * *  CHECK RING STATUS  * * *
  116. ;    THIS ROUTINE CHECKS FOR PHONE RINGING RETURNING
  117. ;    TRUE IF SO.
  118. MDMRIS:
  119.     PUBLIC    MDMRIS
  120.     IN    STAT    ;GET MODEM STATUS.
  121.     ANI    RI    ;PHONE RINGING?
  122.     MVI    A,TRUE
  123.     RZ        ;...YES.
  124.     MVI    A,FALSE
  125.     RET
  126.  
  127. ;        * * *  CHECK FOR MODEM ERROR  * * *
  128. ;    THIS ROUTINE RETURNS THE MODEM ERROR FLAGS IN
  129. ;    REGISTER A.  A=0 IF NO ERRORS.  OTHERWISE,
  130. ;    BIT 0 = PARITY ERROR  BIT 1 = FRAMING ERROR
  131. ;    BIT 2 = OVERRUN ERROR
  132. MDMERR:
  133.     PUBLIC    MDMERR
  134.     IN    STAT    ;GET MODEM STATUS.
  135.     RAR        ;SHIFT BITS RIGHT 2 PLACES.
  136.     RAR
  137.     ANI    7    ;KILL UNWANTED BITS.
  138.     RET
  139.  
  140. ;        * * *  CARRIER CONTROL  * * *
  141. ;    THIS ROUTINE TURNS THE CARRIER ON/OFF ACCORDING
  142. ;    TO REGISTER C.  C=FALSE FOR OFF; C=TRUE FOR ON.
  143. MDMCRC:
  144.     PUBLIC    MDMCRC
  145.     CALL    PLICHR    ;GET THE COMMAND.
  146. MDMCRC$DIR:
  147.     MOV    A,C
  148.     ORA    A
  149.     MVI    A,TXE    ;CARRIER CONTROL BIT.
  150.     JZ    MDMCC2    ;CLEAR IT IF A=FALSE.
  151.     JMP    MDMSC2    ;SET IT IF A=TRUE.
  152.  
  153. ;        * * *  BAUD RATE CONTROL  * * *
  154. ;    THIS ROUTINE SETS THE BAUD RATE GIVEN BY REGISTER
  155. ;    C.  C=FALSE FOR 110; C=TRUE FOR 300.
  156. MDMBDC:
  157.     PUBLIC    MDMBDC
  158.     CALL    PLICHR    ;GET THE COMMAND.
  159. MDMBDC$DIR:
  160.     MOV    A,C
  161.     ORA    A
  162.     MVI    A,BRS    ;BAUD RATE SELECT BIT.
  163.     JZ    MDMCC2    ;CLEAR IT IF A=FALSE.
  164.     JMP    MDMSC2    ;SET IT IF A=TRUE.
  165.  
  166. ;        * * *  HOOK CONTROL  * * *
  167. ;    THIS ROUTINE SETS THE HOOK ON OR OFF ACCORDING
  168. ;    TO REGISTER C.  C=FALSE FOR ON (IDLE); C=TRUE
  169. ;    FOR OFF (ACTIVE).
  170. MDMSWH:
  171.     PUBLIC    MDMSWH
  172.     CALL    PLICHR    ;GET THE COMMAND.
  173. MDMSWH$DIR:
  174.     MOV    A,C
  175.     ORA    A
  176.     MVI    A,OH    ;HOOK CONTROL BIT.
  177.     JZ    MDMCC2    ;CLEAR IT IF A=FALSE.
  178.     JMP    MDMSC2    ;SET IT IF A=TRUE.
  179.  
  180. ;        * * *  GET HOOK STATUS  * * *
  181. ;    THIS ROUTINE RETURNS THE HOOK STATUS IN REGISTER
  182. ;    A.  A=TRUE FOR OFF-HOOK; A=FALSE FOR ON-HOOK.
  183. MDMSHS:
  184.     PUBLIC    MDMSHS
  185.     LDA    MICR2    ;GET CR2.
  186.     ANI    OH    ;MASK FOR OFF-HOOK.
  187.     MVI    A,TRUE
  188.     RNZ        ;...OFF-HOOK.
  189.     MVI    A,FALSE ;...ON-HOOK.
  190.     RET
  191.  
  192. ;        * * *  MODE CONTROL  * * *
  193. ;    THIS ROUTINE SETS THE MODE (ANSWER OR ORIGINATE)
  194. ;    ACCORDING TO REGISTER C.  C=FALSE FOR ANSWER;
  195. ;    C=TRUE FOR ORIGINATE.
  196. MDMMOD:
  197.     PUBLIC    MDMMOD
  198.     CALL    PLICHR    ;GET THE COMMAND.
  199. MDMMOD$DIR:
  200.     MOV    A,C
  201.     ORA    A
  202.     MVI    A,MS    ;MODE SELECT BIT.
  203.     JZ    MDMCC2    ;CLEAR IT IF A=FALSE.
  204.     JMP    MDMSC2    ;SET IT IF A=TRUE.
  205.  
  206. ;        * * *  SELF-TEST CONTROL  * * *
  207. ;    THIS ROUTINE SETS THE SELF-TEST MODE
  208. ;    ACCORDING TO REGISTER C.  C=FALSE FOR NORMAL;
  209. ;    C=TRUE FOR SELF-TEST.
  210. MDMSLT:
  211.     PUBLIC    MDMSLT
  212.     CALL    PLICHR    ;GET THE COMMAND.
  213. MDMSLT$DIR:
  214.     MOV    A,C
  215.     ORA    A
  216.     MVI    A,ST    ;SELF TEST BIT.
  217.     JZ    MDMCC2    ;CLEAR IT IF A=FALSE.
  218.     JMP    MDMSC2    ;SET IT IF A=TRUE.
  219.  
  220. ;        * * *  SEND BREAK  * * *
  221. ;    THIS ROUTINE SENDS A BREAK CONSISTING OF A
  222. ;    SPACE (LOW TONE) FOR A NUMBER OF 50 MS IN-
  223. ;    TERVALS SPECIFIED BY REGISTER C.
  224. MDMBRK:
  225.     PUBLIC    MDMBRK
  226.     CALL    PLICHR    ;GET # OF INTERVALS.
  227. MDMBRK$DIR:
  228.     PUSH    B
  229.     MVI    C,2    ;WAIT 100 MS.
  230.     CALL    MDMDLY$DIR
  231.     POP    B
  232.     PUSH    H    ;SET THE BREAK BIT.
  233.     LXI    H,MICR2
  234.     MVI    A,BRK
  235.     ORA    M
  236.     OUT    CR2
  237.     CALL    MDMDLY$DIR ;DELAY (C)*50 MS.
  238.     MVI    A,BRK    ;RESET BREAK BIT.
  239.     CMA
  240.     ANA    M
  241.     OUT    CR2
  242.     POP    H
  243.     RET
  244.  
  245. ;        * * *  SET PARITY  * * *
  246. ;    THIS ROUTINE SETS THE PARITY ACCORDING TO REG C.
  247. ;    C=0 FOR NO PARITY, C=1 FOR ODD PARITY AND C=2
  248. ;    FOR EVEN PARITY.
  249. MDMPAR:
  250.     PUBLIC    MDMPAR
  251.     CALL    PLICHR    ;GET THE COMMAND.
  252. MDMPAR$DIR:
  253.     MOV    A,C    ;TEST FOR NO PARITY.
  254.     ORA    A
  255.     JZ    MDMPAF    ;TURN OFF PARITY.
  256.     MVI    A,PI    ;CLEAR PARITY INHIBIT BIT.
  257.     CALL    MDMCC1
  258.     MOV    A,C    ;SET LSB FOR EVEN/ODD PARITY.
  259.     RAR
  260.     ANI    1
  261.     MVI    A,EPE    ;CLEAR EPE IF ODD.
  262.     JZ    MDMCC1
  263.     JMP    MDMSC1    ;SET EPE IF EVEN.
  264. MDMPAF:
  265.     MVI    A,PI    ;INHIBIT PARITY.
  266.     JMP    MDMSC1
  267.  
  268. ;        * * *  SELECT WORD LENGTH  * * *
  269. ;    THIS ROUTINE SETS THE WORD LENGTH ACCORDING TO REG C.
  270. ;    C = NUMBER OF BITS (5,6,7,8)
  271. MDMWLN:
  272.     PUBLIC    MDMWLN
  273.     CALL    PLICHR    ;GET THE COMMAND.
  274. MDMWLN$DIR:
  275.     MOV    A,C    ;REMOVE BIAS.
  276.     SUI    5
  277.     RC
  278.     CPI    3+1
  279.     CMC
  280.     RC
  281.     ADD    A    ;SHIFT LEFT 1 PLACE.
  282.     MOV    C,A    ;SAVE RESULT.
  283.     LDA    MICR1    ;GET MEMORY IMAGE.
  284.     ANI    NOT LS1+LS2 ;CLEAR WORD LENGTH BITS.
  285.     ORA    C    ;PUT IN NEW ONES.
  286.     STA    MICR1    ;UPDATE MEMORY IMAGE.
  287.     OUT    CR1    ;WRITE IT TO MODEM.
  288.     RET
  289.  
  290. ;        * * *  SET NUMBER OF STOP BITS  * * *
  291. ;    THIS ROUTINE SETS THE NUMBER OF STOP BITS ACCORDING
  292. ;    TO REGISTER C.  C = STOP BITS (1 OR 2)
  293. MDMNST:
  294.     PUBLIC    MDMNST
  295.     CALL    PLICHR    ;GET THE COMMAND.
  296. MDMNST$DIR:
  297.     MOV    A,C    ;REMOVE BIAS.
  298.     SUI    1
  299.     RC
  300.     CPI    1+1
  301.     CMC
  302.     RC
  303.     ORA    A
  304.     MVI    A,SBS    ;STOP BIT SELECT BIT.
  305.     JZ    MDMCC1    ;CLEAR IT.
  306.     JMP    MDMSC1
  307.  
  308. ;        * * *  DELAY ROUTINE  * * *
  309. ;    THIS ROUTINE WAITS 50MS TIMES THE VALUE OF THE
  310. ;    REGISTER C.
  311. MDMDLY:
  312.     PUBLIC    MDMDLY
  313.     CALL    PLICHR    ;GET THE TIME AMOUNT.
  314. MDMDLY$DIR:
  315.     MOV    A,C
  316.     ORA    A    ;IF ZERO, DON'T WAIT.
  317.     RZ
  318.     PUSH    B
  319. MDMDL1:
  320.     OUT    CR3    ;START TIMER.
  321. MDMDL2:
  322.     IN    STAT    ;WAIT TILL TIMER BIT
  323.     ANI    TMR    ;TIMES OUT.
  324.     JZ    MDMDL2
  325.     DCR    C    ;LOOP (C) TIMES.
  326.     JNZ    MDMDL1
  327.     POP    B
  328.     RET
  329.  
  330. ;        * * *  START 50MS TIMER  * * *
  331. MDMSTM:
  332.     PUBLIC    MDMSTM
  333.     OUT    CR3
  334.     RET
  335.  
  336. ;        * * *  CHECK TIMER STATUS  * * *
  337. MDMCTM:
  338.     IN    STAT    ;GET MODEM STATUS.
  339.     ANI    TMR    ;TIME OUT?
  340.     MVI    A,TRUE
  341.     RNZ        ;...YES.
  342.     MVI    A,FALSE
  343.     RET
  344.  
  345. ;        * * *  GO OFF HOOK  * * *
  346. ;    THIS ROUTINE GOES OFF HOOK AND WAITS FOR A DIAL TONE.
  347. ;    MICROMODEM HAS NO DIAL TONE DETECTOR.  WE JUST GO OFF
  348. ;    HOOK, WAIT 2 SEC, ASSUME A DIAL TONE IS PRESENT AND
  349. ;    RETURN.
  350. MDMDLT:
  351.     PUBLIC    MDMDLT
  352.     PUSH    B
  353.     MVI    C,TRUE    ;GO OFF-HOOK.
  354.     CALL    MDMSWH$DIR
  355.     MVI    C,40    ;WAIT 2 SECONDS.
  356.     CALL    MDMDLY$DIR
  357.     POP    B
  358.     RET
  359.  
  360. ;        * * *  DIAL PULSE GENERATION  * * *
  361. ;    THIS ROUTINE GENERATES A DIALING PULSE FOR THE DIGIT
  362. ;    IN REGISTER C.  IF C=0 THEN 10 PULSES WILL BE
  363. ;    PRODUCED.  THE DIGIT IN THE C REGISTER MAY BE
  364. ;    BINARY OR ASCII.  AFTER THE DIGIT IS OUT-PULSED,
  365. ;    THIS ROUTINE WILL PAUSE FOR 600 MS FOR INTER-DIGIT
  366. ;    SPACING.
  367. MDMPLS:
  368.     PUBLIC    MDMPLS
  369.     CALL    PLICHR    ;GET THE DIGIT.
  370. MDMPLS$DIR:
  371.     PUSH    B
  372.     MOV    A,C    ;GET DIGIT.
  373.     MVI    B,10    ;PRE-LOAD PULSE COUNTER
  374.     ANI    00FH    ;KILL POSSIBLE ASCII BIAS.
  375.     CPI    0    ;SEE IF WE'RE DOING 10 PULSES.
  376.     JZ    MDMPL1
  377.     MOV    B,A    ;PULSE COUNT TO B
  378. MDMPL1:
  379.     MVI    C,FALSE    ;GO ON-HOOK.
  380.     CALL    MDMSWH$DIR
  381.     MVI    C,1    ;WAIT 50 MS.
  382.     CALL    MDMDLY$DIR
  383.     MVI    C,TRUE    ;GO OFF-HOOK AGAIN.
  384.     CALL    MDMSWH$DIR
  385.     MVI    C,1    ;DELAY 50 MS.
  386.     CALL    MDMDLY$DIR
  387.     DCR    B    ;LOOP FOR ALL PULSES.
  388.     JNZ    MDMPL1
  389.     MVI    C,11    ;WAIT 550 MS.
  390.     CALL    MDMDLY$DIR
  391.     POP    B
  392.     RET
  393.  
  394. ;        * * *  DIAL A NUMBER  * * *
  395. ;    THIS ROUTINE GENERATES ALL THE DIALING PULSES
  396. ;    FOR A NUMBER GIVEN AS A VARYING CHARACTER STRING.
  397. ;    THEREFORE, IT DIALS THE NUMBER.
  398. MDMDLN:
  399.     PUBLIC    MDMDLN
  400.     CALL    MDMDLT    ;GET DIAL TONE.
  401.     CALL    PLICHR    ;GET THE STRING LENGTH IN C.
  402.     ORA    A    ;LENGTH=ZERO?
  403.     RZ        ;...YES, RETURN.
  404.     INX    H    ;BUMP TO BEGINNING OF STRING.
  405. MDMDLN$LP:
  406.     MOV    A,M    ;GET THE NEXT NUMBER.
  407.     CPI    '*'    ;DELAY?
  408.     JNZ    MDMDLN$NUM ;...YES.
  409.     PUSH    B
  410.     MVI    C,40    ;WAIT 2 SEC.
  411.     CALL    MDMDLY$DIR
  412.     POP    B
  413.     JMP    MDMDLN$NXT ; GET NEXT CHAR.
  414. MDMDLN$NUM:
  415.     CPI    '9'+1    ;ASCII 0-9?
  416.     JNC    MDMDLN$NXT ;...NO, SKIP IT.
  417.     CPI    '0'
  418.     JC    MDMDLN$NXT ;...NO, SKIP IT.
  419.     PUSH    B    ;SAVE CURRENT COUNT.
  420.     MOV    C,A    ;PULSE OUT THE NUMBER.
  421.     CALL    MDMPLS$DIR
  422.     POP    B
  423. MDMDLN$NXT:
  424.     INX    H    ;BUMP PTR.
  425.     DCR    C    ;DECREMENT COUNT.
  426.     RZ        ;RETURN IF NO MORE DIGITS.
  427.     JMP    MDMDLN$LP ;GO PULSE ANOTHER DIGIT.
  428.  
  429. ;        * * *  SET CR1  * * *
  430. ;    THIS ROUTINE SETS BITS IN CONTROL REGISTER
  431. ;    1.  REGISTER A HAS 1'S WHERE BITS ARE TO
  432. ;    BE SET.
  433. MDMSC1:
  434.     PUSH    H
  435.     LXI    H,MICR1    ;OR IN BITS TO SET.
  436.     ORA    M
  437.     MOV    M,A    ;SAVE RESULT.
  438.     OUT    CR1    ;SET THE MODEM.
  439.     POP    H
  440.     RET
  441.  
  442. ;        * * *  CLEAR CR1 * * *
  443. ;    THIS ROUTINE CLEARS THE BITS IN CONTROL REGISTER
  444. ;    1.  REGISTER A HAS 1'S FOR THE BITS TO BE CLEARED.
  445. MDMCC1:
  446.     PUSH    H
  447.     LXI    H,MICR1    ;MEMORY IMAGE OF CR1.
  448.     CMA
  449.     ANA    M    ;TURN OFF THE BIT.
  450.     MOV    M,A    ;UPDATE MEMORY.
  451.     OUT    CR1    ;UPDATE MODEM.
  452.     POP    H
  453.     RET
  454.  
  455. ;        * * *  SET CR2  * * *
  456. ;    THIS ROUTINE SETS BITS IN CONTROL REGISTER
  457. ;    2.  REGISTER A HAS 1'S WHERE BITS ARE TO
  458. ;    BE SET.
  459. MDMSC2:
  460.     PUSH    H
  461.     LXI    H,MICR2    ;OR IN BITS TO SET.
  462.     ORA    M
  463.     MOV    M,A    ;SAVE RESULT.
  464.     OUT    CR2    ;SET THE MODEM.
  465.     POP    H
  466.     RET
  467.  
  468. ;        * * *  CLEAR CR2 * * *
  469. ;    THIS ROUTINE CLEARS THE BITS IN CONTROL REGISTER
  470. ;    2.  REGISTER A HAS 1'S FOR THE BITS TO BE CLEARED.
  471. MDMCC2:
  472.     PUSH    H
  473.     LXI    H,MICR2    ;MEMORY IMAGE OF CR2.
  474.     CMA
  475.     ANA    M    ;TURN OFF THE BIT.
  476.     MOV    M,A    ;UPDATE MEMORY.
  477.     OUT    CR2    ;UPDATE MODEM.
  478.     POP    H
  479.     RET
  480.  
  481. ;        * * *  GET PL/I PARAMETER * * *
  482. ;    THIS ROUTINE GETS A PL/I PARAMETER ACCORDING TO 
  483. ;    ITS STANDARD CALLING CONVENTIONS.
  484. PLICHR:
  485.     PUSH    D    ;SAVE DE.
  486.     MOV    E,M    ;GET PARM PTR FROM 0(HL).
  487.     INX    H
  488.     MOV    D,M
  489.     LDAX    D    ;GET THE ONE BYTE PARM.
  490.     MOV    C,A    ;PUT IT IN (C).
  491.     XCHG        ;PUT PARM PTR IN HL.
  492.     POP    D
  493.     RET
  494.  
  495. ;        * * *  DATA AREA FOR MODEM I/O  * * *
  496.     DSEG
  497. MICR1:    DB    0    ;MEMORY IMAGE OF CONTROL REGISTER 1
  498. MICR2:    DB    0    ;MEMORY IMAGE OF CONTROL REGISTER 2
  499.     END
  500.