WDOS Software

This commit is contained in:
Oliver Lehmann 1989-08-10 05:54:22 +00:00
parent 91662cfbbc
commit d5276a1452
4 changed files with 2912 additions and 0 deletions

View File

@ -0,0 +1,863 @@
;**************************************************************************
;**************************************************************************
;
; WDOS-BIOS - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
; Programm: bios.asm
;
; Bearbeiter : P. Hoge
; Datum : 24.1.89
; Version : 1.1
;
;**************************************************************************
;
; BIOS I/O INTERFACE
;
;**************************************************************************
;**************************************************************************
STACK: EQU 0030H
DATA: EQU 0040H
XXDATA: EQU 0050H
.EXTERNAL VECTOR_TABLE ;NEAR
.EXTERNAL WORD MEMORY_SIZE
.EXTERNAL WORD EQUIP_FLAG
.EXTERNAL WORD TIMER_LOW
.EXTERNAL WORD TIMER_HIGH
.EXTERNAL BYTE TIMER_OFL
.EXTERNAL BYTE STATUS_BYTE
.EXTERNAL WORD IO_ROM_INIT
.external byte KB_FLAG
.external byte KB_EXT
.EXTERNAL WORD KB_BUFFER
.EXTERNAL WORD BUFFER_HEAD
.EXTERNAL WORD BUFFER_TAIL
.EXTERNAL WORD BUFFER_START
.EXTERNAL WORD BUFFER_END
.EXTERNAL BYTE PRINT_TIM_OUT
.EXTERNAL TOS
.EXTERNAL DUMMY_RET ;NEAR
.EXTERNAL DISK_SETUP ;NEAR
.EXTERNAL byte BOOT_LOCN
.external byte DISK_BASE
.external byte reset
.external byte intin
.external byte clkin
.external byte date
.PUBLIC START
.PUBLIC DDS
.PUBLIC XPC_BYTE
.PUBLIC PRT_HEX
.PUBLIC XLAT_PR
.PUBLIC P_MSG
.PUBLIC PRT_SEG
.PUBLIC BOOT
.PUBLIC MEMSIZE
.PUBLIC EQUIP
.PUBLIC NMIINT
.PUBLIC CASSETTE
.PUBLIC TOFDAY
.PUBLIC TIMERINT
.PUBLIC PRSCREEN
X287 EQU 0F0H ;MATH PROCESSOR
;----------------------------------------
;TIMER DATA AREA
;----------------------------------------
COUNTS_SEC EQU 18
COUNTS_MIN EQU 1092
COUNTS_HOUR EQU 65543
COUNTS_DAY EQU 1573040 = 1800B0H
;----------------------------------------
;TEST
; x286 PROCESSOR TEST (REAL MODE)
;DESCRIPTION
; VERIFY FLAGS, REGISTERS
; AND CONDITIONAL JUMPS
;----------------------------------------
START: ;NEAR
CLI ;DISABLE INTERRUPTS
MOV AH,0D5H ;SET SF, CF, ZF, AND AF FLAGS ON
SAHF
JNC ERR01 ;GO TO ERR ROUTINE IF CF NOT SET
JNZ ERR01 ;GO TO ERR ROUTINE IF ZF NOT SET
JNP ERR01 ;GO TO ERR ROUTINE IF PF NOT SET
JNS ERR01 ;GO TO ERR ROUTINE IF SF NOT SET
LAHF ;LOAD FLAG IMAGE TO AH
MOV CL,5 ;LOAD CNT REG WITH SHIFT CNT
SHR AH,CL ;SHIFT AF INTO CARRY BIT POS
JNC ERR01 ;GO TO ERR ROUTINE IF AF NOT SET
MOV AL,40H ;SET THE OF FLAG ON
SHL AL,1 ;SETUP FOR TESTING
JNO ERR01 ;GO TO ERR ROUTINE IF OF NOT SET
XOR AH,AH ;SET AH = 0
SAHF ;CLEAR SF, CF, ZF, AND PF
JBE ERR01 ;GO TO ERR ROUTINE IF CF ON
;GO TO ERR ROUTINE IF ZF ON
JS ERR01 ;GO TO ERR ROUTINE IF SF ON
JP ERR01 ;GO TO ERR ROUTINE IF PF ON
LAHF ;LOAD FLAG IMAGE TO AH
MOV CL,5 ;LOAD CNT REG WITH SHIFT CNT
SHR AH,CL ;SHIFT 'AF' INTO CARRY BIT POS
JC ERR01 ;GO TO ERR ROUTINE IF ON
SHL AH,1 ;CHECK THAT 'OF' IS CLEAR
JO ERR01 ;GO TO ERR ROUTINE IF ON
;------ READ/WRITE THE X286 GENERAL AND SEGMENTATION REGISTERS
; WITH ALL ONE'S AND ZEROES'S.
MOV AX,0FFFFH ;SETUP ONE'S PATTERN IN AX
STC ;SET CARRY FLAG
JNC ERR01 ;GO IF NO CARRY
T1: MOV DS,AX ;WRITE PATTERN TO ALL REGS
MOV BX,DS
MOV ES,BX
MOV CX,ES
MOV SS,CX
MOV DX,SS
MOV SP,DX
MOV BP,SP
MOV SI,BP
MOV DI,SI
JNC T2
XOR AX,DI ;PATTERN MAKE IT THRU ALL REGS
JNZ ERR01 ;NO - GO TO ERR ROUTINE
CLC ;CLEAR CARRY FLAG
JMP SHORT T1
T2:
OR AX,DI ;ZERO PATTERN MAKE IT THRU?
JZ I1 ;YES - GO TO NEXT TEST
ERR01: HLT ;HALT SYSTEM
;----------------------------------------
; INIT BIOS
;----------------------------------------
;------ CLEAR RAM
I1: MOV CX,1024 ;CLEAR 2K
SUB AX,AX
MOV DI,AX
MOV DS,AX
I2: MOV [DI],AX ;CLEAR
INC DI
INC DI ;POINT TO NEXT LOCATION
LOOP I2
;------ SETUP STACK SEG AND SP
MOV SP,STACK ;SET REAL MODE STACK
MOV SS,SP
MOV SP, OFFSET TOS
SUB AL,AL ;RESET MATH PROCESSOR
OUT X287+1,AL
;------ SET UP THE INTERRUPT VECTORS
MOV CX,78H ;FILL ALL INTERRUPT LOCATIONS
SUB DI,DI ;FIRST INTERRUPT LOCATION
MOV ES,DI ;SET ES ALSO
I3: MOV AX,OFFSET DUMMY_RET ;MOVE ADDRESS OF INT OFFSET
STOSW
MOV AX,CS ;GET THE SEGMENT
STOSW
LOOP I3
;------ ESTABLISH BIOS INTERRUPT VECTORS
SUB DI,DI ;FIRST INTERRUPT LOCATION
PUSH CS
POP DS ;SET UP ADDRESS OF VECTOR TABLE
MOV SI,OFFSET VECTOR_TABLE
MOV CX,32
I4: MOVSW ;MOVE VECTOR TABLE TO RAM
INC DI
INC DI ;SKIP SEGMENT POINTER
LOOP I4
;------ ZERO RESERVED VECTORS
SUB AX,AX
MOV DS,AX
MOV DI,60H*4 ;INT 60 THRU 67 FILL WITH ZERO
MOV CX,14 ;CLEAR 14 WORDS
I5: MOV WORD PTR [DI],0
INC DI ;POINT TO NEXT LOCATION
INC DI
LOOP I5
CALL DDS
MOV MEMORY_SIZE,704 ;MEMORY SIZE SETZEN in KByte
MOV EQUIP_FLAG,4071H ;EQUIPMENT FLAG SETZEN
;80*25 VIDEO BW, 2 FD, 1 LP, 0 RS232
;kein 287
mov KB_EXT,10h ;extended Keyboard
; mov KB_FLAG,20h ;NUM-Lock aktiv
;------ SETUP KEYBOARD PARAMETERS
MOV SI, OFFSET KB_BUFFER ;SETUP KEYBOARD PARAMETERS
MOV BUFFER_HEAD,SI
MOV BUFFER_TAIL,SI
MOV BUFFER_START,SI
ADD SI,32 ;DEFAULT BUFFER OF 32 BYTES
MOV BUFFER_END,SI
STI ;ALLOW INTERRUPTS
;------ INIT VIDEO
MOV AX,0002H ;SET MODE 80*25 B/W
INT 10H ;SEND INIT TO B/W CARD
;------- SET TIME OF DAY
CALL SET_TOD
call DISK_SETUP
;------ ENABLE HARDWARE INTERRUPT IF MATH PROCESSOR (X287)
; SUB AX,AX ;CLEAR IO_ROM_INIT
; MOV IO_ROM_INIT,AX
; ESC 28,BX
; XOR AX,AX
; ESC 15,IO_ROM_INIT
; PUSHA ;TIME FOR 287 TO RESPOND
; POPA
; AND IO_ROM_INIT,01F3FH ;CLEAR UNUSED 287 BITS
; CMP IO_ROM_INIT,0033FH ;IS IF 287 INSTALLED?
; JNZ NO_287 ;GO IF MATH PROCESSOR IS NOT INSTALLED
; WAIT
; ESC 02FH,IO_ROM_INIT ;STORE THE STATUS WORD
; PUSHA ;TIME FOR 287 TO RESPOND
; POPA
; TEST IO_ROM_INIT,0D8BFH ;ALL BITS SHOULD BE OFF
; JNZ NO_287 ;GO IF NOT INSTALLED
; OR BYTE PTR EQUI_FLAG,02H ;SET 287 BIT ON
;NO_287:
; MOV IO_ROM_INIT,0
;------ LOAD SYSTEM
INT 19H ;GO TO BOOT LOADER
CLI
HLT ;HALT CPU
DDS ;PROC NEAR
push ax
mov ax,DATA
mov ds,ax
pop ax
ret
;---------------------------------------------------------------------
;CONVERT AND PRINT ASCII CODE
;
; AL MUST CONTAIN NUMBER TO BE CONVERTED.
;---------------------------------------------------------------------
XPC_BYTE ;PROC NEAR
PUSH AX ;SAVE FOR LOW NIBBLE DISPLAY
MOV CL,4 ;SHIFT COUNT
SHR AL,CL ;NIBBLE SWAP
CALL XLAT_PR ;DO THE HIGH NIBBLE DISPLAY
POP AX ;RECOVER THE NIBBLE
AND AL,0FH ;ISOLATE TO LOW NIBBLE
;FALL INTO LOW NIBBLE CONVERSION
XLAT_PR ;PROC NEAR ;CONVERT 00-0F TO ASCII CHARAKTER
ADD AL,090H ;ADD FIRST CONVERSION FACTOR
DAA ;ADJUST FOR NUMERIC AND ALPHA RANGE
ADC AL,040H ;ADD CONVERSION AND ADJUST LOW NIBBLE
DAA ;ADJUST HIGH NIBBLE TO ASCHI RANGE
PRT_HEX ;PROC NEAR
MOV AH,14 ;DISPLAY CHARAKTER IN AL
MOV BH,0
INT 10H ;CALL VIDIO_IO
RET
;----------------------------------------------------------------------
;THIS SUBROUTINE WILL PRINT A MESSAGE ON THE DISPLAY
;
;ENTRY REQUIREMENTS:
; SI = OFFSET(ADDRESS) OF MESSAGE BUFFER
;----------------------------------------------------------------------
P_MSG ;PROC NEAR
PM1: MOV AL,CS:[SI] ;PUT CHAR IN AL
INC SI ;POINT TO NEXT CHAR
PUSH AX ;SAVE PRINT CHAR
CALL PRT_HEX ;CALL VIDIO IO
POP AX ;RECOVER PRINT CHAR
CMP AL,10 ;WAS IT LINE FEED?
JNE PM1 ;NO, KEEP PRINTING STRING
RET
;-----------------------------------------------------------
; PRINT A SEGMENT VALUE TO LOOK LIKE A 21 BIT ADDRESS
; DX MUST CONTAIN SEGMENT VALUE TO BE PRINTED
;-----------------------------------------------------------
PRT_SEG ;PROC NEAR
MOV AL,DH ;GET MSB
CALL XPC_BYTE
MOV AL,DL ;LSB
CALL XPC_BYTE
MOV AL,'0' ;PRINT A '0'
CALL PRT_HEX
MOV AL,' ' ;SPACE
CALL PRT_HEX
RET
;--- INT 19 ----------------------------------------------------
;BOOT DOS
;---------------------------------------------------------------
MSGRUN: defb '(running)',0dh,0ah
MSGBER: defb 'Boot Error',0dh,0ah
BOOT: sti
mov al,cs:reset
or al,al
jz BOOT0 ;Ausschrift unterdruecken
mov SI,OFFSET MSGRUN
call P_MSG
BOOT0: sub ax,ax
mov cs:reset,al ;Reset verhindern
mov es,ax ;Segment 0
mov ah,2 ;Read Boot Sector
mov al,1 ;Count of Sectors
sub ch,ch ;Track 0
mov cl,al ;Sector 0
mov dh,ch ;Head 0
mov dl,ch ;FD Drive 0
mov bx,offset BOOT_LOCN
int 13h
jnc BOOT1 ;Fehler
mov ax,0201h ;Read Boot Sector HD
mov dl,80h ;HD Drive 0
int 13h
jnc BOOT2
mov si,offset MSGBER ;Fehler
call P_MSG
ret
BOOT1: mov al,es:BOOT_LOCN+24 ;Anzahl Sektoren/Track
mov es:BOOT_LOCN+2fh,al ;Wert im Urlader korrigieren
mov cs:DISK_BASE+4,al
BOOT2: jmp far 0:7c00h
;--- INT 12 ----------------------------------------------------
;MEMORY_SIZE_DETERMINE
;
;OUTPUT
; (AX) = NUMBER OF CONTICUOUS 1K BLOCKS OF MEMORY
;---------------------------------------------------------------
MEMSIZE ;PROC FAR
PUSH DS ;SAVE SEGMENT
CALL DDS ;ESTABLISH ADDRESSING
MOV AX,MEMORY_SIZE ;GET VALUE
POP DS ;RECOVER SEGMENT
IRET ;RETURN TO CALLER
;--- INT 11 ----------------------------------------------------
;EQUIPMENT DETERMINATION
; THIS ROUTINE ATTEMPTS TO DETERMINE WHAT OPTIONAL
; DEVICES ARE ATTACHED TO THE SYSTEM.
;OUTPUT
; (AX) IS SET, BIT SIGNIFICANT, TO INDICATE ATTACHED I/O
; BIT 1 = MATH COPROCESSOR
;---------------------------------------------------------------
EQUIP ;PROC FAR ;>>> ENTRY POINT FOR ORG 0F84DH
PUSH DS ;SAVE SEGMENT REGISTER
CALL DDS ;ESTABLISH ADDRESSING
MOV AX,EQUIP_FLAG ;GET THE CURRENT SETTINGS
POP DS ;RECOVER SEGMENT
IRET ;RETURN TO CALLER
;-- INT 2 -----------------------------------------------------
;NON-MASKABLE INTERRUPT ROUTINE (REAL MODE)
;SERVICE X287 INTERRUPTS
; THIS ROUTINE FIELDS X287 INTERRUPTS
;--------------------------------------------------------------
NMIINT ;PROC NEAR
PUSH AX
XOR AL,AL
OUT X287,AL ;REMOVE THE INT.REQUEST
POP AX
IRET
;- - INT 5 -----------------------------------------------------
; THIS LOGIC WILL BE INVOKED BY INTERRUPT 05H TO PRINT
; THE SCREEN. THE CURSOR POSITION AT THE TIME THIS ROUTINE
; IS INVOKED WILL BE SEVED AND RESTORED UPON COMPETION. THE
; ROUTINT IS INTENDED TO RUN WITH INTERRUPTS ENABLED.
; IF A SUBSEQUENT PRINT SGREEN KEY IS DEPRESSED DURING THE
; TIME THIS ROUTINE IS PRINTING IT WILL BE IGNORED.
; ADDRESS 50:0 CONTAINS THE STATUS OF THE PRINT SCREEN:
;
; 50:0 =0 EITHER PRINT SCREEN HAS NOT BEEN CALLED
; OR UPON RETURN FROM A CALL THIS INDI-
; CATES A SUCCESSFUL OPERATION.
;
; =1 PRINT SCREEN IS IN PROGRESS
;
; =255 ERROR ENCOUNTERED DURING PRINTING
;---------------------------------------------------------------
PRSCREEN ;PROC FAR
STI ;MUST RUN WITH INTERRUPTS ENABLED
PUSH DS ;MUST USE 50:0 FOR DATA ARE STORAGE
PUSH AX
PUSH BX
PUSH CX ;WILL USE THIS LATER FOR CURSOR LIMITS
PUSH DX ;WILL HOLD CURRENT CURSOR POSITION
MOV AX,XXDATA ;HEX 50
MOV DS,AX
CMP STATUS_BYTE,1 ;SEE IF PRINT ALREADY IN PROGRESS
JZ EXIT ;JUNP IF PRINT ALREADY IN PROGRESS
MOV STATUS_BYTE,1 ;INDICATE PRINT NOW IN PROGRESS
MOV AH,15 ;WILL REQUEST THE CURRENT SCEEN MODE
INT 10H ; [AL] = MODE
; [AH] = NUMBER COLUMNS/LINE
; [BH] = VISUAL PAGE
MOV CL,AH ;WILL MAKE USE OF [CX] REGISTER TO
MOV CH,25 ;CONTROL ROW & COLUMNS
CALL CRLF ;CARRIAGE RETURN LINE FEED ROUTINE
PUSH CX ;SAVE SCREEN BOUNDS
MOV AH,3 ;WILL NOW READ THE CURSOR
INT 10H ;AND PRESERVE THE POSITION
POP CX ;RECALL SCREEN BOUNDS
PUSH DX ;RECALL [BH]=VISUAL PAGE
XOR DX,DX ;WILL SET CURSOR POSITION TO [0,0]
;---------------------------------------------------------------------------
; THE LOOP FROM PRI10 TO THE INSTRUCTION PRIOR TO PRI20
; IS THE LOOP TO READ EACH CURSOR POSITION FROM THE SCREEN
; AND PRINT.
;---------------------------------------------------------------------------
PRI10: MOV AH,2 ;TO INDICATE CURSOR SET REQUEST
INT 10H ;NEW CURSOR POSITION ESTABLISHED
MOV AH,8 ;TO INDICATE READ CHARACTER
INT 10H ;CHARACTER NOW IN [AL]
OR AL,AL ;SEE IF VALID CHAR
JNZ PRI15 ;JUMP IF VALID CHAR
MOV AL,' ' ;MAKE A BLANK
PRI15:
PUSH DX ;SAVE CURSOR POSITION
XOR DX,DX ;INDICATE PRINTER 1
XOR AH,AH ;TO INDICATE PRINT CHAR IN [AL]
INT 17H ;PRINT THE CHARACTER
POP DX ;RACALL CURSOR POSITION
TEST AH,29H ;TEST FOR PRINTER ERROR
JNZ ERR10 ;JUMP IF ERROR DETECTED
INC DL ;ADVANCE TO NEXT COLUMN
CMP CL,DL ;SEE IF AT END OF LINE
JNZ PRI10 ;IF NOT PROCEED
XOR DL,DL ;BACK TO COLUMN 0
MOV AH,DL ;[AH]=0
PUSH DX ;SAVE NEW CURSOR POSITION
CALL CRLF ;LINE FEED CARRIAGE RETURN
POP DX ;RECALL CURSOR POSITION
INC DH ;ADVANCE TO NEXT LINE
CMP CH,DH ;FINISHED?
JNZ PRI10 ;IF NOT CONTINUE
PRI20: POP DX ;RECALL CURSOR POSITION
MOV AH,2 ;TO INDICATE CURSOR SET REQUEST
INT 10H ;CURSOR POSITION RESTORED
MOV STATUS_BYTE,0 ;INDICATE FINISHED
JMP SHORT EXIT ;EXIT THE ROUTINE
ERR10: POP DX ;GET CURSOR POSITION
MOV AH,2 ;TO REQUEST CURSOR SET
INT 10H ;CURSOR POSITION RESTORED
ERR20: MOV STATUS_BYTE,0FFH ;INDICATE ERROR
EXIT: POP DX ;RESTORE ALL THE REGISTERS USED
POP CX
POP BX
POP AX
POP DS
IRET
;------ CARRIAGE RETURN, LINE FEED SUBROUTINE
CRLF ;PROC NEAR
XOR DX,DX ;PRINTER 0
XOR AH,AH
MOV AL,0dh
INT 17H
XOR AH,AH
MOV AL,0ah
INT 17H ;SEND THE CARRIAGE RETURN
RET
;---------------------------------------------------------------
; THIS ROUTINE INITIALIZES THE TIMER DATA AREA IN THE
; ROM BIOS DATD AREA. IT IS CALLED BY THE POWER ON
; ROUTINES. IT CONVERTS HR:MIN:SEC TO TIMER
; TICS.
;---------------------------------------------------------------
;
;OUTPUT
; TIMER_LOW
; TIMER_HIGH
; TIMER_OFL
; ALL REGISTER UNCHANGEND
;--------------------------------------------------------------
COUNTS_DHOUR EQU 7 ;65543 - 65536
SET_TOD ;PROC NEAR
CLI
PUSH DS
CALL DDS
mov al,cs:date+0 ;Sekunden
sub ah,ah
MOV BL,COUNTS_SEC
MUL BL ;COUNT FOR SECONDS
MOV CX,AX
mov al,cs:date+1 ;Minuten
sub ah,ah
MOV BX,COUNTS_MIN
MUL BX ;COUNT FOR MINUTES
ADD AX,CX
MOV CX,AX
mov al,cs:date+2 ;Stunden
sub ah,ah
MOV DX,AX
MOV BL,COUNTS_DHOUR
MUL BL ;COUNT FOR HOURS
ADD AX,CX
ADC DX,0000H
MOV TIMER_HIGH,DX
MOV TIMER_LOW,AX
SUB AX,AX
MOV TIMER_OFL,AL ;RESET TIMER ROLL OVER INDICATOR
POP DS
STI
RET
;--- INT 1A -------------------------------------------------------------
;TIME_OF DAY
; THIS ROUTINE ALLOWS THE CLOCK TO BE SET/READ
;
;INPUT
; (AH) = 0 READ THE CURRENT CLOCK SETTING
; (AH) = 1 SET THE CURRENT CLOCK
; (AH) = 2 READ THE REAL TIME CLOCK
; (AH) = 3 SET THE REAL TIME CLOCK - nicht moeglich
; (AH) = 4 READ THE DATE FROM THE REAL TIME CLOCK
; (AH) = 5 SET THE DATE INTO THE REAL TIME CLOCK - nicht moeglich
; (AH) = 6 SET THE ALARM - nicht moeglich
; (AH) = 7 RESET THE ALARM - nicht moeglich
;
;NOTE: FOR AH = 6 - CY FLAG SET for not possible
;------------------------------------------------------------------------
TOFDAY ;PROC FAR
PUSH DS ;SAVE SEGMENT
CALL DDS ;SET DATA SEGMENT
OR AH,AH ;AH=0
JZ TD0 ;READ_TIME
DEC AH ;AH=1
JZ TD1 ;SET_TIME
DEC AH ;AH=2
JZ TD2 ;Read Real Time
DEC AH
DEC AH ;AH=4
JZ TD4
STC ;SET ERROR RETURN
POP DS
STI
RET FAR 2
TD0: MOV AL,TIMER_OFL
MOV TIMER_OFL,0 ;GET OVERFLOW, AND RESET THE FLAG
MOV CX,TIMER_HIGH
MOV DX,TIMER_LOW
POP DS ;RECOVER SEGMENT
IRET ;RETURN TO CALLER
TD1: MOV TIMER_LOW,DX
MOV TIMER_HIGH,CX ;SET THE TIME
MOV TIMER_OFL,0 ;RESET OVERFLOW
POP DS
IRET
TD2: mov al,cs:date+0 ;Sekunde
call CVT_BCD
mov dh,al
mov al,cs:date+1 ;Minute
inc al
call CVT_BCD
mov cl,al
mov al,cs:date+2 ;Stunde
call CVT_BCD
mov ch,al
pop ds
iret
TD4: mov al,cs:date+3 ;Tag
call CVT_BCD
mov dl,al
mov al,cs:date+4 ;Monat
inc al
call CVT_BCD
mov dh,al
mov al,cs:date+5 ;Jahr
call CVT_BCD
mov cl,al
mov ch,19h ;Jahrhundert
pop ds
iret
CVT_BCD ;PROC NEAR
aam
shl ah,1
shl ah,1
shl ah,1
shl ah,1
or al,ah
ret
;- - INT 8 -----------------------------------------------------
;THIS ROUTINE HANDLES THE TIMER INTERRUPTS
;THE INTERRUPT HANDLER MAINTAINS A COUNT OF INTERRUPTS SINCE
;POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.
;THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH
;INTERRUPT 1CH AT EVERY TIME TICK. THE USER MUST CODE A
;ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.
;---------------------------------------------------------------
TIMERINT ;PROC FAIR
mov cs:intin,0 ;weitere Ints erlauben
sti
push ds
push ax
push cx
call DDS
sub ax,ax
mov cx,1
inc cs:TISEC
mov al,cs:TISEC
cmp al,10 ;Korrektur bei 1 Sekunde ?
jnz TI1
mov cs:TISEC,ah
mov cx,9
inc cs:TIMIN
mov al,cs:TIMIN
cmp al,60 ;Korrektur bei 1 Minute ?
jnz TI1
mov cs:TIMIN,ah
mov cx,21
inc cs:TIHOUR
mov al,cs:TIHOUR
cmp al,60 ;Korrektur bei 1 Stunde ?
jnz TI1
mov cs:TIHOUR,ah
mov cx,44
TI1: INC TIMER_LOW ;INCREMENT TIME
JNZ TI2 ;TEST_DAY
INC TIMER_HIGH ;INCERMENT HIGH WORD OF TIME
TI2: CMP TIMER_HIGH,18H ;TEST FOR COUNT EQUALLING 24 HOURS
JNZ TI3
CMP TIMER_LOW,00B0H
JNZ TI3
SUB AX,AX ;TIMER HAS GONE 24 HOURS
MOV TIMER_HIGH,AX
MOV TIMER_LOW,AX
MOV TIMER_OFL,1
TI3: loop TI1
INT 1CH ;TRANSFER CONTROL TO A USER ROUTINE
mov cs:clkin+1,0 ;weiteren Clock-Int erlauben
pop cx
pop ax
pop ds
iret
TISEC: defb 0
TIMIN: defb 0
TIHOUR: defb 0
;--- INT 15 ----------------------------------------------------
; INPUT - CASSETTE I/O FUNCTIONS
; (AH) = 00
; (AH) = 01
; (AH) = 02
; (AH) = 03
; RETURNS FOR THESE FUNCTIONS ALWAYS (AH) = 86H, CF = 1)
; IF CASSETTE PORT NOT PRESENT
;---------------------------------------------------------------
; INPUT - UNUSED FUNCTIONS
; (AH) = 04 THROUGH 7F
; RETURNS FOR THESE FUNCTIONS ALWAYS (AH) = 86H, CF = 1)
;---------------------------------------------------------------
;Extensions
; (AH) = 80H DEVICE OPEN
; (BX) = DEVICE ID
; (CX) = PROCESS ID
;
; (AH) = 81H DEVICE CLOSE
; (BX) = DEVICE ID
; (CX) = PROCESS ID
;
; (AH) = 82H PROGRAM TERMINATION
; (BX) = DEVICE ID
;
; (AH) = 83H EVENT WAIT
; (AL) = 0 SET INTERVAL
; (ES:BX) POINTER TO A BYTE IN CALLERS MEMORY
; THAT WILL HAVE THE HIGH ORDER BIT SET
; AS SOON AS POSSIBLE AFTER THE INTERVAL
; EXPIRES.
; (CX,DX) NUMBER OF MICROSECONDS TO ELAPSE BEFORE
; POSTING.
; (AL) = 1 CANCEL
;
; (AH) = 84H JOYSTICK SUPPORT
; (DX) = 0 - READ THE CURRENT SWITCH SETTINGS
; RETURNS AL = SWITCH SETTINGS (BITS 7-4)
; (DX) = 1 - READ THE RESISTIVE INPUTS
; RETURNS AX = A(x) VALUE
; BX = A(y) VALUE
; CX = B(x) VALUE
; DX = B(y) VALUE
;
; (AH) = 85H SYSTEM REQUEST KEY PRESSED
; (AL) = 00 MAKE OF KEY
; (AL) = 01 BREAK OF KEY
; (AH) = 86H WAIT
; (CX,DX) NUMBER OF MICROSECONDS TO ELPASE BEFORE
; RETURN TO CALLER
; (AH) = 87H MOVE BLOCK
; (CX) NUMBER OF WORDS TO MOVE
; (ES:SI) POINTER TO DESCRIPTOR TABLE
; (AH) = 88H EXTENDENT MEMORY SIZE DETERMINE
; (AH) = 89H PROCESSOR TO VIRTUAL MODE
;
; (AH) = 90H DEVICE BUSY LOOP
; (AL) SEE TYPE CODE
;
; (AH) = 91H INTERRUPT COMPLETE FLAG SET
; (AL) TYPE CODE
; 00H -> 7FH
; SERIALLY REUSABLE DEVICES
; OPERATING SYSTEM MUST SERIALIZE
; ACCESS
; 80H -> BFH
; REENTRANT DEVICES;ES:BX IS
; USED TO DISTINGUISH DIFFERENT
; CALLS (MULTIPLE I/O CALLS ARE
; ALLOWED SIMULTANEUSLY)
; C0H -> FFH
; WAIT ONLY CALLS; THERE IS NO
; COMPLEMENTARY `POST` FOR THESE
; WAITS - - THESE ARE TIMEOUT
; ONLY. TIMES ARE FUNCTION NUMBER
; DEPENDENT
;
; TYPE DESCRIPTION TIMEOUT
;
; 00H = DISK YES
; 01H = DISKETTE YES
; 02H = KEYBOARD NO
; 80H = NETWORK NO
; ES:BX --> NCB
; FDH = DISKETTE MOTOR START YES
; FEH = PRINTER YES
;---------------------------------------------------------------
CASSETTE ;PROC FAR
STI
CMP AH,80H ;CHECK FOR RANGE
JB C1 ;RETURN IF 00-7FH
SUB AH,80H ;BASE ON 0
OR AH,AH
JZ DEV_OPEN ;DEVICE OPEN
DEC AH
JZ DEV_CLOSE ;DEVICE CLOSE
DEC AH
JZ PROG_TERM ;PROGRAM TERMINATION
DEC AH
JZ EVENT_WAIT ;EVENT WAIT
DEC AH
JZ JOY_STICK ;JOYSTICK BIOS
DEC AH
JZ SYS_REQ ;SYSTEM REQUEST KEY
DEC AH
JZ C1_A ;WAIT
DEC AH
JNZ C1_B
JMP BLOCKMOVE ;MOVE BLOCK
C1_A: JMP WAIT ;WAIT
C1_B: DEC AH
JNZ C1_C
JMP EXT_MEMORY ;GO GET THE EXTENDED MEMORY
C1_C: DEC AH ;CHECK FOR FUNCTION 89
JNZ C1_D
JMP SET_VMODE ;SWAP TO VIRTUAL MODE
C1_D: SUB AH,7 ;CHECK FOR FUNCTION 90
JNZ C1_E ;GO IF NOT
JMP DEVICE_BUSY
C1_E: DEC AH ;CHECK FOR FUNCTION 91
JNZ C1 ;GO IF NOT
JMP INT_COMPLETE
C1: MOV AH,86H ;SET BAD COMMAND
C2: STC ;SET CARRY FLAG ON
DEV_OPEN:
DEV_CLOSE:
PROG_TERM:
SYS_REQ:
C1_F:
RET FAR 2
EVENT_WAIT:
WAIT:
JMP SHORT C2 ;SET ERROR - keine CMOS-Uhr
JOY_STICK: ;nicht vorhanden
JMP SHORT C1 ;GO TO ERROR RETURN
BLOCKMOVE: ;nicht implementiert
MOV AH,1 ;Fehler setzen
JMP SHORT C2
EXT_MEMORY:
MOV AX,0 ;kein Speicher ueber 1 MByte
IRET ;RETURN TO USER
SET_VMODE: ;nicht implementiert
MOV AH,0FFH ;SET THE ERROR FLAG
JMP SHORT C2
;--- DEVICS BUSY AND INTERRUPT COMPLETE ------------------------
; THIS ROUTINE IS A TEMPORY HANDLER FOR DEVICE BUSY
; AND INTERRUPT COMPLETE
;
; INPUT
; SEE PROLOG
;---------------------------------------------------------------
DEVICE_BUSY ;PROC NEAR
CLC ;TURN CARRY OFF
JMP short C1_F ;RETURN WITH CARRY FLAG
INT_COMPLETE ;PROC NEAR
IRET ;RETURN
END

