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 / CPM / ZCPR33 / A-R / IOPUG.LBR / IOPSRC.SZ / IOPSRC.SI
Text File  |  2000-06-30  |  21KB  |  613 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. .PN 1
  7. .FO                                B-#
  8. B. Source Code for a Sample IOP
  9.  
  10.      Thi≤ Appendi° present≤ thσ sourcσ codσ oµ ß samplσ IO╨ whicΦ ì
  11. ha≤á beeε testeΣ anΣ used«á  Thσ line≤ arσ numbereΣ fo≥ referencσ ì
  12. purposes«á  Also¼ thσ assembly¼ linking¼ anΣ loadinτ (b∙ LDR⌐ anΣ ì
  13. usσ oµ thσ IO╨ i≤ illustrateΣ b∙ ß termina∞ session.
  14.  
  15.  
  16. B.1. Sample IOP Source
  17. .uj 0
  18.  
  19.     1: ;
  20.     2: ;  SAMPLE IOP for study
  21.     3: ;  by Richard Conn
  22.     4: ;  7/14/85
  23.     5: ;
  24.     6: iop     equ     0EC00H  ;base address of IOP
  25.     7: ;
  26.     8: ctrls   equ     'S'-'@' ;^S
  27.     9: ctrlz   equ     'Z'-'@' ;^Z
  28.    10: ;
  29.    11:         org     iop
  30.    12: 
  31.    13: ;
  32.    14: ;  The IOP jump table
  33.    15: ;
  34.    16:         jmp     status
  35.    17:         jmp     select
  36.    18:         jmp     namer
  37.    19:         jmp     init
  38.    20: ;
  39.    21:         jmp     const
  40.    22:         jmp     conin
  41.    23:         jmp     conout
  42.    24:         jmp     list
  43.    25:         jmp     punch
  44.    26:         jmp     reader
  45.    27:         jmp     listst
  46.    28: ;
  47.    29:         jmp     patch
  48.    30: ;
  49.    31:         jmp     copen
  50.    32:         jmp     cclose
  51.    33:         jmp     lopen
  52.    34:         jmp     lclose
  53.    35: ;
  54.    36: ;  IOP ID (required for LDR)
  55.    37: ;
  56.    38:         db      'Z3IOP'
  57.  
  58. .paè
  59.    39: 
  60.    40: ;
  61.    41: ;  The following is the IOP Status Table
  62.    42: ;
  63.    43: ioptable:
  64.    44: con:    db      5,0     ;5 consoles, select console 0
  65.    45: rdr:    db      1,0     ;1 reader, select reader 0
  66.    46: pun:    db      1,0     ;1 punch, select punch 0
  67.    47: lst:    db      2,0     ;2 lists, select list 0
  68.    48: 
  69.    49: ;
  70.    50: ;  The status routine
  71.    51: ;       Return the address of the IOP Status Table in HL
  72.    52: ;       Return the IOP number in A
  73.    53: ;       This IOP supports recording, so set MSB of A
  74.    54: ;
  75.    55: status:
  76.    56:         lxi     h,ioptable      ;pointer to table
  77.    57:         mvi     a,82h           ;IO Recorder supported, IOP 2
  78.    58:         ora     a               ;set NZ flag
  79.    59:         ret
  80.    60: 
  81.    61: ;
  82.    62: ;  The select routine
  83.    63: ;       On input, B=logical device and C is driver
  84.    64: ;       On output, A=0 and zero flag set if error
  85.    65: ;
  86.    66: select:
  87.    67:         lxi     h,ioptable      ;pt to IOP table
  88.    68:         mov     a,b             ;double B so offset is 0,2,4,6
  89.    69:         cpi     4               ;make sure in range 0-3
  90.    70:         jnc     selerr
  91.    71:         add     b
  92.    72:         mov     e,a             ;DE = offset
  93.    73:         mvi     d,0
  94.    74:         dad     d               ;HL now points to device in IOP
  95.    75:         mov     a,m             ;get max number of devices
  96.    76:         cmp     c               ;check for driver error
  97.    77:         jz      selerr          ;error if C = count
  98.    78:         jc      selerr          ;error if C > count
  99.    79:         inx     h               ;point to selected device byte
  100.    80:         mov     m,c             ;select the device
  101.    81:         mvi     a,0ffh          ;set OK return code
  102.    82:         ora     a
  103.    83:         ret
  104.    84: selerr:
  105.    85:         xra     a               ;set error return code
  106.    86:         ret
  107.    87: 
  108.  
  109. .paè
  110.    88: ;
  111.    89: ;  The Namer Routine
  112.    90: ;       On input, B = logical device and C = driver
  113.    91: ;       On output, HL = address of name string
  114.    92: ;       On output, A=0 and Zero Flag Set if error
  115.    93: ;
  116.    94: namer:
  117.    95:         lxi     h,ioptable      ;check to see that C is
  118.    96:         mov     a,b             ; in range ... begin by
  119.    97:         cpi     4               ; doubling B to 0,2,4,6
  120.    98:         jnc     namerror        ; after making sure in
  121.    99:         add     b               ; range 0-3
  122.   100:         mov     e,a             ;add offset to HL
  123.   101:         mvi     d,0
  124.   102:         dad     d               ;HL now points to IOP Table
  125.   103:         mov     a,m             ;get max device count
  126.   104:         cmp     c
  127.   105:         jz      namerror        ;error if C = count
  128.   106:         jc      namerror        ;error if C > count
  129.   107:         lxi     h,iopdnames     ;get address of logical
  130.   108:         dad     d               ; name table
  131.   109:         mov     e,m
  132.   110:         inx     h
  133.   111:         mov     d,m
  134.   112:         xchg                    ;HL now points to logical
  135.   113:         mov     a,c             ; name table - double C
  136.   114:         add     c               ; to get device driver name
  137.   115:         mov     e,a
  138.   116:         mvi     d,0             ;DE = offset
  139.   117:         dad     d               ;HL now points to driver name
  140.   118:         mov     e,m             ; address - get string address
  141.   119:         inx     h               ; in DE
  142.   120:         mov     d,m
  143.   121:         xchg                    ;HL now has string name address
  144.   122:         mvi     a,0ffh          ;set no error
  145.   123:         ora     a
  146.   124:         ret
  147.   125: namerror:
  148.   126:         lxi     h,errmsg        ;pt to some message
  149.   127:         xra     a               ;set error code
  150.   128:         ret
  151.   129: errmsg:
  152.   130:         db      'Name Error',0
  153.   131: 
  154.  
  155. .paè
  156.   132: ;
  157.   133: ;  This table gives the addresses of the address
  158.   134: ;  tables for each of the logical devices
  159.   135: ;
  160.   136: iopdnames:
  161.   137:         dw      connames
  162.   138:         dw      rdrnames
  163.   139:         dw      punnames
  164.   140:         dw      lstnames
  165.   141: ;
  166.   142: ;  These tables give the addresses of each of the
  167.   143: ;  logical device name strings
  168.   144: ;
  169.   145: connames:
  170.   146:         dw      conn1           ;there are 5 consoles
  171.   147:         dw      conn2           ; (see IOPTABLE above)
  172.   148:         dw      conn3
  173.   149:         dw      conn4
  174.   150:         dw      conn5
  175.   151: rdrnames:
  176.   152:         dw      rdrn1           ;there is 1 reader
  177.   153: punnames:
  178.   154:         dw      punn1           ;there is 1 punch
  179.   155: lstnames:
  180.   156:         dw      listn1          ;there are 2 lists
  181.   157:         dw      listn2
  182.   158: ;
  183.   159: ;  These are the actual text strings returned by NAMER
  184.   160: ;
  185.   161: conn1:  db      'CRT ',0
  186.   162: conn2:  db      'MODEM ',0
  187.   163: conn3:  db      'CRTMOD CRT and Modem in Parallel',0
  188.   164: conn4:  db      'CRTPRT CRT in and CRT/Printer out',0
  189.   165: conn5:  db      'TEST CRT by default',0
  190.   166: ;
  191.   167: rdrn1:  db      'MODEM ',0
  192.   168: ;
  193.   169: punn1:  db      'MODEM ',0
  194.   170: ;
  195.   171: listn1: db      'PRINTER ',0
  196.   172: listn2: db      'MODEM ',0
  197.   173: 
  198.  
  199. .paè
  200.   174: ;
  201.   175: ; This routine initializes the devices in the IOP
  202.   176: ;
  203.   177: init:
  204.   178:         mvi     a,0     ;set no IO Recording active
  205.   179:         sta     crec    ;console off
  206.   180:         sta     lrec    ;list off
  207.   181:         ret
  208.   182: 
  209.   183: ;
  210.   184: ;  This system has three pieces of hardware connected:
  211.   185: ;       1. a CRT
  212.   186: ;       2. a modem
  213.   187: ;       3. a printer
  214.   188: ;  All devices are hypothetical
  215.   189: ;  The following are the simple device drivers for them
  216.   190: ;
  217.   191: 
  218.   192: ;
  219.   193: ;  1. CRT
  220.   194: ;
  221.   195: crtdata equ     0F800H+3F8H     ;CRT data port
  222.   196: crtstat equ     0F800H+3F9H     ;CRT status port
  223.   197: crtrda  equ     4       ;RDA bit
  224.   198: crttbe  equ     8       ;TBE bit
  225.   199: 
  226.   200: ;  Return input status in A (A=0 means no char available)
  227.   201: crtistat:
  228.   202:         lda     crtstat ;check input status
  229.   203:         cma             ;status is inverted
  230.   204:         ani     crtrda  ;mask for RDA
  231.   205:         rz              ;0 if no char pending
  232.   206:         mvi     a,0ffh  ;return 0FFH if char pending
  233.   207:         ret
  234.   208: ;  Return output status in A (A=0 means not ready for output)
  235.   209: crtostat:
  236.   210:         lda     crtstat ;check output status
  237.   211:         cma             ;status is inverted
  238.   212:         ani     crttbe  ;mask for TBE
  239.   213:         rz              ;0 if not ready
  240.   214:         mvi     a,0ffh  ;0FFH if ready
  241.   215:         ret
  242.   216: ;  Return input byte in A (A=byte)
  243.   217: crtin:
  244.   218:         call    crtistat        ;wait for input
  245.   219:         jz      crtin
  246.   220:         lda     crtdata ;get byte
  247.   221:         cma             ;data is inverted
  248.   222:         ani     7fh     ;mask
  249.   223:         ret
  250.  
  251. .paè
  252.   224: ;  Output byte in C to device
  253.   225: crtout:
  254.   226:         call    crtostat        ;wait for ready
  255.   227:         jz      crtout
  256.   228:         mov     a,c     ;get char from C
  257.   229:         cma             ;invert data
  258.   230:         sta     crtdata ;put byte
  259.   231:         ret
  260.   232: 
  261.   233: 
  262.   234: ;
  263.   235: ;  2. Modem
  264.   236: ;
  265.   237: moddata equ     80H     ;Modem data port
  266.   238: modstat equ     81H     ;Modem status port
  267.   239: modrda  equ     2       ;RDA bit
  268.   240: modtbe  equ     1       ;TBE bit
  269.   241: 
  270.   242: ;  Return input status in A (A=0 means no char available)
  271.   243: modistat:
  272.   244:         in      modstat ;check input status
  273.   245:         ani     modrda  ;mask for RDA
  274.   246:         rz              ;0 if no char pending
  275.   247:         mvi     a,0ffh  ;return 0FFH if char pending
  276.   248:         ret
  277.   249: ;  Return output status in A (A=0 means not ready for output)
  278.   250: modostat:
  279.   251:         in      modstat ;check output status
  280.   252:         ani     modtbe  ;mask for TBE
  281.   253:         rz              ;0 if not ready
  282.   254:         mvi     a,0ffh  ;0FFH if ready
  283.   255:         ret
  284.   256: ;  Return input byte in A (A=byte)
  285.   257: modin:
  286.   258:         call    modistat        ;wait for input
  287.   259:         jz      modin
  288.   260:         in      moddata ;get byte
  289.   261:         ret
  290.   262: ;  Output byte in C to device with simple XON/XOFF Processing
  291.   263: modout:
  292.   264:         call    modistat        ;see if char pending
  293.   265:         jz      modout1         ;continue if not
  294.   266:         call    modin           ;get char
  295.   267:         cpi     ctrls           ;see if ^S
  296.   268:         jnz     modout1         ;continue if not
  297.   269:         call    modin           ;wait for any next char
  298.   270: modout1:
  299.   271:         call    modostat        ;wait for ready
  300.   272:         jz      modout
  301.   273:         mov     a,c     ;get char from C
  302.   274:         out     moddata ;put byte
  303.   275:         ret
  304.  
  305. .paè
  306.   276: 
  307.   277: 
  308.   278: ;
  309.   279: ;  3. Printer
  310.   280: ;
  311.   281: prtdata equ     20H     ;Printer data port
  312.   282: prtstat equ     25H     ;Printer status port
  313.   283: prtrda  equ     1       ;RDA bit
  314.   284: prttbe  equ     20H     ;TBE bit
  315.   285: 
  316.   286: ;  Return input status in A (A=0 means no char available)
  317.   287: prtistat:
  318.   288:         in      prtstat ;check input status
  319.   289:         ani     prtrda  ;mask for RDA
  320.   290:         rz              ;0 if no char pending
  321.   291:         mvi     a,0ffh  ;return 0FFH if char pending
  322.   292:         ret
  323.   293: ;  Return output status in A (A=0 means not ready for output)
  324.   294: prtostat:
  325.   295:         in      prtstat ;check output status
  326.   296:         ani     prttbe  ;mask for TBE
  327.   297:         rz              ;0 if not ready
  328.   298:         mvi     a,0ffh  ;0FFH if ready
  329.   299:         ret
  330.   300: ;  Return input byte in A (A=byte)
  331.   301: prtin:
  332.   302:         call    prtistat        ;wait for input
  333.   303:         jz      prtin
  334.   304:         in      prtdata ;get byte
  335.   305:         ret
  336.   306: ;  Output byte in C to device
  337.   307: prtout:
  338.   308:         call    prtostat        ;wait for ready
  339.   309:         jz      prtout
  340.   310:         mov     a,c     ;get char from C
  341.   311:         out     prtdata ;put byte
  342.   312:         ret
  343.   313: 
  344.  
  345. .paè
  346.   314: ;
  347.   315: ;  The following are the device selection routines
  348.   316: ;
  349.   317: const:
  350.   318:         lxi     h,tconst        ;point to driver table
  351.   319:         mvi     b,0             ;CON device
  352.   320:         jmp     drvrun          ;run driver
  353.   321: conin:
  354.   322:         lxi     h,tconin
  355.   323:         mvi     b,0
  356.   324:         jmp     drvrun
  357.   325: conout:
  358.   326:         call    crecord         ;send char to recorder if on
  359.   327:         lxi     h,tconout
  360.   328:         mvi     b,0
  361.   329:         jmp     drvrun
  362.   330: list:
  363.   331:         call    lrecord         ;send char to recorder if on
  364.   332:         lxi     h,tlist
  365.   333:         mvi     b,3             ;LST device
  366.   334:         jmp     drvrun
  367.   335: punch:
  368.   336:         lxi     h,tpunch
  369.   337:         mvi     b,2             ;PUN device
  370.   338:         jmp     drvrun
  371.   339: reader:
  372.   340:         lxi     h,treader
  373.   341:         mvi     b,1             ;RDR device
  374.   342:         jmp     drvrun
  375.   343: listst:
  376.   344:         lxi     h,tlistst
  377.   345:         mvi     b,3             ;LST device
  378.  
  379. .paè
  380.   346: ;
  381.   347: ;  The following routine selects the desired driver
  382.   348: ;       On input, B=logical device number
  383.   349: ;       IOPTABLE is used to find the current driver
  384.   350: ;       On input, HL=address of driver table
  385.   351: ;       Driver table contains address of all drivers
  386.   352: ;               which can be selected
  387.   353: ;
  388.   354: drvrun:
  389.   355:         push    h               ;save ptr to driver table
  390.   356:         lxi     h,ioptable      ;get selected driver number
  391.   357:         mov     a,b             ;double B for offset
  392.   358:         add     b
  393.   359:         mov     e,a
  394.   360:         mvi     d,0
  395.   361:         dad     d               ;HL pts to IOPTABLE entry
  396.   362:         inx     h               ;HL pts to selected driver
  397.   363:         mov     b,m             ;get selected driver in B
  398.   364:         mov     a,b             ; (C not used because it can
  399.   365:         add     b               ; contain a character if output
  400.   366:         mov     e,a             ; driver is being called)
  401.   367:         mvi     d,0
  402.   368:         pop     h               ;HL pts to driver table
  403.   369:         dad     d               ;HL pts to desired driver address
  404.   370:         mov     e,m
  405.   371:         inx     h
  406.   372:         mov     d,m
  407.   373:         xchg                    ;HL pts to driver
  408.   374:         pchl                    ;run the driver
  409.   375: 
  410.  
  411. .paè
  412.   376: ;
  413.   377: ;  These are the device driver tables
  414.   378: ;
  415.   379: tconst:
  416.   380:         dw      crtistat        ;selected driver 0 is CRT
  417.   381:         dw      modistat        ;selected driver 1 is Modem
  418.   382:         dw      crtmodist       ;selected driver 2 is CRT/Modem
  419.   383:         dw      crtistat        ;selected driver 3 is CRT in,
  420.   383:                                 ; Printer out
  421.   384: patistat:                       ;patch point for PATCH routine
  422.   385:         dw      crtistat        ;selected driver 4 is CRT
  423.   386: ;
  424.   387: tconin:
  425.   388:         dw      crtin
  426.   389:         dw      modin
  427.   390:         dw      crtmodin
  428.   391:         dw      crtin
  429.   392: patin:                          ;patch point for PATCH routine
  430.   393:         dw      crtin
  431.   394: ;
  432.   395: tconout:
  433.   396:         dw      crtout
  434.   397:         dw      modout
  435.   398:         dw      crtmodout
  436.   399:         dw      crtprtout
  437.   400: patout:                         ;patch point for PATCH routine
  438.   401:         dw      crtout
  439.   402: ;
  440.   403: tlist:
  441.   404:         dw      prtout          ;selected driver 0 is Printer
  442.   405:         dw      modout          ;selected driver 1 is Modem
  443.   406: ;
  444.   407: treader:
  445.   408:         dw      modin           ;selected driver 0 is Modem
  446.   409: ;
  447.   410: tpunch:
  448.   411:         dw      modout          ;selected driver 0 is Modem
  449.   412: ;
  450.   413: tlistst:
  451.   414:         dw      prtostat        ;selected driver 0 is Printer
  452.   415:         dw      modostat        ;selected driver 1 is Modem
  453.   416: 
  454.  
  455. .paè
  456.   417: ;
  457.   418: ;  This is the driver set for the combination CRT/Modem Device
  458.   419: ;  and the combination CRT/Printer Output Device
  459.   420: ;
  460.   421: crtmodist:
  461.   422:         call    crtistat        ;see if char available on CRT
  462.   423:         rnz                     ;return if so
  463.   424:         call    modistat        ;see if char available on Modem
  464.   425:         ret
  465.   426: crtmodin:
  466.   427:         call    crtistat        ;look for CRT char
  467.   428:         jnz     crtin           ;get char from CRT
  468.   429:         call    modistat        ;look for Modem char
  469.   430:         jnz     modin           ;get char from Modem
  470.   431:         jmp     crtmodin        ;continue until CRT or Modem
  471.   431:                                 ; gives char
  472.   432: crtmodout:
  473.   433:         call    crtout          ;send to CRT
  474.   434:         call    modout          ;send to Modem
  475.   435:         ret
  476.   436: crtprtout:
  477.   437:         call    crtout          ;send to CRT
  478.   438:         call    prtout          ;send to Printer
  479.   439:         ret
  480.   440: ;
  481.   441: ;  These are the drivers for the recorder output device
  482.   442: ;
  483.   443: crecord:
  484.   444:         lda     crec            ;check flag
  485.   445:         ora     a               ;0 means not recording
  486.   446:         rz
  487.   447:         call    modout          ;send char to modem to record
  488.   448:         ret
  489.   449: lrecord:
  490.   450:         lda     lrec            ;check flag
  491.   451:         ora     a               ;0 means not recording
  492.   452:         rz
  493.   453:         call    modout          ;send char to modem to record
  494.   454:         ret
  495.  
  496. .paè
  497.   455: ;
  498.   456: ;  These are the routines which enable device recording
  499.   457: ;  For this IOP, Console and Printer recording amounts to
  500.   458: ;       sending characters to the modem
  501.   459: ;
  502.   460: copen:
  503.   461:         mvi     a,0ffh          ;set flag
  504.   462:         sta     crec
  505.   463:         ret
  506.   464: cclose:
  507.   465:         mvi     a,0             ;clear flag
  508.   466:         sta     crec
  509.   467:         mvi     c,ctrlz         ;send ^Z to modem
  510.   468:         call    modout
  511.   469:         ret
  512.   470: lopen:
  513.   471:         mvi     a,0ffh          ;set flag
  514.   472:         sta     lrec
  515.   473:         ret
  516.   474: lclose:
  517.   475:         mvi     a,0             ;clear flag
  518.   476:         sta     lrec
  519.   477:         mvi     c,ctrlz         ;send ^Z to modem
  520.   478:         call    modout
  521.   479:         ret
  522.   480: ;
  523.   481: crec:   ds      1               ;flag buffer
  524.   482: lrec:   ds      1               ;flag buffer
  525.   483: 
  526.   484: ;
  527.   485: ;  This is the patch routine
  528.   486: ;  It sets the 5th device driver (driver select 4) to
  529.   487: ;       the drivers whose jump table is pointed to by
  530.   488: ;       HL; HL points to a table like the following:
  531.   489: ;               JMP     ISTAT
  532.   490: ;               JMP     INPUT
  533.   491: ;               JMP     OUTPUT
  534.   492: ;
  535.   493: patch:
  536.   494:         shld    patistat        ;set address of input status
  537.   495:         lxi     d,3             ;offset of 3
  538.   496:         dad     d
  539.   497:         shld    patin           ;set address of input char
  540.   498:         dad     d
  541.   499:         shld    patout          ;set address of output char
  542.   500:         ret
  543.   501: 
  544.   502:         end
  545.  
  546. .paè
  547. B.2. Terminal Session
  548.  
  549.  
  550. B1:ASM>lasm samiop.bbz
  551. LINKASM AS OF 7/06/81
  552.  
  553. SAMIOP  
  554. SAMIOP  
  555. EEAD
  556. 006H use factor
  557. 502 input lines read
  558. End of assembly
  559.  
  560. B1:ASM>mload samiop
  561. MLOAD ver. 2.4   Copyright (C) 1983, 1984, 1985
  562. by NightOwl Software, Inc.
  563. Loaded 683 bytes (02ABH) to file B1:SAMIOP.COM
  564. Start address: EC00H  Ending address: EEACH  Bias: 0000H
  565. Saved image size: 768 bytes (0300H, - 6 records)
  566.  
  567. ++ Warning: program origin NOT at 100H ++
  568.  
  569. B1:ASM>ren sample.iop=samiop.com
  570.  
  571. B1:ASM>ldr sample.iop
  572. ZCPR3 LDR, Version 1.3
  573.  Loading SAMPLE.IOP
  574.  
  575. B1:ASM>dev d a
  576.  
  577. CON: Devices --
  578.     TEST     - CRT by default
  579.     CRTPRT   - CRT in and CRT/Printer out
  580.     CRTMOD   - CRT and Modem in Parallel
  581.     MODEM    - 
  582.     CRT      - 
  583.  Assignment is CRT     
  584. RDR: Devices --
  585.     MODEM    - 
  586.  Assignment is MODEM   
  587. Strike Any Key -- 
  588. PUN: Devices --
  589.     MODEM    - 
  590.  Assignment is MODEM   
  591. LST: Devices --
  592.     MODEM    - 
  593.     PRINTER  - 
  594.  Assignment is PRINTER 
  595.  
  596. B1:ASM>dev c test
  597.  CON: Assignment is TEST    
  598.  
  599. .paè
  600. B1:ASM>dev d c
  601.  
  602. CON: Devices --
  603.     TEST     - CRT by default
  604.     CRTPRT   - CRT in and CRT/Printer out
  605.     CRTMOD   - CRT and Modem in Parallel
  606.     MODEM    - 
  607.     CRT      - 
  608.  Assignment is TEST    
  609.  
  610. B1:ASM>dev c crt
  611.  CON: Assignment is CRT     
  612. .uj 1
  613.