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 / SAMIOP.AZM / SAMIOP.ASM
Assembly Source File  |  2000-06-30  |  11KB  |  503 lines

  1. ;
  2. ;  SAMPLE IOP for study
  3. ;  by Richard Conn
  4. ;  7/14/85
  5. ;
  6. iop    equ    0EC00H    ;base address of IOP
  7. ;
  8. ctrls    equ    'S'-'@'    ;^S
  9. ctrlz    equ    'Z'-'@'    ;^Z
  10. ;
  11.     org    iop
  12.  
  13. ;
  14. ;  The IOP jump table
  15. ;
  16.     jmp    status
  17.     jmp    select
  18.     jmp    namer
  19.     jmp    init
  20. ;
  21.     jmp    const
  22.     jmp    conin
  23.     jmp    conout
  24.     jmp    list
  25.     jmp    punch
  26.     jmp    reader
  27.     jmp    listst
  28. ;
  29.     jmp    patch
  30. ;
  31.     jmp    copen
  32.     jmp    cclose
  33.     jmp    lopen
  34.     jmp    lclose
  35. ;
  36. ;  IOP ID (required for LDR)
  37. ;
  38.     db    'Z3IOP'
  39.  
  40. ;
  41. ;  The following is the IOP Status Table
  42. ;
  43. ioptable:
  44. con:    db    5,0    ;5 consoles, select console 0
  45. rdr:    db    1,0    ;1 reader, select reader 0
  46. pun:    db    1,0    ;1 punch, select punch 0
  47. lst:    db    2,0    ;2 lists, select list 0
  48.  
  49. ;
  50. ;  The status routine
  51. ;    Return the address of the IOP Status Table in HL
  52. ;    Return the IOP number in A
  53. ;    This IOP supports recording, so set MSB of A
  54. ;
  55. status:
  56.     lxi    h,ioptable    ;pointer to table
  57.     mvi    a,82h        ;IO Recorder supported, IOP 2
  58.     ora    a        ;set NZ flag
  59.     ret
  60.  
  61. ;
  62. ;  The select routine
  63. ;    On input, B=logical device and C is driver
  64. ;    On output, A=0 and zero flag set if error
  65. ;
  66. select:
  67.     lxi    h,ioptable    ;pt to IOP table
  68.     mov    a,b        ;double B so offset is 0,2,4,6
  69.     cpi    4        ;make sure in range 0-3
  70.     jnc    selerr
  71.     add    b
  72.     mov    e,a        ;DE = offset
  73.     mvi    d,0
  74.     dad    d        ;HL now points to device in IOP
  75.     mov    a,m        ;get max number of devices
  76.     cmp    c        ;check for driver error
  77.     jz    selerr        ;error if C = count
  78.     jc    selerr        ;error if C > count
  79.     inx    h        ;point to selected device byte
  80.     mov    m,c        ;select the device
  81.     mvi    a,0ffh        ;set OK return code
  82.     ora    a
  83.     ret
  84. selerr:
  85.     xra    a        ;set error return code
  86.     ret
  87.  
  88. ;
  89. ;  The Namer Routine
  90. ;    On input, B = logical device and C = driver
  91. ;    On output, HL = address of name string
  92. ;    On output, A=0 and Zero Flag Set if error
  93. ;
  94. namer:
  95.     lxi    h,ioptable    ;check to see that C is
  96.     mov    a,b        ; in range ... begin by
  97.     cpi    4        ; doubling B to 0,2,4,6
  98.     jnc    namerror    ; after making sure in
  99.     add    b        ; range 0-3
  100.     mov    e,a        ;add offset to HL
  101.     mvi    d,0
  102.     dad    d        ;HL now points to IOP Table
  103.     mov    a,m        ;get max device count
  104.     cmp    c
  105.     jz    namerror    ;error if C = count
  106.     jc    namerror    ;error if C > count
  107.     lxi    h,iopdnames    ;get address of logical
  108.     dad    d        ; name table
  109.     mov    e,m
  110.     inx    h
  111.     mov    d,m
  112.     xchg            ;HL now points to logical
  113.     mov    a,c        ; name table - double C
  114.     add    c        ; to get device driver name
  115.     mov    e,a
  116.     mvi    d,0        ;DE = offset
  117.     dad    d        ;HL now points to driver name
  118.     mov    e,m        ; address - get string address
  119.     inx    h        ; in DE
  120.     mov    d,m
  121.     xchg            ;HL now has string name address
  122.     mvi    a,0ffh        ;set no error
  123.     ora    a
  124.     ret
  125. namerror:
  126.     lxi    h,errmsg    ;pt to some message
  127.     xra    a        ;set error code
  128.     ret
  129. errmsg:
  130.     db    'Name Error',0
  131.  
  132. ;
  133. ;  This table gives the addresses of the address
  134. ;  tables for each of the logical devices
  135. ;
  136. iopdnames:
  137.     dw    connames
  138.     dw    rdrnames
  139.     dw    punnames
  140.     dw    lstnames
  141. ;
  142. ;  These tables give the addresses of each of the
  143. ;  logical device name strings
  144. ;
  145. connames:
  146.     dw    conn1        ;there are 5 consoles
  147.     dw    conn2        ; (see IOPTABLE above)
  148.     dw    conn3
  149.     dw    conn4
  150.     dw    conn5
  151. rdrnames:
  152.     dw    rdrn1        ;there is 1 reader
  153. punnames:
  154.     dw    punn1        ;there is 1 punch
  155. lstnames:
  156.     dw    listn1        ;there are 2 lists
  157.     dw    listn2
  158. ;
  159. ;  These are the actual text strings returned by NAMER
  160. ;
  161. conn1:    db    'CRT ',0
  162. conn2:    db    'MODEM ',0
  163. conn3:    db    'CRTMOD CRT and Modem in Parallel',0
  164. conn4:    db    'CRTPRT CRT in and CRT/Printer out',0
  165. conn5:    db    'TEST CRT by default',0
  166. ;
  167. rdrn1:    db    'MODEM ',0
  168. ;
  169. punn1:    db    'MODEM ',0
  170. ;
  171. listn1:    db    'PRINTER ',0
  172. listn2:    db    'MODEM ',0
  173.  
  174. ;
  175. ; This routine initializes the devices in the IOP
  176. ;
  177. init:
  178.     mvi    a,0    ;set no IO Recording active
  179.     sta    crec    ;console off
  180.     sta    lrec    ;list off
  181.     ret
  182.  
  183. ;
  184. ;  This system has three pieces of hardware connected:
  185. ;    1. a CRT
  186. ;    2. a modem
  187. ;    3. a printer
  188. ;  All devices are hypothetical
  189. ;  The following are the simple device drivers for them
  190. ;
  191.  
  192. ;
  193. ;  1. CRT
  194. ;
  195. crtdata    equ    0F800H+3F8H    ;CRT data port
  196. crtstat    equ    0F800H+3F9H    ;CRT status port
  197. crtrda    equ    4    ;RDA bit
  198. crttbe    equ    8    ;TBE bit
  199.  
  200. ;  Return input status in A (A=0 means no char available)
  201. crtistat:
  202.     lda    crtstat    ;check input status
  203.     cma        ;status is inverted
  204.     ani    crtrda    ;mask for RDA
  205.     rz        ;0 if no char pending
  206.     mvi    a,0ffh    ;return 0FFH if char pending
  207.     ret
  208. ;  Return output status in A (A=0 means not ready for output)
  209. crtostat:
  210.     lda    crtstat    ;check output status
  211.     cma        ;status is inverted
  212.     ani    crttbe    ;mask for TBE
  213.     rz        ;0 if not ready
  214.     mvi    a,0ffh    ;0FFH if ready
  215.     ret
  216. ;  Return input byte in A (A=byte)
  217. crtin:
  218.     call    crtistat    ;wait for input
  219.     jz    crtin
  220.     lda    crtdata    ;get byte
  221.     cma        ;data is inverted
  222.     ani    7fh    ;mask
  223.     ret
  224. ;  Output byte in C to device
  225. crtout:
  226.     call    crtostat    ;wait for ready
  227.     jz    crtout
  228.     mov    a,c    ;get char from C
  229.     cma        ;invert data
  230.     sta    crtdata    ;put byte
  231.     ret
  232.  
  233.  
  234. ;
  235. ;  2. Modem
  236. ;
  237. moddata    equ    80H    ;Modem data port
  238. modstat    equ    81H    ;Modem status port
  239. modrda    equ    2    ;RDA bit
  240. modtbe    equ    1    ;TBE bit
  241.  
  242. ;  Return input status in A (A=0 means no char available)
  243. modistat:
  244.     in    modstat    ;check input status
  245.     ani    modrda    ;mask for RDA
  246.     rz        ;0 if no char pending
  247.     mvi    a,0ffh    ;return 0FFH if char pending
  248.     ret
  249. ;  Return output status in A (A=0 means not ready for output)
  250. modostat:
  251.     in    modstat    ;check output status
  252.     ani    modtbe    ;mask for TBE
  253.     rz        ;0 if not ready
  254.     mvi    a,0ffh    ;0FFH if ready
  255.     ret
  256. ;  Return input byte in A (A=byte)
  257. modin:
  258.     call    modistat    ;wait for input
  259.     jz    modin
  260.     in    moddata    ;get byte
  261.     ret
  262. ;  Output byte in C to device with simple XON/XOFF Processing
  263. modout:
  264.     call    modistat    ;see if char pending
  265.     jz    modout1        ;continue if not
  266.     call    modin        ;get char
  267.     cpi    ctrls        ;see if ^S
  268.     jnz    modout1        ;continue if not
  269.     call    modin        ;wait for any next char
  270. modout1:
  271.     call    modostat    ;wait for ready
  272.     jz    modout
  273.     mov    a,c    ;get char from C
  274.     out    moddata    ;put byte
  275.     ret
  276.  
  277.  
  278. ;
  279. ;  3. Printer
  280. ;
  281. prtdata    equ    20H    ;Printer data port
  282. prtstat    equ    25H    ;Printer status port
  283. prtrda    equ    1    ;RDA bit
  284. prttbe    equ    20H    ;TBE bit
  285.  
  286. ;  Return input status in A (A=0 means no char available)
  287. prtistat:
  288.     in    prtstat    ;check input status
  289.     ani    prtrda    ;mask for RDA
  290.     rz        ;0 if no char pending
  291.     mvi    a,0ffh    ;return 0FFH if char pending
  292.     ret
  293. ;  Return output status in A (A=0 means not ready for output)
  294. prtostat:
  295.     in    prtstat    ;check output status
  296.     ani    prttbe    ;mask for TBE
  297.     rz        ;0 if not ready
  298.     mvi    a,0ffh    ;0FFH if ready
  299.     ret
  300. ;  Return input byte in A (A=byte)
  301. prtin:
  302.     call    prtistat    ;wait for input
  303.     jz    prtin
  304.     in    prtdata    ;get byte
  305.     ret
  306. ;  Output byte in C to device
  307. prtout:
  308.     call    prtostat    ;wait for ready
  309.     jz    prtout
  310.     mov    a,c    ;get char from C
  311.     out    prtdata    ;put byte
  312.     ret
  313.  
  314. ;
  315. ;  The following are the device selection routines
  316. ;
  317. const:
  318.     lxi    h,tconst    ;point to driver table
  319.     mvi    b,0        ;CON device
  320.     jmp    drvrun        ;run driver
  321. conin:
  322.     lxi    h,tconin
  323.     mvi    b,0
  324.     jmp    drvrun
  325. conout:
  326.     call    crecord        ;send char to recorder if on
  327.     lxi    h,tconout
  328.     mvi    b,0
  329.     jmp    drvrun
  330. list:
  331.     call    lrecord        ;send char to recorder if on
  332.     lxi    h,tlist
  333.     mvi    b,3        ;LST device
  334.     jmp    drvrun
  335. punch:
  336.     lxi    h,tpunch
  337.     mvi    b,2        ;PUN device
  338.     jmp    drvrun
  339. reader:
  340.     lxi    h,treader
  341.     mvi    b,1        ;RDR device
  342.     jmp    drvrun
  343. listst:
  344.     lxi    h,tlistst
  345.     mvi    b,3        ;LST device
  346. ;
  347. ;  The following routine selects the desired driver
  348. ;    On input, B=logical device number
  349. ;    IOPTABLE is used to find the current driver
  350. ;    On input, HL=address of driver table
  351. ;    Driver table contains address of all drivers
  352. ;        which can be selected
  353. ;
  354. drvrun:
  355.     push    h        ;save ptr to driver table
  356.     lxi    h,ioptable    ;get selected driver number
  357.     mov    a,b        ;double B for offset
  358.     add    b
  359.     mov    e,a
  360.     mvi    d,0
  361.     dad    d        ;HL pts to IOPTABLE entry
  362.     inx    h        ;HL pts to selected driver
  363.     mov    b,m        ;get selected driver in B
  364.     mov    a,b        ; (C not used because it can
  365.     add    b        ; contain a character if output
  366.     mov    e,a        ; driver is being called)
  367.     mvi    d,0
  368.     pop    h        ;HL pts to driver table
  369.     dad    d        ;HL pts to desired driver address
  370.     mov    e,m
  371.     inx    h
  372.     mov    d,m
  373.     xchg            ;HL pts to driver
  374.     pchl            ;run the driver
  375.  
  376. ;
  377. ;  These are the device driver tables
  378. ;
  379. tconst:
  380.     dw    crtistat    ;selected driver 0 is CRT
  381.     dw    modistat    ;selected driver 1 is Modem
  382.     dw    crtmodist    ;selected driver 2 is CRT/Modem
  383.     dw    crtistat    ;selected driver 3 is CRT in, Printer out
  384. patistat:            ;patch point for PATCH routine
  385.     dw    crtistat    ;selected driver 4 is CRT
  386. ;
  387. tconin:
  388.     dw    crtin
  389.     dw    modin
  390.     dw    crtmodin
  391.     dw    crtin
  392. patin:                ;patch point for PATCH routine
  393.     dw    crtin
  394. ;
  395. tconout:
  396.     dw    crtout
  397.     dw    modout
  398.     dw    crtmodout
  399.     dw    crtprtout
  400. patout:                ;patch point for PATCH routine
  401.     dw    crtout
  402. ;
  403. tlist:
  404.     dw    prtout        ;selected driver 0 is Printer
  405.     dw    modout        ;selected driver 1 is Modem
  406. ;
  407. treader:
  408.     dw    modin        ;selected driver 0 is Modem
  409. ;
  410. tpunch:
  411.     dw    modout        ;selected driver 0 is Modem
  412. ;
  413. tlistst:
  414.     dw    prtostat    ;selected driver 0 is Printer
  415.     dw    modostat    ;selected driver 1 is Modem
  416.  
  417. ;
  418. ;  This is the driver set for the combination CRT/Modem Device
  419. ;  and the combination CRT/Printer Output Device
  420. ;
  421. crtmodist:
  422.     call    crtistat    ;see if char available on CRT
  423.     rnz            ;return if so
  424.     call    modistat    ;see if char available on Modem
  425.     ret
  426. crtmodin:
  427.     call    crtistat    ;look for CRT char
  428.     jnz    crtin        ;get char from CRT
  429.     call    modistat    ;look for Modem char
  430.     jnz    modin        ;get char from Modem
  431.     jmp    crtmodin    ;continue until CRT or Modem gives char
  432. crtmodout:
  433.     call    crtout        ;send to CRT
  434.     call    modout        ;send to Modem
  435.     ret
  436. crtprtout:
  437.     call    crtout        ;send to CRT
  438.     call    prtout        ;send to Printer
  439.     ret
  440. ;
  441. ;  These are the drivers for the recorder output device
  442. ;
  443. crecord:
  444.     lda    crec        ;check flag
  445.     ora    a        ;0 means not recording
  446.     rz
  447.     call    modout        ;send char to modem to record
  448.     ret
  449. lrecord:
  450.     lda    lrec        ;check flag
  451.     ora    a        ;0 means not recording
  452.     rz
  453.     call    modout        ;send char to modem to record
  454.     ret
  455. ;
  456. ;  These are the routines which turn on and off device recording
  457. ;  For this IOP, Console and Printer recording amounts to sending
  458. ;    characters to the modem
  459. ;
  460. copen:
  461.     mvi    a,0ffh        ;set flag
  462.     sta    crec
  463.     ret
  464. cclose:
  465.     mvi    a,0        ;clear flag
  466.     sta    crec
  467.     mvi    c,ctrlz        ;send ^Z to modem
  468.     call    modout
  469.     ret
  470. lopen:
  471.     mvi    a,0ffh        ;set flag
  472.     sta    lrec
  473.     ret
  474. lclose:
  475.     mvi    a,0        ;clear flag
  476.     sta    lrec
  477.     mvi    c,ctrlz        ;send ^Z to modem
  478.     call    modout
  479.     ret
  480. ;
  481. crec:    ds    1        ;flag buffer
  482. lrec:    ds    1        ;flag buffer
  483.  
  484. ;
  485. ;  This is the patch routine
  486. ;  It sets the 5th device driver (driver select 4) to the drivers
  487. ;    whose jump table is pointed to by HL; HL points to a table
  488. ;    like the following:
  489. ;        JMP    ISTAT
  490. ;        JMP    INPUT
  491. ;        JMP    OUTPUT
  492. ;
  493. patch:
  494.     shld    patistat    ;set address of input status
  495.     lxi    d,3        ;offset of 3
  496.     dad    d
  497.     shld    patin        ;set address of input char
  498.     dad    d
  499.     shld    patout        ;set address of output char
  500.     ret
  501.  
  502.     end
  503.