home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols100 / vol143 / resxios.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  20.5 KB  |  846 lines

  1. ;=====================================================================
  2. ;    MP/M-80 II Resident Extended Input/Output System, Version 1.0
  3. ;=====================================================================
  4. ;
  5. ; Copyright (C) 1981 ,by MICROCOSM.All rights reserved.No part may be
  6. ; reproduced,transmitted,transcribed ,stored in retrieval system,  or
  7. ; translated into any language or  computer language, in any form  or
  8. ; by any means,electronic,mechanical,magnetic,optical,chemical,manual
  9. ; or  otherwise,  without the prior written  permission of MICROCOSM,
  10. ; 3055 Waco St.,Simi Valley,California 93063.
  11. ;
  12. ;                           Disclaimer
  13. ;                           ==========
  14. ;
  15. ; MICROCOSM  makes no representation or warranties with respect to the
  16. ; contents herof and specifically disclaims any implied warranties  of
  17. ; merchantability  or  fitness for any particular purpose.   Further ,
  18. ; MICROCOSM  reserves the  right to  revise and to   make changes from
  19. ; time to  time in the  content hereof without obligation of MICROCOSM
  20. ; to notify any person of such revision or changes.
  21. ;
  22. ;
  23. ;
  24. ;
  25. ; THIS MODULE CONTAINS ALL THE INPUT/OUTPUT ROUTINES FOR THE MP/M-80 II SYSTEM
  26. ;
  27. ;
  28. ; CONSOLE PORT #0 I/O PARAMETER EQUATES
  29. ;
  30. CCTRL    EQU    010H    ; CONSOLE STATUS PORT 
  31. CCTRL    EQU    010H    ; CONSOLE COMMAND PORT 
  32. CDATA    EQU    011H    ; CONSOLE DATA PORT 
  33. CRRDY    EQU    001H    ; CONSOLE RECEIVER READY BIT
  34. CTRDY    EQU    002H    ; CONSOLE TRANSMITTER READY BIT
  35. CNULL    EQU    000H    ; CONSOLE NULL COUNT 
  36. ;
  37. ; CONSOLE PORT #1 I/O PARAMETER EQUATES
  38. ;
  39. MCTRL    EQU    01AH    ; MODEM CONTROL/STATUS PORT
  40. MDATA    EQU    01BH    ; MODEM DATA PORT
  41. MRRDY    EQU    001H    ; MODEM RECEIVER READY BIT
  42. MTRDY    EQU    002H    ; MODEM TRANSMITTER READY BIT
  43. CARDET    EQU    004H    ; DATA CARRIER DETECT MASK
  44.  
  45. ROMBOOT EQU    0F13DH    ; ROM BOOT ENTRY ADDRESS
  46.  
  47. ;
  48. ;  VECTOR INTERRUPT/REAL TIME CLOCK I/O PARAMETER EQUATES
  49. VICNTRL    EQU    0FEH    ; 88-VI(RTC) CONTROL PORT
  50. FLAGSET    EQU    133
  51. DSPTCH    EQU    142
  52. ;  VECTOR INTERRUPT/REAL TIME CLOCK VECTOR LEVEL EQUATES
  53. VEC1    EQU    0DDH    ; VECTOR LEVEL 1 (RST 1), ADDRESS 0008 HEX
  54. ;  DISK I/O PARAMETER EQUATES
  55. CNTRL    EQU    0C0H    ; ICOM 3712 DISK CONTROL COMMAND PORT
  56. DATAO    EQU    0C1H    ; ICOM 3712 DISK DATA OUT PORT
  57. DATAI    EQU    0C0H    ; ICOM 3712 DISK DATA IN PORT
  58. ;  LIST DEVICE I/O PARAMETER EQUATES
  59. LSTAT    EQU    002H    ; LIST STATUS PORT
  60. LCOM    EQU    002H    ; LIST COMMAND PORT
  61. LDATA    EQU    003H    ; LIST DATA PORT
  62. LRBIT    EQU    080H    ; LISTER READY BIT 
  63. LNULL    EQU    000H    ; LIST NULL COUNT
  64. LINCNT    EQU    66    ; LINES PER PRINTER PAGE
  65. ;  ASCII CHARACTER EQUATES
  66. ;
  67. RUBOUT    EQU    7FH
  68. SPACE    EQU    20H
  69. ;
  70. TDISKS    EQU    2    ; NUMBER OF AVAILABLE DISKS
  71. ;
  72. NMBDEV    EQU    6    ; NUMBER OF DEVICES IN POLL TABLE
  73. ;
  74. NMBCNS    EQU    2    ; NUMBER OF CONSOLES
  75. ;
  76. POLL    EQU    131    ; XDOS POLL FUNCTION
  77. ;
  78. PLLPT    EQU    0    ; POLL PRINTER
  79. PLDSK    EQU    1    ; POLL DISK
  80. PLCO0    EQU    2    ; POLL CONSOLE OUT #0
  81. PLCO1    EQU    3    ; POLL CONSOLE OUT #1 (MODEM)
  82. PLCI0    EQU    4    ; POLL CONSOLE IN #0
  83. PLCI1    EQU    5    ; POLL CONSOLE IN #1 (MODEM)
  84. ;
  85. RTCNT    EQU    10    ; RETRY COUNT 
  86. ;
  87. IOBYTE    EQU    3    ; ADDRESS OF I/O BYTE 
  88. ;
  89. OFFSET    EQU    2    ; NUMBER OF TRACKS USED BY MP/M-80 II
  90.  
  91.     ORG    00000H    ; START OF REL-0 XIOS FOR MP/M-80 II
  92. ;
  93. ;        +++ I/O JUMP VECTOR +++
  94. ;
  95. ;
  96.     JMP    COMMONBASE    ; COMMON BASE, TERMINATE PROCESS
  97. WBOOTE:    JMP    WBOOT        ; WARM BOOT, TERMINATE PROCESS
  98.     JMP    CONST        ; CONSOLE STATUS
  99.     JMP    CONIN        ; CONSOLE CHARACTER IN
  100.     JMP    CONOUT        ; CONSOLE CHARACTER OUT
  101.     JMP    LIST        ; LIST CHARACTER OUT
  102.     JMP    PUNCH        ; PUNCH NOT IMPLEMENTED
  103.     JMP    READER        ; READER NOT IMPLEMENTED
  104.     JMP    HOME        ; MOVE HEAD TO HOME
  105.     JMP    SELDSK        ; SELECT DISK
  106.     JMP    SETTRK        ; SET TRACK NUMBER
  107.     JMP    SETSEC        ; SET SECTOR NUMBER
  108.     JMP    SETDMA        ; SET DMA ADDRESS
  109.     JMP    READ        ; READ DISK
  110.     JMP    WRITE        ; WRITE DISK
  111.     JMP    POLLPT        ; LIST STATUS
  112.     JMP    SECTRAN        ; SECTOR TRANSLATE
  113. ;  EXTENDED I/O SYSTEM JUMP VECTOR
  114.     JMP    SELMEMORY    ; SELECT MEMORY
  115.     JMP    POLLDEVICE    ; POLL DEVICE
  116.     JMP    STARTCLOCK    ; START CLOCK
  117.     JMP    STOPCLOCK    ; STOP CLOCK
  118.     JMP    EXITREGION    ; EXIT REGION
  119.     JMP    MAXCONSOLE    ; MAXIMUM CONSOLE NUMBER
  120.     JMP    SYSTEMINIT    ; SYSTEM INITIALIZATION
  121.     DB    0,0,0        ; IDLE PROCEDURE, NOT USED
  122.  
  123. ;
  124. COMMONBASE:            ; TERMINATE PROCESS
  125. ;
  126.     JMP    COLDSTART
  127. SWTUSER:JMP    $-$
  128. SWTSYS:    JMP    $-$
  129. PDISP:    JMP    $-$
  130. XDOS:    JMP    $-$
  131. SYSDAT:    DW    $-$
  132. ;
  133. COLDSTART:
  134. WARMSTART:
  135. ;
  136.     MVI    C,0        ; SYETM RESET, TERMINATE PROCESS
  137.     JMP    XDOS
  138. ;
  139. ;  MP/M-80 II   CONSOLE HANDLERS
  140. ;
  141. CONST:            ; CONSOLE STATUS
  142.     CALL    PTBLJMP    ; COMPUTE AND JUMP TO HANDLER
  143.     DW    PT0ST    ; CONSOLE #0 STATUS ROUTINE
  144.     DW    PT1ST    ; CONSOLE #1 (MODEM) STATUS RT
  145.  
  146. READER:            ; READER NOT IMPLEMENTED
  147.     MVI    D,0    ; DEFAULT TO CONIN #0
  148.  
  149. CONIN:            ; CONSOLE INPUT
  150.     CALL    PTBLJMP    ; COMPUTE AND JUMP TO HANDLER
  151.     DW    PT0IN    ; CONSOLE #0 INPUT
  152.     DW    PT1IN    ; CONSOLE #1 (MODEM) INPUT
  153.  
  154. PUNCH:            ; PUNCH NOT IMPLEMENTED
  155.     MVI    D,0    ; DEFAULT TO CONOUT #0
  156.  
  157. CONOUT:            ; CONSOLE OUTPUT
  158.     CALL    PTBLJMP    ; COMPUTE AND JUMP TO HANDLER
  159.     DW    PT0OUT    ; CONSOLE #0 OUTPUT
  160.     DW    PT1OUT    ; CONSOLE #1 (MODEM) OUTPUT
  161.  
  162. ;
  163. PTBLJMP:        ; COMPUTE AND JUMP TO HANDLER
  164.             ; D = CONSOLE #
  165.             ; DO NOT DESTROY <D>
  166.     MOV    A,D
  167.     CPI    NMBCNS
  168.     JC    TBLJMP
  169.     POP    PSW    ; THROW AWAY TABLE ADDRESS
  170. RTNEMPTY:
  171.     XRA    A
  172.     RET
  173. TBLJMP:            ; COMPUTE AND JUMP TO HANDLER
  174.             ; A = TABLE INDEX
  175.     ADD    A    ; DOUBLE TABLE INDEX FOR ADR OFFST
  176.     POP    H    ; RETURN ADR POINTS TO JUMP TBL
  177.     MOV    E,A
  178.     MVI    D,0
  179.     DAD    D    ; ADD TABLE INDEX * 2 TO TBL BASE
  180.     MOV    E,M    ; GET HANDLER ADDRESS
  181.     INX    H
  182.     MOV    D,M
  183.     XCHG
  184.     PCHL        ; JUMP TO COMPUTED CNS HANDLER
  185. ;
  186. ; CHECK CONSOLE INPUT STATUS
  187. ;
  188. ; POLL CONSOLE #0 INPUT
  189.  
  190. POLCI0:
  191. PT0ST:            ; RETURN 0FFH IF READY,
  192.             ;        000H IF NOT
  193.     IN    CCTRL    ; READ CONSOLE STATUS
  194.     ANI    CRRDY    ; LOOK AT RECEIVER READY BIT
  195.     MVI    A,0    ; SET A=0 FOR RETURN
  196.     RZ        ; NOT READY, WHEN 0
  197.     MVI    A,0FFH    ; IF READY A=FF
  198.     RET        ; RETURN FROM POLCI0
  199. ;
  200. ; READ A CHARACTER FROM CONSOLE.
  201. ;
  202. ; CONSOLE #0 INPUT
  203. ;
  204. PT0IN:            ; RETURN CHARACTER IN REG A
  205.     MVI    C,POLL
  206.     MVI    E,PLCI0
  207.     CALL    XDOS    ; POLL CONSOLE #0 INPUT
  208.     IN    CDATA    ; READ A CHARACTER 
  209.     ANI    7FH    ; MAKE MOST SIG. BIT = 0
  210.     CPI    RUBOUT    ; IS IT A RUBOUT?
  211.     RNZ        ; RETURN IF NOT
  212.     MVI    A,0FFH    ; SET NO PRINT FLAG
  213.     STA    CONOTF
  214.     MVI    A,7FH    ; RESTORE RUBOUT
  215.     RET        ; RETURN FROM PT0IN
  216. ;
  217. ; WRITE A CHARACTER TO THE CONSOLE DEVICE
  218. ;
  219. ; CONSOLE #0 OUTPUT
  220. ;
  221. PT0OUT:            ; REG C = CHARACTER TO OUTPUT
  222.     PUSH    B
  223.     CALL    PT0WAIT    ; POLL CONSOLE #0 OUTPUT
  224.     POP    B
  225.     MOV    A,C    ; GET CHARACTER
  226.     OUT    CDATA    ; PRINT IT
  227.     RET        ; RETURN FROM PT0OUT
  228. ;
  229. ; WAIT FOR CONSOLE #0 OUTPUT READY
  230. ;
  231. PT0WAIT:
  232.     MVI    C,POLL
  233.     MVI    E,PLCO0
  234.     JMP    XDOS    ; POLL CONSOLE #0 OUTPUT
  235. ;    RET
  236.  
  237. ;
  238. ; POLL CONSOLE #0 OUTPUT
  239. ;
  240. POLCO0:
  241.             ; RETURN 0FFH IF READY,
  242.             ;        000H IF NOT
  243.     IN    CCTRL    ; READ CONSOLE STATUS
  244.     ANI    CTRDY    ; IF NOT READY,
  245.     MVI    A,0    ; RETURN WITH ZERO'S
  246.     RZ        ; NOT READY, WHEN 0
  247.     MVI    A,0FFH
  248.     RET        ; RETURN FROM POLCO0
  249. ;
  250. ; WRITE A CHARACTER ON LISTING DEVICE
  251. ;
  252. LIST:            ; LIST OUTPUT
  253.     PUSH    B
  254.     PUSH    D
  255.     MVI    C, POLL
  256.     MVI    E, PLLPT
  257.     CALL    XDOS
  258.     POP    D
  259.     POP    B
  260.     MOV    A,C    ; GET DATA BYTE
  261.     OUT    LDATA    ; PRINT IT
  262.     RET        ; RETURN FROM LIST
  263. ; RETURN LIST STATUS
  264. ;
  265. LISTST:    XRA    A    ; FLAG LISTER NOT READY
  266.     RET
  267.  
  268. ;
  269. ;  POLL PRINTER OUTPUT
  270. ;
  271. POLLPT:
  272.             ; RETURN 0FFH IF READY,
  273.             ;        000H IF NOT
  274.     IN    LSTAT    ; READ LISTER STATUS.
  275.     ANI    LRBIT    ; LOOK AT READY BIT.
  276.     MVI    A,0    ; RETURN WITH ZERO'S IF NOT READY
  277.     RNZ
  278.     MVI    A,0FFH
  279.     RET
  280. ;
  281. ;  POLL CONSOLE #1 (MODEM) INPUT
  282. ;
  283. POLCI1:
  284. PT1ST:
  285.             ; RETURN 0FFH IF READY,
  286.             ;        000H IF NOT
  287.     IN    MCTRL    ; GET MODEM STATUS
  288.     ANI    CARDET    ; DATA CARRIER DETECT ON?
  289.     JNZ    RESTART    ; EXIT, IF NO CARRIER
  290.     IN    MCTRL    ; GET MODEM STATUS
  291.     ANI    MRRDY    ; MASK MODEM RECEIVER READY
  292.     MVI    A,0    ; RETURN WITH ZERO'S
  293.     RZ        ; RETURN IF ZERO FLAG SET
  294.     MVI    A,0FFH    ; IF READY,A=FFH
  295.     RET        ; RETURN FROM POLCI1
  296. ;
  297. ;  CONSOLE #1 (MODEM) INPUT
  298. ;
  299. PT1IN:
  300.             ; RETURN CHARACTER IN REG A
  301.     IN    MCTRL    ; GET MODEM STATUS
  302.     ANI    CARDET    ; DATA CARRIER DETECT ON?
  303.     JNZ    RESTART    ; EXIT, IF NO CARRIER
  304.     MVI    C,POLL
  305.     MVI    E,PLCI1
  306.     CALL    XDOS    ; POLL CONSOLE #1 INPUT
  307.     IN    MDATA    ; GET MODEM DATA BYTE
  308.     ANI    07FH    ; STRIP OFF MSB FOR ASCII
  309.     RET        ; RETURN FROM CONIN
  310. ;  CONSOLE #1 (MODEM) OUTPUT
  311. ;
  312. PT1OUT:
  313.             ; REG C = CHARACTER TO OUTPUT
  314.     IN    MCTRL    ; GET MODEM STATUS
  315.     ANI    CARDET    ; DATA CARRIER DETECT ON?
  316.     JNZ    RESTART    ; EXIT, IF NO CARRIER
  317.     PUSH    B
  318.     CALL    PT1WAIT
  319.     POP    B
  320.     MOV    A,C    ; GET CHARACTER
  321.     OUT    MDATA    ; OUT TO MODEM
  322.     RET        ; RETURN FROM CONOUT
  323.  
  324. ;  WAIT FOR CONSOLE #1 (MODEM) OUTPUT READY
  325.  
  326. PT1WAIT:
  327.     MVI    C,POLL
  328.     MVI    E,PLCO1
  329.     JMP    XDOS        ; POLL CONSOLE #1 OUTPUT
  330. ;    RET
  331.  
  332. ;  POLL CONSOLE #1 (MODEM) OUTPUT
  333.  
  334. POLCO1:
  335.             ; RETURN 0FFH IF READY,
  336.             ;        000H IF NOT
  337.     IN    MCTRL    ; GET MODEM STATUS
  338.     ANI    CARDET    ; DATA CARRIER DETECT ON?
  339.     JNZ    RESTART    ; EXIT, IF NO CARRIER
  340.     IN    MCTRL    ; GET MODEM STATUS
  341.     ANI    MTRDY    ; MASK MODEM TRANSMITTER READY
  342.     MVI    A,0    ; RETURN WITH ZERO'S
  343.     RZ
  344.     MVI    A,0FFH    ; IF READY,A=FFH
  345.     RET        ; RETURN FROM POLCO1
  346. ;  WAIT FOR DATA CARRIER DETECT, THEN RESTART AT "BOOT"
  347. LIGHTS    EQU    0FFH    ; IMSAI FRONT PANEL DATA LIGHTS
  348. SWITCH    EQU    0FFH    ; IMSAI FRONT PANEL DATA SWITCHES
  349. RESTART:MVI    B,10    ; SET MAJOR DELAY LOOP
  350.     XRA    A    ; RESET FRON PANEL LIGHTS
  351.     OUT    LIGHTS
  352. DELAY:    LXI    H,0FFFFH; SET MINOR DELAY LOOP
  353. DELAY1: DCX    H
  354.     MOV    A,H
  355.     ORA    L
  356.     JNZ    DELAY1    ; LOOP MINOR DELAY
  357.     CMA        ; SET FRONT PANEL LIGHTS
  358.     OUT    LIGHTS
  359.     DCR    B
  360.     JNZ    DELAY    ; LOOP MAJOR DELAY
  361.     MVI    A,003H    ; RESET MODEM 2SI/O PORT
  362.     OUT    MCTRL
  363.     MVI    A,011H    ; SET 8 DATA BITS,2 STOP, NO PARITY
  364.     OUT    MCTRL
  365. CARWAIT:IN    MCTRL    ; GET MODEM STATUS, AND WAIT FOR CARRIER
  366.     ANI    CARDET    ; DATA CARRIER DETECT ON?
  367.     JNZ    RESTART    ; LOOP HERE 'TILL IT IS
  368.     JMP    ROMBOOT    ; ROM BOOT WHEN READY
  369. ;
  370. ;    MP/M-80 II EXTENDED I/O SYSTEM
  371. ;
  372. POLLDEVICE:
  373.             ; REG C = DEVICE # TO BE POLLED
  374.             ; RETURN 0FFH IF READY,
  375.             ;        000H IF NOT
  376.     MOV    A,C
  377.     CPI    NMBDEV
  378.     JC    DEVOK
  379.     MVI    A,NMBDEV; IF DEV # >= NMBDEV,
  380.             ; SET TO NMBDEV
  381. DEVOK:
  382.     CALL    TBLJMP    ; JUMP TO DEV POLL CODE
  383.  
  384.     DW    POLLPT    ; POLL PRINTER OUTPUT
  385.     DW    POLDSK    ; POLL DISK READY
  386.     DW    POLCO0    ; POLL CONSOLE #0 OUTPUT
  387.     DW    POLCO1    ; POLL CONSOLE #1 (MODEM) OUTPUT
  388.     DW    POLCI0    ; POLL CONSOLE #0 INPUT
  389.     DW    POLCI1    ; POLL CONSOLE #1 (MODEM) INPUT
  390.     DW    RTNEMPTY; BAD DEVICE HANDLER
  391.  
  392.  
  393. ; SELECT / PROTECT MEMORY
  394.  
  395. SELMEMORY:
  396.             ; REG BC = ADR OF MEM DESCRIPTOR
  397.             ; BC ->  BASE   1 BYTE,
  398.             ;        SIZE   1 BYTE,
  399.             ;        ATTRIB 1 BYTE,
  400.             ;        BANK   1 BYTE.
  401.  
  402. ; THIS HARDWARE DOES NOT HAVE MEMORY PROTECTION OR BANK SWITCHING
  403.  
  404.     RET
  405.  
  406.  
  407. ; START CLOCK
  408.  
  409. STARTCLOCK:
  410.             ; WILL CAUSE FLAG #1 TO BE SET
  411.             ;  AT EACH SYSTEM TIME UNIT TICK
  412.     MVI    A,0FFH
  413.     STA    TICKN
  414.     RET
  415.  
  416. ; STOP CLOCK
  417.  
  418. STOPCLOCK:
  419.             ; WILL STOP FLAG #1 SETTING AT
  420.             ;  SYSTEM TIME UNIT TICK
  421.     XRA    A
  422.     STA    TICKN
  423.     RET
  424.  
  425. ; EXIT REGION
  426.  
  427. EXITREGION:
  428.             ; EI IF NOT PREEMPTED
  429.     LDA    PREEMP
  430.     ORA    A
  431.     RNZ
  432.     EI
  433.     RET
  434.  
  435. ; MAXIMUM CONSOLE NUMBER
  436.  
  437. MAXCONSOLE:
  438.     MVI    A,NMBCNS
  439.     RET
  440.  
  441. ;  SYSTEM INITIALIZATION
  442.  
  443. SYSTEMINIT:
  444. ;
  445.     MVI    A,003H    ; CONSOLE AND MODEM RESET
  446.     OUT    CCTRL
  447.     OUT    MCTRL
  448.     MVI    A,011H    ; NO INTERRUPTS,8 DATA BITS,NO PARITY,1 STOP BIT
  449.     OUT    CCTRL
  450.     OUT    MCTRL
  451. ;
  452. ;    CLEAR XIOS VARIABLE AREA
  453. ;
  454.     MVI    C,ENDZ-STARTZ    ; GET LENGTH OF ZERO AREA
  455.     LXI    H,STARTZ    ; POINT TO THE START OF ZERO AREA
  456. CLEAR:    XRA    A    ; MAKE ZERO
  457.     MOV    M,A    ; JAM INTO MEMORY
  458.     INX    H    ; BUMP POINTER
  459.     DCR    C    ; DE-BUMP LENGTH
  460.     JNZ    CLEAR    ; LOOP UNTIL ALL CLEARED
  461. ;
  462. ;    SETUP RESTART JUMP VECTORS
  463.     MVI    A,0C3H
  464.     STA    1*8
  465.     LXI    H,INT1HND
  466.     SHLD    1*8+1    ; JMP INT1HND AT RESTART 1
  467.     MVI    A,0C9H    ; RETURNS FOR ALL REMAINING INTERRUPT VECTORS
  468.     STA    2*8
  469.     STA    3*8
  470.     STA    4*8
  471.     STA    5*8
  472.     STA    6*8
  473.     MVI    A,0F0H    ; ENABLE VI AND RTC, RESET INTERRUPT, CLEAR COUNTERS
  474.     OUT    VICNTRL
  475.     RET
  476.  
  477. ;  MP/M-80 II   INTERRUPT HANDLERS
  478.  
  479. INT1HND:
  480.             ; INTERRUPT 1 HANDLER ENTRY POINT
  481.             ;  
  482.             ;  LOCATION 0008H CONTAINS A JMP
  483.             ;  TO INT1HND.
  484.     PUSH    PSW
  485.     MVI    A,VEC1    ; SET VECTOR LEVEL 1 (RST 1), ADDRESS 0008 HEX
  486.     OUT    VICNTRL
  487.     LDA    SLICE
  488.     DCR    A    ; ONLY SERVICE EVERY 2ND SLICE
  489.     STA    SLICE
  490.     JZ    T40MS    ; JUMP IF 40MS ELAPSED
  491.     POP    PSW
  492.     EI
  493.     RET
  494.  
  495. T40MS:
  496.     MVI    A,4
  497.     STA    SLICE    ; RESET SLICE COUNTER
  498.     POP    PSW
  499.     SHLD    SVDHL
  500.     POP    H
  501.     SHLD    SVDRET
  502.     PUSH    PSW
  503.     LXI    H,0
  504.     DAD    SP
  505.     SHLD    SVDSP        ; SAVE USERS STK PTR
  506.     LXI    SP,INTSTK+48    ; LCL STK FOR INTR HNDL
  507.     PUSH    D
  508.     PUSH    B
  509.  
  510.     MVI    A,0FFH
  511.     STA    PREEMP    ; SET PREEMPTED FLAG
  512.  
  513.     LDA    TICKN
  514.     ORA    A        ; TEST TICKN, INDICATES
  515.                 ;  DELAYED PROCESS(ES)
  516.     JZ    NOTICKN
  517.     MVI    C,FLAGSET
  518.     MVI    E,1
  519.     CALL    XDOS        ; SET FLAG #1 EACH TICK
  520. NOTICKN:
  521.     LXI    H,CNT25
  522.     DCR    M        ; DEC 25 TICK CNTR
  523.     JNZ    NOT1SEC
  524.     MVI    M,25
  525.     MVI    C,FLAGSET
  526.     MVI    E,2
  527.     CALL    XDOS        ; SET FLAG #2 @ 1 SEC
  528. NOT1SEC:
  529.     XRA    A
  530.     STA    PREEMP    ; CLEAR PREEMPTED FLAG
  531.     POP    B
  532.     POP    D
  533.     LHLD    SVDSP
  534.     SPHL            ; RESTORE STK PTR
  535.     POP    PSW
  536.     LHLD    SVDRET
  537.     PUSH    H
  538.     LHLD    SVDHL
  539.  
  540. ; THE FOLLOWING DISPATCH CALL WILL FORCE ROUND ROBIN
  541. ; SCHEDULING OF PROCESSES EXECUTING AT THE SAME PRIORITY
  542. ; EVERY 40 MILLI-SECONDS.
  543. ;
  544. ; NOTE: INTERRUPTS ARE NOT ENABLED UNTIL THE DISPATCHER
  545. ; RESUMES THE NEXT PROCESS.  THIS PREVENTS INTERRUPT
  546. ; OVER-RUN OF THE STACKS WHEN STUCK OR HIGH FREQUENCY
  547. ; INTERRUPTS ARE ENCOUNTERED.
  548.  
  549.     JMP    PDISP        ; MP/M DISPATCH
  550. ;
  551. ; FIXED DATA TABLES FOR TWO-DRIVE STANDARD IBM-COMPATIBLE 8" DISKS
  552. ;
  553.     MACLIB DISKDEF    ; DISK DEFINITION MACRO LIBRARY
  554.  
  555.     DISKS  2    ; TWO DISK SYSTEM
  556.  
  557.     DISKDEF 0,1,26,6,1024,243,64,64,OFFSET,(0)
  558.     DISKDEF 1,0
  559. ;
  560. BOOT:
  561. WBOOT:
  562.     MVI    C,0
  563.     JMP    XDOS
  564.  
  565. ;
  566. ;  ROUTINE TO SELECT GIVEN BY REGISTER C
  567. SELDSK:    MOV    A,C    ; GET NEW UNIT #
  568.     LXI    H,0    ; RETURN 0000 IN H&L REGS., IF ERROR
  569.     CPI    TDISKS    ; BIGGER THAN # OF DISKS AVAILABLE?
  570.     RNC        ; OOPS.....        
  571.     STA    UNITNO    ; VALID UNIT #, SAVE IT
  572.     MOV    L,C    ; L REG =DISK #
  573.     DAD    H    ; *2
  574.     DAD    H    ; *4
  575.     DAD    H    ; *8
  576.     DAD    H    ; *16
  577.     LXI    D,DPBASE; D&E REGS =DISK PARAMETER BASE
  578.     DAD    D    ; H&L REGS =BIAS OFFSET INTO TABLE
  579.     XRA    A    ; SET A = 0 
  580.     RET        ; RETURN FROM SELDSK 
  581. ;  MOVE DISK TO TRACK ZERO 
  582. HOME:    MVI    A,RTCNT    ; GET RETRY COUNT
  583. HRETRY: STA    SERCNT    ; STORE IN SEEK ERROR COUNTER
  584.     XRA    A    ; SET TRKNO TO ZERO
  585.     STA    TRKNO
  586.     CALL    XMTUS    ; XMIT UNIT/SECTOR #
  587.     MVI    A,00DH    ; SET SEEK TRACK ZERO COMMAND
  588.     CALL    XMITW    ; XMIT AND WAIT
  589.     RZ        ; RETURN FROM HOME, IF O.K. 
  590.     CALL    CLRER    ; CLEAR DISK ERROR
  591.     PUSH    H    ; SAVE CURRENT DMAADR
  592.     LXI    H,SECNT    ; GET SEEK ERR COUNT ADDRESS
  593.     INR    M    ; ONE MORE ERROR 
  594.     POP    H    ; RECOVER CURRENT DMAADR
  595.     LDA    SERCNT    ; GET SEEK ERROR COUNT 
  596.     DCR    A    ; DECREMENT COUNT 
  597.     JNZ    HRETRY    ; TRY TO HOME AGAIN 
  598.     JMP    EREXIT    ; OOPS...PERMANENT DISK I/O ERROR
  599. ;  SET TRACK NUMBER TO WHATEVER IS IN REGISTER C 
  600. ;  ALSO PERFORM MOVE TO THE CORRECT TRACK (SEEK) 
  601. SETTRK:    MOV    A,C    ; GET TRACK # INTO A REG 
  602.     CPI    0    ; TRACK ZERO REQUESTED?
  603.     JZ    HOME    ; DO SEEK TRACK ZERO, IF SO
  604.     STA    TRKNO    ; SAVE TRACK #
  605.     MVI    A,RTCNT    ; GET RETRY COUNT
  606. SRETRY: STA    SERCNT    ; STORE IN SEEK ERROR COUNTER
  607.     CALL    XMTUS    ; XMIT UNIT/SECTOR #
  608.     CALL    XMTTK    ; XMIT TRACK #
  609.     MVI    A,009H    ; SET SEEK TRACK COMMAND
  610.     CALL    XMITW    ; XMIT AND WAIT
  611.     RZ        ; RETURN FROM SETTRK, IF O.K. 
  612.     CALL    CLRER    ; CLEAR DISK ERROR
  613.     PUSH    H    ; SAVE CURRENT DMAADR
  614.     LXI    H,SECNT    ; GET ADDRESS OF SEEK ERROR COUNTER 
  615.     INR    M    ; ONE MORE SEEK ERROR 
  616.     POP    H    ; RECOVER CURRENT DMAADR
  617.     LDA    SERCNT    ; GET ERROR COUNT 
  618.     DCR    A    ; DECREMENT COUNT 
  619.     JNZ    SRETRY    ; RETRY SEEK 
  620.     JMP    EREXIT    ; ARGH.....
  621.  
  622. ;  TRANSLATE THE SECTOR GIVEN BY BC USING THE TRANSLATE TABLE GIVEN BY DE
  623. SECTRAN:MVI    B,0    ; DOUBLE PRECISION SECTOR NUMBER
  624.     XCHG        ; TRANSLATE TABLE ADDRESS TO H&L REGS 
  625.     DAD    B    ; TRANSLATE SECTOR ADDRESS
  626.     MOV    A,M    ; TRANSLATE SECTOR # TO A REG 
  627.     MOV    L,A    ; RETURN SECTOR # IN L REG 
  628.     RET        ; RETURN FROM SECTRAN
  629. ;  SET DISK SECTOR GIVEN BY REGISTER C 
  630. SETSEC: MOV    A,C    ; GET SECTOR NUMBER
  631.     STA    SECNO    ; PUT AT SECT # ADDRESS
  632.     RET        ; RETURN FROM SETSEC
  633. ;  SET DISK DMA ADDRESS GIVEN BY REGISTER PAIR B AND C 
  634. SETDMA: MOV    H,B    ; MOVE B&C TO H&L
  635.     MOV    L,C
  636.     SHLD    DMAADR    ; PUT AT DMA ADR ADDRESS
  637.     RET        ; RETURN FROM SETDMA
  638. ;  READ THE SECTOR AT SECT, FROM THE PRESENT TRACK 
  639. ;  USE STARTING ADDRESS AT DMAADR 
  640. READ:    MVI    A,RTCNT    ; GET RETRY COUNT 
  641. RRETRY:    STA    ERCNT    ; STORE IN ERROR CTR 
  642.     CALL    XMTUS    ; XMIT UNIT/SECTOR #
  643.     MVI    A,003H    ; SET READ SECTOR COMMAND
  644.     CALL    XMITW    ; XMIT AND WAIT
  645.     JZ    READOK    ; IF READ O.K.,GET DATA FROM BUFFER
  646.     CALL    CLRER    ; CLEAR DISK ERROR
  647.     PUSH    H    ; SAVE CURRENT DMAADR
  648.     LXI    H,RECNT    ; GET READ ERROR COUNT ADDRESS 
  649.     INR    M    ; ONE MORE ERROR 
  650.     POP    H    ; RECOVER CURRENT DMAADR
  651.     LDA    ERCNT    ; GET ERROR COUNT 
  652.     DCR    A    ; DECREMENT COUNT 
  653.     JNZ    RRETRY    ; TRY TO READ AGAIN 
  654. EREXIT:    IN    DATAI    ; GET DISK STATUS
  655.     STA    IOERR    ; SAVE ERROR STATUS
  656.     MVI    A,1    ; INFORM CP/M OF ERROR
  657.     ORA    A    ; SET FLAGS 
  658.     RET
  659.  
  660. READOK:    LHLD    DMAADR    ; GET STARTING ADDRESS 
  661.     MVI    D,128    ; SET BYTE COUNT
  662.     MVI    A,040H    ; SET READ BUFFER COMMAND
  663.     CALL    XMT4X    ; XMIT 04XH COMMAND
  664.     INX    H    ; BUMP POINTER
  665.     DCR    D    ; DE-BUMP BYTE COUNT
  666. READL:    MVI    A,041H    ; GET DATA BYTE FROM BUFFER
  667.     CALL    XMT4X    ; XMIT 04XH COMMAND
  668.     INX    H    ; BUMP POINTER
  669.     DCR    D    ; DE-BUMP BYTE COUNT
  670.     JNZ    READL    ; LOOP UNTIL ALL BYTES IN
  671.     RET        ; RETURN FROM READ
  672. ;  WRITE THE SECTOR AT SECT, ON THE PRESENT TRACK 
  673. ;  USE STARTING ADDRESS AT DMAADR 
  674. WRITE:    MVI    A,RTCNT    ; GET RETRY COUNT 
  675. WRETRY:    STA    ERCNT    ; STORE IN ERROR COUNTER 
  676.     LHLD    DMAADR    ; GET STARTING ADR 
  677.     MVI    D,128    ; SET BYTE COUNT
  678. WRITEL:    MOV    A,M    ; GET BYTE FROM DMAADR
  679.     OUT    DATAO    ; SEND TO CONTROLLER
  680.     MVI    A,031H    ; XMIT SHIFT WRITE BUFFER
  681.     CALL    XMIT
  682.     INX    H    ; BUMP POINTER
  683.     DCR    D    ; DE-BUMP BYTE COUNT
  684.     JNZ    WRITEL    ; LOOP UNTIL ALL BYTES OUT
  685.     CALL    XMTUS    ; XMIT UNIT/SECTOR #
  686.     MVI    A,005H    ; SET WRITE COMMAND
  687.     CALL    XMITW    ; XMIT AND WAIT
  688.     RZ        ; RETURN FROM WRITE, IF O.K. 
  689.     CALL    CLRER    ; CLEAR DISK ERROR
  690.     PUSH    H    ; SAVE CURRENT DMAADR
  691.     LXI    H,WECNT    ; GET ADR OF WRITE ERR CTR 
  692.     INR    M    ; ONE MORE WRITE ERROR 
  693.     POP    H    ; RECOVER CURRENT DMAADR
  694.     LDA    ERCNT    ; GET ERROR COUNT 
  695.     DCR    A    ; DECREMENT COUNT 
  696.     JNZ    WRETRY    ; TRY TO WRITE AGAIN 
  697.     JMP    EREXIT    ; ARGH.....
  698. ;  TRANSMIT UNIT AND SECTOR NUMBER
  699. XMTUS:    LDA    UNITNO    ; GET UNIT NUMBER FOR DISK
  700.     ANI    003H    ; PRESERVE UNIT # ONLY
  701.     RRC        ; POSITION TO BITS 6&7 FOR 3712 CONTROLLER
  702.     RRC
  703.     MOV    B,A    ; SAVE IN B REG 
  704.     LDA    SECNO    ; GET SECTOR NUMBER
  705.     ORA    B    ; MERGE UNIT NUMBER
  706.     OUT    DATAO    ; SEND DATA OUT
  707.     MVI    A,021H    ; XMIT UNIT/SECTOR NUMBER
  708.     JMP    XMIT    
  709. ;  TRANSMIT TRACK NUMBER
  710. XMTTK:    LDA    TRKNO    ; GET TRACK NUMBER
  711.     OUT    DATAO    ; SEND DATA OUT
  712.     MVI    A,011H    ; XMIT TRACK NUMBER
  713. XMIT:    PUSH    PSW    ; SAVE COMMAND
  714. DRCHK:    IN    DATAI    ; GET DISK STATUS
  715.     ANI    020H    ; MASK FOR DRIVE NOT READY
  716.     JNZ    DRCHK    ; LOOP UNTILL DISK READY
  717.     POP    PSW    ; RECOVER COMMAND
  718.     OUT    CNTRL    ; SEND CONTROL
  719.     XRA    A    ; RESET CPU0 BIT
  720.     OUT    CNTRL    ; SEND CONTROL
  721.     RET
  722. ;  TRANSMIT "BUSY" TYPE COMMAND, AND WAIT FOR "NOT BUSY"
  723. XMITW:    CALL    XMIT    ; XMIT COMMAND
  724. BUSY:    IN    DATAI    ; GET STATUS
  725.     RAR        ; SET BUSY FLAG
  726.     JC    BUSY    ; LOOP IF BUSY
  727.     IN    DATAI    ; GET DISK STATUS
  728.     ANI    028H    ; DISK NOT READY OR CRC ERROR?
  729.     RET        ; RETURN FROM XMITW WITH ERROR STATUS
  730. ;  TRANSMIT "4X" (READ BUFFER OR SHIFT READ BUFFER) TYPE COMMAND
  731. XMT4X:    OUT    CNTRL    ; SEND CONTROL
  732.     IN    DATAI    ; GET DATA BYTE
  733.     MOV    M,A    ; STUFF DATA BYTE INTO MEMORY
  734.     XRA    A    ; RESET CPU0 BIT
  735.     OUT    CNTRL    ; SEND CONTROL
  736.     RET        ; RETURN FROM XMT4X
  737.  
  738. CLRER:    MVI    A,00BH    ; CLEAR ERROR FLAGS
  739.     CALL    XMIT
  740.     RET
  741.  
  742. ;
  743. ; POLL DISK READY STATUS
  744. ;
  745. POLDSK:
  746.             ; RETURN 0FFH IF READY,
  747.             ;     000H IF NOT
  748.     IN    DATAI    ; GET DISK STATUS
  749.     ANI    020H    ; MASK FOR DISK NOT READY
  750.     MVI    A,0    ; SET A REG. TO ZERO FOR POSSIBLE NOT READY
  751.     RNZ
  752.     MVI    A,0FFH    ; DISK IS READY
  753.     RET
  754. ;
  755. ;  SCRATCH RAM AREA REQUIRED FOR XIOS VARIABLES
  756. ;  NOTE:    AS THERE ARE ONLY SEVEN SECTORS
  757. ;  AVAILABLE FOR XIOS ON THE SECOND SYSTEM TRACK (1),
  758. ;  THE LAST ADDRESS BEFORE THIS POINT SHOULD BE NO
  759. ;  GREATER THAN THE XIOS STARTING ADDRESS + 0380 (HEX).
  760. TRKNO:    DS    1    ; CURRENT TRACK NUMBER 
  761. SECNO:    DS    1    ; CURRENT SECTOR NUMBER 
  762. DMAADR:    DS    2    ; DISK TRANSFER ADDRESS.
  763. ;  THE NEXT SEVERAL BYTES, BETWEEN STARTZ AND
  764. ;  ENDZ, ARE SET TO ZERO AT COLD BOOT TIME.
  765. STARTZ:            ; START OF ZEROED AREA.
  766. UNITNO:    DS    1    ; DISK NUMBER (TO MP/M) 
  767. ;  THESE LOCATIONS KEEP TRACK OF THE NUMBER OF ERRORS THAT OCCUR DURING
  768. ;  READ, WRITE, OR SEEK OPERATIONS. THEY ARE INITIALIZED ONLY WHEN A
  769. ;  COLD START IS PERFORMED BY THE BOOT STRAP.
  770. IOERR:    DS    1    ; DISK I/O ERROR TYPE
  771. RECNT:    DS    1    ; READ ERROR COUNTER
  772. WECNT:    DS    1    ; WRITE ERROR COUNTER
  773. SECNT:    DS    1    ; SEEK ERROR COUNTER
  774. ;  SPECIAL FLAGS
  775. CONOTF:    DS    1    ; NO PRINT FLAG (WHEN FF HEX)
  776. ;
  777. ENDZ:            ; END OF ZEROED AREA
  778. ;
  779. NODSKS:    DS    1    ; NUMBER OF DISKS
  780. ERCNT:    DS    1    ; ERROR COUNTER FOR DISK I/O RETRIES
  781. SERCNT:    DS    1    ; ERROR COUNTER FOR DISK SEEK RETRIES
  782. TEMP:    DS    1    ; TEMPORARY DISK UNIT NUMBER
  783. ;
  784. SLICE:    DB    4    ; 4 SLICES = 40MS = 1 TICK
  785. CNT25:    DB    25    ; 25 TICK CNTR = 1 SEC
  786. INTSTK:    DS    48    ; LOCAL INTRPT STK
  787. SVDHL:    DW    0    ; SAVED REGS HL DURING INTERRUPT
  788. SVDSP:    DW    0    ; SAVED SP DURING INTERRUPT
  789. SVDRET:    DW    0    ; SAVED RETURN DURING INTERRUPT
  790. TICKN:    DB    0    ; TICKING BOOLEAN,TRUE = DELAYED
  791. PREEMP:    DB    0    ; PREEMPTED BOOLEAN
  792. ;
  793.     ENDEF
  794. ;
  795.     DB    0    ; FORCE OUT LAST BYTE IN HEX FIELD FOR RMAC
  796. ;
  797.     END
  798.