home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol172 / xbios.a86 < prev   
Encoding:
Text File  |  1984-05-30  |  42.1 KB  |  1,901 lines

  1.     PAGESIZE    74
  2.     PAGEWIDTH    132
  3. ;
  4. ; A BIOS FOR CPM-86 (v1.X) USING A HARD DISK, 2 FLOPPY DISKS & A RAMDISK
  5. ;
  6. ; IT IS SETUP AT THE MOMENT FOR ONE MINISCRIBE 10MG BYTE HARD DISK DRIVE &
  7. ; ONLY 2 8" DRIVES CONTROLLED BY THE 1791 CHIP. THIS BIOS IS VERY HARDWARE
  8. ; DEPENDENT AND WOULD REQUIRE SOME REWORKING FOR OTHERE S-100 BOARDS.
  9. ; THE S100 BOARDS ARE THE VERSAFLOPPY II, THE XCOMP HARD DISK CONTROLLERS.
  10. ; THE BIOS HAS SOME LINKS TO OTHER HOMEBREW BOARDS I USE. THESE ARE AN IO
  11. ; MAPPED 1MG BYTE MEMORY DISK, A SPEECH SYNTHESIS BOARD, AND A KEYBOARD WITH
  12. ; TYPE-AHEAD,TRANSLATION ETC. THESE NEED NOT CONCERN YOU SINCE THEY ARE ONLY
  13. ; INITILIZED IN THE BIOS.
  14. ;
  15. ;
  16. ;    AUTHOR:    JOHN J. MONAHAN        (201)583-1548        7/1/82
  17. ;    MODIFIED FOR RAMDISK                     7/5/83
  18. ;    MODIFIED FOR SPEECH SYNTHESIS                10/29/83
  19. ;    MODIFIED FOR SD 8024 BOARD / KEYBOARD Z80 CONTROLLER    1/1/84
  20. ;
  21. ;-------- PORTS USED IN IO DRIVERS FOR CONSOLE ETC.------------------
  22. ;
  23. IOBYTE    EQU    0FFH        ;IOBYTE (SEE BELOW)
  24. SDSTAT    EQU    0H
  25. SDDATA    EQU    1H
  26. KEYSTAT    EQU    0H        ;SEPERATE PORT TO SEE IF ANYTHING AT KEYBOARD
  27. KEYIN    EQU    01H
  28. resetkey equ    0f8h        ;inputting from this port causes an NMI on my
  29. ;                ;z80 keyboard board to force the CPM keyboard
  30. ;                
  31. CENTOUT    EQU    5H        ;CENTRONICS PRINTER PORT
  32. CENTSTAT EQU    5H
  33. CENTSTROBE EQU    4H
  34. ;
  35. TALKSTAT EQU    0B0H        ;REQ FOR SPEECH SYNTHESIS
  36. TALKOUT    EQU    0B1H
  37. ;
  38. ; MISC. EQUATES FOR RAMDISK
  39. ;
  40. CMDDLY    EQU    0FFFFH
  41. MAXTRK    EQU    2        ;RETURN MAXIMUM TRACK # OF MEMORY DISK
  42. RDSECTOR EQU    0
  43. WRTSECTOR EQU    1
  44. CTRLPORT EQU    0B6H        ;WAS 7
  45. DATAPORT EQU    0B8H        ;WAS 6
  46. ;
  47. ;------- HARD DISK PARAMETERS --------------------------------------
  48. ;
  49. MAXSEC    EQU    32            ;SECTORS PER TRACK ON HARD DISK
  50. MAXCYL    EQU    500            ;NUMBER OF CYLINDERS/HEAD
  51. LZONE    EQU    656
  52. BLKSIZ    EQU    2048            ;BYTES PER BLOCK FOR HARD DISK
  53. CPMSPT    EQU    2*MAXSEC        ;CPM SECTORS PER TRACK FOR HARD DISK
  54. HSKCMD    EQU    3            ;SEEK CMD FOR HARD DISK CONTROLLER
  55. SKOUT    EQU    1
  56. NOPC    EQU    40H            ;NO PRE-COMPENSATION
  57. LOWRT    EQU    80H            ;LOW WRITE CURRENT
  58. READY    EQU    1            ;HARD DISK DRIVE READY
  59. WRTFLT    EQU    2            ;HARD DISK WRITE FAULT
  60. TK00    EQU    4            ;HARD DISK TRACK ZERO
  61. RAWINDX    EQU    20H            ;HARD DISK RAW INDEX
  62. BANK0    EQU    0            ;BANK 0 SELECT ON XCOMP CONTROLLER
  63. BANK1    EQU    1            ;BANK 1 SELECT
  64. DBENB    EQU    2            ;DATA BUFFER ENABLE
  65. CBENB    EQU    4            ;COMPARE BUFFER ENABLE
  66. START    EQU    8            ;START COMMAND FOR XCOMP CONTROLLER
  67. VSA    EQU    8            ;SEEK VERIFY START ADDRESS
  68. VCA    EQU    1BH            ;SEEK VERIFY COMPARE ADDRESS
  69. CBASE    EQU    70H            ;BASE ADR OF THE XCOMP CONT PORTS
  70. DRCSR    EQU    CBASE            ;DRIVE COMMAND/STATUS
  71. EXTCMD    EQU    CBASE+1            ;EXTENDED COMMNAND REGISTER
  72. LOSC    EQU    CBASE+2            ;SEEK COUNT, LSB
  73. HISC    EQU    CBASE+3            ;SEEK COUNT, MSB
  74. CTCSR    EQU    CBASE+4            ;CONTROLLER COMMAND/STATUS
  75. CTBFR    EQU    CBASE+5            ;CONTROLLER BUFFER ADDRESS
  76. CTDP    EQU    CBASE+6            ;CONTROLLER DATA PORT
  77. ;
  78. ;------    VERSAFLOPPY II DISK PARAMETERS ---------------------------------
  79. ;
  80. X    EQU    60H            ;BASE ADDRESS OF PORTS FOR 1791
  81. RSET    EQU    X+0            ;CONTROLLER RESET ADDRESS
  82. SELECT    EQU    X+3            ;DRIVE SELECT PORT
  83. STATUS    EQU    X+4            ;STATUS PORT
  84. TRACK    EQU    X+5            ;TRACK PORT
  85. SECTOR    EQU    X+6            ;SECTOR PORT
  86. DATA    EQU    X+7            ;DATA PORT
  87. CMD    EQU    X+4            ;COMMAND PORT
  88. RDACMD    EQU    0C0H            ;READ ADDRESS CODE
  89. RDCMD    EQU    088H            ;READ SECTOR CODE
  90. WRCMD    EQU    0A8H            ;WRITE SECTOR CODE
  91. WRTCMD    EQU    0F4H            ;WRITE TRACK CODE
  92. RSCMD    EQU    009H            ;RESTORE COMMAND
  93. SKNCMD    EQU    019H            ;SEEK NO VERIFY
  94. SKCMD    EQU    1DH            ;SEEK WITH VERIFY
  95. STDSDT    EQU    26            ;STANDARD 8" 26 SECTORS/TRACK
  96. STDDDT    EQU    50            ;STANDARD DD 8" 50 SECTORS/TRACK
  97. NBYTES    EQU    128            ;BYTES/SECTOR 
  98. NTRKS    EQU    77            ;TRACKS/DISK
  99. ;
  100. ;
  101. ;   ASCII CHARACTERS
  102. ;
  103. CR    EQU    0DH            ;CARRIAGE RETURN
  104. LF    EQU    0AH            ;LINE FEED
  105. BELL    EQU    7            ;DING
  106. ;
  107. ;
  108.     CSEG
  109.     ORG    0H
  110. CCP:
  111. ;
  112. ;============================================================================
  113. ;                                         
  114. ;    THE CPM-86 CCP AND BDOS WILL GO HERE ( ABSOLUTE 500H TO 25FFH)
  115. ;
  116. ;    {I leave 100h bytes for an 8089 below cpm for my system. so the
  117. ;    org value is 2500h.  You may want to use 2400h as DR does}
  118. ;
  119. ;    NOTE WITH THIS 8089 VERSION I HAVE EVERYTHING 100H HIGHER
  120. ;    THAN EVERYTHING IN THE DIGITAL RESEARCH MANUAL.
  121. ;    SO THE CCP AND BDOS WILL BE FROM 500H TO 25FFH AND 8089
  122. ;    TABLE AT 400H TO 500H.
  123. ;                                         
  124. ;============================================================================
  125. ;
  126.     ORG    2500H            ;NOW THE START OF THE CUSTOM BIOS
  127.                     ;NOTE ACTUAL ADDRESS IS 2A00H BECAUSE
  128.                     ;OF [CS] OFFSET
  129. ;    ---JUMP TABLE---
  130. ;
  131. CPMINIT:JMP    INIT            ;  0 - COLD BOOT
  132. WBX:    JMP    WBOOT            ;  1 - WARM BOOT
  133.     JMP    CSTS            ;  2 - CONSOLE STATUS REQUEST
  134. ZCI:    JMP    CI            ;  3 - CONSOLE INPUT
  135. ZCO:    JMP    CO            ;  4 - CONSOLE OUTPUT
  136. ZLO:    JMP    LO            ;  5 - LIST OUTPUT
  137.     JMP    POO            ;  6 - PUNCH OUTPUT
  138.     JMP    RI            ;  7 - READER INPUT
  139.     JMP    HOME            ;  8 - TRACK ZERO SEEK
  140.     JMP    SETDR            ;  9 - SET DRIVE #
  141.     JMP    SETTK            ; 10 - SET TRACK ADR
  142.     JMP    SETSEC            ; 11 - SET SECTOR ADR
  143.     JMP    SETDMA            ; 12 - SET BUFFER ADDRESS
  144.     JMP    READ            ; 13 - READ A SECTOR
  145.     JMP    WRITE            ; 14 - WRITE A SECTOR
  146. ZLISTS:    JMP    LSTAT            ; 15 - LIST OUTPUT READY TEST
  147.     JMP    SXR            ; 16 - SECTOR XLATE ROUTINE
  148.     JMP    SETDMAB            ; 17 - SET SEG BASE FOR BUFFER
  149.     JMP    GETSEGT            ; 18 - GET MEM DESC TABLE OFFSET
  150.     JMP    GETIOBF            ; 19 - RETURN IO BYTE
  151.     JMP    SETIOBF            ; 20 - SET IO BYTE
  152. ;
  153. ;        =====================
  154. ;        ** CBIOS FUNCTIONS **
  155. ;        =====================
  156. ;          ---COLD BOOT---
  157. ;
  158. ;
  159. INIT:    MOV    AX,CS
  160.     MOV    SS,AX
  161.     MOV    DS,AX
  162.     MOV    ES,AX
  163.     MOV    SP, OFFSET STKBASE        ;USE A LOCAL STACK
  164.     CLD
  165.     PUSH    DS
  166.     MOV    AX,0
  167.     MOV    DS,AX
  168.     MOV    ES,AX
  169.     MOV    INT0_OFFSET, OFFSET INT_TRAP    ;INT0 TO ADDRESS TRAP ROUTINE
  170.     MOV    INT0_SEGMENT, CS
  171.     MOV    DI,4
  172.     MOV    SI,0
  173.     MOV    CX,510                ;TRAP VECTOR TO ALL 256 INTS
  174.    REP    MOVS     AX,AX
  175.     MOV    BDOS_OFFSET, 0B06H        ;BDOS OFFSET TO PROPER INT0
  176.     MOV    BDOS_SEGMENT,CS
  177.     MOV    INT0_OFFSET, OFFSET INT0_TRAP
  178.     MOV    INT4_OFFSET, OFFSET INT4_TRAP
  179.     POP    DS
  180. ;        
  181.     CALL    XTKZ            ;BRING HEADS OF HDISK TO TRK 0
  182. ;
  183.     MOV    BX,OFFSET FLAGS        ;CLEAR RAM STORAGE AREA
  184.     MOV    CH, FLGSIZ
  185.     XOR    AL,AL
  186. INIT1:    MOV    BYTE PTR [BX],AL    ;CLEAR FLAGS & VARIABLES
  187.     INC    BX
  188.     DEC    CH
  189.     JNZ    INIT1
  190.     MOV    BYTE PTR IOBYT, AL    ;CLEAR IOBYTE
  191.     DEC    AL            ;0FFH IN AL
  192.     MOV    BYTE PTR ADRIVE, AL    ;COME ON WITH B: & C: DENSITY UNKNOWN
  193.     MOV    BYTE PTR BDRIVE, AL
  194.     OUT    CENTSTROBE,AL        ;CLEAR PRINTER PORT JUST IN CASE
  195.     IN    AL,DATAPORT        ;CLEAR GARBAGE FROM PARALLEL PORT FOR
  196.                     ;MDISK
  197.     in    al,resetkey        ;to insure cpm table in z80board
  198.     MOV    WORD PTR DMASEG, CS    ;SET DEFAULT SEGMENT DMA TO HERE
  199.     MOV    BX,OFFSET SIGNON
  200.     CALL    PMSG
  201.     MOV    BX,OFFSET SPEAKON
  202.     CALL    SMSG
  203.     MOV    CL,0            ;DEFAULT TO DRIVE A:
  204.     JMP    CCP
  205. ;
  206. ;    ---WARM BOOT---
  207. ;
  208. WBOOT:    in    al,resetkey        ;to insure cpm table in z80board
  209.     XOR    AL,AL
  210.     DEC    AL
  211.     MOV    BYTE PTR ADRIVE,AL    ;PUT 0FFH IN FLOPPY A & B STORE
  212.     MOV    BYTE PTR BDRIVE,AL
  213.     JMP    CCP + 6            ;GOTO CPM
  214. ;    
  215. ;
  216. ;    --- INT TRAP ROUTINES ---
  217. INT0_TRAP: CLI    
  218.     MOV    BX,OFFSET INT0_TRP    ;DIVIDE TRAP HALT
  219.     JMPS    INT_HALT
  220.  
  221. INT4_TRAP: CLI
  222.     MOV    BX,OFFSET INT4_TRP    ;OVERFLOW TRAP HALT
  223.     JMPS    INT_HALT
  224.  
  225. INT_TRAP: CLI
  226.     MOV    BX,OFFSET INT_TRP    ;INTERRUPT TRAP HALT
  227.  
  228. INT_HALT:MOV    AX,CS
  229.     MOV    DS,AX
  230.     CALL    PMSG
  231.     POP    BX            ;GET SEGMENT
  232.     POP    AX            ;PRINT SEGMENT
  233.     PUSH    BX
  234.     CALL    PHEX
  235.     MOV    CL,':'
  236.     CALL    ZCO            ;PRINT OFFSET
  237.     POP    AX
  238.     CALL    PHEX
  239.     HLT                ;HOLD EVERYTHING
  240. ;
  241. PHEX:    PUSH    AX
  242.     MOV    AL,AH
  243.     CALL    PHXB
  244.     POP    AX
  245. PHXB:    PUSH    AX
  246.     MOV    CL,4
  247.     SHR    AL,CL
  248.     CALL    PHXD
  249.     POP    AX
  250.     AND    AL,0FH            ;ISOLATE LOWER NIBBLE
  251. PHXD:    ADD    AL,90H            ;DISPLAY A NIBBLE
  252.     DAA
  253.     ADC    AL,40H
  254.     DAA
  255.     MOV    CL,AL
  256.     CALL    ZCO
  257.     RET
  258. ;
  259. GETIOBF: MOV    AL,IOBYT
  260.     RET
  261. ;
  262. SETIOBF: MOV    IOBYT,CL
  263.     RET
  264. ;
  265.  
  266. PMSG:    MOV    AL,[BX]            ;PRINT A STRING
  267.     TEST    AL,AL
  268.     JZ    RETURN
  269.     MOV    CL,AL
  270.     CALL    ZCO
  271.     INC    BX
  272.     CALL    PMSG
  273. RETURN:    RET
  274.  
  275.  
  276. ;    ---SECTOR TRANSLATE ROUTINE---
  277. ;
  278. SXR:     TEST    DX,DX
  279.     JNZ    SXR1            ;IF Z THEN NO TRANSLATION IS REQ
  280.     MOV    BX,CX
  281.     RET
  282. ;
  283. SXR1:    MOV    BX,CX            ;TRANS SEC [CX] USING TABLE AT [DX]
  284.     ADD    BX,DX            ;WILL HAVE NO TRANSLATION FOR MDISK
  285.     MOV    BL,[BX]
  286.     RET
  287. ;
  288. ;    ---HOME---
  289. ;
  290. HOME:    MOV    AL,BYTE PTR RRDSK    ;DRIVE #
  291.     CMP    AL,1            ;SET AT THE MOMENT FOR ONE HARD DISK
  292.     JNB    HOMEX
  293.     JMP    XSTZ            ;JIF REZERO HARD DISK
  294. HOMEX:    MOV    CX,0            ;RETURN ZERO JUST IN CASE
  295.     JMP    SETTK
  296. ;
  297. ;    ---READ---
  298. ;
  299. READ:    MOV    AL,BYTE PTR RRDSK    ;DRIVE #
  300.     CMP    AL,1
  301.     JNB    LAB13    
  302.     JMP    HDREAD            ;JIF READ FROM H/D
  303. LAB13:    CMP    AL,3
  304.     JNB    LAB14    
  305.     JMP    FREAD            ;JIF READ FROM F/D
  306. LAB14:    CMP    AL,12            ;CHECK IF MDISK
  307.     JNZ    SELERR            ;IF M: THEN MDISK
  308.     JMP    MREAD
  309. ;
  310. SELERR:    XOR    AL,AL
  311.     DEC    AL
  312.     RET                ;RETURN WITH NZ FLAG FOR ERROR
  313. ;
  314. ;    ---WRITE---
  315. ;
  316. WRITE:    MOV    AL,BYTE PTR RRDSK    ;DRIVE #
  317.     CMP    AL,1
  318.     JNB    LAB15    
  319.     JMP    HDWRT            ;JIF WRITE ONTO H/D
  320. LAB15:    CMP    AL,3
  321.     JNB    LAB16    
  322.     JMP    FWRITE            ;JIF WRITE ONTO F/D
  323. LAB16:    CMP    AL,12            ;CHECK IF MDISK
  324.     JNZ    SELERR            ;IF F: THEM MDISK
  325.     JMP    MWRITE
  326. ;
  327. ;    ---SET DRIVE NUMBER---
  328. ;
  329. SETDR:    MOV    AL,CL            ;A = NEW DRIVE #
  330.     MOV    BYTE PTR RRDSK,AL    ;  SAVE IT
  331.     MOV    BX,0
  332.     CMP    AL,12            ;TEST FOR MDISK
  333.     JE    MDSELDSK
  334.     CMP    AL,3
  335.     JNAE    LAB17            ;NOT M:, A:, B:, OR C: SO ERROR
  336.     RET                ;RIF INVALID DRIVE # WITH [BX]=0
  337. ;
  338. LAB17:    CMP    AL,0            ;IF NOT 0 IE. [A:] MUST BE FLOPPYS
  339.     JE    LAB18    
  340.     CALL    FSELDSK            ;RET WITH LOGICAL DRIVE OFFSET IN [A]
  341. LAB18:    MOV    BL,AL            ;B: OR C: (OR FOR DD D: OR E:)
  342.     MOV    BH,0            
  343.     MOV    CL,4
  344.     SHL    BX,CL            ;TIMES 16 
  345.     ADD    BX,OFFSET DPHDR
  346.     RET
  347. ;
  348. MDSELDSK:
  349.     TEST    DL,01
  350.     JZ    GETMDSK            ;UPDATE DPB
  351.     MOV    BX,OFFSET DPE12        ;HEADER FOR DISK WILL ALWAYS BE HERE
  352.     RET
  353. ;
  354. GETMDSK:MOV    CL,MAXTRK        ;NEED MAXIMUM TRACK # FROM RAMDISK
  355.     CALL    MRDCMD            ;SO SEND COMMAND TO RAMDISK
  356.     JNB    MDINIT1            ;SKIP NEXT IF COMMAND SENT OK
  357. MDINIT0:MOV    BX,0            ;THIS WILL FLAG BDOS
  358.     RET
  359. ;
  360. MDINIT1:CALL    RDREAD            ;WAIT FOR MAXIMUM TRACK BYTE
  361.     CMP    AL,-1            ;IF TRACK =-1 THEN NO MDISK AVAILABLE
  362.     JZ    MDINIT0
  363.     INC    AL            ;PUT TRACK INTO RANGE 1 - N
  364.     MOV    BL,AL            ;MAKE TRACK DOUBLE PRECISION IN [HL]
  365.     MOV    BH,0
  366.     MOV    DX,BX            ;KEEP COPY IN [DX]
  367.     MOV    CL,5
  368.     SHL    BX,CL            ;X32
  369.     SUB    BX,DX            ;X31
  370.     SUB    BX,DX            ;X30 (THIS IS # 2K BLOCKS / TRACK)
  371.     MOV    AL,BH            ;GET HI BYTE OF DSM TO [A]
  372.     OR    AL,AL            ;IS IT > 0 ?
  373.     MOV    AL,0            ;ASSUME >= 256 BLOCKS
  374.     JNZ    MDINIT2
  375.     MOV    AL,1            ;ELSE EXM MUST = 1
  376. MDINIT2:
  377.     MOV    BYTE PTR DPB_EXM,AL        ;STORE EXM BYTE INTO DPB
  378.     DEC    BX            ;# 2K BLOCKS - 1
  379.     MOV    WORD PTR DPB_DSM,BX    ;UPDATE DPB DSM FIELD
  380.     MOV    BX,OFFSET DPE12
  381.     RET
  382. ;
  383. ;    ---SET SECTOR ADR---
  384. ;
  385. SETSEC:    MOV    WORD PTR RRSEC,CX    ;SAVE SECTOR ADR (NEED CX BECAUSE THE
  386.                     ;MDISK HAS UP TO 480 SECTORS/"TRACK"
  387.                     ;SET REAL SEC ADR FOR THE HARD DISK
  388.     AND    CL,0FEH            ;DRIVER.
  389.     ROR    CL,1            ;THERE ARE 2 CPM SECTORS PER H/D SECT
  390.     MOV    BYTE PTR RSA,CL        ;SAVE REAL SECTOR ADR 
  391.     RET
  392. ;    
  393. ;    ---SET TRACK ADDRESS---
  394. ;
  395. SETTK:    MOV    WORD PTR RRTRK,CX    ;SAVE TRACK ADR
  396.     RET
  397. ;
  398. ;    ---SET DMA ADDRESS---
  399. ;
  400. SETDMA:    MOV    WORD PTR DMADR,CX    ;SAVE DMA ADR
  401.     RET
  402. ;
  403. ;    ---- SET DMA SEGMENT ---
  404. ;
  405. SETDMAB:MOV    WORD PTR DMASEG,CX
  406.     RET
  407. ;
  408. ;    ---- GET MEMORY MAP ---
  409. GETSEGT:MOV    BX, OFFSET SEG_TABLE
  410.     RET
  411. ;
  412. ;    ======================================
  413. ;    ** HARD DISK BLOCK/DEBLOCK ROUTINES **
  414. ;    ======================================
  415. ;
  416. ;    ---HARD DISK READ---
  417. ;
  418. HDREAD:    XOR    AL,AL
  419.     MOV    BYTE PTR ERFLG,AL    ;CLEAR THE ERROR FLAG
  420.     MOV    AL,BYTE PTR FLAGS    ;SET READ OPERATION FLAG
  421.     OR    AL,00000001B        ;SET    0,A
  422.     MOV    BYTE PTR FLAGS,AL
  423.     AND    AL,00000100B        ;BIT     2,A
  424.     JZ    LAB19    
  425.     CALL    XWRT            ;YES, WRITE DATA BEFORE READ
  426. LAB19:    MOV    AL,BYTE PTR FLAGS
  427.     AND    AL,11111011B        ;RES    2,A    RESET WIP FLAG
  428.     MOV    BYTE PTR FLAGS,AL
  429.     CALL    TSTHST            ;HOST = REQ ?
  430.     JNZ    HDRD1            ;NO, READ A BLOCK
  431.     MOV    AL,BYTE PTR FLAGS
  432.     AND    AL,02H            ;PRIOR BLOCK READ ?
  433.     JNZ    HDRD2            ;YES, JUST EXTRACT DATA FROM BFR
  434. HDRD1:    CALL    SETHST            ;MAKE HOST=REQ
  435.     CALL    XREAD            ;READ A BLOCK
  436. HDRD2:    CALL    GETDMA            ;GET DMA ADR, SET POINTERS
  437.     PUSH    ES
  438.     MOV    ES, WORD PTR DMASEG     ;GET CORRECT SEGMENT
  439.     MOV    DI,BX
  440.     CLD                ;SET DIRECTION FLAG
  441.     IN    AL,CTDP            ;PRIME DATA INPUT
  442. HDRD3:    IN    AL,CTDP            ;<<<<<<<<<<<<<< INPUT 128 BYTES >>>>>
  443.     STOS    AL            ;NOTE POINTER IS [ES] & [DI]
  444.     LOOP    HDRD3            ;WILL HAVE AUTO INC OF [CX] & [DI]
  445.     POP    ES    
  446.     MOV    AL,BYTE PTR FLAGS
  447.     OR    AL,00000010B        ;SET  1,A  SET READ-IN-PROGRESS FLAG
  448.     MOV    BYTE PTR FLAGS,AL
  449.     MOV    AL,BYTE PTR ERFLG    ;ERROR FLAG
  450.     RET
  451. ;    
  452. ;    ---HARD DISK WRITE---
  453. ;
  454. ;
  455. HDWRT:    XOR    AL,AL
  456.     MOV    BYTE PTR ERFLG,AL    ;CLEAR THE ERROR FLAG
  457.     MOV    AL,BYTE PTR FLAGS
  458.     AND    AL,11111101B        ;RES  1,A CLEAR READ-IN-PROGRESS FLAG
  459.     MOV    BYTE PTR FLAGS,AL
  460.     MOV    AL,CL            ;AL= 0 NORMAL = 1 DIR = 2 UNALLOCATED
  461.     DEC    AL
  462.     JNZ    LAB20    
  463.     JMP    WDIR            ;DO DIRECTORY WRITE
  464. LAB20:    JNS    WUN
  465.     JMP    WNORM            ;DO NORMAL WRITE
  466. ;
  467. ;   UNALLOCATED WRITE
  468. ;
  469. WUN:    MOV    AL,BYTE PTR FLAGS
  470.     AND    AL,00000100B        ;BIT    2,A     WRITE IN PROGRESS ?
  471.     JZ    LAB21    
  472.     CALL    XWRT            ;YES, WRITE DATA IN BFR
  473. LAB21:    MOV    AL,BLKSIZ/128        ;SET UNALLOC RECORD PARAMETERS
  474.     MOV    BYTE PTR URCNT,AL    ;SET UNALLOC RECORD COUNT
  475.     MOV    BX,WORD PTR RRDSK
  476.     MOV    WORD PTR URDSK,BX    ;UPDATE DRIVE & SECTOR
  477.     MOV    BX,WORD PTR RRTRK
  478.     MOV    WORD PTR URTRK,BX    ;UPDATE TRACK ADR
  479.     CALL    SETHST            ;SET HOST = REQ
  480.     CALL    BUMP            ;BUMP UNALC PARMS FOR NEXT PASS
  481.                     ;XFER DATA TO CTLR BFR
  482. WXFER:    MOV    AL,BYTE PTR FLAGS
  483.     AND    AL,11111110B        ;RES  0,A        CLEAR READ OPER FLAG
  484.     MOV    BYTE PTR FLAGS,AL
  485.     CALL    GETDMA            ;GET DMA ADR, SET FOR WRITE
  486.     PUSH    DS
  487.     MOV    DS, WORD PTR DMASEG    ;GET CORRECT SEGMENT
  488.     CLD
  489.     MOV    SI,BX
  490. WXFER1:    LODS    AL            ;>>>>>>>>>OUTPUT 128 BYTES<<<<<<<<<<<
  491.     OUT    CTDP,AL            ;POINTER WILL BE [DS] AND [SI]
  492.     LOOP    WXFER1
  493.     POP    DS            ;RESTORE [DS]
  494.     MOV    AL,BYTE PTR FLAGS
  495.     OR    AL,00000100B        ;SET  2,A  SET WRITE-IN-PROGRESS FLAG
  496.     MOV    BYTE PTR FLAGS,AL
  497.     MOV    AL,BYTE PTR ERFLG    ;ERROR FLAG
  498.     RET
  499. ;
  500. ;   NORMAL WRITE
  501. ;
  502. WNORM:    MOV    AL,BYTE PTR URCNT    ;UNALC RECORD COUNT
  503.     OR    AL,AL
  504.     JZ    WALC            ;JIF DO ALLOC WRITE
  505.     MOV    BX,(OFFSET URTRK)
  506.     CALL    DSKCMP            ;UNALC DSK/TRK = REQ DSK/TRK ?
  507.     JNZ    WALC            ;NO, DO ALLOC WRITE
  508.     MOV    AL,BYTE PTR RRSEC
  509.     CMP    AL,BYTE PTR [BX]    ;UNALC SECT = REQ SECT ?
  510.     JNZ    WALC            ;NO, DO ALLOC WRITE
  511.     CALL    BUMP            ;BUMP UNALC PARMS FOR NEXT PASS
  512.     CALL    TSTHST            ;HOST = REQ ?
  513.     JZ    WN1            ;YES, CON'T TO FILL THE BFR
  514.     MOV    AL,BYTE PTR FLAGS
  515.     AND    AL,00000100B        ;BIT 2,A   WRITE IN PROGRESS ?
  516.     JZ    LAB22    
  517.     CALL    XWRT            ;YES, WRITE OLD DATA ONTO DISK
  518. LAB22:    CALL    SETHST            ;MAKE HOST = REQ
  519. ;
  520. WN1:    MOV    AL,BYTE PTR FLAGS
  521.     AND    AL,00000001B        ;BIT  0,A          INTERVENING READ ?
  522.     JZ    LAB23    
  523.     CALL    XREAD            ;YES, READ OLD UNALC DATA
  524. LAB23:    JMPS    WXFER            ;MOVE DATA TO BFR, EXIT
  525. ;
  526. ;   ALLOCATED WRITE
  527. ;
  528. WALC:    XOR    AL,AL
  529.     MOV    BYTE PTR URCNT,AL    ;CLEAR UNALC RECORD COUNT
  530.     CALL    TSTHST            ;HOST = REQ ?
  531.     JZ    WXFER            ;YES -  MOVE DATA TO BFR, EXIT
  532.     MOV    AL,BYTE PTR FLAGS
  533.     AND    AL,00000100B        ;BIT  2,A      WRITE IN PROGRESS ?
  534.     JZ    LAB24    
  535.     CALL    XWRT            ;YES, WRITE OLD DATA ONTO DISK
  536. LAB24:    CALL    SETHST            ;MAKE HOST = REQ
  537.     CALL    XREAD            ;READ IN ALLOCATED DATA
  538.     JMPS    WXFER            ;MOVE NEW DATA IN BFR, EXIT
  539. ;
  540. ;   DIRECTORY WRITE
  541. ;
  542. WDIR:    XOR    AL,AL
  543.     MOV    BYTE PTR URCNT,AL    ;CLEAR UNALC RECORD COUNT
  544.     MOV    AL,BYTE PTR FLAGS
  545.     AND    AL,11111110B        ;RES   0,A          RESET 'RDOP' FLAG
  546.     MOV    BYTE PTR FLAGS,AL
  547.     AND    AL,00000100B        ;BIT   2,A       WRITE IN PROGRESS ?
  548.     JZ    LAB25    
  549.     CALL    XWRT            ;YES, WRITE OLD DATA ONTO THE DISK
  550. LAB25:    MOV    AL,BYTE PTR FLAGS
  551.     AND    AL,11111011B        ;RES  2,A           CLEAR 'WIP' FLAG
  552.     MOV    BYTE PTR FLAGS,AL
  553.     CALL    SETHST            ;MAKE HOST = REQ
  554.     CALL    XREAD            ;READ DIR DATA
  555.     JZ    LAB26    
  556.     RET                ;RIF READ ERROR
  557. LAB26:    CALL    GETDMA            ;GET DMA ADR, SET POINTERS
  558.     PUSH    DS
  559.     MOV    DS, WORD PTR DMASEG    ;GET THE CORRECT SEGMENT FOR [BX]
  560.     MOV    SI,BX
  561.     CLD
  562. WDIRX:    LODS    AL            ;<<<<<<<<<<<< OUTPUT 128 BYTES >>>>>>
  563.     OUT    CTDP,AL
  564.     LOOP    WDIRX
  565.     POP    DS            ;GET BACK OLD VALUE OF [DS]
  566.     JMPS    XWRT            ;WRITE DIR DATA, EXIT
  567. ;
  568. ;    ---TEST HOST---
  569. ;
  570. ;   DETERMINES IF THE HOST DISK ADDRESS IS
  571. ;   THE SAME AS THE REQUESTED DISK ADDRESS.
  572. ;
  573. ;
  574. TSTHST:    MOV    BX,(OFFSET HHTRK)
  575.     CALL    DSKCMP            ;TRACK & DRIVE THE SAME ?
  576.     JZ    LAB27    
  577.     RET                ;RIF NO
  578. LAB27:    MOV    AL,BYTE PTR RSA
  579.     CMP    AL,BYTE PTR [BX]    ;SECTOR THE SAME ?
  580.     RET                ;IF A = 0 THEN THEY MATCH
  581. ;
  582. ;    ---SET HOST---
  583. ;
  584. ;   SETS THE HOST DISK ADDRESS TO BE THE
  585. ;   SAME AS THE REQUESTED DISK ADDRESS.
  586. ;
  587. ;
  588. SETHST:    MOV    AL,BYTE PTR RRDSK
  589.     MOV    BYTE PTR HHDSK,AL    ;DRIVE #
  590.     MOV    BX,WORD PTR RRTRK
  591.     MOV    WORD PTR HHTRK,BX    ;TRACK ADR
  592.     MOV    AL,BYTE PTR RSA
  593.     MOV    BYTE PTR HHSEC,AL    ;SECTOR ADR
  594.     RET
  595. ;
  596. ;    ---BUMP---
  597. ;
  598. ;   BUMPS PARAMETERS FOR UNALLOCATED WRITES.
  599. ;   PARMS ARE CHANGED FOR THE NEXT PASS THRU
  600. ;   THE CODE (NOT THE CURRENT PASS).
  601. ;
  602. BUMP:    MOV    BX,(OFFSET URCNT)    ;UNALC RECORD COUNT
  603.     DEC    BYTE PTR [BX]        ;  DECR IT
  604.     DEC    BX            ;[BX] = URSEC
  605.     INC    BYTE PTR [BX]        ;  INCR IT
  606.     MOV    AL,BYTE PTR [BX]
  607.     CMP    AL,CPMSPT        ;CPM SECTORS PER TRACK
  608.     JNB    LAB28    
  609.     RET                ;RIF STAY ON SAME TRACK
  610. LAB28:                    ;OVERFLOW TO NEXT TRACK
  611.     MOV    BYTE PTR [BX],0        ;RESET SECTOR ADR
  612.     MOV    BX,WORD PTR URTRK
  613.     INC    BX            ;INC TRACK ADDRESS
  614.     MOV    WORD PTR URTRK,BX
  615.     RET
  616. ;
  617. ;    ---GET DMA ADDRESS---
  618. ;
  619. ;   SETS THE CONTROLLER BUFFER ADDRESS TO THE CORRECT
  620. ;   STARTING POINT. ALSO SETS CX=128 & [BX] = DMADR.
  621. ;
  622. ;
  623. GETDMA:    MOV    BX,WORD PTR DMADR    ;DMA ADR
  624.     MOV    CX,128            ;BYTE COUNT
  625.     MOV    AL,DBENB
  626.     OUT    CTCSR,AL        ;ENB DATA BFR
  627.     MOV    AL,BYTE PTR RRSEC    ;REQUESTED SECTOR
  628.     ROR    AL,1
  629.     MOV    AL,0
  630.     JNB    GET1            ;JIF USE 1ST HALF OF BFR
  631.     MOV    AL,CL            ;[CL] =128    USE 2ND HALF OF BFR
  632. GET1:    OUT    CTBFR,AL        ;SET CTLR DATA BFR ADR
  633.     RET
  634. ;
  635. ;
  636. ;    ======================================
  637. ;    ** HARD DISK I/O & SUPPORT ROUTINES **
  638. ;    ======================================
  639. ;    ---READ A BLOCK---
  640. ;
  641. XREAD:    MOV    BX,(OFFSET RTBL)    ;READ CMD TBL
  642.     CALL    DORW            ;READ
  643. ;
  644. XR1:    MOV    AL,0
  645.     JNZ    LAB29    
  646.     RET                ;RIF READ/WRITE OK
  647. LAB29:    INC    AL
  648.     MOV    BYTE PTR ERFLG,AL    ;SET ERROR FLAG
  649.     RET
  650. ;
  651. ;    ---WRITE A BLOCK---
  652. ;
  653. XWRT:    MOV    BX,(OFFSET WTBL)    ;WRITE CMD TBL
  654.     CALL    DORW            ;WRITE A SECTOR
  655.     JMPS    XR1            ;SET ERROR FLAG
  656. ;
  657. ;    ---EXECUTE READ/WRITE COMMANDS---
  658. ;
  659. DORW:    MOV    Word Ptr CTA,BX        ;SAVE CMD TBL ADR
  660.     CALL    XSEK            ;SEEK TO NEW TRACK (IF REQUIRED)
  661.     JZ    PAT1
  662.     RET                ;RIF SEEK FAILED
  663. PAT1:
  664.     CALL    XSEL            ;HEAD SELECT
  665.     MOV    BX,Word Ptr CTA
  666. ;
  667. DO0:    MOV    AL,Byte Ptr [BX]
  668.     MOV    Byte Ptr RETRY,AL    ;SET RETRY COUNT
  669.     INC    BX
  670.     MOV    AL,Byte Ptr [BX]
  671.     OUT    CTCSR,AL        ;ENB CMP BFR
  672.     INC    BX
  673.     MOV    AL,Byte Ptr [BX]
  674.     OUT    CTBFR,AL        ;SET CMP BFR ADR
  675.     INC    BX
  676.     MOV    Word Ptr CTA,BX        ;SAVE CMD TBL ADR
  677. ;
  678.     MOV    BX,(Offset RCA)        ;REAL TK ADR
  679.     MOV    CH,3
  680. DO1:    MOV    AL,Byte Ptr [BX]
  681.     OUT    CTDP,AL            ;PUT HDR INFO INTO CMP BFR
  682.     INC    BX
  683.     DEC    CH
  684.     JNZ    DO1
  685.     MOV    AL,Byte Ptr HHSEC
  686.     OUT    CTDP,AL            ;SET SECT ADR FOR COMPARE
  687. ;
  688. DO2:    CALL    XRDY            ;DRIVE READY ?
  689.     JZ    PAT2    
  690.     RET                ;  RIF NO
  691. PAT2:
  692.     MOV    BX,Word Ptr CTA        ;CMD TBL ADR
  693.     MOV    AL,Byte Ptr [BX]    ;A = CNTL BANK
  694.     INC    BX
  695.     MOV    CH,AL
  696.     OUT    CTCSR,AL        ;SLCT CNTL BANK
  697.     MOV    AL,Byte Ptr [BX]
  698.     OUT    CTBFR,AL        ;SET START ADR
  699.     INC    BX
  700.     MOV    AL,CH
  701.     OR    AL,START
  702.     OUT    CTCSR,AL        ;START R/W CMD
  703. ;
  704. DO3:    CALL    WFD            ;WAIT FOR READ/WRITE TO FINISH
  705.     JNB    PAT3    
  706.     RET                ;ABORT IF TIMEOUT
  707. PAT3:
  708.     AND    AL,Byte Ptr [BX]    ;TEST CTLR STATUS (0=OK)
  709.     MOV    CH,AL
  710.     IN    AL,DRCSR        ;DRIVE STATUS
  711.     AND    AL,WRTFLT
  712.     JZ    PAT4    
  713.     CALL    CLRDF            ;CIF CLEAR DRIVE FAULT
  714. PAT4:
  715.     OR    AL,CH            ;SET/CLEAR ERROR FLAG (0=OK)
  716.     JNZ    PAT5    
  717.     RET                ;RIF READ/WRITE OK
  718. PAT5:
  719.     MOV    BX,(Offset RETRY)
  720.     DEC    BYTE PTR [BX]        ;DECR RETRY COUNT
  721.     JNZ    DO2            ;JIF RETRY READ/WRITE
  722. ;
  723. ;   SET ERROR FLAG
  724. ;
  725. SEF:    MOV    AL,1            ;A = ERROR FLAG
  726.     OR    AL,AL            ;SET 8080 FLAGS
  727.     RET                ;TAKE ERROR EXIT
  728. ;
  729. ;    ---WAIT FOR DONE---
  730. ;
  731. WFD:    PUSH    BX
  732.     MOV    BX,0            ;TIMEOUT DELAY COUNT
  733. ;
  734. WFD1:    IN    AL,CTCSR        ;CTLR STATUS
  735.     ROR    AL,1
  736.     JB    WFD2            ;WAIT FOR DONE
  737.     DEC    BX
  738.     MOV    AL,BH
  739.     OR    AL,BL
  740.     JNZ    WFD1
  741. ;
  742.     OUT    CTCSR,AL
  743.     POP    BX
  744.     MOV    AL,1
  745.     OR    AL,AL
  746.     STC
  747.     RET
  748. ;
  749. WFD2:    POP    BX
  750.     IN    AL,CTCSR        ;GET NON-CHANGING STATUS
  751.     MOV    CH,AL
  752.     XOR    AL,AL
  753.     OUT    CTCSR,AL        ;STOP CTLR
  754.     MOV    AL,CH
  755.     RET
  756. ;
  757. ;    ---REZERO---
  758. ;
  759. XTKZ:    MOV    BX,0
  760.     MOV    Word Ptr RCA,BX
  761.     CALL    TZT            ;TEST IF TRK 0
  762.     JNZ    PAT6
  763.     RET
  764. PAT6:    MOV    BX,511            ;#OF CYL WE CAN COUNT ON CONTROLLER
  765.     CALL    RTZ            ;SEEK OUT
  766.     JNB    PAT7    
  767.     RET                ;ABORT DRIVE NOT READY
  768. PAT7:    JNZ    PAT8    
  769.     RET                ;IS AT 0
  770. PAT8:    MOV    BX,LZONE+10-511
  771.     CALL    RTZ            ;TRY SECOND PUMP
  772.     JNB    PAT9
  773.     RET
  774. PAT9:    JNZ    PAT10
  775.     RET
  776. PAT10:    JMPS    SEF            ;ABORT RESTORE FAILED
  777. ;
  778. ;    SEEK OUTWARD
  779. ;
  780. RTZ:    CALL    XRDY
  781.     STC
  782.     JZ    PAT11
  783.     RET
  784. PAT11:
  785.     MOV    AL,BL
  786.     OUT    LOSC,AL            ;SET LSB OF SEEK COUNT
  787.     MOV    AL,BH
  788.     OUT    HISC,AL            ;SET MSB
  789.     MOV    AL,SKOUT
  790.     OUT    EXTCMD,AL        ;SET SEEK DIRECTION OUTWARD
  791.     MOV    AL,HSKCMD
  792.     OUT    DRCSR,AL        ;ISSUE SEEK
  793.     CALL    WSC
  794.     JNB    TZT
  795.     RET
  796. ;
  797. TZT:    IN    AL,DRCSR        ;GET DRIVE STATUS
  798.     AND    AL,TK00
  799.     XOR    AL,TK00
  800.     RET
  801. ;
  802. XSTZ:    MOV    AL,BYTE PTR FLAGS
  803.     AND    AL,00000100B
  804.     JNZ    XSTZ1
  805.     MOV    BYTE PTR FLAGS,AL
  806. XSTZ1:    MOV    BX,0
  807.     MOV    WORD PTR RRTRK,BX
  808.     XOR    AL,AL
  809.     RET
  810. ;
  811. ;
  812. ;    ---SEEK---
  813. ;
  814. XSEK:    MOV    AL,3
  815.     MOV    Byte Ptr SKRTC,AL    ;SET SEEK RETRY COUNT
  816. ;
  817. XSEK1:    MOV    BX,Word Ptr HHTRK    ;REQUESTED TRACK
  818.     SHR    BX,1
  819.     CMP    BX,MAXCYL
  820.     JNAE    XSEK2
  821.     JMP    SEF            ;ABORT IF INVALID ADDRESS
  822. ;
  823. XSEK2:    MOV    DX,Word Ptr RCA        ;LOAD UP CURRENT REAL ADR
  824.     MOV    Word Ptr RCA,BX        ;SAVE NEW ADDRESS
  825.     XCHG    BX,DX
  826.     SUB    BX,DX
  827.     JNZ    PAT14    
  828.     RET                ;RETURN IF SAME
  829. PAT14:    MOV    CH,1            ;DIR = OUT
  830.     JNB    XSEK3            ;OK SEEK OUTWARD
  831. ;
  832.     MOV    CH,3            ;SEEK INWARD
  833.     MOV    AL,BL
  834.     NOT    AL            ;MAKE SEEK POSITIVE
  835.     MOV    BL,AL
  836.     MOV    AL,BH
  837.     NOT    AL
  838.     MOV    BH,AL
  839.     INC    BX
  840. ;
  841. XSEK3:    MOV    AL,CH            ;GO TO SEEKING INWARD
  842.     MOV    Byte Ptr SKDIR,AL
  843.     MOV    DX,512
  844.     CMP    BX,DX
  845.     JNB    XSEK4            ;JIF DOUBLE PUMP IS REQ
  846.     CALL    PSK            ;DO PARTIAL SEEK
  847.     JZ    PAT15
  848.     RET
  849. PAT15:    JMPS    XSEK5
  850. ;
  851. XSEK4:    DEC    DX            ;DX = 511
  852.     SUB    BX,DX
  853.     MOV    Word Ptr RSKNT,BX    ;SAVE RESIDUAL COUNT
  854.     XCHG    BX,DX
  855.     CALL    PSK
  856.     JZ    PAT16    
  857.     RET                ;ABORT IF SEEK FAILED
  858. PAT16:    MOV    BX,Word Ptr RSKNT
  859.     CALL    PSK            ;SEND THE REST
  860.     JZ    XSEK5
  861.     RET
  862. ;
  863. ;                    ;SEEK VERIFY
  864. XSEK5:    MOV    AL,3
  865.     MOV    Byte Ptr VSRTC,AL    ;SET RETRY COUNT
  866.     MOV    AL,CBENB
  867.     OUT    CTCSR,AL        ;ENABLE BANK ZERO CMP BFR
  868.     MOV    AL,VCA
  869.     OUT    CTBFR,AL        ;SET CMP BFR ADR
  870.     MOV    BX,Word Ptr RCA        ;REAL (CURR) CYL ADR
  871.     MOV    AL,BL
  872.     OUT    CTDP,AL            ;SET CYL ADR, LSB
  873.     MOV    AL,BH
  874.     OUT    CTDP,AL            ;SET CYL ADR, MSB
  875. XSEK6:    MOV    AL,VSA
  876.     OUT    CTBFR,AL        ;SET M/CODE START ADR
  877.     MOV    AL,START
  878.     OUT    CTCSR,AL        ;START VERIFY
  879.     CALL    WFD            ;WAIT FOR DONE
  880.     AND    AL,0CH            ;TEST CTLR STATUS
  881.     JNZ    PAT18    
  882.     RET                ;RIF VERIFY OK
  883. PAT18:    MOV    BX,(Offset VSRTC)
  884.     DEC    BYTE PTR [BX]        ;DECR RETRY COUNT
  885.     JNZ    XSEK6            ;JIF RETRY SEEK VERIFY
  886.                     ; VERIFY FAILED
  887.     CALL    XTKZ            ;RESTORE
  888.     MOV    BX,(Offset SKRTC)
  889.     DEC    BYTE PTR [BX]        ;DECR RETRY COUNT
  890.     JZ    PAT19    
  891.     JMP    XSEK1            ;JIF RETRY SEEK
  892. PAT19:    OR    AL,1            ;SET ERROR FLAG
  893.     RET                ;ABORT
  894. ;
  895. ;   PARTIAL SEEK
  896. ;
  897. PSK:    CALL    XRDY            ;DRIVE READY ?
  898.     JZ    PAT20
  899.     RET
  900. PAT20:    MOV    AL,BL
  901.     OUT    LOSC,AL            ;SET SEEK COUNT, LSB
  902.     MOV    AL,BH
  903.     OUT    HISC,AL            ;   * MSB
  904.     MOV    AL,Byte Ptr SKDIR
  905.     OUT    EXTCMD,AL        ;SET SEEK DIRECTION
  906.     MOV    AL,3
  907.     OUT    DRCSR,AL        ;ISSUE SEEK CMD
  908. ;
  909. ;     ---> FALL THRU TO 'WSC' <---
  910. ;
  911. ;    ---WAIT FOR SEEK COMPLETE---
  912. ;
  913. ;
  914. WSC:    PUSH    BX            ;SAVE REGS
  915.     PUSH    CX
  916.     MOV    BX,0            ;TIME-OUT DELAY COUNT
  917.     MOV    CH,6    ;WAS 3 FOR XCOMP;..DITTO
  918. ;
  919. WSC1:    IN    AL,DRCSR        ;DRIVE STATUS
  920.     RCL    AL,1
  921.     JB    WSC2            ;JIF SEEK DONE
  922.     DEC    BX            ;DECR DELAY COUNT
  923.     MOV    AL,BH
  924.     OR    AL,BL
  925.     JNZ    WSC1            ;JIF CON'T WAITING
  926.     DEC    CH
  927.     JNZ    WSC1
  928.                     ; TIME-OUT ERROR
  929.     POP    CX            ;RESTORE REGS
  930.     POP    BX
  931.     MOV    AL,1
  932.     OR    AL,AL            ;SET CPM ERROR FLAG
  933.     STC                ;SET INTERNAL ERROR FLAG
  934.     RET
  935. ;
  936. WSC2:    POP    CX            ;RESTORE REGS
  937.     POP    BX
  938.     XOR    AL,AL            ;SET FLAG = OK
  939.     RET
  940. ;
  941. ;
  942. ;
  943. ;    ---CLEAR DRIVE FAULT---
  944. ;
  945. CLRDF:    XOR    AL,AL
  946.     OUT    EXTCMD,AL        ;DE-SELECT (FALL THRU TO 'XSEL' TO
  947.                     ;RE-SELECT THE DRIVE)
  948. ;
  949. ;    ---HEAD SELECT---
  950. ;
  951. XSEL:    MOV    AL,Byte Ptr HHTRK    ;REQUESTED TRACK
  952.     AND    AL,1            ;2 HEADS
  953.     MOV    Byte Ptr RHD,AL        ;SAVE REAL HEAD #
  954.     ADD    AL,AL            ;SHIFT HEAD # LEFT TWICE FOR H/W
  955.     ADD    AL,AL
  956.     OR    AL,1            ;TO MAINTAIN DRIVE SLCT
  957.     OUT    EXTCMD,AL        ;SELECT HEAD 0 OR 1
  958.     RET
  959. ;
  960. ;    ---DRIVE READY TEST---
  961. ;
  962. XRDY:    IN    AL,DRCSR        ;DRIVE STATUS
  963.     AND    AL,1            ;DRIVE RDY BIT
  964.     XOR    AL,1            ;  MAKE IT LO-TRUE
  965.     JNZ    PAT21    
  966.     RET                ;RIF DRIVE READY
  967. PAT21:    OR    AL,1            ;SET ERROR FLAG
  968.     RET
  969. ;
  970. DSKCMP:    MOV    DX,(OFFSET RRTRK)    ;GET REQUESTED TRACK
  971.     MOV    CH,3
  972. DC1:    MOV    SI,DX
  973.     MOV    AL,[SI]
  974.     CMP    AL,BYTE PTR [BX]
  975.     JZ    LAB43
  976.     RET
  977. LAB43:    INC    BX
  978.     INC    DX
  979.     DEC    CH
  980.     JNZ    DC1
  981.     RET
  982. ;
  983. ;
  984. ;    ======================================
  985. ;         FLOPPY DISK ROUTINES
  986. ;    ======================================
  987. ;
  988. FSELDSK:DEC    AL            ;FOR FLOPPY MAKE B:=A: (OR C:== B:) 
  989.     MOV    CL,AL            ; (NOTE A:, B: & C: DRIVES ONLY)
  990.     OR    AL,AL            ;IF REQ DRIVE IS A: THEN [A] = 0
  991.     JNZ    BBBB            ;MUST BE B: DRIVE
  992.     MOV    AL,BYTE PTR ADRIVE    ;IS IT THE FIRST TIME FOR THIS DRIVE
  993.     CMP    AL,0FFH
  994.     JNZ    LAB44    
  995.     CALL    GETTYPE
  996. LAB44:    MOV    BYTE PTR ADRIVE,AL    ;STORE DENSITY FLAG
  997.     JMPS    ALLOK
  998. BBBB:    MOV    AL,BYTE PTR BDRIVE    ;IS IT THE FIRST TIME FOR THIS DRIVE
  999.     CMP    AL,0FFH
  1000.     JNZ    LAB45    
  1001.     CALL    GETTYPE
  1002. LAB45:    MOV    BYTE PTR BDRIVE,AL    ;STORE DENSITY FLAG
  1003. ;
  1004. ALLOK:    OR    AL,CL            ;MIX DRIVE TYPE WITH DRIVE#
  1005.     MOV    BYTE PTR UNIT,AL    ;STORE IT FOR SECTOR R/W ROUTINES ETC
  1006.     TEST    AL,40H            ;BIT 6,A
  1007.     JNZ    LAB46
  1008.     MOV    AL, BYTE PTR RRDSK    ;GET ORRIGIONAL DISK REQUESTED
  1009.     RET                ;RET WITH TABLE OFFSET B:=B: & C:=C:
  1010. ;
  1011. LAB46:    MOV    AL,00000011B        ;FOR DOUBLE DENS DISKS WE MUST USE 
  1012.     ADD    AL,CL            ;THE LOOKUP TABLE FOR DRIVES D: & E:
  1013.     RET                ;RETURNS TABLE OFFSET B:=D: & C:=E:
  1014. ;
  1015. GETTYPE:MOV    AL,CL            ;FIND OUT TYPE OF DRIVE
  1016.     CALL    UNITSL
  1017.     JNZ    HB101            ;IF NZ PROBLEMS ABORT
  1018.     MOV    AL,BYTE PTR UNIT
  1019.     AND    AL,01000000B        ;GET DENSITY FLAG
  1020.     RET
  1021. ;
  1022. HB101:    MOV    BX,0            ;ABORT BECAUSE CANNOT GET DISK TYPE
  1023.     POP    AX            ;DROP STACK BACK ONE LEVEL
  1024.     XOR    AL,AL            ;JUST IN CASE
  1025.     DEC    AL
  1026.     RET
  1027.  
  1028. ; THIS ROUTINE SETS UP THE FLOPPY DISK UNIT BYTE
  1029. ; THE REQUIRED DRIVE IS IN [A]
  1030. ;
  1031. UNITSL:    MOV    CH,5            ;WILL TRY 5 TIMES
  1032.     AND    AL,0FH
  1033.     OR    AL,40H            ;COME UP DEFALT IN 8" DD
  1034.     MOV    BYTE PTR UNIT,AL
  1035.     MOV    BX,WORD PTR DMADR
  1036.     MOV    WORD PTR TEMP2,BX
  1037.     CALL    USL1
  1038.     MOV    BX,WORD PTR TEMP2
  1039.     MOV    WORD PTR DMADR,BX
  1040.     MOV    AL,BYTE PTR UNIT
  1041.     RET
  1042. ;
  1043. USL1:    PUSH    CX
  1044.     PUSH    BX
  1045.     MOV    WORD PTR SPSV,SP    ;TEMP SAVE SP IN SPSV
  1046.     POP    BX
  1047.     CALL    DRVSET            ;SELECT DRIVE IN HARDWARE
  1048.     CALL    IDRD            ;TRY READING TRACK ID
  1049.     POP    CX
  1050.     JNZ    LAB48    
  1051.     RET                ;IF CORRECT DENSITY WILL BE Z
  1052. LAB48:    DEC    CH            ;DECREASE 5.......0 IF Z THEN ERROR
  1053.     JZ    SPECIAL
  1054.     CALL    CHGTYP
  1055.     JMPS    USL1
  1056. ;
  1057. SPECIAL:XOR    AL,AL            ;MAY FOR SPECIAL SECTOR SIZE ETC
  1058.     DEC    AL
  1059.     RET                ;RET NZ SO SELDSK KNOWS WAS PROBLEM
  1060. ;
  1061. CHGTYP:    MOV    AL,BYTE PTR UNIT
  1062.     ADD    AL,01000000B        ;TOGGLE DENSITY BIT
  1063.     AND    AL,01111111B        ;CLEAR BIT 7
  1064.     MOV    BYTE PTR UNIT,AL
  1065.     RET
  1066. ;
  1067. ;    READ A SECTOR
  1068. FREAD:    MOV    CX,301H
  1069. READ1:    PUSH    CX
  1070.     CALL    RDSC
  1071.     POP    CX
  1072.     JNZ    LAB49
  1073.     RET
  1074. LAB49:    CALL    FRETRY
  1075.     JMPS    READ1
  1076. ;
  1077. ;    WRITE A SECTOR
  1078. FWRITE:    MOV    CX,301H            ;RTRY= 3 RSEEK = 1 
  1079. WRITE1:    PUSH    CX
  1080.     CALL    WRSC
  1081.     POP    CX
  1082.     JNZ    LAB50
  1083.     RET
  1084. LAB50:    CALL    FRETRY
  1085.     JMPS    WRITE1
  1086. ;
  1087. FRETRY:    DEC    CH
  1088.     JNZ    RETRY2
  1089.     MOV    AL,BYTE PTR RTRY
  1090.     MOV    CH,AL
  1091.     DEC    CL
  1092.     JNS    RETRY1
  1093.     POP    AX            ;DROP STACK BACK ONE LEVEL
  1094.     XOR    AL,AL            ;IF PROBLEM
  1095.     INC    AL
  1096.     RET
  1097. ;
  1098. RETRY1:    PUSH    CX
  1099.     CALL    HOME1
  1100.     POP    CX
  1101. RETRY2:    RET
  1102. ;
  1103. HOME1:    MOV    WORD PTR SPSV,SP    
  1104.     MOV    AL,RSCMD
  1105.     CALL    SEEK4
  1106.     XOR    AL,AL
  1107.     RET
  1108. ;
  1109. ;    SELECT DRIVE IN HARDWARE
  1110. ;
  1111. DRVSET:    MOV    DX,OFFSET UNIT
  1112.     PUSH    SI
  1113.     MOV    SI,DX
  1114.     MOV    AL,[SI]
  1115.     AND    AL,0E0H
  1116.     MOV    CL,AL            ;STORE DRIVE TYPE IN [CL]
  1117.     MOV    SI,DX
  1118.     MOV    AL,[SI]
  1119.     AND    AL,03
  1120.     MOV    CH,AL            ;STORE DRIVE # IN [CH]
  1121.     MOV    AL,1
  1122.     JZ    DRVSEL
  1123. CKDRV1:    ROL    AL,1
  1124.     DEC    CH
  1125.     JNZ    CKDRV1
  1126. DRVSEL:    OR    AL,CL            ;COMBINE TYPE & DRIVE#
  1127.     AND    AL,7FH
  1128.     MOV    CH,AL            ;[CH] CONTAINS INFO FOR HARDWARE
  1129.     MOV    AL,STDSDT        ;SETUP FOR SD
  1130.     MOV    BYTE PTR COUNT,AL    ;STORE AS 26 SECTORS/TRACK
  1131.     MOV    AL,40H            ;WAS IT DD
  1132. DRV1:    CMP    AL,CL
  1133.     JNZ    CKDRV
  1134.     MOV    AL,STDDDT        ;SETUP FOR DD 
  1135.     MOV    BYTE PTR COUNT,AL    ;SET TO 50 SECTORS/TRACK
  1136. CKDRV:    MOV    AL,CH            ;GET HARDWARE SELECT DATA
  1137.     NOT    AL            ;HARDWARE IS INVERTED
  1138.     OUT    SELECT,AL
  1139.     MOV    SI,DX
  1140.     MOV    AL,[SI]
  1141.     MOV    BYTE PTR UNITCK,AL
  1142.     CALL    DELAY
  1143.     POP    SI
  1144. RDYCK:    IN    AL,STATUS
  1145.     AND    AL,80H
  1146.     JNZ    END2X
  1147.     RET
  1148. END2X:    JMP    END2
  1149. ;
  1150. ;    READ PRESENT DISK ADDRESS
  1151. IDRD:    CALL    WAIT
  1152.     MOV    BX,OFFSET IDSV        ;WILL STORE THE 6 ID BYTES HERE
  1153.     MOV    CX,6            ;READ 6 BYTES
  1154.     MOV    AL,0F8H
  1155.     MOV    BYTE PTR ERMASK,AL
  1156.     CALL    SWEB
  1157.     MOV    AL,RDACMD        ;DO THE ID READ
  1158.     CALL    RDSCO
  1159.     MOV    AL,BYTE PTR IDSV
  1160.     CMP    AL,NTRKS        ;IS IT REASONABLE
  1161.     JNAE    LAB51    
  1162.     JMP    SEEK0
  1163. LAB51:    OUT    TRACK,AL
  1164.     XOR    AL,AL
  1165.     RET
  1166. ;
  1167. DELAY:    MOV    AL,040H            ;DELAY ~32 MS (SEEMS NOT CRITICAL)
  1168. DELAY1:    MOV    CH,0
  1169. M0:    DEC    CH
  1170.     JNZ    M0
  1171.     DEC    AL
  1172.     JNZ    DELAY1
  1173.     RET
  1174. ;
  1175. ;    READ SECTOR COMMAND
  1176. RDSC:    CALL    DRINIT
  1177.     MOV    AL,RDCMD
  1178. RDSCO:    MOV    BYTE PTR CMDSV,AL
  1179.     CLI
  1180.     OUT    CMD,AL
  1181.     PUSH    ES
  1182.     PUSH    DI
  1183.     MOV    ES,WORD PTR DMASEG    ;GET CORRECT SEGMENT
  1184.     MOV    DI,BX
  1185.     CLD
  1186. RDSCX:    IN    AL,DATA            ;>>>>>>>>>>READ 128 BYTES<<<<<<<<<<<<
  1187.     STOS    AL            ;NOTE POINTER IS [ES] [DI]
  1188.     LOOP    RDSCX
  1189.     POP    DI
  1190.     POP    ES            ;GET BACK OLD VALUE OF [DS]
  1191.     STI
  1192.     JMPS    ENDX
  1193. ;
  1194. ;
  1195. ;    WRITE SECTOR COMMAND
  1196. WRSC:    CALL    DRINIT
  1197.     MOV    AL,WRCMD
  1198.     MOV    BYTE PTR CMDSV,AL
  1199.     CLI
  1200.     OUT    CMD,AL
  1201.     PUSH    DS
  1202.     PUSH    SI
  1203.     MOV    DS, WORD PTR DMASEG    ;GET CORRECT SEGMENT
  1204.     MOV    SI,BX
  1205.     CLD
  1206. WRSCX:    LODS    AL            ;>>>>>>>>> WRITE 128 BYTES <<<<<<<<<
  1207.     OUT    DATA,AL
  1208.     LOOP    WRSCX
  1209.     POP    SI
  1210.     POP    DS            ;GET BACK OLD VALUE OF [DS]
  1211.     STI
  1212. ;
  1213. ;    END  OF COMMAND
  1214. ENDX:    CALL    WAIT
  1215.     IN    AL,STATUS
  1216.     MOV    DH,AL
  1217.     MOV    AL,BYTE PTR ERMASK
  1218.     AND    AL,DH
  1219.     JNZ    END1
  1220.     RET
  1221. END1:    MOV    AL,DH
  1222. END2:    MOV    BYTE PTR ERSTAT,AL
  1223.     CALL    DELAY
  1224.     MOV    SP,WORD PTR SPSV    
  1225.     XOR    AL,AL
  1226.     DEC    AL            ;RETURN NZ TO INDICATE AN ERROR
  1227.     MOV    BYTE PTR UNITCK,AL
  1228.     RET
  1229. ;
  1230. ;
  1231. ;    DRIVE INITIALIZATION
  1232. ;
  1233. DRINIT:    POP    BX
  1234.     MOV    WORD PTR SPSV, SP    
  1235.     PUSH    BX
  1236.     MOV    AL,BYTE PTR UNIT
  1237.     MOV    DH,AL
  1238.     MOV    AL,BYTE PTR UNITCK
  1239.     CMP    AL,DH
  1240.     JZ    DINIT1
  1241.     CALL    DRVSET
  1242.     CALL    IDRD
  1243. DINIT1:    CALL    SEEK
  1244.     MOV    AL,0FEH
  1245.     MOV    BYTE PTR ERMASK,AL
  1246. ;
  1247. TRINT:    MOV    BX,WORD PTR DMADR    ;SETUP DMA ADDRESS AND BYTE COUNT
  1248.     MOV    AL,BYTE PTR RRSEC
  1249.     OUT    SECTOR,AL
  1250.     MOV    CX,NBYTES        ;USED BY LOOP INST IN SEC RD/WRT
  1251. ;
  1252. SWEB:    IN    AL,SELECT        ;ENABLE WAIT STATES
  1253.     AND    AL,7FH
  1254.     OUT    SELECT,AL
  1255.     RET
  1256. ;
  1257. ;    SEEK TRACK
  1258. ;
  1259. SEEK:    CALL    RDYCK
  1260.     MOV    CL,NTRKS        ;MUST BE REASONABLE TRACK #
  1261.     MOV    AL,BYTE PTR RRTRK    ;ALWAYS < 0FFH TRACKS FOR FLOPPY
  1262.     CMP    AL,CL
  1263.     JB    SEEK1
  1264. SEEK0:    MOV    AL,0FH
  1265.     JMPS    END2
  1266. SEEK1:    MOV    CL,AL
  1267.     IN    AL,TRACK
  1268.     CMP    AL,CL
  1269.     JNZ    LAB53    
  1270.     RET                ;IF SAME TRACK NO NEED TO SEEK
  1271. LAB53:    MOV    AL,SKCMD
  1272. SEEK4:    MOV    BYTE PTR CMDSV,AL
  1273.     MOV    CH,210
  1274. S0:    DEC    CH
  1275.     JNZ    S0
  1276.     CALL    WAIT
  1277.     MOV    AL,BYTE PTR RRTRK
  1278.     OUT    DATA,AL
  1279.     MOV    AL,80H
  1280.     MOV    BYTE PTR ERMASK,AL
  1281.     MOV    AL,BYTE PTR CMDSV
  1282.     OUT    CMD,AL
  1283.     MOV    CH,10
  1284. D0:    DEC    CH
  1285.     JNZ    D0
  1286.     CALL    ENDX
  1287.     CALL    DELAY
  1288.     MOV    AL,BYTE PTR CMDSV
  1289.     CMP    AL,RSCMD        ;NO NEED TO CHECK RESTORE COMMAND
  1290.     JNZ    LAB54
  1291.     RET
  1292. LAB54:    IN    AL,STATUS
  1293.     AND    AL,10H
  1294.     JNZ    SEEK2
  1295.     IN    AL,TRACK
  1296.     CMP    AL,CL
  1297.     JNZ    SEEK2
  1298.     RET
  1299. SEEK2:    MOV    AL,20H
  1300. END2JP:    JMP    END2
  1301. ;
  1302. WAIT:    MOV    DL,0
  1303.     PUSH    CX
  1304.     MOV    CL,2
  1305. WAIT2:    IN    AL,STATUS
  1306.     AND    AL,1
  1307.     JZ    DWAIT
  1308.     DEC    CH
  1309.     JNZ    WAIT2
  1310.     DEC    DL
  1311.     JNZ    WAIT2
  1312.     DEC    CL
  1313.     JNZ    WAIT2
  1314.     POP    CX
  1315.     IN    AL,SELECT        ;IF BY THIS TIME NOT READY FORCE
  1316.     OR    AL,80H            ;A HARDWARE RESET
  1317.     OUT    RSET,AL
  1318. F0:    DEC    CH
  1319.     JNZ    F0
  1320.     IN    AL,RSET
  1321.     CALL    FRCINT
  1322.     MOV    AL,RSCMD
  1323.     CALL    SEEK4
  1324.     MOV    AL,0FEH
  1325.     JMPS    END2JP
  1326. ;
  1327. ;    DISABLE WAIT STATES
  1328. DWAIT:    POP    CX            ;TO BALANCE THE ABOVE PUSH IN WAIT
  1329.     IN    AL,SELECT
  1330.     OR    AL,80H
  1331.     OUT    SELECT,AL
  1332.     RET
  1333. ;
  1334. ;
  1335. ;
  1336. ;    FORCE CHIP INTERUPT
  1337. FRCINT:    MOV    AL,0D0H
  1338.     OUT    CMD,AL
  1339.     MOV    AL,10
  1340. FRC1:    DEC    AL
  1341.     JNZ    FRC1
  1342.     IN    AL,STATUS
  1343.     RET
  1344. ;
  1345. ;>>>>>>>>>>>>>>>> MDISK SECTOR READ AND WRITE ROUTINES <<<<<<<<<<<<<<<<<
  1346. ;
  1347. MREAD:    MOV    CL,RDSECTOR        ;[CL] = READ SECTOR COMMAND
  1348.     CALL    MRDCMD            ;SEND IT TO THE RAMDISK
  1349.     JNB    MRDERR
  1350.     JMP    RWERR            ;IF FAIL TO SEND THEN ERROR ROUTINE.
  1351. MRDERR:    CALL    SEND@TRKSEC        ;ELSE SEND TRACK AND SECTOR TO RAMDSK
  1352.                     ;SET UP REGS FOR SECTOR TRANSFER:
  1353.     MOV    BX,WORD PTR DMADR    ;[BX] = DMA ADDRESS
  1354.     PUSH    ES            ;CPM86 DOES NOT SAVE ES IN BDOS
  1355.     MOV    ES,WORD PTR DMASEG
  1356.     MOV    CX,NBYTES        ;[CX] = 128 = # BYTES TO READ
  1357.     MOV    DI,BX            ;>>>>>>>>> INPUT 128 BYTES <<<<<<<<
  1358. RDLOOP:    CALL    RDREAD            ;GET NEXT SECTOR BYTE
  1359.     STOS    AL            ;DEPOSIT INTO MEMORY
  1360.     LOOP    RDLOOP            ;LOOP FOR ALL BYTES [CX TO 0]
  1361.     POP    ES            ;GET BACK ES
  1362.     CALL    RDREAD            ;GET THE RESULT BYTE
  1363.     OR    AL,AL            ;SHOULD BE ALL 0 BITS IF GOOD R/W
  1364.     JZ    MDONE
  1365.     JMP    RWERR            ;[A] = 0 ON RETURN IF GOOD R/W
  1366. MDONE:    RET
  1367. ;
  1368. ;
  1369. MWRITE:    MOV    CL,WRTSECTOR        ;[CL] = WRITE SECTOR COMMAND
  1370.     CALL    MRDCMD
  1371.     MOV    BX,(OFFSET MD@OFFLINE)    ;IF RAMDISK OFFLINE SAY SO
  1372.     JNB    MWNER
  1373.     JMP    RWERR1
  1374. MWNER:    CALL    SEND@TRKSEC        ;ELSE SEND TRACK AND SECTOR TO RAMDSK
  1375.                     ;SET UP REGS FOR SECTOR TRANSFER:
  1376.     MOV    BX,WORD PTR DMADR    ;[BX] = DMA ADDRESS
  1377.     PUSH    DS
  1378.     MOV    DS,WORD PTR DMASEG
  1379.     MOV    CX,NBYTES        ;[CX] = 128 = # BYTES TO READ
  1380.     MOV    SI,BX            ;>>>>>>>>> OUTPUT 128 BYTES <<<<<<<<
  1381. WRLOOP:    LODS    AL
  1382.     MOV    AH,AL            ;TEMP STORE DATA HERE
  1383. WRLOOP1:IN    AL,CTRLPORT        ;GET STATUS BYTE
  1384.     AND    AL,1            ;CHECK FOR RAMDISK READY TO RECEIVE
  1385.     JZ    WRLOOP1
  1386.     MOV    AL,AH
  1387.     OUT    DATAPORT,AL
  1388.     LOOP    WRLOOP            ;LOOP FOR ALL BYTES [CX TO 0]
  1389.     POP    DS            ;GET BACK DS
  1390.     CALL    RDREAD            ;GET THE RESULT BYTE
  1391.     OR    AL,AL            ;SHOULD BE ALL 0 BITS IF GOOD R/W
  1392.     JZ    MDONE
  1393.     JMP    RWERR            ;[A] = 0 ON RETURN IF GOOD R/W
  1394. ;
  1395.  
  1396. ;SENDS THE TRACK AND SECTOR FOR THE NEXT R/W OPERATION TO THE
  1397. SEND@TRKSEC:
  1398.     MOV    CX,WORD PTR RRSEC    ;GET THE SECTOR TO [BC]
  1399.     CALL    RDWRITE            ;SEND THE LOW BYTE FIRST
  1400.     MOV    CL,CH            ;THEN THE HIGH BYTE
  1401.     CALL    RDWRITE
  1402.     MOV    CX,WORD PTR RRTRK    ;GET TRACK # TO [CL]
  1403.     JMPS    RDWRITE            ;SEND IT AND RETURN...
  1404. ;
  1405. ; ROUTINE SENDS A CHARACTER TO THE RAMDISK:
  1406. RDWRITE:
  1407.     IN    AL,CTRLPORT        ;GET STATUS BYTE
  1408.     AND    AL,1            ;CHECK FOR RAMDISK READY TO RECEIVE
  1409.     JZ    RDWRITE
  1410.     MOV    AL,CL            ;GET OUTPUT BYTE
  1411.     OUT    DATAPORT,AL        ;SEND IT
  1412.     RET
  1413. ;
  1414. ; ROUTINE READS 1 CHARACTER FROM THE RAMDISK:
  1415. RDREAD:    IN    AL,CTRLPORT        ;WAIT UNTIL PORT IS READY
  1416.     AND    AL,80H
  1417.     JZ    RDREAD            ;LOOP UNTIL INPUT STATUS IS TRUE
  1418.     IN    AL,DATAPORT        ;GET CHARACTER WAITING
  1419.     RET
  1420. ;
  1421. ; ROUTINE GETS RAMDISK INPUT STATUS:
  1422. RDINSTAT:IN    AL,CTRLPORT        ;GET STATUS BYTE
  1423.     AND    AL,80H            ;SEE IF DATA WAITING
  1424.     RET                ;WITH STATUS Z FLAG
  1425. ;
  1426. ; ROUTINE SENDS A COMMAND TO THE RAMDISK:
  1427. MRDCMD:    CALL    RDWRITE            ;SEND COMMAND TO THE RAMDISK
  1428.     CALL    RDWAIT            ;WAIT FOR ECHO
  1429.     JNB    LM4    
  1430.     RET                ;RETURN ON TIMEOUT OR NO BYTE MATCH..
  1431. LM4:    MOV    AL,CL            ;GET COMMAND JUST SENT
  1432.     NOT    AL            ;AND COMPLEMENT IT
  1433.     MOV    CL,AL
  1434.     CALL    RDWRITE            ;SEND IT
  1435.     CALL    RDWAIT            ;WAIT FOR ECHO
  1436.     RET                ;WITH FLAGS SET
  1437. ;
  1438. ; ROUTINE WAITS FOR ECHO RESPONSE FROM HOST FOR A SPECIFIED DELAY
  1439. ; TIME AND IF NO RESPONSE IS GOTTEN IT RETURNS WITH AN ERROR FLAG:
  1440. RDWAIT:    PUSH    CX            ;SAVE [CX]
  1441.     MOV    CX,CMDDLY        ;LOAD DELAY CONSTANT
  1442. RDW0:    CALL    RDINSTAT        ;GET INPUT STATUS
  1443.     JNZ    RDW2            ;Z = 0 MEANS WE GOT SOMETHING
  1444.     DEC    CX            ;ELSE DROP DELAY COUNT
  1445.     MOV    AL,CL            ;CHECK FOR DELAY TIMEOUT
  1446.     OR    AL,CH
  1447.     JNZ    RDW0            ;KEEP CHECKING HOST IF NO TIMEOUT
  1448. RDW1:    POP    CX            ;SYNCHRONIZE STACK
  1449. RDW1A:    STC                ;SET ERROR FLAG
  1450.     RET
  1451. RDW2:    CALL    RDREAD            ;GET ECHOED CHARACTER
  1452.     POP    CX            ;CHARACTER SENT BACK TO [CX]
  1453.     CMP    AL,CL            ;IS ECHOED CHAR = CHAR SENT ?
  1454.     JNZ    RDW1A            ;NO -- RETURN ERROR...
  1455.     RET
  1456. ;
  1457. ; R/W ERROR  HERE TO INSPECT RESULT BYTE BITS FOR MESSAGE TO DISPLAY:
  1458. RWERR:    TEST    AL,01000000B
  1459.     JZ    RW3
  1460.     MOV    BX,(OFFSET MD@WP)
  1461. RWERR1:    CALL    PMSG            ;DISPLAY MESSAGE IF SO
  1462. RWERR2:    MOV    AL,1            ;RETURN ONLY 0 OR 1 FOR CPM86
  1463.     RET
  1464. ;
  1465. RW3:    TEST    AL,10000000B        ;CHECK FOR TRACK / SECTOR ERROR
  1466.     MOV    BX,(OFFSET MD@TRKSEC)
  1467.     JNZ    RWERR1
  1468. ;
  1469.     TEST    AL,00100000B        ;CHECKSUM ERROR ?
  1470.     MOV    BX,(OFFSET MD@CKSUM)
  1471.     JNZ    RWERR1
  1472. ;
  1473.     JMP    RWERR2            ;UNKNOWN ERROR
  1474. ;
  1475. ;
  1476. ;<<<<<<<<<<<<<<<<<<<<<< MAIN CONSOL OUTPUT ROUTINE >>>>>>>>>>>>>>>>>>>>>>>>>
  1477. ;        NOTE THIS CODE IS SPECIFIC FOR MY SYSTEM
  1478. ;
  1479. CO:    IN    AL,IOBYTE
  1480.     TEST    AL,1H        ;BIT 0,A  CHECK IF OUTPUT TO LIST IS ALSO REQ
  1481.     JZ    LOX
  1482.     TEST    AL,8H        ;BIT 3,A  CHECK IF PRINTER IS CONSOL
  1483.     JNZ    COX1
  1484.     JMP    LO
  1485. COX1:    TEST    AL,10H        ;BIT 4,A  KILL LF'S IF THIS IS 0
  1486.     JNZ    SDCONO
  1487.     MOV    AL,CL
  1488.     CMP    AL,LF
  1489.     JZ    SDCON5        ;KILL LF'S
  1490.     PUSH    CX        ;ALL OTHERE CHARACTRS SEND EOL THEN CHARACTER
  1491.     MOV    CL,']'-40H    ;FOR CLEAR TO END OF LINE
  1492.     CALL    SDCONO        ;BECAUSE EOL IS SENT FOR EACH CHARACTER THE
  1493.     POP    CX        ;TYPE RATE IS NICELY SLOWED DOWN TO ~ 60 BAUD
  1494.     JMPS    SDCONO        ;AT NO FURTHER EXPENSE |
  1495. SDCON5:    MOV    AL,CL
  1496.     RET
  1497. ;
  1498. LOX:    CALL    SDCONO        ;OUTPUT TO BOTH PRINTER & CONSOLE
  1499.     JMP    LO
  1500. ;
  1501. SDCONO:    IN    AL,SDSTAT    ;SD SYSTEMS VIDIO BOARD PORT
  1502.     AND    AL,4H
  1503.     JZ    SDCONO
  1504.     MOV    AL,CL
  1505.     CMP    AL,07H        ;IS IT A BELL
  1506.     JZ    BELL1
  1507.     CMP    AL,0H        ;SD BOARD CANNOT TAKE A NULL
  1508.     JNZ    LX2
  1509.     RET
  1510.  
  1511. LX2:    OUT    SDDATA,AL
  1512.     IN    AL,IOBYTE
  1513.     TEST    AL,20H        ;BIT 5,A SEE IF TIME DELAY REQ WITH CO:
  1514.     JNZ    LX3
  1515.     MOV    AL,20
  1516.     CALL    TDELAY
  1517. LX3:    MOV    AL,CL        ;BE SURE TO RETURN WITH [AL] CONTAINING CHAR
  1518.     RET
  1519. ;
  1520. BELL1:    MOV    AL,06H        ;SEND A BELL
  1521.     OUT    SDDATA,AL
  1522.     MOV    AL,3FH
  1523.     CALL    TDELAY
  1524.     MOV    AL,CL
  1525.     OUT    SDDATA,AL
  1526.     RET
  1527. ;
  1528. ;
  1529. TDELAY:    DEC    AL        ;GENERAL COUNT DOWN TIME DELAY
  1530.     JNZ    LX4    
  1531.     RET            ;LENGTH SET IN [A]
  1532. LX4:    PUSH    AX
  1533.     MOV    AL,05H
  1534. MORE:    DEC    AL
  1535.     PUSH    AX
  1536.     XOR    AL,AL
  1537. MORE2:    DEC    AL
  1538.     JNZ    MORE2
  1539.     POP    AX
  1540.     JNZ    MORE
  1541.     POP    AX
  1542.     JMPS    TDELAY
  1543. ;
  1544. ;<<<<<<<<<<<<<<<<<<< MAIN CONSOL STATUS ROUTINE >>>>>>>>>>>>>>>>>>>>>>
  1545. ;
  1546. CSTS:    IN    AL,KEYSTAT
  1547.     AND    AL,02H
  1548.     JNZ    CST1
  1549.     RET                ;RETURN WITH 0 IN [A] IF NOTHING THERE
  1550. CST1:    DEC    AL
  1551.     RET                ;RETURN WITH 0FFH IN [A] IF SOMETHING
  1552. ;
  1553. ;
  1554. ;<<<<<<<<<<<<<<<<<<<< MAIN CONSOL INPUT ROUTINE >>>>>>>>>>>>>>>>>>>>
  1555. ;
  1556. CI:    CALL    CSTS        ;NEED CONSTAT TO CLEAN UP SHIFT KEYS ETC
  1557.     JZ    CI
  1558.     IN    AL,KEYIN
  1559.     AND    AL,7FH
  1560.     RET
  1561. ;
  1562. ;<<<<<<<<<<<<<<<<<<<<<< MAIN PRINTER STATUS ROUTINE >>>>>>>>>>>>>>>>>>>>>>>>>
  1563. ;
  1564. LSTAT:    IN    AL,CENTSTAT        ;FIRST FIND WHICH PRINTER IS SELECTED
  1565.     TEST    AL,2
  1566.     JNZ    CENSTAT
  1567.     TEST    AL,20H
  1568.     JNZ    TRANSTAT
  1569.     XOR    AL,AL            ;NONE SELECTED
  1570.     DEC    AL
  1571.     RET
  1572.  
  1573. CENSTAT:AND    AL,00001111B    ;XXXX0110 IS READY (BIT 3=PAPER BIT 2=FAULT
  1574.     CMP    AL,00000110B        ;BIT 1=SELECT  BIT 0=BUSY
  1575.     JZ    LSTAT1
  1576.     XOR    AL,AL
  1577.     RET
  1578.  
  1579. TRANSTAT:AND    AL,11110000B    ;0110XXX IS READY (BIT 7=ALERT BIT 6=FAULT
  1580.     CMP    AL,01100000B        ;BIT 5=SELECT BIT 4=BUSY
  1581.     JZ    LSTAT1
  1582.     XOR    AL,AL
  1583.     RET
  1584.  
  1585. LSTAT1:    XOR    AL,AL        ;PUT 0FFH IN [A] IF READY & NO ZERO FLAG
  1586.     DEC    AL
  1587.     RET
  1588. ;
  1589. ;<<<<<<<<<<<<<<<<<<<<<< MAIN PRINTER OUTPUT ROUTINE >>>>>>>>>>>>>>>>>>>>>>>>>
  1590. ;
  1591. LO:    CALL    LSTAT
  1592.     JZ    LO
  1593.     MOV    AL,0FFH
  1594.     OUT    CENTSTROBE,AL
  1595.     MOV    AL,CL
  1596.     OUT    CENTOUT,AL
  1597.     IN    AL,CENTSTAT
  1598.     TEST    AL,2
  1599.     JNZ    LCENT
  1600.     TEST    AL,20H
  1601.     JNZ    LTRANS
  1602.     RET                ;NO STROBE SINCE NOT SELECTED
  1603. ;
  1604. LCENT:    MOV    AL,11111110B        ;STROBE FOR CENTRONICS
  1605.     JMPS    OVERLS
  1606. LTRANS:    MOV    AL,11111101B
  1607. OVERLS:    OUT    CENTSTROBE,AL
  1608.     MOV    AL,0FFH
  1609.     OUT    CENTSTROBE,AL
  1610.     RET
  1611. ;
  1612. ;
  1613. POO:    RET            ;NO PUNCH OUTPUT AT THE MOMENT
  1614. RI:    MOV    AL,1AH        ;NO READER AT THE MOMENT
  1615.     RET
  1616. ;
  1617. SCO:    MOV    AL,15H        ;SEND CHARACTER TO TALKER
  1618.     OUT    TALKSTAT,AL
  1619.     IN    AL,TALKSTAT
  1620.     AND    AL,02H
  1621.     JZ    SCO
  1622.     MOV    AL,CL
  1623.     OUT    TALKOUT,AL
  1624.     RET
  1625. ;
  1626. SMSG:    MOV    AL,[BX]        ;SPEAK A STRING
  1627.     TEST    AL,AL
  1628.     JZ    RETURS
  1629.     MOV    CL,AL
  1630.     CALL    SCO
  1631.     INC    BX
  1632.     JMP    SMSG
  1633. RETURS:    MOV    CL,CR
  1634.     JMP    SCO
  1635. ;
  1636. ;
  1637. ;
  1638. LAB57    EQU    $
  1639. ;
  1640. ;---------------------> START OF DATA SEGMENT <---------------------
  1641. ;
  1642. ;
  1643.         DSEG
  1644.         ORG OFFSET LAB57
  1645. ;
  1646. ;
  1647. ;    ---MESSAGES---
  1648. ;
  1649. ;
  1650. SIGNON     DB    1AH,1H,10H,11H,LF,09H,09H
  1651.      DB    '128K CP/M-86 V1.1  (With Intelladisk)',CR,LF
  1652. CLEANUP     DB    1H,10H,11H,17H,07H,0H
  1653. SPEAKON  DB    '1 HUNDRED AND TWENTY EIGHT KAY  C  P  M EIGHTY SIX ',0
  1654. DRNRDY     DB    CR,LF,'DRIVE NOT READY',0
  1655. INT_TRP  DB    CR,LF,'INTERRUPT TRAP HALT AT:- ',0H
  1656. INT0_TRP DB    CR,LF,'DIVIDE TRAP HALT AT:- ',0H
  1657. INT4_TRP DB    CR,LF,'OVERFLOW TRAP HALT AT:- ',0H
  1658. ;
  1659. ; MEMORY DISK ERROR MESSAGES:
  1660. MD@OFFLINE DB    ' MEMORY DISK APPEARS TO BE OFFLINE',0
  1661. MD@WP    DB    ' MEMORY DISK WRITE-PROTECTED',0
  1662. MD@CKSUM DB    ' MEMORY DISK CHECKSUM ERROR',0
  1663. MD@TRKSEC DB    ' MEMORY DISK TRACK / SECTOR OUT OF RANGE',0
  1664. ;
  1665. ;
  1666. ;    ---MICROCODE COMMAND TABLES FOR XCOMP CONTROLLER---
  1667. ;WRITE
  1668. WTBL    DB    5            ;RETRY COUNT
  1669.     DB    5            ;CMP BFR ENB
  1670.     DB    0E6H            ;CMP BFR ADR
  1671.     DB    BANK1            ;CNTL BANK
  1672.     DB    0D3H            ;START ADR
  1673.     DB    0EH            ;STATUS MASK
  1674. ;
  1675. ;READ
  1676. RTBL    DB    10            ;RETRY COUNT
  1677.     DB    4            ;CMP BFR ENB
  1678.     DB    0EAH            ;CMP BFR ADR
  1679.     DB    BANK0            ;CNTL BANK
  1680.     DB    0D7H            ;START ADDRESS
  1681.     DB    0EH            ;STATUS MASK
  1682.  
  1683. ;    ---PROGRAM STORAGE---
  1684. ;
  1685. SEGTABLE DB    1            ;SYSTEM MEMORY TABLE
  1686.      DW    TPASEG            ;FIRST SEGMENT STARTS AFTER BIOS
  1687.      DW    TPALEN            ;AND GOES UP TO 01FFFH
  1688. ;
  1689. ;    --- DISK DEFINITIONS TABLE ---
  1690. ;
  1691. ;            DISKS 6
  1692. DPHDR    EQU    $        ;BASE OF DISK PARAMETER BLOCKS
  1693. DPE0    DW    0000,0000H    ;TRANSLATE TABLE (NONE FOR HARD DISK)
  1694.     DW    0000H,0000H    ;SCRATCH AREA
  1695.     DW    DIRBUF,DPB0    ;DIR BUFF, PARM BLOCK
  1696.     DW    CSV0,ALV0    ;CHECK, ALLOC VECTORS
  1697. DPE1    DW    XLT1,0000H    ;TRANSLATE TABLE (SD FLOPPY)
  1698.     DW    0000H,0000H    ;SCRATCH AREA
  1699.     DW    DIRBUF,DPB1    ;DIR BUFF, PARM BLOCK
  1700.     DW    CSV1,ALV1    ;CHECK, ALLOC VECTORS
  1701. DPE2    DW    XLT2,0000H    ;TRANSLATE TABLE (SD FLOPPY)
  1702.     DW    0000H,0000H    ;SCRATCH AREA
  1703.     DW    DIRBUF,DPB2    ;DIR BUFF, PARM BLOCK
  1704.     DW    CSV2,ALV2    ;CHECK, ALLOC VECTORS
  1705. DPE3    DW    0000,0000H    ;TRANSLATE TABLE (DD FLOPPY)
  1706.     DW    0000H,0000H    ;SCRATCH AREA
  1707.     DW    DIRBUF,DPB3    ;DIR BUFF, PARM BLOCK
  1708.     DW    CSV3,ALV3    ;CHECK, ALLOC VECTORS
  1709. DPE4    DW    0000,0000H    ;TRANSLATE TABLE  (DD FLOPPY)
  1710.     DW    0000H,0000H    ;SCRATCH AREA
  1711.     DW    DIRBUF,DPB4    ;DIR BUFF, PARM BLOCK
  1712.     DW    CSV4,ALV4    ;CHECK, ALLOC VECTORS
  1713. DPE12    DW    0000,0000H    ;TRANSLATE TABLE (NOT USED FOR RAMDISK)
  1714.     DW    0000,0000H    ;SCRATCH AREA
  1715.     DW    DIRBUF,MD@DPB    ;DIR BUFFER PARM BLOCK
  1716.     DW    CSV12,ALV12    ;CHECK, ALLOC VECTORS FOR RAMDISK
  1717. ;
  1718. ;
  1719. ;            DISKDEF 0,0,63,0,2048,3992,1024,0,2
  1720. ;
  1721. DPB0    EQU    OFFSET $    ;DISK PARAMETER BLOCK
  1722.     DW    64        ;SECTORS PER TRACK
  1723.     DB    4        ;BLOCK SHIFT
  1724.     DB    15        ;BLOCK MASK
  1725.     DB    0        ;EXTNT MASK
  1726.     DW    3991        ;DISK SIZE - 1(1000-2tracks x 4blks/track -1)
  1727.     DW    1023        ;DIRECTORY MAX
  1728.     DB    255        ;ALLOC0
  1729.     DB    255        ;ALLOC1
  1730.     DW    0        ;CHECK SIZE
  1731.     DW    2        ;OFFSET
  1732. ;
  1733. ;        DISKDEF 1,1,26,6,1024,243,64,64,2
  1734. ;
  1735. DPB1    EQU    OFFSET $    ;DISK PARAMETER BLOCK
  1736.     DW    26        ;SECTORS PER TRACK
  1737.     DB    3        ;BLOCK SHIFT
  1738.     DB    7        ;BLOCK MASK
  1739.     DB    0        ;EXTNT MASK
  1740.     DW    242        ;DISK SIZE - 1 (75tracks x 3.25bkks/trk -1)
  1741.     DW    63        ;DIRECTORY MAX
  1742.     DB    192        ;ALLOC0
  1743.     DB    0        ;ALLOC1
  1744.     DW    16        ;CHECK SIZE
  1745.     DW    2        ;OFFSET
  1746. XLT1    EQU    OFFSET $    ;TRANSLATE TABLE
  1747.     DB    1,7,13,19
  1748.     DB    25,5,11,17
  1749.     DB    23,3,9,15
  1750.     DB    21,2,8,14
  1751.     DB    20,26,6,12
  1752.     DB    18,24,4,10
  1753.     DB    16,22
  1754. ;
  1755. ;            DISKDEF 2,1
  1756. ;
  1757. DPB2    EQU    DPB1        ;EQUIVALENT PARAMETERS
  1758. XLT2    EQU    XLT1        ;SAME TRANSLATE TABLE
  1759. ;
  1760. ;            DISKDEF 3,1,50,0,2048,234,64,64,2
  1761. ;
  1762. DPB3    EQU    OFFSET $    ;DISK PARAMETER BLOCK
  1763.     DW    50        ;SECTORS PER TRACK
  1764.     DB    4        ;BLOCK SHIFT
  1765.     DB    15        ;BLOCK MASK
  1766.     DB    1        ;EXTNT MASK
  1767.     DW    233        ;DISK SIZE - 1
  1768.     DW    63        ;DIRECTORY MAX
  1769.     DB    128        ;ALLOC0
  1770.     DB    0        ;ALLOC1
  1771.     DW    16        ;CHECK SIZE
  1772.     DW    2        ;OFFSET
  1773. ;
  1774. ;
  1775. ;            DISKDEF 4,3
  1776. ;
  1777. DPB4    EQU    DPB3        ;EQUIVALENT PARAMETERS
  1778. ;
  1779. ;            DISKDEF 12,1,480,1,2048,960,128,128,0
  1780. ;
  1781. MD@DPB    equ    offset $    ;Disk Parameter Block
  1782.     dw    480        ;Sectors Per Track
  1783.     db    4        ;Block Shift
  1784.     db    15        ;Block Mask
  1785. DPB_EXM    RS    1        ;Extnt Mask
  1786. DPB_DSM    RS    2        ;Disk Size - 1 (WHEN FULL RAM 959)
  1787.     dw    127        ;Directory Max
  1788.     db    192        ;Alloc0
  1789.     db    0        ;Alloc1
  1790.     dw    32        ;Check Size
  1791.     dw    0        ;Offset
  1792. ;
  1793. ;    Uninitialized Scratch Memory Follows:
  1794. ;
  1795. ;
  1796. FLAGS    RS    1            ;BIT FLAGS
  1797.                     ;BIT 0 SET FOR READ OPERATION
  1798.                     ;BIT 1 SET FOR READ IN PROGRESS
  1799.                     ;BIT 2 SET FOR WRITE IN PROGRESS
  1800. ;
  1801. RRTRK    RS    2            ;CP/M REQUESTED TRACK ADDRESS
  1802. RRDSK    RS    1            ;CP/M REQUESTED DRIVE #
  1803. RRSEC    RS    2            ;CP/M REQUESTED SECTOR
  1804. ;
  1805. URTRK    RS    2            ;UNALLOCATED TRACK ADDRESS
  1806. URDSK    RS    1            ;   DRIVE #
  1807. URSEC    RS    1            ;   SECTOR ADDRESS
  1808. URCNT    RS    1            ;   RECORD COUNT
  1809. ;
  1810. HHTRK    RS    2            ;HOST (SCRIBE & SHUGART) TRACK ADDRESS
  1811. HHDSK    RS    1            ;   DRIVE #
  1812. HHSEC    RS    1            ;   SECTOR ADDRESS
  1813. ;
  1814. RCA    RS    2            ;REAL TRACK ADDRESS
  1815. RHD    RS    1            ;  HEAD
  1816. RSA    RS    1            ;  SECTOR
  1817. ;
  1818. RETRY    RS    1            ;RETRY COUNT
  1819. CTA    RS    2            ;COMMAND TABLE ADDRESS
  1820. ERFLG    RS    1            ;ERROR FLAG
  1821. DMADR    RS    2            ;BUFFER (DMA) ADDRESS
  1822. WRTMODE    RS    1            ;WRITE MODE
  1823. SKRTC    RS    1            ;SEEK RETRY COUNT
  1824. VSRTC    RS    1            ;SEEK VEREFY RETRY COUNT
  1825. SKDIR    RS    1            ;SEEK DIRECTION
  1826. RSKNT    RS    2            ;RESIDUAL SEEK COUNT
  1827. TEMP    RS    2            ;TEMPORARY STORAGE
  1828. IOBYT   RS    1            ;STORAGE FOR IOBYTE
  1829. DMASEG    RS    2            ;STORAGE FOR CURRENT SEGMENT ADDRESS
  1830. ;---
  1831. UNIT    RS    1            ;STORE FOR FLOPPY NEW UNIT BYTE
  1832. ERMASK    RS    1            ;FLOPPY ERROR MASK
  1833. ERSTAT    RS    1            ;STORE OF ERROR FLAG
  1834. CMDSV    RS    1            ;FLOPPY COMMAND STORE
  1835. SPSV    RS    2            ;SP SAVE
  1836. TEMP2    RS    2            ;
  1837. COUNT    RS    1            ;SECTORS/TRACK SORE
  1838. UNITCK    RS    1            ;OLD FLOPPY STORE BYTE
  1839. RSEEK    RS    1            ;NBR OF RESEEKS
  1840. RTRY    RS    1            ;NBR OF RTRYS
  1841. ADRIVE    RS    1            ;STORE OF A: TYPE
  1842. BDRIVE    RS    1            ;STORE OF B: TYPE
  1843. MDINIT    RS    1            ;FLAG FOR MDISK INITILIZATION
  1844. IDSV    RS    6            ;STORE FOR TRACK ID DETREMINATION
  1845. SPARE    RS    2
  1846. ;
  1847. FLGSIZ    EQU    (OFFSET $)-(OFFSET FLAGS)   ;DEFINES SIZE OF VARIABLE STORAGE
  1848. ;
  1849. LOC_STK    RW    64            ;LOCAL STACK FOR INITILIZATION
  1850. STKBASE    EQU    OFFSET $
  1851. ;
  1852. ;
  1853. ;    UNINITIALIZED SCRATCH MEMORY FOLLOWS:
  1854. ;
  1855. BEGDAT    EQU    OFFSET $    ;START OF SCRATCH AREA
  1856. DIRBUF    RS    128        ;DIRECTORY BUFFER
  1857. ALV0    RS    500        ;ALLOC VECTOR
  1858. CSV0    RS    0        ;CHECK VECTOR
  1859. ALV1    RS    31        ;ALLOC VECTOR
  1860. CSV1    RS    16        ;CHECK VECTOR
  1861. ALV2    RS    31        ;ALLOC VECTOR
  1862. CSV2    RS    16        ;CHECK VECTOR
  1863. ALV3    RS    30        ;ALLOC VECTOR
  1864. CSV3    RS    16        ;CHECK VECTOR
  1865. ALV4    RS    30        ;ALLOC VECTOR
  1866. CSV4    RS    16        ;CHECK VECTOR
  1867. alv12    rs    120        ;Alloc Vector
  1868. csv12    rs    32        ;Check Vector
  1869. ENDDAT    EQU    OFFSET $    ;END OF SCRATCH AREA
  1870. DATSIZ    EQU    OFFSET $-BEGDAT    ;SIZE OF SCRATCH AREA
  1871.     DB    0        ;MARKS END OF MODULE
  1872. ;
  1873. ;
  1874. XLAST    EQU    OFFSET $
  1875. ;
  1876. TPASEG    EQU    (XLAST + 0400H+15)/16    ;
  1877. TPALEN  EQU    01FFFH - TPASEG        ;<---- TOP PARAGRAPH OF RAM FOR CP/M
  1878.     DB    0            ;FOR GENCMD
  1879. ;
  1880. ;    ----- LOW MEMORY -------
  1881.  
  1882.     DSEG    0H
  1883.     ORG    0H            ;AT LOW MEMORY
  1884. ;
  1885. INT0_OFFSET    RW    1
  1886. INT0_SEGMENT    RW    1
  1887.                     ;PAD TO OVERFLOW TRAP VECTOR
  1888.         RW    6
  1889. INT4_OFFSET    RW    1
  1890. INT4_SEGMENT    RW    1
  1891.                     ;PAD TO SYSTEM CALL VECTOR
  1892. ;
  1893.     ORG    380H
  1894. ;
  1895. BDOS_OFFSET    RW    1
  1896. BDOS_SEGMENT    RW    1
  1897. ;
  1898. END
  1899.