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 >
Wrap
Assembly Source File
|
1984-04-29
|
16KB
|
783 lines
;***********************************************;
;
; CBIOS FOR IMSAI WITH SIO2-2 AND TELETYPE
; INCLUDES IOBYTE FUNCTION
; AND DRIVER FOR PROCESSOR TECHNOLOGY VDM
; WRITTEN BY JEFF KRAVITZ, 05/21/77
;
;***********************************************;
;NOTE : MSIZE DETERMINES WHERE THIS CBIOS IS LOCATED
MSIZE EQU 31 ;CP/M MEMORY SIZE IN KBYTES
PATCH EQU MSIZE*1024-2*256 ;START OF THE CBIOS
;***********************************************;
;
; I/O DEVICE VALUES
;
;***********************************************;
IOBYT EQU 0003H ;I/O CONTROL BYTE
TTYD EQU 02H ;TELETYPE DATA PORT
TTYS EQU 03H ;TELETYPE STATUS PORT
TTYDA EQU 02H ;TTY DATA AVAIL BIT
TTYBE EQU 01H ;TTY BUFER EMPTY BIT
CRTD EQU 04H ;CRT DATA PORT
CRTS EQU 05H ;CRT STATUS PORT
CRTDA EQU 02H ;CRT DATA AVAIL BIT
CRTBE EQU 01H ;CRT BUFFER EMPTY BIT
TTYMD EQU 0CEH ;TTY MODE BYTE
TTYCM EQU 017H ;TTY COMMAND BYTE
CRTMD EQU 0CEH ;CRT MODE BYTE
CRTCM EQU 017H ;CRT COMMAND BYTE
;************************************************;
;
; MISC EQUATES
;
;************************************************;
;*************************************************;
;
; WE WILL USE A SCRATCH AREA STARTING AT 40H
; FOR HOLDING THE VALUES OF:
; TRACK = LAST SELECTED TRACK
; SECTOR = LAST SELECTED SECTOR
; DMAAD = LAST SELECTED DMA ADDRESS
; DISKNO = LAST SELECTED DISK NUMBER
;(NOTE THAT ALL ARE BYTE VALUES EXCEPT FOR DMAAD)
;
;*************************************************;
SCRAT EQU 40H ;START OF SCRATCH AREA
TRACK EQU SCRAT ;CURRENT TRACK ON DRIVE 0
TRAK1 EQU TRACK+1 ;CURRENT TRACK ON DRIVE 1
SECTOR EQU SCRAT+2 ;CURRENTLY SELECTED SECTOR
DMAAD EQU SCRAT+3 ;CURRENT DMA ADDRESS
DISKNO EQU SCRAT+5 ;CURRENT DISK NUMBER
DUMMY EQU DISKNO+1 ;MUST BE 0 FOR DOUBLE ADD
ORG PATCH ;ORIGIN OF THIS PROGRAM
CBASE EQU (MSIZE-16)*1024 ;BIAS FOR SYSTEMS>16K
CPMB EQU CBASE+2900H ;BASE OF CP/M
BDOS EQU CBASE+3206H ;BASE OF RESIDENT CODE
CPML EQU $-CPMB ;LENGTH OF CP/M
NSECTS EQU CPML/128 ;# OF SECTORS TO LOAD
;************************************************;
;
; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES
;
;************************************************;
JMP SCPM ;COLD START
WBOTE: JMP WBOOT ;WARM START
JMP CONST ;CONSOLE STATUS
JMP CONIN ;CONSOLE CHARACTER IN
JMP CONOUT ;CONSOLE CHARACTER OUT
JMP LIST ;LIST CHARACTER OUT
JMP PUNCH ;PUNCH CHARACTER OUT
JMP READER ;READER CHARACTER OUT
JMP HOME ;MOVE HEAD TO HOME
JMP SELDSK ;SELECT DISK
JMP SETTRK ;SET TRACK NUMBER
JMP SETSEC ;SET SECTOR NUMBER
JMP SETDMA ;SET DMA ADDRESS
JMP READ ;READ DISK
JMP WRITE ;WRITE DISK
;************************************************;
;
; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION
;
;************************************************;
WBOOT: ;READ THE DISK UNTIL ALL SECTORS LOADED
LXI SP,80H ;STACK BELOW BUFFER
MVI C,0 ;SELECT DISK 0
CALL SELDSK
CALL HOME ;GO TO TRACK 00
MVI B,NSECTS ;B = # SECTORS TO LOAD
MVI C,0 ;C HAS THE CURRENT TRACK NUMBER
MVI D,2 ;D HAS THE NEXT SECTOR TO READ
; NOTE THAT WE BEGIN BY READING TRACK 0, SECTOR 2 SINCE SECTOR 1
; CONTAINS THE COLD START LOADER, WHICH IS SKIPPED IN A WARM START
LXI H,CPMB ;BASE OF CP/M (INITIAL LOAD POINT)
LOAD1: ;LOAD ONE MORE SECTOR
PUSH B ;SAVE SECTOR COUNT, CURRENT TRACK
PUSH D ;SAVE NEXT SECTOR TO READ
PUSH H ;SAVE DMA ADDRESS
MOV C,D ;GET SECTOR ADDRESS TO REG. C
CALL SETSEC ;SET SECTOR ADDRESS FROM REG. C
POP B ;RECALL DMA ADDRESS TO B,C
PUSH B ;REPLACE ON STACK
CALL SETDMA ;SET DMA ADDRESS FROM B,C
;
; DRIVE SET TO 0, TRACK SET, SECTOR SET, DMA ADDRESS SET
CALL READ
ORA A ;ANY ERRORS?
JNZ WBOOT ;RETRY IF ERROR
;
; NO ERROR, MOVE TO NEXT SECTOR
POP H ;RECALL DMA ADDRESS
LXI D,128 ;DMA=DMA+128
DAD D ;NEW DMA ADDRESS IS IN H,L
POP D ;RECALL SECTOR ADDRESS
POP B ;GET NUM. SECTORS & TRACK
DCR B ;SECTORS=SECTORS-1
JZ GOCPM ;GOTO CPM WHEN DONE
;
; MORE SECTORS REMAIN TO LOAD, CHECK FOR TRACK CHANGE
INR D
MOV A,D ;SEC=27?,IF SO,CHANGE TRACKS
CPI 27
JC LOAD1 ;CARRY GENERATED IF SECTOR<27
;
; END OF CURRENT TRACK, GO TO NEXT TRACK
MVI D,1 ;1ST SEC OF NEXT TRACK
INR C ;TRACK=TRACK+1
;
; SAVE REGISTER STATE, AND CHANGE TRACKS
PUSH B
PUSH D
PUSH H
CALL SETTRK ;TRACK ADDR SET FROM REG C
POP H
POP D
POP B
JMP LOAD1 ;FOR ANOTHER SECTOR
;
; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M
GOCPM: LXI SP,80H
MVI A,0C3H ;C3 IS A JMP INSTRUCTION
STA 0 ;FOR JMP TO WBOOT
LXI H,WBOTE ;WBOOT ENTRY POINT
SHLD 1 ;SET ADDRESS FIELD FOR JMP AT 0
;
STA 5 ;FOR JMP TO BDOS
LXI H,BDOS ;BDOS ENTRY POINT
SHLD 6 ;ADDRESS FIELD OF JUMP AT 5 TO BDOS
;
LXI B,80H ;DEFAULT DMA ADDRESS IS 80H
CALL SETDMA
;
;PUT ACTIVE DISK NUMBER (STORED IN LOCATION 4) IN C
LDA 04H
MOV C,A
EI ;ENABLE INTERRUPTS
JMP CPMB ;GO TO CP/M FOR FURTHER PROCESSING
;**********************************************;
;
; COLD START ROUTINE
;
;**********************************************;
SCPM: XRA A ;INITIALIZE IOBYT
STA IOBYT
MVI A,0AAH ;DUMMY MODE BYTE
OUT TTYS ;CLEAR TTY
MVI A,040H ;RESET COMMAND
OUT TTYS
MVI A,TTYMD
OUT TTYS
MVI A,TTYCM
OUT TTYS ;SET UP TTY USART
LXI SP,80H ;SET STACK
CALL DSINT ;INITIALIZE DISPLAY
LXI D,CPMSG ;POINT TO STARTUP MESSAGE
MVI C,09 ;WRITE BUFFER
CALL BDOS ;CALL BDOS
JMP GOCPM ;CONTINUE INITIALIZATION
CPMSG: DB 0DH,0AH,'CP/M V1-3.5 L0.1 31K$'
;*************************************************;
;
;
; I/O DRIVERS FOR THE DISK
;
;*************************************************;
HOME: ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE
LDA DISKNO ;SELECTED DISK
MOV C,A ;FOLLOW PARAMETER CONVENTIONS
CALL SELDSK ;ROUTINE TO SELECT THE DISK
;SET UP H,L TO POINT TO WORD WITH TRACK FOR SELECTED DISK
LXI D,TRACK
LHLD DISKNO
DAD D
HOMEL:
MVI M,00 ;SET CURRENT TRACK PTR BACK TO 0
IN 127 ;READ FDC STATUS
ANI 4 ;TEST TRACK 0 BIT
RNZ ;RETURN IF AT 0
STC ;DIRECTION=OUT
CALL STEP ;STEP ONE TRACK
JMP HOMEL ;LOOP
;
SELDSK: ;SELECT DISK GIVEN BY REGISTER C
;MAKE SURE DUMMY IS 0 (FOR USE IN DOUBLE ADD TO H,L)
XRA A
STA DUMMY
MOV A,C
STA DISKNO
RRC ;PUT INTO BITS 4,5
RRC
RRC
RRC
ORI 08 ;ENABLE DISK SELECT
OUT 127 ;SELECT THE DISK
RET
;
SETTRK: ;SET TRACK GIVEN BY REGISTER C
;FIRST REFERENCE CORRECT TRACK INDICATOR ACCORDING TO
;SELECTED DISK
LXI D,TRACK ;ADDRESS OF TRACK FOR DISK 0
LHLD DISKNO ;FIND OUT WHICH DISK IS SELECTED
DAD D
MOV A,C ;DESIRED TRACK
CMP M
RZ ;WE ARE ALREADY ON THE TRACK
SETTKX:
CALL STEP ;STEP TRACK-CARRY HAS DIRECTION
;STEP WILL UPDATE TRACK INDICATOR
MOV A,C
CMP M ;ARE WE WHERE WE WANT TO BE
JNZ SETTKX ;NOT YET
;HAVE STEPPED ENOUGH
SEEKRT:
;DELAY 18 MSEC FOR FINAL STEP TIME AND HEAD SETTLE TIME
MVI A,18D
CALL DELAY
RET ;END OF SETTRK ROUTINE
;
DELAY: ;ROUTINE TO DELAY C(A) MILLISECONDS
MVI C,82H ;ADJUST FOR 1 MSEC LOOP DELAY
;THIS IS THE VALUE FOR OUR IMSAI
LDXA:
DCR C
JNZ LDXA ;LOOP 1 MSEC
DCR A
JNZ DELAY
RET ;END OF DELAY ROUTINE
;
SETSEC: ;SET SECTOR GIVEN BY REGISTER C
MOV A,C
STA SECTOR
RET
;
SETDMA: ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C
MOV L,C ;LOW ORDER ADDRESS
MOV H,B ;HIGH ORDER ADDRESS
SHLD DMAAD ;SAVE THE ADDRESS
RET
;
;
ERRORS: DB 0 ;KEEP TRACK OF NUMBER OF ERRORS
READ: ;PERFORM READ OPERATION.
;THIS IS SIMILAR TO WRITE, SO SET UP READ COMMAND AND USE
;COMMON CODE IN WRITE
MVI D,40H ;SET READ FLAG
JMP WAITIO ;TO PERFORM THE ACTUAL I/O
;
WRITE: ;PERFORM A WRITE OPERATION
MVI D,80H ;SET WRITE COMMAND
;
WAITIO:
;ENTER HERE FROM READ AND WRITE TO PERFORM THE ACTUAL I/O
;OPERATION. RETURN A 00H IN REGISTER A IF THE OPERATION COMPLETES
;PROPERLY, AND 01H IF AN ERROR OCCURS DURING THE READ OR WRITE
;
;IN THIS CASE, WE HAVE SAVED THE DISK NUMBER IN 'DISKNO' (0,1)
; THE TRACK NUMBER IN 'TRACK' (0-76)
; THE SECTOR NUMBER IN 'SECTOR' (1-26)
; THE DMA ADDRESS IN 'DMAAD' (3-3F80H)
;D STILL HAS R/W FLAG
MVI A,10D ;SET ERROR COUNT
STA ERRORS ;RETRY SOME FAILURES 10 TIMES
;BEFORE GIVING UP
TRYAGN:
;FIRST WE HAVE TO FIGURE OUT WHICH DRIVE IS SELECTED
;AND WHICH TRACK IS DESIRED
LXI B,TRACK
LHLD DISKNO
DAD B ;H,L POINT TO CORRECT TRACK INDICATOR
MOV A,M
PUSH PSW ;NEED IT LATER
LHLD DMAAD ;GET BUFFER ADDRESS
DCX H ;SAVE AND REPLACE 3 BYTES BELOW
;BUF WITH TRACK,SECTOR,ADDRESS MARK
MOV B,M
MVI A,0FBH ;ADDRESS MARK
MOV M,A
DCX H
MOV C,M
LDA SECTOR ;NOTE THAT INVALID SECTOR NUMBER
;WILL RESULT IN HEAD UNLOADED
;ERROR, SO DONT CHECK
MOV M,A
DCX H
MOV E,M
POP PSW
MOV M,A
MOV A,H ;SET UP FDC DMA ADDRESS
OUT 126 ;HIGH BYTE
MOV A,L
OUT 125 ;LOW BYTE
MOV A,D ;GET R/W FLAG
OUT 127 ;START DISK READ/WRITE
RWWAIT: IN 127 ;READ FDC STATUS
ANI 0F8H ;TEST FOR ANY ERROR OR IOF
JZ RWWAIT
MOV M,E ;RESTORE 3 BYTES BELOW BUF
INX H
MOV M,C
INX H
MOV M,B
IN 127 ;TEST FOR ERRORS
ANI 0F0H
RZ ;A WILL BE 0 IF NO ERRORS
;COME HERE ON ERROR FROM DISK
PUSH PSW ;SAVE ERROR CONDITION
;CHECK FOR 10 ERRORS
LXI H,ERRORS
DCR M
JNZ REDO ;NOT TEN YET. DO A RETRY
;WE HAVE TOO MANY ERRORS. PRINT OUT HEX NUMBER FOR LAST
;RECEIVED ERROR TYPE. CPM WILL PRINT PERM ERROR MESSAGE.
POP PSW ;GET CODE
RRC
RRC
RRC
RRC
;MAKE IT ASCII
ORI 030H
MOV C,A
CALL CONOUT
;SET ERROR RETURN FOR OPERATING SYSTEM
MVI A,1
RET
REDO:
;D STILL HAS READ/WRITE FLAG
POP PSW ;GET ERROR CODE
ANI 0E0H ;RETRY IF NOT TRACK ERROR
JNZ TRYAGN
;WAS A TRACK ERROR SO NEED TO RESEEK
PUSH D ;SAVE READ/WRITE INDICATOR
;FIGURE OUT THE DESIRED TRACK
LXI D,TRACK
LHLD DISKNO ;SELECTED DISK
DAD D ;POINT TO CORRECT TRACK INDICATOR
MOV A,M ;DESIRED TRACK
PUSH PSW ;SAVE IT
CALL HOME
POP PSW
MOV C,A
CALL SETTRK
POP D ;GET READ/WRITE INDICATOR
JMP TRYAGN
;
;
;
STEP: ;STEP HEAD OUT TOWARDS ZERO
;IF CARRY IS SET; ELSE
;STEP IN
; H,L POINT TO CORRECT TRACK INDICATOR WORD
PUSH PSW ;SAVE DIRECTION
STWAIT: IN 127 ;INPUT FDC STATUS
ANI 2 ;TEST STEP READY BIT
JZ STWAIT ;WAIT FOR STEP READY(MAX 10 MSEC)
POP PSW ;GET DIRECTION TO STEP
JC OUTX
INR M ;INCREMENT CURRENT TRACK BYTE
MVI A,4 ;SET DIRECTION = IN
DOSTEP:
OUT 127 ;SET DIRECTION BIT IN FDC
ORI 2
OUT 127 ;PULSE STEP BIT
ANI 0FDH
OUT 127 ;TURN OFF PULSE
RET
;
OUTX:
DCR M ;UPDATE TRACK BYTE
XRA A ;SET DIRECTION = OUT
JMP DOSTEP
;*************************************************;
;
; PERIPHERAL I/O DRIVERS
;
;*************************************************;
;
; CONSOLE STATUS
;
CONST: CALL CONS ;GET DEVICE STATUS
ORA A ;SET FLAGS
RZ ;ZERO IF NO CHAR AVAIL
MVI A,0FFH ;FF IF CHAR OK
RET
CONS: LDA IOBYT ;GET IOBYT
CALL IOCAL ;EXIT TO SELECTED ROUTINE
DW TTYST ;TELETYPE STATUS ROUTIE
DW CRTST ;CRT STATUS ROUTINE
DW RDRST ;READER STATUS ROUTINE
DW NULST ;NULL STATUS ROUTINE
;
; CONSOLE INPUT
;
CONIN: LDA IOBYT ;GET IOBYT
CALL IOCAL ;EXIT TO SELECTED ROUTINE
DW TTYIN ;TTY INPUT ROUTINE
DW CRTIN ;CRT INPUT ROUTINE
DW RDRIN ;READER INPUT ROUTINE
DW NULIN ;NULL INPUT ROUTINE
;
; CONSOLE OUTPUT
;
CONOUT: LDA IOBYT ;GET IOBYT
CALL IOCAL ;EXIT TO SELECTED ROUTINE
DW TTYOUT ;TTY OUTPUT ROUTINE
DW CRTOUT ;CRT OUTPUT ROUTINE
DW PRTOUT ;PRINTER OUTPUT ROUTINE
DW NULOUT ;NULL OUTPUT ROUTINE
;
; LISTING OUTPUT
;
LIST: LDA IOBYT ;GET IOBYT
RLC
RLC ;SHIFT BITS
CALL IOCAL ;EXIT TO SELECTED ROUTINE
DW TTYOUT ;TTY OUTPUT ROUTINE
DW CRTOUT ;CRT OUTPUT ROUTINE
DW PRTOUT ;PRINTER OUTPUT ROUTINE
DW NULOUT ;NULL OUTPUT ROUTINE
;
; PUNCH OUTPUT
;
PUNCH: LDA IOBYT ;GET IOBYT
RRC
RRC
RRC ;SHIFT BITS
RRC
CALL IOCAL ;EXIT TO SELECTED ROUTINE
DW TTYOUT ;TTY OUTPUT ROUTINE
DW CRTOUT ;CRT OUTPUT ROUTIE
DW PUNOUT ;PUNCH OUTPUT ROUTINE
DW NULOUT ;NULL OUTPUT ROUTINE
;
; READER INPUT
;
READER: LDA IOBYT ;GET IOBYT
RRC ;SHIFT BITS
RRC
CALL IOCAL ;EXIT TO SELECTED ROUTINE
DW TTYIN ;TTY INPUT ROUTINE
DW CRTIN ;CRT INPUT ROUTINE
DW RDRIN ;READER INPUT ROUTINE
DW NULIN ;NULL INPUT ROUTINE
;***************************************************;
;
; I/O DISPATCHER
;
;***************************************************;
IOCAL: RLC ;SHIFT BITS
ANI 06H ;MASK BITS
XTHL ;SAVE HL, GET TABLE ADDRESS
PUSH D ;SAVE DE
MOV E,A ;GET SELECTION VALUE IN A
MVI D,0
DAD D ;CALCULATE TABLE ENTRY ADDRESS
MOV A,M ;GET TABLE ENTRY
INX H
MOV H,M
MOV L,A ;INTO HL
POP D ;RESTORE DE
XTHL ;PUT EXIT ADDR ON STACK, RESTORE HL
RET ;EXIT TO ROUTINE
;****************************************************;
;
; PHYSICAL I/O ROUTINES
;
;***************************************************;
TTYST: IN TTYS
ANI TTYDA ;TEST FOR TTY DATA AVAIL.
RET ;EXIT WITH ZERO IF NOT AVAIL
TTYIN: CALL TTYST ;TEST FOR CHAR AVAIL
JZ TTYIN ;NOT YET, WAIT
IN TTYD ;GET DATA
ANI 7FH ;STRIP PARITY
RET
TTYOUT: IN TTYS ;GET TTY STATUS
ANI TTYBE ;TEST FOR XMIT BUFFER EMPTY
JZ TTYOUT ;WAIT TIL READY
MOV A,C ;GET OUTPUT CHAR
OUT TTYD ;OUTPUT CHAR
RET
CRTST: CALL TTYST
RET
CRTIN: CALL TTYIN ;CRT KEYBOARD = TTY
RET ;EXIT
CRTOUT: MOV A,C
PUSH PSW ;SAVE A
PUSH B
PUSH D
PUSH H ;SAVE REGS
CPI 0DH ;CARRIAGE RETURN?
JZ COCR ;YES
CPI 0AH ;LF?
JZ COLF ;YES
CPI 08H ;BACKSPACE?
JZ COBS
CPI 0CH ;FORM FEED?
JZ COFF ;YES
CPI 7FH ;RUBOUT?
JZ CO4 ;YES, IGNORE IT
JNC CO4 ;IGNORE CHARS>7F
CPI 20H ;OTHER CONTROL CHAR
JC CO4 ;YES, IGNORE
STA CHR
CALL DSWRT ;DISPLAY CHARACTER
CO4: POP H
POP D
POP B
POP PSW
RET
COCR: CALL CSRET
JMP CO4
COLF: CALL CSDWN
JMP CO4
COBS: CALL CSLFT
JMP CO4
COFF: CALL CSHOM
CALL DSERS
JMP CO4
DSINT: LXI H,VDMLC
SHLD DSPLOC
MVI A,0
STA CURVRT
STA CURHOR
CALL DSERS
CALL CSON
MVI A,00
OUT 0C8H ;SET UP VDM PORT
RET
DSERS: LHLD DSPLOC
LDA CURVRT
MOV C,A
D1001: MVI B,LINSIZ
MVI A,' '
D1002: MOV M,A
INX H
DCR B
JNZ D1002
INR C
MVI A,DSPSIZ
CMP C
JNZ D1001
CALL CSON
RET
DSWRT: LDA CHR
LHLD DSPLOC
MOV M,A
CALL CSRGT
IN 0FFH ;READ SWITCHES
ORA A ;TEST
RZ ;ZERO, RUN FULL SPEED
MOV H,A ;PUT SWITCHES IN H
MVI L,0
DLLP: DCX H ;CHECK HL
MOV A,H
ORA L
JNZ DLLP
RET
DSSCR: LXI H,VDMLC
MOV D,H
MOV E,L
LXI B,LINSIZ
DAD B
MVI B,DSPSIZ-1
D7003: MVI C,LINSIZ
D7004: MOV A,M
STAX D
INX H
INX D
DCR C
JNZ D7004
DCR B
JNZ D7003
MVI C,LINSIZ
MVI A,' '
D7005: STAX D
INX D
DCR C
JNZ D7005
RET
CSRGT: CALL CSOFF
LDA CURHOR
INR A
CPI LINSIZ
JC D2001
CALL CSRET
CALL CSDWN
RET
D2001: STA CURHOR
LHLD DSPLOC
INX H
SHLD DSPLOC
CALL CSON
RET
CSLFT: CALL CSOFF
LDA CURHOR
CPI 00
JNZ D3001
CALL CSON
RET
D3001: DCR A
STA CURHOR
LHLD DSPLOC
DCX H
SHLD DSPLOC
CALL CSON
RET
CSRET: CALL CSOFF
LHLD DSPLOC
LDA CURHOR
MOV B,A
MOV A,L
SUB B
MOV L,A
MOV A,H
SBI 0
MOV H,A
SHLD DSPLOC
XRA A
STA CURHOR
CALL CSON
RET
CSDWN: CALL CSOFF
LDA CURVRT
CPI DSPSIZ-1
JNZ D4001
CALL DSSCR
CALL CSON
RET
D4001: LDA CURVRT
INR A
STA CURVRT
LHLD DSPLOC
LXI B,LINSIZ
DAD B
SHLD DSPLOC
CALL CSON
RET
CSUP: CALL CSOFF
LDA CURVRT
CPI 00
JNZ D5001
CALL CSON
RET
D5001: LDA CURVRT
DCR A
STA CURVRT
LHLD DSPLOC
LXI B,LINSIZ
MOV A,L
SUB C
MOV L,A
MOV A,H
SBB B
MOV H,A
SHLD DSPLOC
CALL CSON
RET
CSHOM: CALL CSOFF
LXI H,VDMLC
SHLD DSPLOC
LXI H,0000
SHLD CURHOR
CALL CSON
RET
CSON: LHLD DSPLOC
MOV A,M
ORI 80H
MOV M,A
RET
CSOFF: LHLD DSPLOC
MOV A,M
ANI 7FH
MOV M,A
RET
DSPLOC EQU 0047H
CURHOR EQU 0049H
CURVRT EQU 004AH
CHR EQU 004BH
DSPSIZ EQU 16
LINSIZ EQU 64
VDMLC EQU 0CC00H
RDRST: CALL TTYST ;NOTE: READER IS TTY
RET
RDRIN: CALL TTYIN ;NOTE: READER IS TTY
NULST: MVI A,0FFH ;IF NULL DEVICE IS CONSOLE, CHAR
;IS ALWAYS READY
ORA A
RET
NULIN: MVI A,1AH ;NULL INPUT RETURNS EOF CHARS
RET
NULOUT: MOV A,C ;COPY C TO A
RET
PRTOUT: CALL TTYOUT ;NOE: PRINTER IS TTY
RET
PUNOUT: CALL TTYOUT ;NOTE: PUNCH IS TTY
RET
;**************************************************;
;
; END OF BIOS ROUTINES
;
;**************************************************;
END