View File

@ -0,0 +1,321 @@
;**************************************************************************
;**************************************************************************
;
; WDOS-BIOS - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
; Programm: orgs.asm
;
; Bearbeiter : P. Hoge
; Datum : 24.1.89
; Version : 1.1
;
;**************************************************************************
;
; System-Einspruenge und Vereinbarungen
;
;**************************************************************************
;**************************************************************************
.EXTERNAL DISK_SETUP;NEAR
.EXTERNAL SEEK;NEAR
.EXTERNAL START;NEAR
.EXTERNAL NMIINT;NEAR
.EXTERNAL BOOT;NEAR
.EXTERNAL KBOARD;NEAR
.EXTERNAL KBINT;NEAR
.EXTERNAL DISK;NEAR
.EXTERNAL DISKINT;NEAR
.EXTERNAL PRINTER;NEAR
.EXTERNAL VIDEO;NEAR
.EXTERNAL MEMSIZE;NEAR
.EXTERNAL EQUIP;NEAR
.EXTERNAL CASSETTE;NEAR
.EXTERNAL TOFDAY;NEAR
.EXTERNAL TIMERINT;NEAR
.EXTERNAL RS232;NEAR
.EXTERNAL PRSCREEN;NEAR
.public connect
.public reset
.public intin
.public ttyin
.public clkin
.public diskin
.public intout
.public ttyout
.public lpout
.public diskout
.public hdtyp
.public date
.public ttybuf
.public lpbuf
.public diskrq
.PUBLIC VECTOR_TABLE
.PUBLIC DUMMY_RET
.PUBLIC FD_TBL
.PUBLIC FD1_TBL
.PUBLIC FD2_TBL
.PUBLIC DISK_BASE
ORG 0D000H
connect: ;---- Uebergabe-Bereich
reset: db -1 ;reset
intin: db 0 ;intin
db 0 ;dummy in
db 0
db 0
db 0
ttyin: db 9 ;vector Tastatur
db 0 ;instop
db 0 ;inbyte
db 0 ;dummy
clkin: db 8 ;vector Timer
db 0 ;instop
db 0 ;inbyte
db 0 ;dummy
diskin: db 0eh ;vector Disk
db 0 ;instop
db 0 ;inbyte
db 0 ;dummy
intout: db 0 ;intout
db 0 ;dummy
db 0 ;dummy out
db 0
db 0
db 0
ttyout: db 0 ;outstop TTY
db 0 ;dummy
dw 0 ;noutb
lpout: db 0 ;outstop LP
db 0 ;dummy
dw 0 ;noutb
diskout db 0 ;outstop Disk
db 0 ;dummy
dw 0 ;noutb
hdtyp: db 0 ;Harddisk 0 Typ
db 0 ;Harddisk 1 Typ
date: db 0 ;sec Date/Time
db 0 ;min
db 0 ;hour
db 0 ;day
db 0 ;mon
db 0 ;year
ttybuf: blkb 800h
lpbuf: blkb 100h
diskrq: blkb 10h
ORG 0E05BH
RESET: JMP START
ORG 0E2C3H ;----- NMI ENTRY
NMI_INT:
JMP NMIINT
;------ FIXED DISK PARAMETER TABLE
FD_TBL: ;Drive 5 MByte
DW 500 ;CYLINDERS
DB 2 ;HEADS
DW 0 ;nicht benutzt
DW -1 ;(WRITE PRE-COMPENSATION CYL)
DB 0 ;nicht benutzt
DB 0 ;(CONTROL BYTE)
DB 0,0,0 ;nicht benutzt
DW 0 ;(LANDING ZONE) nicht benutzt
DB 10 ;SECTORS/TRACK
DB 0 ;nicht benutzt
FD1_TBL: ;Drive 10 MByte
DW 500 ;CYLINDERS
DB 4 ;HEADS
DW 0 ;nicht benutzt
DW -1 ;(WRITE PRE-COMPENSATION CYL)
DB 0 ;nicht benutzt
DB 0 ;(CONTROL BYTE)
DB 0,0,0 ;nicht benutzt
DW 0 ;(LANDING ZONE) nicht benutzt
DB 10 ;SECTORS/TRACK
DB 0 ;nicht benutzt
FD2_TBL: ;Drive 20 MByte
DW 500 ;CYLINDERS
DB 8 ;HEADS
DW 0 ;nicht benutzt
DW -1 ;(WRITE PRE-COMPENSATION CYL)
DB 0 ;nicht benutzt
DB 0 ;(CONTROL BYTE)
DB 0,0,0 ;nicht benutzt
DW 0 ;(LANDING ZONE) nicht benutzt
DB 10 ;SECTORS/TRACK
DB 0 ;nicht benutzt
ORG 0E6F2H ;------ BOOT LOADER INTERRUPT
BOOTSTRAP:
JMP BOOT
ORG 0E739H ;----- RS232
RS232_IO:
JMP RS232
ORG 0E82EH ;------ KEYBOARD
KBOARD_IO:
JMP KBOARD
ORG 0E987H ;------ KEYBOARD INT
KB_INT:
JMP KBINT
ORG 0EC59H ;------ DISKETTE I/O
DKETTE_IO:
JMP DISK
ORG 0EF57H ;------ DISKETTE INT
DISK_INT:
JMP DISKINT
ORG 0EFC7H ;------ DISK BASE
DISK_BASE:
DB 0
DB 0
DB 0
DB 2 ;512 Byte/Sector
DB 9 ;letzter Sector
DB 1BH ;GPL
DB 0FFH
DB 54H ;GPL fuer Format
DB 0F6H ;Datenbyte fuer Format
DB 0
DB 0
ORG 0EFD2H ;------ PRINTER IO
PRINTR_IO:
JMP PRINTER
ORG 0F045H ;------ VIDEO IO
.EXTERNAL SET_MODE;NEAR
.EXTERNAL SET_CTYPE;NEAR
.EXTERNAL SET_CPOS;NEAR
.EXTERNAL READ_CURSOR;NEAR
.EXTERNAL READ_LPEN;NEAR
.EXTERNAL ACT_DISP_PAGE;NEAR
.EXTERNAL SCROLL_UP;NEAR
.EXTERNAL SCROLL_DOWN;NEAR
.EXTERNAL READ_AC_CURRENT;NEAR
.EXTERNAL WRITE_AC_CURRENT;NEAR
.EXTERNAL WRITE_C_CURRENT;NEAR
.EXTERNAL SET_COLOR;NEAR
.EXTERNAL WRITE_DOT;NEAR
.EXTERNAL READ_DOT;NEAR
.EXTERNAL WRITE_TTY;NEAR
.EXTERNAL VIDEO_STATE;NEAR
M1: DW SET_MODE ;TABLE OF ROUTINES WITHIN VIDEO I/O
DW SET_CTYPE
DW SET_CPOS
DW READ_CURSOR
DW READ_LPEN
DW ACT_DISP_PAGE
DW SCROLL_UP
DW SCROLL_DOWN
DW READ_AC_CURRENT
DW WRITE_AC_CURRENT
DW WRITE_C_CURRENT
DW SET_COLOR
DW WRITE_DOT
DW READ_DOT
DW WRITE_TTY
DW VIDEO_STATE
M1L EQU $-M1
ORG 0F065H
VIDEO_IO:
JMP VIDEO
ORG 0F0A4H
VIDEO_PARMS:
DB 0
ORG 0F841H ;------ MEMORY SIZE
MEMSIZE_D:
JMP MEMSIZE
ORG 0F84DH ;------ EQUIPMENT DETERMINE
EQUIPMENT:
JMP EQUIP
ORG 0F859H ;------ CASSETTE (NO BIOS SUPPORT)
CASSET_IO:
JMP CASSETTE
ORG 0FE6EH ;------ TIME OF DAY
T_OF_DAY:
JMP TOFDAY
ORG 0FEA5H ;------ TIMER INTERRUPT
TIMER_INT:
JMP TIMERINT
ORG 0FEE3H ;------ VECTOR TABLE
VECTOR_TABLE:
DW DUMMY_RET ;INT 0
DW DUMMY_RET ;INT 1
DW NMI_INT ;INT 2
DW DUMMY_RET ;INT 3
DW DUMMY_RET ;INT 4
DW PR_SCREEN ;INT 5
DW DUMMY_RET ;INT 6
DW DUMMY_RET ;INT 7
DW TIMER_INT ;INT 8
DW KB_INT ;INT 9
DW DUMMY_RET ;INT A
DW DUMMY_RET ;INT B
DW DUMMY_RET ;INT C
DW DUMMY_RET ;INT D
DW DISK_INT ;INT E
DW DUMMY_RET ;INT F
;------ SOFTWARE INTERRUPTS
DW VIDEO_IO ;INT 10H
DW EQUIPMENT ;INT 11H
DW MEMSIZE_D ;INT 12H
DW DKETTE_IO ;INT 13H
DW RS232_IO ;INT 14H
DW CASSET_IO ;INT 15H
DW KBOARD_IO ;INT 16H
DW PRINTR_IO ;INT 17H
DW DUMMY_RET ;INT 18H
DW BOOTSTRAP ;INT 19H
DW T_OF_DAY ;INT 1AH
DW DUMMY_RET ;INT 1BH -- KEYBOARD BREAK ADDR
DW DUMMY_RET ;INT 1CH -- TIMER BREAK ADDR
DW VIDEO_PARMS ;INT 1DH -- VIDEO PARAMETERS
DW DISK_BASE ;INT 1EH -- DISK PARMS
DW 0 ;INT 1FH -- POINTER TO VIDEO EXT
ORG 0FF53H ;------ DUMMY INT HANDLER
DUMMY_RET:
IRET
ORG 0FF54H ;------ PRINT SCREEN
PR_SCREEN:
JMP PRSCREEN
ORG 0FFF0H ;------ POWER ON RESET
P_O_R: DB 0EAH ;HARD CODE JUMP
DW RESET ;OFFSET
DW 0F000H ;SEGMENT
db '01/10/88' ;RELEASE MARKER
;bei 01/10/84 (Original) wird Harddisk-
;Treiber im Disketten-BIOS benutzt
ORG 0FFFEH
DB 0FCH ;THIS PC'S ID
END

