home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG001.ARK / VBIOS31.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  16KB  |  783 lines

  1. ;***********************************************;
  2. ;
  3. ;   CBIOS FOR IMSAI WITH SIO2-2 AND TELETYPE
  4. ;           INCLUDES IOBYTE FUNCTION
  5. ;   AND DRIVER FOR PROCESSOR TECHNOLOGY VDM
  6. ;    WRITTEN BY JEFF KRAVITZ, 05/21/77
  7. ;
  8. ;***********************************************;
  9.  
  10. ;NOTE :  MSIZE DETERMINES WHERE THIS CBIOS IS LOCATED
  11. MSIZE    EQU    31    ;CP/M MEMORY SIZE IN KBYTES
  12. PATCH    EQU    MSIZE*1024-2*256  ;START OF THE CBIOS
  13. ;***********************************************;
  14. ;
  15. ;               I/O DEVICE VALUES
  16. ;***********************************************;
  17.  
  18. IOBYT    EQU    0003H    ;I/O CONTROL BYTE
  19.  
  20. TTYD    EQU    02H    ;TELETYPE DATA PORT
  21. TTYS    EQU    03H    ;TELETYPE STATUS PORT
  22. TTYDA    EQU    02H    ;TTY DATA AVAIL BIT
  23. TTYBE    EQU    01H    ;TTY BUFER EMPTY BIT
  24.  
  25. CRTD    EQU    04H    ;CRT DATA PORT
  26. CRTS    EQU    05H    ;CRT STATUS PORT
  27. CRTDA    EQU    02H    ;CRT DATA AVAIL BIT
  28. CRTBE    EQU    01H    ;CRT BUFFER EMPTY BIT
  29.  
  30. TTYMD    EQU    0CEH    ;TTY MODE BYTE
  31. TTYCM    EQU    017H    ;TTY COMMAND BYTE
  32.  
  33. CRTMD    EQU    0CEH    ;CRT MODE BYTE
  34. CRTCM    EQU    017H    ;CRT COMMAND BYTE
  35.  
  36. ;************************************************;
  37. ;
  38. ;        MISC EQUATES
  39. ;
  40. ;************************************************;
  41.  
  42.  
  43. ;*************************************************;
  44. ;
  45. ;    WE WILL USE A SCRATCH AREA STARTING AT 40H
  46. ;     FOR HOLDING THE VALUES OF:
  47. ;        TRACK   =  LAST SELECTED TRACK
  48. ;        SECTOR  =  LAST SELECTED SECTOR
  49. ;        DMAAD   =  LAST SELECTED DMA ADDRESS
  50. ;        DISKNO  =  LAST SELECTED DISK NUMBER
  51. ;(NOTE THAT ALL ARE BYTE VALUES EXCEPT FOR DMAAD)
  52. ;
  53. ;*************************************************;
  54.  
  55. SCRAT    EQU    40H      ;START OF SCRATCH AREA
  56. TRACK    EQU    SCRAT      ;CURRENT TRACK ON DRIVE 0
  57. TRAK1    EQU    TRACK+1      ;CURRENT TRACK ON DRIVE 1
  58. SECTOR    EQU    SCRAT+2      ;CURRENTLY SELECTED SECTOR
  59. DMAAD    EQU    SCRAT+3      ;CURRENT DMA ADDRESS
  60. DISKNO    EQU    SCRAT+5      ;CURRENT DISK NUMBER
  61. DUMMY    EQU    DISKNO+1  ;MUST BE 0 FOR DOUBLE ADD
  62.  
  63.     ORG    PATCH    ;ORIGIN OF THIS PROGRAM
  64. CBASE    EQU    (MSIZE-16)*1024    ;BIAS FOR SYSTEMS>16K
  65. CPMB    EQU    CBASE+2900H    ;BASE OF CP/M 
  66. BDOS    EQU    CBASE+3206H    ;BASE OF RESIDENT CODE
  67. CPML    EQU    $-CPMB        ;LENGTH OF CP/M
  68. NSECTS    EQU    CPML/128    ;# OF SECTORS TO LOAD
  69.  
  70.  
  71. ;************************************************;
  72. ;
  73. ;    JUMP VECTOR FOR INDIVIDUAL SUBROUTINES
  74. ;
  75. ;************************************************;
  76.     JMP    SCPM        ;COLD START
  77. WBOTE:    JMP    WBOOT        ;WARM START
  78.     JMP    CONST        ;CONSOLE STATUS
  79.     JMP    CONIN        ;CONSOLE CHARACTER IN
  80.     JMP    CONOUT        ;CONSOLE CHARACTER OUT
  81.     JMP    LIST        ;LIST CHARACTER OUT
  82.     JMP    PUNCH        ;PUNCH CHARACTER OUT
  83.     JMP    READER        ;READER CHARACTER OUT
  84.     JMP    HOME        ;MOVE HEAD TO HOME 
  85.     JMP    SELDSK        ;SELECT DISK
  86.     JMP    SETTRK        ;SET TRACK NUMBER
  87.     JMP    SETSEC        ;SET SECTOR NUMBER
  88.     JMP    SETDMA        ;SET DMA ADDRESS
  89.     JMP    READ        ;READ DISK
  90.     JMP    WRITE        ;WRITE DISK
  91.  
  92. ;************************************************;
  93. ;
  94. ; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION
  95. ;
  96. ;************************************************;
  97. WBOOT:    ;READ THE DISK UNTIL ALL SECTORS LOADED
  98.     LXI    SP,80H    ;STACK BELOW BUFFER
  99.     MVI    C,0    ;SELECT DISK 0
  100.     CALL    SELDSK
  101.     CALL    HOME    ;GO TO TRACK 00
  102.  
  103.     MVI    B,NSECTS    ;B = # SECTORS TO LOAD
  104.     MVI    C,0    ;C HAS THE CURRENT TRACK NUMBER
  105.     MVI    D,2    ;D HAS THE NEXT SECTOR TO READ
  106. ; NOTE THAT WE BEGIN BY READING TRACK 0, SECTOR 2 SINCE SECTOR 1
  107. ; CONTAINS THE COLD START LOADER, WHICH IS SKIPPED IN A WARM START
  108.     LXI    H,CPMB    ;BASE OF CP/M (INITIAL LOAD POINT)
  109. LOAD1:    ;LOAD ONE MORE SECTOR
  110.     PUSH    B    ;SAVE SECTOR COUNT, CURRENT TRACK
  111.     PUSH    D    ;SAVE NEXT SECTOR TO READ
  112.     PUSH    H    ;SAVE DMA ADDRESS
  113.     MOV    C,D    ;GET SECTOR ADDRESS TO REG. C
  114.     CALL    SETSEC    ;SET SECTOR ADDRESS FROM REG. C
  115.     POP    B    ;RECALL DMA ADDRESS TO B,C
  116.     PUSH    B    ;REPLACE ON STACK 
  117.     CALL    SETDMA    ;SET DMA ADDRESS FROM B,C
  118. ;
  119. ; DRIVE SET TO 0, TRACK SET, SECTOR SET, DMA ADDRESS SET
  120.     CALL    READ
  121.     ORA    A    ;ANY ERRORS?
  122.     JNZ    WBOOT    ;RETRY IF ERROR
  123. ;
  124. ;    NO ERROR, MOVE TO NEXT SECTOR
  125.     POP    H    ;RECALL DMA ADDRESS
  126.     LXI    D,128    ;DMA=DMA+128
  127.     DAD    D    ;NEW DMA ADDRESS IS IN H,L
  128.     POP    D    ;RECALL SECTOR ADDRESS
  129.     POP    B    ;GET NUM. SECTORS & TRACK
  130.     DCR    B    ;SECTORS=SECTORS-1
  131.     JZ    GOCPM    ;GOTO CPM WHEN DONE
  132. ;
  133. ; MORE SECTORS REMAIN TO LOAD, CHECK FOR TRACK CHANGE
  134.     INR    D
  135.     MOV    A,D    ;SEC=27?,IF SO,CHANGE TRACKS
  136.     CPI    27
  137.     JC    LOAD1    ;CARRY GENERATED IF SECTOR<27
  138. ;
  139. ;    END OF CURRENT TRACK, GO TO NEXT TRACK
  140.     MVI    D,1    ;1ST SEC OF NEXT TRACK
  141.     INR    C    ;TRACK=TRACK+1
  142. ;
  143. ;    SAVE REGISTER STATE, AND CHANGE TRACKS
  144.     PUSH    B
  145.     PUSH    D
  146.     PUSH    H
  147.     CALL    SETTRK    ;TRACK ADDR SET FROM REG C
  148.     POP    H
  149.     POP    D
  150.     POP    B
  151.     JMP    LOAD1    ;FOR ANOTHER SECTOR
  152. ;
  153. ;    END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M
  154. GOCPM:    LXI    SP,80H
  155.     MVI    A,0C3H    ;C3 IS A JMP INSTRUCTION
  156.     STA    0    ;FOR JMP TO WBOOT
  157.     LXI    H,WBOTE    ;WBOOT ENTRY POINT
  158.     SHLD    1    ;SET ADDRESS FIELD FOR JMP AT 0
  159. ;
  160.     STA    5    ;FOR JMP TO BDOS
  161.     LXI    H,BDOS    ;BDOS ENTRY POINT
  162.     SHLD    6    ;ADDRESS FIELD OF JUMP AT 5 TO BDOS
  163. ;
  164.     LXI    B,80H    ;DEFAULT DMA ADDRESS IS 80H
  165.     CALL    SETDMA
  166. ;
  167. ;PUT ACTIVE DISK NUMBER (STORED IN LOCATION 4) IN C
  168.     LDA    04H
  169.     MOV    C,A
  170.     EI        ;ENABLE INTERRUPTS
  171.     JMP    CPMB    ;GO TO CP/M FOR FURTHER PROCESSING
  172.  
  173. ;**********************************************;
  174. ;
  175. ;        COLD START ROUTINE
  176. ;
  177. ;**********************************************;
  178.  
  179. SCPM:    XRA    A    ;INITIALIZE IOBYT
  180.     STA    IOBYT
  181.     MVI    A,0AAH    ;DUMMY MODE BYTE
  182.     OUT    TTYS    ;CLEAR TTY
  183.     MVI    A,040H    ;RESET COMMAND
  184.     OUT    TTYS
  185.     MVI    A,TTYMD
  186.     OUT    TTYS
  187.     MVI    A,TTYCM
  188.     OUT    TTYS    ;SET UP TTY USART
  189.     LXI    SP,80H    ;SET STACK
  190.     CALL    DSINT    ;INITIALIZE DISPLAY
  191.     LXI    D,CPMSG    ;POINT TO STARTUP MESSAGE
  192.     MVI    C,09    ;WRITE BUFFER
  193.     CALL    BDOS    ;CALL BDOS
  194.     JMP    GOCPM    ;CONTINUE INITIALIZATION
  195.  
  196. CPMSG:    DB    0DH,0AH,'CP/M V1-3.5 L0.1 31K$'
  197. ;*************************************************;
  198. ;
  199. ;
  200. ;    I/O DRIVERS FOR THE DISK 
  201. ;
  202. ;*************************************************;
  203.  
  204. HOME:    ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE
  205.     LDA    DISKNO    ;SELECTED DISK
  206.     MOV    C,A    ;FOLLOW PARAMETER CONVENTIONS
  207.     CALL    SELDSK    ;ROUTINE TO SELECT THE DISK
  208. ;SET UP H,L TO POINT TO WORD WITH TRACK FOR SELECTED DISK
  209.     LXI    D,TRACK
  210.     LHLD    DISKNO
  211.     DAD    D
  212. HOMEL:
  213.     MVI    M,00    ;SET CURRENT TRACK PTR BACK TO 0
  214.     IN    127    ;READ FDC STATUS
  215.     ANI    4    ;TEST TRACK 0 BIT
  216.     RNZ        ;RETURN IF AT 0
  217.     STC        ;DIRECTION=OUT
  218.     CALL    STEP    ;STEP ONE TRACK
  219.     JMP    HOMEL    ;LOOP
  220. ;
  221. SELDSK:    ;SELECT DISK GIVEN BY REGISTER C
  222. ;MAKE SURE DUMMY IS 0 (FOR USE IN DOUBLE ADD TO H,L)
  223.     XRA    A
  224.     STA    DUMMY
  225.     MOV    A,C
  226.     STA    DISKNO
  227.     RRC        ;PUT INTO BITS 4,5
  228.     RRC
  229.     RRC
  230.     RRC
  231.     ORI    08    ;ENABLE DISK SELECT
  232.     OUT    127    ;SELECT THE DISK
  233.     RET
  234. ;
  235. SETTRK:    ;SET TRACK GIVEN BY REGISTER C
  236. ;FIRST REFERENCE CORRECT TRACK INDICATOR ACCORDING TO
  237. ;SELECTED DISK
  238.     LXI    D,TRACK    ;ADDRESS OF TRACK FOR DISK 0
  239.     LHLD    DISKNO    ;FIND OUT WHICH DISK IS SELECTED
  240.     DAD    D
  241.     MOV    A,C    ;DESIRED TRACK
  242.     CMP    M
  243.     RZ        ;WE ARE ALREADY ON THE TRACK
  244. SETTKX:
  245.     CALL    STEP    ;STEP TRACK-CARRY HAS DIRECTION
  246.             ;STEP WILL UPDATE TRACK INDICATOR
  247.     MOV    A,C
  248.     CMP    M    ;ARE WE WHERE WE WANT TO BE
  249.     JNZ    SETTKX    ;NOT YET
  250. ;HAVE STEPPED ENOUGH
  251. SEEKRT:
  252. ;DELAY 18 MSEC FOR FINAL STEP TIME AND HEAD SETTLE TIME
  253.     MVI    A,18D
  254.     CALL    DELAY
  255.     RET        ;END OF SETTRK ROUTINE
  256. ;
  257. DELAY:    ;ROUTINE TO DELAY C(A) MILLISECONDS
  258.     MVI    C,82H    ;ADJUST FOR 1 MSEC LOOP DELAY
  259.             ;THIS IS THE VALUE FOR OUR IMSAI
  260. LDXA:
  261.     DCR    C
  262.     JNZ    LDXA    ;LOOP 1 MSEC
  263.     DCR    A
  264.     JNZ    DELAY
  265.     RET        ;END OF DELAY ROUTINE
  266. ;
  267. SETSEC:    ;SET SECTOR GIVEN BY REGISTER C
  268.     MOV    A,C
  269.     STA    SECTOR
  270.     RET
  271. ;
  272. SETDMA:    ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C
  273.     MOV    L,C    ;LOW ORDER ADDRESS
  274.     MOV    H,B    ;HIGH ORDER ADDRESS
  275.     SHLD    DMAAD    ;SAVE THE ADDRESS
  276.     RET
  277. ;
  278. ;
  279. ERRORS:    DB    0    ;KEEP TRACK OF NUMBER OF ERRORS
  280. READ:    ;PERFORM READ OPERATION.
  281.     ;THIS IS SIMILAR TO WRITE, SO SET UP READ COMMAND AND USE
  282.     ;COMMON CODE IN WRITE
  283.     MVI    D,40H    ;SET READ FLAG
  284.     JMP    WAITIO    ;TO PERFORM THE ACTUAL I/O
  285. ;
  286. WRITE:    ;PERFORM A WRITE OPERATION
  287.     MVI    D,80H    ;SET WRITE COMMAND
  288. ;
  289. WAITIO:
  290. ;ENTER HERE FROM READ AND WRITE TO PERFORM THE ACTUAL I/O 
  291. ;OPERATION.  RETURN A 00H IN REGISTER A IF THE OPERATION COMPLETES
  292. ;PROPERLY, AND 01H IF AN ERROR OCCURS DURING THE READ OR WRITE
  293. ;
  294. ;IN THIS CASE, WE HAVE SAVED THE DISK NUMBER IN 'DISKNO' (0,1)
  295. ;    THE TRACK NUMBER IN 'TRACK' (0-76)
  296. ;    THE SECTOR NUMBER IN 'SECTOR' (1-26)
  297. ;    THE DMA ADDRESS IN 'DMAAD' (3-3F80H)
  298.             ;D STILL HAS R/W FLAG
  299.     MVI    A,10D    ;SET ERROR COUNT
  300.     STA    ERRORS    ;RETRY SOME FAILURES 10 TIMES
  301.             ;BEFORE GIVING UP
  302. TRYAGN:
  303. ;FIRST WE HAVE TO FIGURE OUT WHICH DRIVE IS SELECTED
  304. ;AND WHICH TRACK IS DESIRED
  305.     LXI    B,TRACK
  306.     LHLD    DISKNO
  307.     DAD    B    ;H,L POINT TO CORRECT TRACK INDICATOR
  308.     MOV    A,M
  309.     PUSH    PSW    ;NEED IT LATER
  310.     LHLD    DMAAD    ;GET BUFFER ADDRESS
  311.     DCX    H    ;SAVE AND REPLACE 3 BYTES BELOW
  312.             ;BUF WITH TRACK,SECTOR,ADDRESS MARK
  313.     MOV    B,M
  314.     MVI    A,0FBH    ;ADDRESS MARK
  315.     MOV    M,A
  316.     DCX    H
  317.     MOV    C,M
  318.     LDA    SECTOR    ;NOTE THAT INVALID SECTOR NUMBER
  319.             ;WILL RESULT IN HEAD UNLOADED
  320.             ;ERROR, SO DONT CHECK
  321.     MOV    M,A
  322.     DCX    H
  323.     MOV    E,M
  324.     POP    PSW
  325.     MOV    M,A
  326.     MOV    A,H    ;SET UP FDC DMA ADDRESS
  327.     OUT    126    ;HIGH BYTE
  328.     MOV    A,L
  329.     OUT    125    ;LOW BYTE
  330.     MOV    A,D    ;GET R/W FLAG
  331.     OUT    127    ;START DISK READ/WRITE
  332. RWWAIT:    IN    127    ;READ FDC STATUS
  333.     ANI    0F8H    ;TEST FOR ANY ERROR OR IOF
  334.     JZ    RWWAIT
  335.     MOV    M,E    ;RESTORE 3 BYTES BELOW BUF
  336.     INX    H
  337.     MOV    M,C
  338.     INX    H
  339.     MOV    M,B
  340.     IN    127    ;TEST FOR ERRORS
  341.     ANI    0F0H
  342.     RZ        ;A WILL BE 0 IF NO ERRORS
  343. ;COME HERE ON ERROR FROM DISK
  344.     PUSH    PSW    ;SAVE ERROR CONDITION
  345. ;CHECK FOR 10 ERRORS
  346.     LXI    H,ERRORS
  347.     DCR    M
  348.     JNZ    REDO    ;NOT TEN YET.  DO A RETRY
  349. ;WE HAVE TOO MANY ERRORS. PRINT OUT HEX NUMBER FOR LAST
  350. ;RECEIVED ERROR TYPE. CPM WILL PRINT PERM ERROR MESSAGE.
  351.     POP    PSW    ;GET CODE
  352.     RRC
  353.     RRC
  354.     RRC
  355.     RRC
  356. ;MAKE IT ASCII
  357.     ORI    030H
  358.     MOV    C,A
  359.     CALL    CONOUT
  360. ;SET ERROR RETURN FOR OPERATING SYSTEM
  361.     MVI    A,1
  362.     RET
  363. REDO:
  364. ;D STILL HAS READ/WRITE FLAG
  365.     POP    PSW    ;GET ERROR CODE
  366.     ANI    0E0H    ;RETRY IF NOT TRACK ERROR
  367.     JNZ    TRYAGN
  368. ;WAS A TRACK ERROR SO NEED TO RESEEK
  369.     PUSH    D    ;SAVE    READ/WRITE INDICATOR
  370. ;FIGURE OUT THE DESIRED TRACK
  371.     LXI    D,TRACK
  372.     LHLD    DISKNO    ;SELECTED DISK
  373.     DAD    D    ;POINT TO CORRECT TRACK INDICATOR
  374.     MOV    A,M    ;DESIRED TRACK
  375.     PUSH    PSW    ;SAVE IT
  376.     CALL    HOME
  377.     POP    PSW
  378.     MOV    C,A
  379.     CALL    SETTRK
  380.     POP    D    ;GET READ/WRITE INDICATOR
  381.     JMP    TRYAGN
  382. ;
  383. ;
  384. ;
  385. STEP:                ;STEP HEAD OUT TOWARDS ZERO
  386.                 ;IF CARRY IS SET; ELSE
  387.                 ;STEP IN
  388. ; H,L POINT TO CORRECT TRACK INDICATOR WORD
  389.     PUSH    PSW    ;SAVE DIRECTION
  390. STWAIT:    IN    127    ;INPUT FDC STATUS
  391.     ANI    2    ;TEST STEP READY BIT
  392.     JZ    STWAIT    ;WAIT FOR STEP READY(MAX 10 MSEC)
  393.     POP    PSW    ;GET DIRECTION TO STEP
  394.     JC    OUTX
  395.     INR    M    ;INCREMENT CURRENT TRACK BYTE
  396.     MVI    A,4    ;SET DIRECTION = IN
  397. DOSTEP:
  398.     OUT    127    ;SET DIRECTION BIT IN FDC
  399.     ORI    2
  400.     OUT    127    ;PULSE STEP BIT
  401.     ANI    0FDH
  402.     OUT    127    ;TURN OFF PULSE
  403.     RET
  404. ;
  405. OUTX:
  406.     DCR    M    ;UPDATE TRACK BYTE
  407.     XRA    A    ;SET DIRECTION = OUT
  408.     JMP    DOSTEP
  409.  
  410. ;*************************************************;
  411. ;
  412. ;        PERIPHERAL I/O DRIVERS
  413. ;
  414. ;*************************************************;
  415.  
  416. ;
  417. ;        CONSOLE STATUS
  418. ;
  419. CONST:    CALL    CONS    ;GET DEVICE STATUS
  420.     ORA    A    ;SET FLAGS
  421.     RZ        ;ZERO IF NO CHAR AVAIL
  422.     MVI    A,0FFH    ;FF IF CHAR OK
  423.     RET
  424.  
  425. CONS:    LDA    IOBYT    ;GET IOBYT
  426.     CALL    IOCAL    ;EXIT TO SELECTED ROUTINE
  427.     DW    TTYST    ;TELETYPE STATUS ROUTIE
  428.     DW    CRTST    ;CRT STATUS ROUTINE
  429.     DW    RDRST    ;READER STATUS ROUTINE
  430.     DW    NULST    ;NULL STATUS ROUTINE
  431.  
  432. ;
  433. ;        CONSOLE INPUT
  434. ;
  435. CONIN:    LDA    IOBYT    ;GET IOBYT
  436.     CALL    IOCAL    ;EXIT TO SELECTED ROUTINE
  437.     DW    TTYIN    ;TTY INPUT ROUTINE
  438.     DW    CRTIN    ;CRT INPUT ROUTINE
  439.     DW    RDRIN    ;READER INPUT ROUTINE
  440.     DW    NULIN    ;NULL INPUT ROUTINE
  441.  
  442. ;
  443. ;        CONSOLE OUTPUT
  444. ;
  445. CONOUT:    LDA    IOBYT    ;GET IOBYT
  446.     CALL    IOCAL    ;EXIT TO SELECTED ROUTINE
  447.     DW    TTYOUT    ;TTY OUTPUT ROUTINE
  448.     DW    CRTOUT    ;CRT OUTPUT ROUTINE
  449.     DW    PRTOUT    ;PRINTER OUTPUT ROUTINE
  450.     DW    NULOUT    ;NULL OUTPUT ROUTINE
  451.  
  452. ;
  453. ;        LISTING OUTPUT
  454. ;
  455. LIST:    LDA    IOBYT    ;GET IOBYT
  456.     RLC
  457.     RLC        ;SHIFT BITS
  458.     CALL    IOCAL    ;EXIT TO SELECTED ROUTINE
  459.     DW    TTYOUT    ;TTY OUTPUT ROUTINE
  460.     DW    CRTOUT    ;CRT OUTPUT ROUTINE
  461.     DW    PRTOUT    ;PRINTER OUTPUT ROUTINE
  462.     DW    NULOUT    ;NULL OUTPUT ROUTINE
  463.  
  464. ;
  465. ;        PUNCH OUTPUT
  466. ;
  467. PUNCH:    LDA    IOBYT    ;GET IOBYT
  468.     RRC
  469.     RRC
  470.     RRC        ;SHIFT BITS
  471.     RRC
  472.     CALL    IOCAL    ;EXIT TO SELECTED ROUTINE
  473.     DW    TTYOUT    ;TTY OUTPUT ROUTINE
  474.     DW    CRTOUT    ;CRT OUTPUT ROUTIE
  475.     DW    PUNOUT    ;PUNCH OUTPUT ROUTINE
  476.     DW    NULOUT    ;NULL OUTPUT ROUTINE
  477.  
  478. ;
  479. ;        READER INPUT
  480. ;
  481. READER:    LDA    IOBYT    ;GET IOBYT
  482.     RRC        ;SHIFT BITS
  483.     RRC
  484.     CALL    IOCAL    ;EXIT TO SELECTED ROUTINE
  485.     DW    TTYIN    ;TTY INPUT ROUTINE
  486.     DW    CRTIN    ;CRT INPUT ROUTINE
  487.     DW    RDRIN    ;READER INPUT ROUTINE
  488.     DW    NULIN    ;NULL INPUT ROUTINE
  489.  
  490. ;***************************************************;
  491. ;
  492. ;        I/O DISPATCHER
  493. ;
  494. ;***************************************************;
  495.  
  496. IOCAL:    RLC        ;SHIFT BITS
  497.     ANI    06H    ;MASK BITS
  498.     XTHL        ;SAVE HL, GET TABLE ADDRESS
  499.     PUSH    D    ;SAVE DE
  500.     MOV    E,A    ;GET SELECTION VALUE IN A
  501.     MVI    D,0
  502.     DAD    D    ;CALCULATE TABLE ENTRY ADDRESS
  503.     MOV    A,M    ;GET TABLE ENTRY
  504.     INX    H
  505.     MOV    H,M
  506.     MOV    L,A    ;INTO HL
  507.     POP    D    ;RESTORE DE
  508.     XTHL        ;PUT EXIT ADDR ON STACK, RESTORE HL
  509.     RET        ;EXIT TO ROUTINE
  510.  
  511. ;****************************************************;
  512. ;
  513. ;        PHYSICAL I/O ROUTINES
  514. ;
  515. ;***************************************************;
  516.  
  517. TTYST:    IN    TTYS
  518.     ANI    TTYDA    ;TEST FOR TTY DATA AVAIL.
  519.     RET        ;EXIT WITH ZERO IF NOT AVAIL
  520.  
  521. TTYIN:    CALL    TTYST    ;TEST FOR CHAR AVAIL
  522.     JZ    TTYIN    ;NOT YET, WAIT
  523.     IN    TTYD    ;GET DATA
  524.     ANI    7FH    ;STRIP PARITY
  525.     RET
  526.  
  527. TTYOUT:    IN    TTYS    ;GET TTY STATUS
  528.     ANI    TTYBE    ;TEST FOR XMIT BUFFER EMPTY
  529.     JZ    TTYOUT    ;WAIT TIL READY
  530.     MOV    A,C    ;GET OUTPUT CHAR
  531.     OUT    TTYD    ;OUTPUT CHAR
  532.     RET
  533.  
  534. CRTST:    CALL    TTYST
  535.     RET
  536.  
  537. CRTIN:    CALL    TTYIN    ;CRT KEYBOARD = TTY
  538.     RET        ;EXIT
  539.  
  540. CRTOUT:    MOV    A,C
  541.     PUSH    PSW    ;SAVE A
  542.     PUSH    B
  543.     PUSH    D
  544.     PUSH    H    ;SAVE REGS
  545.     CPI    0DH    ;CARRIAGE RETURN?
  546.     JZ    COCR    ;YES
  547.     CPI    0AH    ;LF?
  548.     JZ    COLF    ;YES
  549.     CPI    08H    ;BACKSPACE?
  550.     JZ    COBS
  551.     CPI    0CH    ;FORM FEED?
  552.     JZ    COFF    ;YES
  553.     CPI    7FH    ;RUBOUT?
  554.     JZ    CO4    ;YES, IGNORE IT
  555.     JNC    CO4    ;IGNORE CHARS>7F
  556.     CPI    20H    ;OTHER CONTROL CHAR
  557.     JC    CO4    ;YES, IGNORE
  558.     STA    CHR
  559.     CALL    DSWRT    ;DISPLAY CHARACTER
  560. CO4:    POP    H
  561.     POP    D
  562.     POP    B
  563.     POP    PSW
  564.     RET
  565.  
  566. COCR:    CALL    CSRET
  567.     JMP    CO4
  568. COLF:    CALL    CSDWN
  569.     JMP    CO4
  570. COBS:    CALL    CSLFT
  571.     JMP    CO4
  572. COFF:    CALL    CSHOM
  573.     CALL    DSERS
  574.     JMP    CO4
  575.  
  576. DSINT:    LXI    H,VDMLC
  577.     SHLD    DSPLOC
  578.     MVI    A,0
  579.     STA    CURVRT
  580.     STA    CURHOR
  581.     CALL    DSERS
  582.     CALL    CSON
  583.     MVI    A,00
  584.     OUT    0C8H        ;SET UP VDM PORT
  585.     RET
  586.  
  587. DSERS:    LHLD    DSPLOC
  588.     LDA    CURVRT
  589.     MOV    C,A
  590. D1001:    MVI    B,LINSIZ
  591.     MVI    A,' '
  592. D1002:    MOV    M,A
  593.     INX    H
  594.     DCR    B
  595.     JNZ    D1002
  596.     INR    C
  597.     MVI    A,DSPSIZ
  598.     CMP    C
  599.     JNZ    D1001
  600.     CALL    CSON
  601.     RET
  602.  
  603. DSWRT:    LDA    CHR
  604.     LHLD    DSPLOC
  605.     MOV    M,A
  606.     CALL    CSRGT
  607.     IN    0FFH    ;READ SWITCHES
  608.     ORA    A    ;TEST
  609.     RZ        ;ZERO, RUN FULL SPEED
  610.     MOV    H,A    ;PUT SWITCHES IN H
  611.     MVI    L,0
  612. DLLP:    DCX    H    ;CHECK HL
  613.     MOV    A,H
  614.     ORA    L
  615.     JNZ    DLLP
  616.     RET
  617.  
  618. DSSCR:    LXI    H,VDMLC
  619.     MOV    D,H
  620.     MOV    E,L
  621.     LXI    B,LINSIZ
  622.     DAD    B
  623.     MVI    B,DSPSIZ-1
  624. D7003:    MVI    C,LINSIZ
  625. D7004:    MOV    A,M
  626.     STAX    D
  627.     INX    H
  628.     INX    D
  629.     DCR    C
  630.     JNZ    D7004
  631.     DCR    B
  632.     JNZ    D7003
  633.     MVI    C,LINSIZ
  634.     MVI    A,' '
  635. D7005:    STAX    D
  636.     INX    D
  637.     DCR    C
  638.     JNZ    D7005
  639.     RET
  640.  
  641. CSRGT:    CALL    CSOFF
  642.     LDA    CURHOR
  643.     INR    A
  644.     CPI    LINSIZ
  645.     JC    D2001
  646.     CALL    CSRET
  647.     CALL    CSDWN
  648.     RET
  649. D2001:    STA    CURHOR
  650.     LHLD    DSPLOC
  651.     INX    H
  652.     SHLD    DSPLOC
  653.     CALL    CSON
  654.     RET
  655.  
  656. CSLFT:    CALL    CSOFF
  657.     LDA    CURHOR
  658.     CPI    00
  659.     JNZ    D3001
  660.     CALL    CSON
  661.     RET
  662. D3001:    DCR    A
  663.     STA    CURHOR
  664.     LHLD    DSPLOC
  665.     DCX    H
  666.     SHLD    DSPLOC
  667.     CALL    CSON
  668.     RET
  669.  
  670. CSRET:    CALL    CSOFF
  671.     LHLD    DSPLOC
  672.     LDA    CURHOR
  673.     MOV    B,A
  674.     MOV    A,L
  675.     SUB    B
  676.     MOV    L,A
  677.     MOV    A,H
  678.     SBI    0
  679.     MOV    H,A
  680.     SHLD    DSPLOC
  681.     XRA    A
  682.     STA    CURHOR
  683.     CALL    CSON
  684.     RET
  685.  
  686. CSDWN:    CALL    CSOFF
  687.     LDA    CURVRT
  688.     CPI    DSPSIZ-1
  689.     JNZ    D4001
  690.     CALL    DSSCR
  691.     CALL    CSON
  692.     RET
  693. D4001:    LDA    CURVRT
  694.     INR    A
  695.     STA    CURVRT
  696.     LHLD    DSPLOC
  697.     LXI    B,LINSIZ
  698.     DAD    B
  699.     SHLD    DSPLOC
  700.     CALL    CSON
  701.     RET
  702.  
  703. CSUP:    CALL    CSOFF
  704.     LDA    CURVRT
  705.     CPI    00
  706.     JNZ    D5001
  707.     CALL    CSON
  708.     RET
  709. D5001:    LDA    CURVRT
  710.     DCR    A
  711.     STA    CURVRT
  712.     LHLD    DSPLOC
  713.     LXI    B,LINSIZ
  714.     MOV    A,L
  715.     SUB    C
  716.     MOV    L,A
  717.     MOV    A,H
  718.     SBB    B
  719.     MOV    H,A
  720.     SHLD    DSPLOC
  721.     CALL    CSON
  722.     RET
  723.  
  724. CSHOM:    CALL    CSOFF
  725.     LXI    H,VDMLC
  726.     SHLD    DSPLOC
  727.     LXI    H,0000
  728.     SHLD    CURHOR
  729.     CALL    CSON
  730.     RET
  731.  
  732. CSON:    LHLD    DSPLOC
  733.     MOV    A,M
  734.     ORI    80H
  735.     MOV    M,A
  736.     RET
  737.  
  738. CSOFF:    LHLD    DSPLOC
  739.     MOV    A,M
  740.     ANI    7FH
  741.     MOV    M,A
  742.     RET
  743.  
  744. DSPLOC    EQU    0047H
  745. CURHOR    EQU    0049H
  746. CURVRT    EQU    004AH
  747. CHR    EQU    004BH
  748.  
  749. DSPSIZ    EQU    16
  750. LINSIZ    EQU    64
  751. VDMLC    EQU    0CC00H
  752.  
  753.  
  754. RDRST:    CALL    TTYST    ;NOTE: READER IS TTY
  755.     RET
  756.  
  757. RDRIN:    CALL    TTYIN    ;NOTE: READER IS TTY
  758.  
  759. NULST:    MVI    A,0FFH    ;IF NULL DEVICE IS CONSOLE, CHAR 
  760.             ;IS ALWAYS READY
  761.     ORA    A
  762.     RET
  763.  
  764. NULIN:    MVI    A,1AH    ;NULL INPUT RETURNS EOF CHARS
  765.     RET
  766.  
  767. NULOUT:    MOV    A,C    ;COPY C TO A
  768.     RET
  769.  
  770. PRTOUT:    CALL    TTYOUT    ;NOE: PRINTER IS TTY
  771.     RET
  772.  
  773. PUNOUT:    CALL    TTYOUT    ;NOTE: PUNCH IS TTY
  774.     RET
  775.  
  776. ;**************************************************;
  777. ;
  778. ;        END OF BIOS ROUTINES
  779. ;
  780. ;**************************************************;
  781.     END
  782.