View File

@ -0,0 +1,864 @@
;**************************************************************************
;**************************************************************************
;
; WDOS-BIOS - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
;
; Programm: termp8.asm
;
; Bearbeiter : P. Hoge
; Datum : 24.1.89
; Version : 1.1
;
;**************************************************************************
;
; normales P8000-Terminal (ADM31) ohne Bildwiederholspeicher
;
;**************************************************************************
;**************************************************************************
.EXTERNAL DDS ;NEAR
.EXTERNAL BYTE KB_FLAG
.EXTERNAL WORD BUFFER_START
.EXTERNAL WORD BUFFER_END
.EXTERNAL WORD BUFFER_HEAD
.EXTERNAL WORD BUFFER_TAIL
.EXTERNAL WORD CURSOR_POSN
.EXTERNAL WORD CURSOR_MODE
.EXTERNAL BYTE CRT_MODE
.EXTERNAL WORD CRT_COLS
.EXTERNAL WORD CRT_LEN
.external byte intin
.external byte intout
.external byte ttyin
.external byte ttyout
.external byte lpout
.external byte ttybuf
.external byte lpbuf
.PUBLIC PUTA
.PUBLIC KBOARD
.PUBLIC KBINT
.PUBLIC VIDEO
.PUBLIC PRINTER
.PUBLIC RS232
;---- INT 16 ------------------------------------------------------------------
;KEYBOARD I/O
; THESE ROUTINES PROVIDE KEYBOARD SUPPORT
;INPUT
; (AH)=0 READ THE NEXT ASCII CHARACTER STRUCK FROM THE KEYBOARD
; RETURN THE RESULT IN (AL), SCAN CODE IN (AH)
; (AH)=1 SET THE Z FLAG TO INDICATE IF AN ASCII CHARACTER IS AVAILABLE
; (ZF)=1 -- NO CODE AVAILABLE
; (ZF)=0 -- CODE IS AVAILABLE
; IF ZF = 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS
; IN AX, AND THE ENTRY REMAINS IN THE BUFFER
; (AH)=2 RETURN THE CURRENT SHIFT STATUS IN AL REGISTER
; THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE
; THE EQUATES FOR KB_FLAG
;OUTPUT
; AS NOTED ABOVE, ONLY AX AND FLAGS CHANGED
; ALL REGISTERS RETAINED
;------------------------------------------------------------------------------
KBOARD ;PROC FAR ;>>> ENTRY POINT FOR ORG 0E82EH
STI ;INTERRUPTS BACK ON
PUSH DS ;SAVE CURRENT DS
PUSH BX ;SAVE BX TEMPORARILY
CALL DDS ;ESTABLISH POINTER TO DATA REGION
call CURSOR_OUT
OR AH,AH ;AH=0
JZ K0 ;ASCII_READ
DEC AH ;AH=1
JZ K1 ;ASCII_STATUS
DEC AH ;AH=2
JZ K2 ;SHIFT_STATUS
POP BX ;RECOVER REGISTER
POP DS
IRET ;INVALID COMMAND
;------ READ THE KEY TO FIGURE OUT WHAT TO DO
K0:
; MOV BX,BUFFER_HEAD ;GET POINTER TO HEAD OF BUFFER
; CMP BX,BUFFER_TAIL ;TEST END OF BUFFER
; JNE K0B ;IF ANYTHING IN BUFFER DONT DO INTERRUPT
; MOV AX,09002H ;MOVE IN WAIT CODE & TYPE
; INT 15H ;PERFORM OTHER FUNCTION
K0A: ;ASCII READ
STI ;INTERRUPTS BACK ON DURING LOOP
NOP ;ALLOW AN INTERRUPT TO OCCUR
K0B: CLI ;INTERRUPTS BACK OFF
MOV BX,BUFFER_HEAD ;GET POINTER TO HEAD OF BUFFER
CMP BX,BUFFER_TAIL ;TEST END OF BUFFER
JZ K0A ;LOOP UNTIL SOMETHING IN BUFFER
MOV AX,[BX] ;GET SCAN CODE AND ASCII CODE
CALL K3 ;MOVE POINTER TO NEXT POSITION
MOV BUFFER_HEAD,BX ;STORE VALUE IN VARIABLE
POP BX ;RECOVER REGISTER
POP DS ;RECOVER SEGMENT/
IRET ;RETURN TO CALLER
;------ ASCII STATUS
K1: CLI ;INTERRUPTS OFF
MOV BX,BUFFER_HEAD ;GET HEAD POINTER
CMP BX,BUFFER_TAIL ;IF EQUAL (Z=1) THEN NOTHING THERE
MOV AX,[BX]
POP BX ;RECOVER REGISTER
POP DS ;RECOVER SEGMENT
STI ;INTERRUPTS BACK ON
RET FAR 2 ;THROW AWAY FLAGS
;------ SHIFT STATUS
K2: MOV AL,KB_FLAG ;GET THE SHIFT STATUS FLAGS
POP BX ;RECOVER REGISTER
POP DS ;RECOVER REGISTERS
IRET ;RETURN TO CALLER
;------ INCREMENT A BUFFER POINTER
K3 ;PROC NEAR
INC BX ;MOVE TO NEXT WORD IN LIST
INC BX
CMP BX,BUFFER_END ;AT END OF BUFFER?
JNE K3A ;NO, CONTINUE
MOV BX,BUFFER_START ;YES, RESET TO BUFFER BEGINNING
K3A: RET
;------ KEYBOARD INTERRUPT ROUTINE
KBINT ;PROC FAR
STI
PUSH AX
PUSH BX
PUSH SI
PUSH DS
CALL DDS ;SET UP ADDRESSING
mov cs:intin,0 ;naechsten Int freigeben
mov al,cs:ttyin+2
and al,7fh
xor ah,ah
;------ PUT CHARACTER INTO BUFFER
MOV BX,BUFFER_TAIL ;GET THE END POINTER TO THE BUFFER
MOV SI,BX ;SAVE THE VALUE
CALL K3 ;ADVANCE THE TAIL
CMP BX,BUFFER_HEAD ;HAS THE BUFFER WRAPPED AROUND
JE K4B ;BUFFER_FULL_BEEP
MOV [SI],AX ;STORE THE VALUE
MOV BUFFER_TAIL,BX ;MOVE THE POINTER UP
K4A: POP DS
POP SI
POP BX
POP AX
mov cs:ttyin+1,0
IRET ;RETURN, INTERRUPTS BACK ON WITH FLAG CHANGE
K4B: mov al,07h ;BUFFER FULL BEEP
call PUTA
JMP SHORT K4A
;--- INT 10 --------------------------------------------------------------
;VIDEO_IO
; THESE ROUTINES PROVIDE THE CRT INTERFACE
; THE FOLLOWING FUNCTIONS ARE PROVIDED:
; (AH)=0 SET MODE - nur Mode 7 moeglich
; (AH)=1 SET CURSOR TYPE - nicht moeglich
; (AH)=2 SET CURSOR POSITION
; (AH)=3 READ CURSOR POSITION
; (AH)=4 READ LIGHT PEN POSITION - nicht moeglich
; (AH)=5 SELECT ACTIVE DISPLAY PAGE - nur Page 0
; (AH)=6 SCROLL ACTIVE PAGE UP - nur Loeschen (al = 0)
; (AH)=7 SCROLL ACTIVE PAGE DOWN - nur Loeschen (al = 0)
;CHARAKTER HANDLING ROUTINES
; (AH)=8 READ ATTRIBUTE/CHARAKTER AT CURRENT CURSOR POSITION
; (AH)=9 WRITE ATTRIBUTE/CHARAKTER AT CURRENT CURSOR POSITION
; (AH)=10 WRITE CHARACTER ONLY AT CURRENT CURSOR POSITION
;GRAPHICS INTERFACE
; (AH)=11 SET COLOR PALETTE - nicht moeglich
; (AH)=12 WRITE DOT - nicht moeglich
; (AH)=13 READ DOT - nicht moeglich
;ASCII TELETYPE ROUTINE FOR OUTPUT
; (AH)=14 WRITE TELETYPE TO ACTIVE PAGE
; (AH)=15 CURRENT VIDEO STATE
; (AH)=16 RESERVED
; (AH)=17 RESERVED
; (AH)=18 RESERVED
; (AH)=19 WRITE STRING
; (AL) = 0
; BL - ATTRIBUTE
; STRING IS [CHAR,CHAR, ... ,CHAR]
; CURSOR NOT MOVED
; (AL) = 1
; BL - ATTRIBUTE
; STRING IS [CHAR,CHAR, ... ,CHAR]
; CURSOR IS MOVED
; (AL) = 2
; STRING IS [CHAR,ATTR,CHAR,ATTR, ... ,CHAR,ATTR]
; CURSOR IS NOT MOVED
; (AL) = 3
; STRING IS [CHAR,ATTR,CHAR,ATTR, ... ,CHAR,ATTR]
; CURSOR IS MOVED
; NOTE: CARRIAGE RETURN, LINE FEED, BACKSPACE, AND BELL ARE
; TREATED AS COMMANDS RATHER THEN PRINTABLE CHARACTERS.
;
; SS,SP,ES,DS,DX,CX,BX,SI,DI,BP PRESERVED DURING CALL
; ALL OTHERS DESTROYED.
;-------------------------------------------------------------------------
.PUBLIC SET_MODE
.PUBLIC SET_CTYPE
.PUBLIC SET_CPOS
.PUBLIC READ_CURSOR
.PUBLIC READ_LPEN
.PUBLIC ACT_DISP_PAGE
.PUBLIC SCROLL_UP
.PUBLIC SCROLL_DOWN
.PUBLIC READ_AC_CURRENT
.PUBLIC WRITE_AC_CURRENT
.PUBLIC WRITE_C_CURRENT
.PUBLIC SET_COLOR
.PUBLIC WRITE_DOT
.PUBLIC READ_DOT
.PUBLIC WRITE_TTY
.PUBLIC VIDEO_STATE
V1 DW SET_MODE
DW SET_CTYPE
DW SET_CPOS
DW READ_CURSOR
DW READ_LPEN
DW ACT_DISP_PAGE
DW SCROLL_UP
DW SCROLL_DOWN
DW READ_AC_CURRENT
DW WRITE_AC_CURRENT
DW WRITE_C_CURRENT
DW SET_COLOR
DW WRITE_DOT
DW READ_DOT
DW WRITE_TTY
DW VIDEO_STATE
DW VIDEO_RETURN ;Reserved
DW VIDEO_RETURN ;Reserved
DW VIDEO_RETURN ;Reserved
DW WRITE_STRING ;CASE 19h, Write string
V1L EQU $-V1
VIDEO ;PROC NEAR ;ENTRY POINT FOR ORG 0F065H
STI ;INTERRUPTS BACK ON
CLD ;SET DIRECTION FORWARD
PUSH ES
PUSH DS ;SAVE SEGMENT REGISTERS
PUSH DX
PUSH CX
PUSH BX
PUSH SI
PUSH DI
PUSH BP
PUSH AX ;SAVE AX VALUE
MOV AL,AH ;GET INTO LOW BYTE
XOR AH,AH ;ZERO TO HIGH BYTE
SAL AX,1 ;*2 FOR TABLE LOOKUP
MOV SI,AX ;PUT INTO SI FOR BRANCH
CMP AX,V1L ;TEST FOR WITHIN RANGE
JB V2 ;BRANCH AROUND BRANCH
POP AX ;THROW AWAY THE PARAMETER
JMP short VIDEO_RETURN
V2: CALL DDS
POP AX ;RECOVER VALUE
CMP AH,13H ;TEST FOR WRITE STRING OP
JNE V3
PUSH BP ;IF IT'S WRITE STRING THEN GET THE
MOV BP,SP ;STRINGS SEGMENT,SINCE IT GET CLOBBERED
MOV ES,[BP]+10H ;MOV ES,[BP].ES_POS ????
POP BP
V3: JMP CS:[SI]+V1
;---------------------------------------------------------------
;LIGHT PEN Implementation nicht moeglich
;ACT_DISP_PAGE
;SET_COLOR
;READ DOT -- WRITE DOT
;---------------------------------------------------------------
READ_LPEN: ;AH = 0 = nicht verfuegbar
mov ah,0 ;nicht verfuegbar
jmp short VIDEO_RETURN
READ_DOT: ;AL = DOT VALUE
sub al,al
ACT_DISP_PAGE:
SET_COLOR:
WRITE_DOT:
;------ NORMAL RETURN FROM ALL VIDEO RETURNS
VIDEO_RETURN:
POP BP
POP DI
POP SI
POP BX
POP CX
POP DX
POP DS
POP ES
IRET
;-----------------------------------------------------
;SET_MODE
;Mode setzen und Bildschirm loeschen
;-----------------------------------------------------
CURSOR_TTY:
defw -1
SET_MODE ;PROC NEAR
mov CRT_MODE,7
mov CRT_COLS,80
mov CRT_LEN,2*25*80
call CLR_TTY ;Bildschirm loeschen
mov CURSOR_POSN,0 ;Cursor Home setzen
jmp short VIDEO_RETURN
CLR_TTY:
;------ ADM 31 Escape-Folge Bildschirm loeschen
push ax
mov al,1bh
call PUTA
mov al,'*'
call PUTA
mov ax,-1
mov cs:CURSOR_TTY,ax ;Cursor synchronisieren
call CURSOR_OUT
pop ax
ret
;---------------------------------------------------------
;SET_CTYPE
;---------------------------------------------------------
SET_CTYPE ;PROC NEAR ;**** nicht moeglich
mov CURSOR_MODE,cx
jmp short VIDEO_RETURN
;---------------------------------------------------------------
;SET_CPOS
; THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
; NEW X-Y VALUES PASSED
;INPUT
; DX - ROW, COLUMN OF NEW CURSOR
;OUTPUT
; CURSOR IS SET
;---------------------------------------------------------------
SET_CPOS ;PROC NEAR ;nur 1 Page moeglich
mov CURSOR_POSN,dx
jmp short VIDEO_RETURN
;---------------------------------------------------------------
;READ_CURSOR
; THIS ROUTINE READS THE CURRENT CURSOR VALUE
;OUTPUT
; DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
; CX - CURRENT CURSOR MODE
;---------------------------------------------------------------
READ_CURSOR ;PROC NEAR ;nur 1 Page
mov dx,CURSOR_POSN
mov cx,CURSOR_MODE
POP BP
POP DI
POP SI
POP BX
POP AX ;DISCARD SAVED CX AND DX
POP AX
POP DS
POP ES
IRET
;---------------------------------------------------------------
;VIDEO_STATE
; RETURNS THE CURRENT VIDEO STATE IN AX
; AH = NUMBER OF COLUMNS ON THE SCREEN
; AL = CURRENT VIDEO MODE
; BH = CURRENT ACTIVE PAGE
;---------------------------------------------------------------
VIDEO_STATE ;PROC NEAR
mov ah,80 ;GET NUMBER OF COLUMNS
mov al,7 ;CURRENT MODE
mov bh,0 ;GET CURRENT ACTIVE PAGE
POP BP
POP DI
POP SI
POP CX ;DISCARD SAVED BX
POP CX
POP DX
POP DS
POP ES
IRET
;---------------------------------------------------------------
;SCROLL_UP / SCROLL_DOWN
; realisiert nur Bildschirmloeschen
;INPUT
; (AL) = 0 = Loeschen Bildschirm
;---------------------------------------------------------------
SCROLL_UP ;PROC NEAR
SCROLL_DOWN ;PROC NEAR
or al,al ;Loeschen
jnz SUP0
call CLR_TTY
jmp VIDEO_RETURN
SUP0: push ax ;Rollen durch LF realisieren
mov ax,0e0ah ;Write TTY: LF ausgeben
int 10h
pop ax
dec al
jnz SUP0
jmp VIDEO_RETURN
;---------------------------------------------------------------
;READ_AC_CURRENT
; nicht moeglich, Return mit 0720h
;OUTPUT
; (AL) = 20h (Space)
; (AH) = 07h (Attribut)
;----------------------------------------------------------------
READ_AC_CURRENT ;PROC NEAR
mov ax,0720h
JMP VIDEO_RETURN
;---------------------------------------------------------------
;WRITE_AC_CURRENT
; nicht moeglich, Funktion wie WRITE_C_CURRENT
;---------------------------------------------------------------
WRITE_AC_CURRENT ;PROC NEAR
;---------------------------------------------------------------
;WRITE_C_CURRENT
; THIS ROUTINE WRITES THE CHARACTER AT
; THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
;INPUT
; (CX) = COUNT OF CHARACTERS TO WRITE
; (AL) = CHAR TO WRITE
; (DS) = DATA SEGMENT
;OUTPUT
; NONE
;---------------------------------------------------------------
WRITE_C_CURRENT ;PROC NEAR
call CURSOR_OUT
WCC0: ;WRITE_LOOP
inc word ptr cs:CURSOR_TTY
cmp al,07h ;Diese Zeichen haben hier
jz WCC1 ;keine Sonderbedeutung
cmp al,08h
jz WCC1
cmp al,0ah
jz WCC1
cmp al,0dh
jnz WCC2
WCC1: mov al,20h
WCC2: call PUTA
LOOP WCC0 ;AS MANY TIMES AS REQUESTED
JMP VIDEO_RETURN
;WRITE_AC_CURRENT
;---------------------------------------------------------------
;WRITE_TTY
; THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE.
;ENTRY --
; (AL) = CHARACTER TO BE WRITTEN
; NOTE THAT BACK SPACE, CR, BELL AND LINE FEED ARE HANDLED
; AS COMMANDS RATHER THAN AS DISPLAYABLE GRAPHICS
;EXIT --
; ALL REGISTERS SAVED
;---------------------------------------------------------------
WRITE_TTY ;PROC NEAR
call CURSOR_OUT
call PUTA
mov dx,CURSOR_POSN ;READ CURSOR POSITION
;------ DX NOW HAS THE CURRENT CURSOR POSITION
CMP AL,8 ;IS IT A BACKSPACE
JE U5 ;BACK_SPACE
CMP AL,0DH ;IS IT CARRIAGE RETURN
JE U6 ;CAR_RET
CMP AL,0AH ;IS IT A LINE FEED
JE U7 ;LINE_FEED
CMP AL,07H ;IS IT A BELL
JE U4 ;Return
;------ POSITION THE CURSOR FOR NEXT CHAR
INC DL
CMP DL,80 ;TEST FOR COLUMN OVERFLOW
JNZ U3 ;SET_CURSOR
MOV DL,0 ;COLUMN FOR CURSOR
CMP DH,24
JNZ U2 ;SET_CURSOR_INC
;------ SCROLL REQUIRED
U1: jmp short U3
U2: inc dh ;SET-CURSOR-INC NEXT ROW
U3: mov CURSOR_POSN,dx ;SET-CURSOR
mov cs:CURSOR_TTY,dx
U4: JMP VIDEO_RETURN
;------ BACK SPACE FOUND
U5: CMP DL,0 ;ALREADY AT END OF LINE
JE U3 ;SET_CURSOR
DEC DL ;NO -- JUST MOVE IT BACK
JMP short U3 ;SET_CURSOR
;------ CARRIAGE RETURN FOUND
U6: MOV DL,0 ;MOVE TO FIRST COLUMN
JMP short U3 ;SET_CURSOR
;------ LINE FEED FOUND
U7: CMP DH,24 ;BOTTOM OF SCREEN
JNE U2 ;YES, SCROLL THE SCREEN
JMP short U1 ;NO, JUST SET THE CURSOR
;---------------------------------------------------------------
;WRITE STRING
; This routine writes a string of characters to the crt.
;INPUT
; (AL) = WRITE STRING COMMAND 0 - 3
; (CX) = COUNT OF CHARACTERS TO WRITE. IF CX == 0 THEN RETURN
; (DX) = CURSOR POSITION
; (BL) = ATTRIBUTE OF CHAR TO WRITE IF AL == 0 | AL == 1
; (ES) = STRING SEGMENT
; (BP) = STRING OFFSET
;OUTPUT
; N/A
;----------------------------------------------------------------
WRITE_STRING ;PROC NEAR
CMP AL,04 ;TEST FOR INVALID WRITE STRING OPTION
JB W0 ;IF OPTION INVALID THEN RETURN
JMP DONE
W0: OR CX,CX ;TEST FOR ZERO LENGTH STRING
JNZ W1
JMP short DONE ;IF ZERO LENGTH STRING THEN RETURN
W1: MOV SI,CURSOR_POSN
PUSH SI ;SAVE CURRENT CURSOR POSITION
mov CURSOR_POSN,dx ;SET NEW CURSOR POSITION
WRITE_CHAR:
PUSH CX
PUSH BX
PUSH AX
PUSH ES
XCHG AH,AL ;PUT THE WRITE STRING OPTION INTO AH
MOV AL,ES:[BP] ;GET CHARACTER FROM INPUT STRING
INC BP ;BUMP POINTER TO CHARACTER
;------ TEST FOR SPECIAL CHARACTER'S
CMP AL,8 ;IS IT A BACKSPACE
JE DO_TTY ;BACK_SPACE
CMP AL,0DH ;IS IT CARRIAGE RETURN
JE DO_TTY ;CAR_RET
CMP AL,0AH ;IS IT A LINE FEED
JE DO_TTY ;LINE_FEED
CMP AL,07H ;IS IT A BELL
JNE GET_ATTRIBUTE ;IF NOT THEN DO WRITE CHARACTER
DO_TTY:
MOV AH,14 ;WRITE TTY CHARACTER TO THE CRT
INT 10H
MOV DX,CURSOR_POSN ;GET CURRENT CURSOR POSITION
POP ES
POP AX ;RESTORE REGISTERS
POP BX
POP CX
JMP short ROWS_SET
GET_ATTRIBUTE:
MOV CX,1 ;SET CHARACTER WRITE AMOUNT TO ONE
CMP AH,2 ;IS THE ATTRIBUTE IN THE STRING
JB GOT_IT ;IF NOT THEN JUMP
MOV BL,ES:[BP] ;ELSE GET IT
INC BP ;BUMP STRING POINTER
GOT_IT: MOV AH,09 ;WRITE CHARACTER TO THE CRT
INT 10H
POP ES
POP AX ;RESTORE REGISTERS
POP BX
POP CX
INC DL ;INCREMENT COLUMN COUNTER
CMP DL,80 ;IF COLS ARE WITHIN RANGE FOR THIS MODE
JB COLUMNS_SET ;THEN GOTO COLS SET
INC DH ;BUMP ROW COUNTER BY ONE
SUB DL,DL ;SET COLUMN COUNTER TO ZERO
CMP DH,25 ;IF ROWS ARE < 25 THEN
JB ROWS_SET ;GOTO ROWS_SET
;SAVE WRITE STRING PARAMETER REGS
PUSH ES ;SAVE REG'S THAT GET CLOBBERED
PUSH AX
MOV AX,0E0AH ;DO SCROLL ONE LINE
INT 10H ;RESET ROW COUNTER TO 24
DEC DH
POP AX ;RESTORE REG'S
POP ES
ROWS_SET:
COLUMNS_SET:
mov CURSOR_POSN,dx
LOOP WRITE_CHAR ;DO IT ONCE MORE UNTIL CX = ZERO
POP DX ;RESTORE OLD CURSOR COORDINATES
CMP AL,1 ;IF CURSOR WAS TO BE MOVED THEN
JE DONE ;WE'RE DONE
CMP AL,3
JE DONE
mov CURSOR_POSN,dx ;ELSE RESTORE OLD CURSOR POSITION
DONE:
JMP VIDEO_RETURN ;RETURN TO CALLER
;---------------------------------------------------------------
; Cursor-Stand vergleichen und Differenzen ausgeben
;---------------------------------------------------------------
CURSOR_OUT: ;CURSOR-Stand vergleichen und Cursor setzen
push ax
push dx
mov dx,CURSOR_POSN
cmp dx,cs:CURSOR_TTY
jz COUT2 ;Cursor steht auf Bildschirm richtig
mov al,1bh ;ADM 31 ESC-Folge
call PUTA
mov cs:CURSOR_TTY,dx
mov al,'='
call PUTA
mov al,dh
cmp al,24 ;Terminal hat nur 24 Zeilen
jnz COUT1
dec al ;25 = 24 Zeile, da 24 Zeilen-Terminal
COUT1: add al,20h
call PUTA
mov al,dl
add al,20h
call PUTA
COUT2: pop dx
pop ax
ret
;---------------------------------------------------------------
;PUTA
;---------------------------------------------------------------
PUTA: push ax
push bx
push di
mov di,offset ttybuf
PU1: mov bx, word ptr cs:ttyout+2
xchg bh,bl
cmp bx,800h
jnc PU1 ;warten, da Puffer voll
cmp al,80h
jc PU2
mov al,20h
PU2: sti
nop
cli
mov ah,cs:ttyout+0 ;outstop
or ah,ah
jnz PU2
mov bx, word ptr cs:ttyout+2
xchg bh,bl
mov cs:[bx+di],al
inc bx
xchg bh,bl
mov word ptr cs:ttyout+2,bx ;noutb
cmp bx,0100h
jnz PU4
PU3: sti ;beim 1.Zeichen INT geben
nop
cli
mov ah,cs:intout ;kann INT gegeben werden ?
or ah,ah
jnz PU3
mov cs:intout,1 ;tty
out 0,al ;INT geben
PU4: sti
pop di
pop bx
pop ax
ret
;--- INT 17 --------------------------------------------------------------
;PRINTER_IO
; THIS ROUTINE PROVIDES COMMUNICATION WITH THE PRINTER
;INPUT
; (AH)=0 PRINT THE CHARACTER IN (AL)
; ON RETURN, (AH) BITS SET AS ON NORMAL STATUS CALL
; (AH)=1 INITIALIZE THE PRINTER PORT
; RETURNS WITH (AH) SET WITH PRINTER STATUS
; (AH)=2 READ THE PRINTER STATUS INTO (AH)
;
; (DX) = PRINTER TO BE USED (0,1,2) - nur ein Printer moeglich
;
;REGISTERS AH IS MODIFIED
; ALL OTHERS UNCHANGED
;-------------------------------------------------------------------------
PRINTER ;PROC FAR ;ENTRY POINT FOR ORG 0EFD2H
STI ;INTERRUPTS BACK ON
OR AH,AH ;TEST FOR (AH)=0
JZ P0 ;PRINT_AL
DEC AH ;TEST FOR (AH)=1
JZ P1 ;INIT_PRT - nicht implementiert
DEC AH ;TEST FOR (AH)=2
JZ P1 ;PRINTER STATUS
JMP SHORT P3
;------ PRINT THE CHARACTER IN (AL)
P0: push bx
push di
mov di,offset lpbuf
P0A: mov bx, word ptr cs:lpout+2
xchg bh,bl
cmp bx,100h
jnc P0A ;warten Uebergabepuffer voll
P0B: sti
nop
cli
mov ah,cs:lpout+0 ;outstop
or ah,ah
jnz P0A
mov bx, word ptr cs:lpout+2
xchg bh,bl
mov cs:[bx+di],al
inc bx
xchg bh,bl
mov word ptr cs:lpout+2,bx ;noutb
cmp bx,0100h
jnz P0D
P0C: sti ;beim 1.Zeichen INT geben
nop
cli
mov ah,cs:intout ;kann INT gegeben werden ?
or ah,ah
jnz P0C
mov cs:intout,2 ;lp
out 0,al ;INT geben
P0D: sti
pop di
pop bx
;------ PRINTER STATUS
P1: push bx
mov bx,word ptr cs:lpout+2
xchg bh,bl
cmp bx,100h ;Puffer voll ?
jnc P2
mov bh,cs:lpout+0 ;outstop
or bh,bh
jnz P2
mov ah,0d0h ;bereit fuer naechstes Zeichen
pop bx
iret
P2: mov ah,50h ;nicht bereit fuer naechstes Zeichen
pop bx
P3: iret
;------- INT_14 -----------------------------------------------------
;RS232_IO
; THIS ROUTINE PROVIDES BYTE STREAM I/O TO THE COMMUNICATIONS
; PORT ACCORDING TO THE PARAMETERS:
; (AH)=0 INITIALIZE THE COMMUNICATIONS PORT
; (AL) HAS PARMS FOR INITIALIZATION
;
; 7 6 5 4 3 2 1 0
; ----- BAUD RATE -- -PARITY-- STOPBIT --WORD LENGTH--
;
; 000 - 110 XO - NONE 0 - 1 10 - 7 BITS
; 001 - 150 01 - ODD 1 - 2 11 - 8 BITS
; 010 - 300 11 - EVEN
; 011 - 600
; 100 - 1200
; 101 - 2400
; 110 - 4800
; 111 - 9600
; ON RETURN, CONDITIONS SET AS IN CALL TO COMMO STATUS (AH=3)
; (AH)=1 SEND THE CHARACTER IN (AL) OVER THE COMMO LINE
; (AL) REGISTER IS PRESERVED.
; ON EXIT, BIT 7 OF AH IS SET IF THE ROUTINE HAS UNABLE TO
; TO TRNASMIT THE BYTE OF DATA OVER THE LINE.
; IF BIT 7 OF AH IS NOT SET, THE
; REMAINDER OF AH IS SET AS IN A STATUS REQUEST,
; REFLECTING THE CURRENT STATUS OF THE LINE.
; (AH)=2 RECEIVE A CHARACTER IN (AL) FROM COMMO LINE BEFORE
; RETURNIND TO CALLER
; ON EXIT, AH HAS THE CURRENT LINE STATUS, AS SET BY THE
; THE STATUS ROUTINE, EXCEPT THAT THE ONLY BITS
; LEFT ON ARE THE ERROR BITS (7,4,3,2,1)
; IF AH HAS BIT 7 ON (TIME OUT) THE REMAINING
; BITS ARE NOT PREDICTABLE.
; THUS, AH IS NON ZERO ONLY WHEN AH ERROR OCCURRED.
; (AH)=3 RETURN THE COMMO PORT STATUS IN (AX)
; AH CONTAINS THE LINE CONTROL STATUS
; BIT 7 = TIME OUT
; BIT 6 = TRANS HOLDING REGISTER EMPTY
; BIT 5 = TRAN HOLDING REGISTER EMPTY
; BIT 4 = BREAK DETECT
; BIT 3 = FRANING ERROR
; BIT 2 = PARITY ERROR
; BIT 1 = OVERRUN ERROR
; BIT 0 = DATA READY
; AL CONTAINS THE MODEM STATUS
; BIT 7 = RECEVED LINE SIGNAL DETECT
; BIT 6 = RING INDICATOR
; BIT 5 = DATA SET READY
; BIT 4 = CLEAR TO SEND
; BIT 3 = DELTA RECEIVE LINE SIGNAL DETECT
; BIT 2 = TRAILING EDCE RING DETECTOR
; BIT 1 = DELTA DATA SET READY
; BIT 0 = DELTA CLEAR TO SEND
;
; (DX) = PARAMETER INDICATING WHICH RS232 CARD (0,1 ALLOWED)
;
;OUTPUT
; AX MODIFIED ACCORDING TO PARMS OF CALL
; ALL OTHERS UNCHANCED:
;----------------------------------------------------------------------
RS232 ;PROC FAR
;------ VECTOR TO APPROPRIATE ROUTINE
STI ;INTERRUPTS BACK ON
OR AH,AH ;TEST FOR (AH)=0
JZ RS0 ;COMMUN INIT
DEC AH ;TEST FOR (AH)=1
JZ RS1 ;SEND AL
DEC AH ;TEST FOR (AH)=2
JZ RS2 ;RECEIVE INTO AL
DEC AH ;TEST FOR (AH)=3
JZ RS3 ;COMMUNICATION STATUS
JMP SHORT RS4
;------ INITIALIZE THE COMMUNICATIONS PORT
RS0:
;------ RECEIVE CHARACTER FROM COMMO LINE
RS2:
;------ COMMO PORT STATUS ROUTINE
RS3: MOV AL,0
;------ SEND CHARACTER IN (AL) OVER COMMO LINE
RS1: MOV AH,80H ;INDICATE TIME OUT
RS4: IRET
END

View File

@ -0,0 +1,864 @@
;**************************************************************************
;**************************************************************************
;
; WDOS-BIOS - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
; Programm: test.asm
;
; Bearbeiter : P. Hoge
; Datum : 24.1.89
; Version : 1.1
;
;**************************************************************************
;
; BIOS Testversion fuer Erweiterungsmodule
;
;**************************************************************************
;**************************************************************************
;--------------------------------------------------------------------
;
;BIOS I/O INTERFACE
;
;--------------------------------------------------------------------
STACK: EQU 0030H
DATA: EQU 0040H
XXDATA: EQU 0050H
.EXTERNAL VECTOR_TABLE ;NEAR
.EXTERNAL WORD MEMORY_SIZE
.EXTERNAL WORD EQUIP_FLAG
.EXTERNAL WORD TIMER_LOW
.EXTERNAL WORD TIMER_HIGH
.EXTERNAL BYTE TIMER_OFL
.EXTERNAL BYTE STATUS_BYTE
.EXTERNAL WORD IO_ROM_INIT
.EXTERNAL WORD KB_BUFFER
.EXTERNAL WORD BUFFER_HEAD
.EXTERNAL WORD BUFFER_TAIL
.EXTERNAL WORD BUFFER_START
.EXTERNAL WORD BUFFER_END
.EXTERNAL BYTE PRINT_TIM_OUT
.EXTERNAL TOS
.EXTERNAL DUMMY_RET ;NEAR
.EXTERNAL DISK_SETUP ;NEAR
.EXTERNAL byte BOOT_LOCN
.external byte DISK_BASE
.external byte reset
.external byte intin
.external byte clkin
.external byte date
.PUBLIC START
.PUBLIC DDS
.PUBLIC XPC_BYTE
.PUBLIC PRT_HEX
.PUBLIC XLAT_PR
.PUBLIC P_MSG
.PUBLIC PRT_SEG
.PUBLIC BOOT
.PUBLIC MEMSIZE
.PUBLIC EQUIP
.PUBLIC NMIINT
.PUBLIC CASSETTE
.PUBLIC TOFDAY
.PUBLIC TIMERINT
.PUBLIC PRSCREEN
X287 EQU 0F0H ;MATH PROCESSOR
;----------------------------------------
;TIMER DATA AREA
;----------------------------------------
COUNTS_SEC EQU 18
COUNTS_MIN EQU 1092
COUNTS_HOUR EQU 65543
COUNTS_DAY EQU 1573040 = 1800B0H
;----------------------------------------
;TEST
; x286 PROCESSOR TEST (REAL MODE)
;DESCRIPTION
; VERIFY FLAGS, REGISTERS
; AND CONDITIONAL JUMPS
;----------------------------------------
START: ;NEAR
CLI ;DISABLE INTERRUPTS
MOV AH,0D5H ;SET SF, CF, ZF, AND AF FLAGS ON
SAHF
JNC ERR01 ;GO TO ERR ROUTINE IF CF NOT SET
JNZ ERR01 ;GO TO ERR ROUTINE IF ZF NOT SET
JNP ERR01 ;GO TO ERR ROUTINE IF PF NOT SET
JNS ERR01 ;GO TO ERR ROUTINE IF SF NOT SET
LAHF ;LOAD FLAG IMAGE TO AH
MOV CL,5 ;LOAD CNT REG WITH SHIFT CNT
SHR AH,CL ;SHIFT AF INTO CARRY BIT POS
JNC ERR01 ;GO TO ERR ROUTINE IF AF NOT SET
MOV AL,40H ;SET THE OF FLAG ON
SHL AL,1 ;SETUP FOR TESTING
JNO ERR01 ;GO TO ERR ROUTINE IF OF NOT SET
XOR AH,AH ;SET AH = 0
SAHF ;CLEAR SF, CF, ZF, AND PF
JBE ERR01 ;GO TO ERR ROUTINE IF CF ON
;GO TO ERR ROUTINE IF ZF ON
JS ERR01 ;GO TO ERR ROUTINE IF SF ON
JP ERR01 ;GO TO ERR ROUTINE IF PF ON
LAHF ;LOAD FLAG IMAGE TO AH
MOV CL,5 ;LOAD CNT REG WITH SHIFT CNT
SHR AH,CL ;SHIFT 'AF' INTO CARRY BIT POS
JC ERR01 ;GO TO ERR ROUTINE IF ON
SHL AH,1 ;CHECK THAT 'OF' IS CLEAR
JO ERR01 ;GO TO ERR ROUTINE IF ON
;------ READ/WRITE THE X286 GENERAL AND SEGMENTATION REGISTERS
; WITH ALL ONE'S AND ZEROES'S.
MOV AX,0FFFFH ;SETUP ONE'S PATTERN IN AX
STC ;SET CARRY FLAG
JNC ERR01 ;GO IF NO CARRY
T1: MOV DS,AX ;WRITE PATTERN TO ALL REGS
MOV BX,DS
MOV ES,BX
MOV CX,ES
MOV SS,CX
MOV DX,SS
MOV SP,DX
MOV BP,SP
MOV SI,BP
MOV DI,SI
JNC T2
XOR AX,DI ;PATTERN MAKE IT THRU ALL REGS
JNZ ERR01 ;NO - GO TO ERR ROUTINE
CLC ;CLEAR CARRY FLAG
JMP SHORT T1
T2:
OR AX,DI ;ZERO PATTERN MAKE IT THRU?
JZ I1 ;YES - GO TO NEXT TEST
ERR01: HLT ;HALT SYSTEM
;----------------------------------------
; INIT BIOS
;----------------------------------------
;------ CLEAR RAM
I1: MOV CX,1024 ;CLEAR 2K
SUB AX,AX
MOV DI,AX
MOV DS,AX
I2: MOV [DI],AX ;CLEAR
INC DI
INC DI ;POINT TO NEXT LOCATION
LOOP I2
;------ SETUP STACK SEG AND SP
MOV SP,STACK ;SET REAL MODE STACK
MOV SS,SP
MOV SP, OFFSET TOS
SUB AL,AL ;RESET MATH PROCESSOR
OUT X287+1,AL
;------ SET UP THE INTERRUPT VECTORS
MOV CX,78H ;FILL ALL INTERRUPT LOCATIONS
SUB DI,DI ;FIRST INTERRUPT LOCATION
MOV ES,DI ;SET ES ALSO
I3: MOV AX,OFFSET DUMMY_RET ;MOVE ADDRESS OF INT OFFSET
STOSW
MOV AX,CS ;GET THE SEGMENT
STOSW
LOOP I3
;------ ESTABLISH BIOS INTERRUPT VECTORS
SUB DI,DI ;FIRST INTERRUPT LOCATION
PUSH CS
POP DS ;SET UP ADDRESS OF VECTOR TABLE
MOV SI,OFFSET VECTOR_TABLE
MOV CX,32
I4: MOVSW ;MOVE VECTOR TABLE TO RAM
INC DI
INC DI ;SKIP SEGMENT POINTER
LOOP I4
;------ ZERO RESERVED VECTORS
SUB AX,AX
MOV DS,AX
MOV DI,60H*4 ;INT 60 THRU 67 FILL WITH ZERO
MOV CX,14 ;CLEAR 14 WORDS
I5: MOV WORD PTR [DI],0
INC DI ;POINT TO NEXT LOCATION
INC DI
LOOP I5
CALL DDS
MOV MEMORY_SIZE,704-64 ;MEMORY SIZE SETZEN in KByte
MOV EQUIP_FLAG,4071H ;EQUIPMENT FLAG SETZEN
;80*25 VIDEO BW, 2 FD, 1 LP, 0 RS232
;kein 287
;------ SETUP KEYBOARD PARAMETERS
MOV SI, OFFSET KB_BUFFER ;SETUP KEYBOARD PARAMETERS
MOV BUFFER_HEAD,SI
MOV BUFFER_TAIL,SI
MOV BUFFER_START,SI
ADD SI,32 ;DEFAULT BUFFER OF 32 BYTES
MOV BUFFER_END,SI
STI ;ALLOW INTERRUPTS
;------ INIT VIDEO
MOV AX,0002H ;SET MODE 80*25 B/W
INT 10H ;SEND INIT TO B/W CARD
;------- SET TIME OF DAY
CALL SET_TOD
call DISK_SETUP
;------ ENABLE HARDWARE INTERRUPT IF MATH PROCESSOR (X287)
; SUB AX,AX ;CLEAR IO_ROM_INIT
; MOV IO_ROM_INIT,AX
; ESC 28,BX
; XOR AX,AX
; ESC 15,IO_ROM_INIT
; PUSHA ;TIME FOR 287 TO RESPOND
; POPA
; AND IO_ROM_INIT,01F3FH ;CLEAR UNUSED 287 BITS
; CMP IO_ROM_INIT,0033FH ;IS IF 287 INSTALLED?
; JNZ NO_287 ;GO IF MATH PROCESSOR IS NOT INSTALLED
; WAIT
; ESC 02FH,IO_ROM_INIT ;STORE THE STATUS WORD
; PUSHA ;TIME FOR 287 TO RESPOND
; POPA
; TEST IO_ROM_INIT,0D8BFH ;ALL BITS SHOULD BE OFF
; JNZ NO_287 ;GO IF NOT INSTALLED
; OR BYTE PTR EQUI_FLAG,02H ;SET 287 BIT ON
;NO_287:
; MOV IO_ROM_INIT,0
;------ LOAD SYSTEM
INT 19H ;GO TO BOOT LOADER
CLI
HLT ;HALT CPU
DDS ;PROC NEAR
push ax
mov ax,DATA
mov ds,ax
pop ax
ret
;---------------------------------------------------------------------
;CONVERT AND PRINT ASCII CODE
;
; AL MUST CONTAIN NUMBER TO BE CONVERTED.
;---------------------------------------------------------------------
XPC_BYTE ;PROC NEAR
PUSH AX ;SAVE FOR LOW NIBBLE DISPLAY
MOV CL,4 ;SHIFT COUNT
SHR AL,CL ;NIBBLE SWAP
CALL XLAT_PR ;DO THE HIGH NIBBLE DISPLAY
POP AX ;RECOVER THE NIBBLE
AND AL,0FH ;ISOLATE TO LOW NIBBLE
;FALL INTO LOW NIBBLE CONVERSION
XLAT_PR ;PROC NEAR ;CONVERT 00-0F TO ASCII CHARAKTER
ADD AL,090H ;ADD FIRST CONVERSION FACTOR
DAA ;ADJUST FOR NUMERIC AND ALPHA RANGE
ADC AL,040H ;ADD CONVERSION AND ADJUST LOW NIBBLE
DAA ;ADJUST HIGH NIBBLE TO ASCHI RANGE
PRT_HEX ;PROC NEAR
MOV AH,14 ;DISPLAY CHARAKTER IN AL
MOV BH,0
INT 10H ;CALL VIDIO_IO
RET
;----------------------------------------------------------------------
;THIS SUBROUTINE WILL PRINT A MESSAGE ON THE DISPLAY
;
;ENTRY REQUIREMENTS:
; SI = OFFSET(ADDRESS) OF MESSAGE BUFFER
;----------------------------------------------------------------------
P_MSG ;PROC NEAR
PM1: MOV AL,CS:[SI] ;PUT CHAR IN AL
INC SI ;POINT TO NEXT CHAR
PUSH AX ;SAVE PRINT CHAR
CALL PRT_HEX ;CALL VIDIO IO
POP AX ;RECOVER PRINT CHAR
CMP AL,10 ;WAS IT LINE FEED?
JNE PM1 ;NO, KEEP PRINTING STRING
RET
;-----------------------------------------------------------
; PRINT A SEGMENT VALUE TO LOOK LIKE A 21 BIT ADDRESS
; DX MUST CONTAIN SEGMENT VALUE TO BE PRINTED
;-----------------------------------------------------------
PRT_SEG ;PROC NEAR
MOV AL,DH ;GET MSB
CALL XPC_BYTE
MOV AL,DL ;LSB
CALL XPC_BYTE
MOV AL,'0' ;PRINT A '0'
CALL PRT_HEX
MOV AL,' ' ;SPACE
CALL PRT_HEX
RET
;--- INT 19 ----------------------------------------------------
;BOOT DOS (hier ersetzt durch MP600-Test)
;---------------------------------------------------------------
MSGRUN: defb 'test running',0dh,0ah
BOOT: sti
BOOT0: mov SI,OFFSET MSGRUN
call P_MSG
mov cx,-1
sub ax,ax
mov ds,ax
mov bx,1000h
BOOT1: mov al,[bx] ;Byte gerade Adresse
mov dl,cs:[bx]
mov [bx],al
mov cs:[bx],bl
inc bx
mov al,[bx] ;Byte ungerade Adresse
mov dl,cs:[bx]
mov [bx],al
mov [bx],dl
dec bx
mov ax,[bx] ;Wort gerade Adresse
mov dx,cs:[bx]
mov [bx],ax
mov cs:[bx],dx
inc bx
mov ax,[bx] ;Wort ungerade Adresse
mov dx,cs:[bx]
mov [bx],ax
mov cs:[bx],dx
dec bx
loopnz BOOT1
jmp short BOOT0
;--- INT 12 ----------------------------------------------------
;MEMORY_SIZE_DETERMINE
;
;OUTPUT
; (AX) = NUMBER OF CONTICUOUS 1K BLOCKS OF MEMORY
;---------------------------------------------------------------
MEMSIZE ;PROC FAR
PUSH DS ;SAVE SEGMENT
CALL DDS ;ESTABLISH ADDRESSING
MOV AX,MEMORY_SIZE ;GET VALUE
POP DS ;RECOVER SEGMENT
IRET ;RETURN TO CALLER
;--- INT 11 ----------------------------------------------------
;EQUIPMENT DETERMINATION
; THIS ROUTINE ATTEMPTS TO DETERMINE WHAT OPTIONAL
; DEVICES ARE ATTACHED TO THE SYSTEM.
;OUTPUT
; (AX) IS SET, BIT SIGNIFICANT, TO INDICATE ATTACHED I/O
; BIT 1 = MATH COPROCESSOR
;---------------------------------------------------------------
EQUIP ;PROC FAR ;>>> ENTRY POINT FOR ORG 0F84DH
PUSH DS ;SAVE SEGMENT REGISTER
CALL DDS ;ESTABLISH ADDRESSING
MOV AX,EQUIP_FLAG ;GET THE CURRENT SETTINGS
POP DS ;RECOVER SEGMENT
IRET ;RETURN TO CALLER
;-- INT 2 -----------------------------------------------------
;NON-MASKABLE INTERRUPT ROUTINE (REAL MODE)
;SERVICE X287 INTERRUPTS
; THIS ROUTINE FIELDS X287 INTERRUPTS
;--------------------------------------------------------------
NMIINT ;PROC NEAR
PUSH AX
XOR AL,AL
OUT X287,AL ;REMOVE THE INT.REQUEST
POP AX
IRET
;- - INT 5 -----------------------------------------------------
; THIS LOGIC WILL BE INVOKED BY INTERRUPT 05H TO PRINT
; THE SCREEN. THE CURSOR POSITION AT THE TIME THIS ROUTINE
; IS INVOKED WILL BE SEVED AND RESTORED UPON COMPETION. THE
; ROUTINT IS INTENDED TO RUN WITH INTERRUPTS ENABLED.
; IF A SUBSEQUENT PRINT SGREEN KEY IS DEPRESSED DURING THE
; TIME THIS ROUTINE IS PRINTING IT WILL BE IGNORED.
; ADDRESS 50:0 CONTAINS THE STATUS OF THE PRINT SCREEN:
;
; 50:0 =0 EITHER PRINT SCREEN HAS NOT BEEN CALLED
; OR UPON RETURN FROM A CALL THIS INDI-
; CATES A SUCCESSFUL OPERATION.
;
; =1 PRINT SCREEN IS IN PROGRESS
;
; =255 ERROR ENCOUNTERED DURING PRINTING
;---------------------------------------------------------------
PRSCREEN ;PROC FAR
STI ;MUST RUN WITH INTERRUPTS ENABLED
PUSH DS ;MUST USE 50:0 FOR DATA ARE STORAGE
PUSH AX
PUSH BX
PUSH CX ;WILL USE THIS LATER FOR CURSOR LIMITS
PUSH DX ;WILL HOLD CURRENT CURSOR POSITION
MOV AX,XXDATA ;HEX 50
MOV DS,AX
CMP STATUS_BYTE,1 ;SEE IF PRINT ALREADY IN PROGRESS
JZ EXIT ;JUNP IF PRINT ALREADY IN PROGRESS
MOV STATUS_BYTE,1 ;INDICATE PRINT NOW IN PROGRESS
MOV AH,15 ;WILL REQUEST THE CURRENT SCEEN MODE
INT 10H ; [AL] = MODE
; [AH] = NUMBER COLUMNS/LINE
; [BH] = VISUAL PAGE
MOV CL,AH ;WILL MAKE USE OF [CX] REGISTER TO
MOV CH,25 ;CONTROL ROW & COLUMNS
CALL CRLF ;CARRIAGE RETURN LINE FEED ROUTINE
PUSH CX ;SAVE SCREEN BOUNDS
MOV AH,3 ;WILL NOW READ THE CURSOR
INT 10H ;AND PRESERVE THE POSITION
POP CX ;RECALL SCREEN BOUNDS
PUSH DX ;RECALL [BH]=VISUAL PAGE
XOR DX,DX ;WILL SET CURSOR POSITION TO [0,0]
;---------------------------------------------------------------------------
; THE LOOP FROM PRI10 TO THE INSTRUCTION PRIOR TO PRI20
; IS THE LOOP TO READ EACH CURSOR POSITION FROM THE SCREEN
; AND PRINT.
;---------------------------------------------------------------------------
PRI10: MOV AH,2 ;TO INDICATE CURSOR SET REQUEST
INT 10H ;NEW CURSOR POSITION ESTABLISHED
MOV AH,8 ;TO INDICATE READ CHARACTER
INT 10H ;CHARACTER NOW IN [AL]
OR AL,AL ;SEE IF VALID CHAR
JNZ PRI15 ;JUMP IF VALID CHAR
MOV AL,' ' ;MAKE A BLANK
PRI15:
PUSH DX ;SAVE CURSOR POSITION
XOR DX,DX ;INDICATE PRINTER 1
XOR AH,AH ;TO INDICATE PRINT CHAR IN [AL]
INT 17H ;PRINT THE CHARACTER
POP DX ;RACALL CURSOR POSITION
TEST AH,29H ;TEST FOR PRINTER ERROR
JNZ ERR10 ;JUMP IF ERROR DETECTED
INC DL ;ADVANCE TO NEXT COLUMN
CMP CL,DL ;SEE IF AT END OF LINE
JNZ PRI10 ;IF NOT PROCEED
XOR DL,DL ;BACK TO COLUMN 0
MOV AH,DL ;[AH]=0
PUSH DX ;SAVE NEW CURSOR POSITION
CALL CRLF ;LINE FEED CARRIAGE RETURN
POP DX ;RECALL CURSOR POSITION
INC DH ;ADVANCE TO NEXT LINE
CMP CH,DH ;FINISHED?
JNZ PRI10 ;IF NOT CONTINUE
PRI20: POP DX ;RECALL CURSOR POSITION
MOV AH,2 ;TO INDICATE CURSOR SET REQUEST
INT 10H ;CURSOR POSITION RESTORED
MOV STATUS_BYTE,0 ;INDICATE FINISHED
JMP SHORT EXIT ;EXIT THE ROUTINE
ERR10: POP DX ;GET CURSOR POSITION
MOV AH,2 ;TO REQUEST CURSOR SET
INT 10H ;CURSOR POSITION RESTORED
ERR20: MOV STATUS_BYTE,0FFH ;INDICATE ERROR
EXIT: POP DX ;RESTORE ALL THE REGISTERS USED
POP CX
POP BX
POP AX
POP DS
IRET
;------ CARRIAGE RETURN, LINE FEED SUBROUTINE
CRLF ;PROC NEAR
XOR DX,DX ;PRINTER 0
XOR AH,AH
MOV AL,0dh
INT 17H
XOR AH,AH
MOV AL,0ah
INT 17H ;SEND THE CARRIAGE RETURN
RET
;---------------------------------------------------------------
; THIS ROUTINE INITIALIZES THE TIMER DATA AREA IN THE
; ROM BIOS DATD AREA. IT IS CALLED BY THE POWER ON
; ROUTINES. IT CONVERTS HR:MIN:SEC TO TIMER
; TICS.
;---------------------------------------------------------------
;
;OUTPUT
; TIMER_LOW
; TIMER_HIGH
; TIMER_OFL
; ALL REGISTER UNCHANGEND
;--------------------------------------------------------------
COUNTS_DHOUR EQU 7 ;65543 - 65536
SET_TOD ;PROC NEAR
CLI
PUSH DS
CALL DDS
mov al,cs:date+0 ;Sekunden
sub ah,ah
MOV BL,COUNTS_SEC
MUL BL ;COUNT FOR SECONDS
MOV CX,AX
mov al,cs:date+1 ;Minuten
sub ah,ah
MOV BX,COUNTS_MIN
MUL BX ;COUNT FOR MINUTES
ADD AX,CX
MOV CX,AX
mov al,cs:date+2 ;Stunden
sub ah,ah
MOV DX,AX
MOV BL,COUNTS_DHOUR
MUL BL ;COUNT FOR HOURS
ADD AX,CX
ADC DX,0000H
MOV TIMER_HIGH,DX
MOV TIMER_LOW,AX
SUB AX,AX
MOV TIMER_OFL,AL ;RESET TIMER ROLL OVER INDICATOR
POP DS
STI
RET
;--- INT 1A -------------------------------------------------------------
;TIME_OF DAY
; THIS ROUTINE ALLOWS THE CLOCK TO BE SET/READ
;
;INPUT
; (AH) = 0 READ THE CURRENT CLOCK SETTING
; (AH) = 1 SET THE CURRENT CLOCK
; (AH) = 2 READ THE REAL TIME CLOCK
; (AH) = 3 SET THE REAL TIME CLOCK - nicht moeglich
; (AH) = 4 READ THE DATE FROM THE REAL TIME CLOCK
; (AH) = 5 SET THE DATE INTO THE REAL TIME CLOCK - nicht moeglich
; (AH) = 6 SET THE ALARM - nicht moeglich
; (AH) = 7 RESET THE ALARM - nicht moeglich
;
;NOTE: FOR AH = 6 - CY FLAG SET for not possible
;------------------------------------------------------------------------
TOFDAY ;PROC FAR
PUSH DS ;SAVE SEGMENT
CALL DDS ;SET DATA SEGMENT
OR AH,AH ;AH=0
JZ TD0 ;READ_TIME
DEC AH ;AH=1
JZ TD1 ;SET_TIME
DEC AH ;AH=2
JZ TD2 ;Read Real Time
DEC AH
DEC AH ;AH=4
JZ TD4
STC ;SET ERROR RETURN
POP DS
STI
RET FAR 2
TD0: MOV AL,TIMER_OFL
MOV TIMER_OFL,0 ;GET OVERFLOW, AND RESET THE FLAG
MOV CX,TIMER_HIGH
MOV DX,TIMER_LOW
POP DS ;RECOVER SEGMENT
IRET ;RETURN TO CALLER
TD1: MOV TIMER_LOW,DX
MOV TIMER_HIGH,CX ;SET THE TIME
MOV TIMER_OFL,0 ;RESET OVERFLOW
POP DS
IRET
TD2: mov al,cs:date+0 ;Sekunde
call CVT_BCD
mov dh,al
mov al,cs:date+1 ;Minute
inc al
call CVT_BCD
mov cl,al
mov al,cs:date+2 ;Stunde
call CVT_BCD
mov ch,al
pop ds
iret
TD4: mov al,cs:date+3 ;Tag
call CVT_BCD
mov dl,al
mov al,cs:date+4 ;Monat
inc al
call CVT_BCD
mov dh,al
mov al,cs:date+5 ;Jahr
call CVT_BCD
mov cl,al
mov ch,19h ;Jahrhundert
pop ds
iret
CVT_BCD ;PROC NEAR
aam
shl ah,1
shl ah,1
shl ah,1
shl ah,1
or al,ah
ret
;- - INT 8 -----------------------------------------------------
;THIS ROUTINE HANDLES THE TIMER INTERRUPTS
;THE INTERRUPT HANDLER MAINTAINS A COUNT OF INTERRUPTS SINCE
;POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.
;THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH
;INTERRUPT 1CH AT EVERY TIME TICK. THE USER MUST CODE A
;ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.
;---------------------------------------------------------------
TIMERINT ;PROC FAIR
mov cs:intin,0 ;weitere Ints erlauben
sti
push ds
push ax
push cx
call DDS
sub ax,ax
mov cx,1
inc cs:TISEC
mov al,cs:TISEC
cmp al,10 ;Korrektur bei 1 Sekunde ?
jnz TI1
mov cs:TISEC,ah
mov cx,9
inc cs:TIMIN
mov al,cs:TIMIN
cmp al,60 ;Korrektur bei 1 Minute ?
jnz TI1
mov cs:TIMIN,ah
mov cx,21
inc cs:TIHOUR
mov al,cs:TIHOUR
cmp al,60 ;Korrektur bei 1 Stunde ?
jnz TI1
mov cs:TIHOUR,ah
mov cx,44
TI1: INC TIMER_LOW ;INCREMENT TIME
JNZ TI2 ;TEST_DAY
INC TIMER_HIGH ;INCERMENT HIGH WORD OF TIME
TI2: CMP TIMER_HIGH,18H ;TEST FOR COUNT EQUALLING 24 HOURS
JNZ TI3
CMP TIMER_LOW,00B0H
JNZ TI3
SUB AX,AX ;TIMER HAS GONE 24 HOURS
MOV TIMER_HIGH,AX
MOV TIMER_LOW,AX
MOV TIMER_OFL,1
TI3: loop TI1
INT 1CH ;TRANSFER CONTROL TO A USER ROUTINE
mov cs:clkin+1,0 ;weiteren Clock-Int erlauben
pop cx
pop ax
pop ds
iret
TISEC: defb 0
TIMIN: defb 0
TIHOUR: defb 0
;--- INT 15 ----------------------------------------------------
; INPUT - CASSETTE I/O FUNCTIONS
; (AH) = 00
; (AH) = 01
; (AH) = 02
; (AH) = 03
; RETURNS FOR THESE FUNCTIONS ALWAYS (AH) = 86H, CF = 1)
; IF CASSETTE PORT NOT PRESENT
;---------------------------------------------------------------
; INPUT - UNUSED FUNCTIONS
; (AH) = 04 THROUGH 7F
; RETURNS FOR THESE FUNCTIONS ALWAYS (AH) = 86H, CF = 1)
;---------------------------------------------------------------
;Extensions
; (AH) = 80H DEVICE OPEN
; (BX) = DEVICE ID
; (CX) = PROCESS ID
;
; (AH) = 81H DEVICE CLOSE
; (BX) = DEVICE ID
; (CX) = PROCESS ID
;
; (AH) = 82H PROGRAM TERMINATION
; (BX) = DEVICE ID
;
; (AH) = 83H EVENT WAIT
; (AL) = 0 SET INTERVAL
; (ES:BX) POINTER TO A BYTE IN CALLERS MEMORY
; THAT WILL HAVE THE HIGH ORDER BIT SET
; AS SOON AS POSSIBLE AFTER THE INTERVAL
; EXPIRES.
; (CX,DX) NUMBER OF MICROSECONDS TO ELAPSE BEFORE
; POSTING.
; (AL) = 1 CANCEL
;
; (AH) = 84H JOYSTICK SUPPORT
; (DX) = 0 - READ THE CURRENT SWITCH SETTINGS
; RETURNS AL = SWITCH SETTINGS (BITS 7-4)
; (DX) = 1 - READ THE RESISTIVE INPUTS
; RETURNS AX = A(x) VALUE
; BX = A(y) VALUE
; CX = B(x) VALUE
; DX = B(y) VALUE
;
; (AH) = 85H SYSTEM REQUEST KEY PRESSED
; (AL) = 00 MAKE OF KEY
; (AL) = 01 BREAK OF KEY
; (AH) = 86H WAIT
; (CX,DX) NUMBER OF MICROSECONDS TO ELPASE BEFORE
; RETURN TO CALLER
; (AH) = 87H MOVE BLOCK
; (CX) NUMBER OF WORDS TO MOVE
; (ES:SI) POINTER TO DESCRIPTOR TABLE
; (AH) = 88H EXTENDENT MEMORY SIZE DETERMINE
; (AH) = 89H PROCESSOR TO VIRTUAL MODE
;
; (AH) = 90H DEVICE BUSY LOOP
; (AL) SEE TYPE CODE
;
; (AH) = 91H INTERRUPT COMPLETE FLAG SET
; (AL) TYPE CODE
; 00H -> 7FH
; SERIALLY REUSABLE DEVICES
; OPERATING SYSTEM MUST SERIALIZE
; ACCESS
; 80H -> BFH
; REENTRANT DEVICES;ES:BX IS
; USED TO DISTINGUISH DIFFERENT
; CALLS (MULTIPLE I/O CALLS ARE
; ALLOWED SIMULTANEUSLY)
; C0H -> FFH
; WAIT ONLY CALLS; THERE IS NO
; COMPLEMENTARY `POST` FOR THESE
; WAITS - - THESE ARE TIMEOUT
; ONLY. TIMES ARE FUNCTION NUMBER
; DEPENDENT
;
; TYPE DESCRIPTION TIMEOUT
;
; 00H = DISK YES
; 01H = DISKETTE YES
; 02H = KEYBOARD NO
; 80H = NETWORK NO
; ES:BX --> NCB
; FDH = DISKETTE MOTOR START YES
; FEH = PRINTER YES
;---------------------------------------------------------------
CASSETTE ;PROC FAR
STI
CMP AH,80H ;CHECK FOR RANGE
JB C1 ;RETURN IF 00-7FH
SUB AH,80H ;BASE ON 0
OR AH,AH
JZ DEV_OPEN ;DEVICE OPEN
DEC AH
JZ DEV_CLOSE ;DEVICE CLOSE
DEC AH
JZ PROG_TERM ;PROGRAM TERMINATION
DEC AH
JZ EVENT_WAIT ;EVENT WAIT
DEC AH
JZ JOY_STICK ;JOYSTICK BIOS
DEC AH
JZ SYS_REQ ;SYSTEM REQUEST KEY
DEC AH
JZ C1_A ;WAIT
DEC AH
JNZ C1_B
JMP BLOCKMOVE ;MOVE BLOCK
C1_A: JMP WAIT ;WAIT
C1_B: DEC AH
JNZ C1_C
JMP EXT_MEMORY ;GO GET THE EXTENDED MEMORY
C1_C: DEC AH ;CHECK FOR FUNCTION 89
JNZ C1_D
JMP SET_VMODE ;SWAP TO VIRTUAL MODE
C1_D: SUB AH,7 ;CHECK FOR FUNCTION 90
JNZ C1_E ;GO IF NOT
JMP DEVICE_BUSY
C1_E: DEC AH ;CHECK FOR FUNCTION 91
JNZ C1 ;GO IF NOT
JMP INT_COMPLETE
C1: MOV AH,86H ;SET BAD COMMAND
C2: STC ;SET CARRY FLAG ON
DEV_OPEN:
DEV_CLOSE:
PROG_TERM:
SYS_REQ:
C1_F:
RET FAR 2
EVENT_WAIT:
WAIT:
JMP SHORT C2 ;SET ERROR - keine CMOS-Uhr
JOY_STICK: ;nicht vorhanden
JMP SHORT C1 ;GO TO ERROR RETURN
BLOCKMOVE: ;nicht implementiert
MOV AH,1 ;Fehler setzen
JMP SHORT C2
EXT_MEMORY:
MOV AX,0 ;kein Speicher ueber 1 MByte
IRET ;RETURN TO USER
SET_VMODE: ;nicht implementiert
MOV AH,0FFH ;SET THE ERROR FLAG
JMP SHORT C2
;--- DEVICS BUSY AND INTERRUPT COMPLETE ------------------------
; THIS ROUTINE IS A TEMPORY HANDLER FOR DEVICE BUSY
; AND INTERRUPT COMPLETE
;
; INPUT
; SEE PROLOG
;---------------------------------------------------------------
DEVICE_BUSY ;PROC NEAR
CLC ;TURN CARRY OFF
JMP short C1_F ;RETURN WITH CARRY FLAG
INT_COMPLETE ;PROC NEAR
IRET ;RETURN
END