home *** CD-ROM | disk | FTP | other *** search
- ;"8051"
- ;;
- ;; COPYRIGHT 1984, 1985, 1986 JAMES H. HERZOG, JOHN T. EBNER
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; X-TENDER OPERATING SYSTEM VERSION 1.0
- ;;
- ;; JIM HERZOG
- ;; JOHN EBNER
- ;; JULY 16, 1986
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;
- ;; TASK REGISTER BANK (RB0) ASSIGNMENTS
- ;;
- RB0 EQU 00H ; PSW FOR REG BANK 0 FOR QUEUED TASKS
- RB1 EQU 08H ; PSW FOR REG BANK 1 FOR IMMED TASKS
- RB2 EQU 10H ; PSW FOR REG BANK 2 FOR TIMER OPERATIONS
- RB3 EQU 18H ; PSW FOR REG BANK 3 FOR OPSYS
- ;;
- ;; INTERNAL DATA MEMORY ASSIGNMENTS
- ;;
- ;; TASK REGISTER BANK (RB0) ASSIGNMENTS
- ;;
- ; 00H ; TASK REG 0, REG 0 OF RB0, GEN PTR
- ; 01H ; TASK REG 1, REG 1 OF RB0, GEN PTR
- ; 02H ; TASK REG 2, BEG OF TASK QUEUE PTR
- ; 03H ; TASK REG 3, ARG #1
- ; 04H ; TASK REG 4, ARG #2
- ; 05H ; TASK REG 5, ARG #3
- ; 06H ; TASK REG 6, ARG #4
- ; 07H ; TASK REG 7, ARG #5
- ;;
- ;; IMMED TASK REGISTER BANK (RB1) ASSIGNMENTS
- ;;
- ;;
- ; 08H ; TASK REG 0, REG 0 OF RB1, GEN PTR
- ; 09H ; TASK REG 1, REG 1 OF RB1, GEN PTR
- ; 0AH ; TASK REG 2, BEG OF TASK QUEUE PTR
- ; 0BH ; TASK REG 3, ARG #1
- ; 0CH ; TASK REG 4, ARG #2
- ; 0DH ; TASK REG 5, ARG #3
- ; 0EH ; TASK REG 6, ARG #4
- ; 0FH ; TASK REG 7, ARG #5
- ;;
- ;; TIMER REGISTER BANK (RB2) ASSIGNMENTS
- ;;
- HBTOC EQU 12H ; R2 :HI BYTE TIME OUT COUNTER
- MBTOC EQU 13H ; R3 :MID BYTE TIME OUT COUNTER
- LBTOC EQU 14H ; R4 :LO BYTE TIME OUT COUNTER
- HBTIM EQU 15H ; R5 :HI BYTE TIME CONST
- MBTIM EQU 16H ; R6 :MID BYTE TIME CONST
- LBTIM EQU 17H ; R7 :LO BYTE TIME CONST
- ;;
- ;; OPERATING SYSTEM REGISTER BANK (RB3) ASSIGNMENTS
- ;;
- ; 18H ; OP SYS REG 0, GEN PTR
- ; 19H ; OP SYS REG 1, GEN PTR
- ; 1AH ; OP SYS REG 2, BEG OF TASK QUE PTR
- ; 1BH ; OP SYS REG 3, END OF TASK QUE PTR
- ; 1CH ; OP SYS REG 4, PTR FOR HOST COM PKT
- ; 1DH ; OP SYS REG 5, STORE R0 DURING INT
- ; 1EH ; OP SYS REG 6, GEN PURPOSE
- ; 1FH ; OP SYS REG 7, GEN PURPOSE
- ;;
- ;; DATA MEMORY ALLOCATION
- ;;
- ;; BIT ADDRESSABLE LOCATIONS
- ;;
- SWD EQU 20H ; EVENT REGISTER
- ;
- ; BIT 7=1 ACKNOWLEDGEMENT REQUIRED
- ; BIT 6=1 IMMEDIATE TASK RUNNING
- ; BIT 5=1 QUEUED TASK RUNNING
- ; BIT 4=1 LOCAL ASYNC PORT SENSITIZED
- ; BIT 3=1 UNREPORTED ERROR ;PAR PORT SENS
- ; BIT 2=1 PACKET IN PROGRESS
- ; BIT 1=1 PAUSE BIT
- ; BIT 0=1 QUEUE OVERFLOW ;;; KB SENS
- ;
- SENSR EQU 21H ; SENSITIZE REG SER/PAR PORT
- ;
- ; BIT 7=1 SERIAL OUTPUT PORT SENSITIZED
- ; BIT 6=1 SERIAL INPUT PORT SENSITIZED
- ; BIT 5=1 PARALLEL PRINTER PORT SENSITIZED
- ; BIT 4=1 SOFTSWITCH INPUT SENSITIZED
- ; BIT 3=1 TIME-OUT ACTIVE
- ; BIT 2=1 INTERNAL TRANSMITTER READY FLAG
- ; BIT 1 <SPARE>
- ; BIT 0 <SPARE>
- ;
- EVENT EQU 22H ; EVENT SENSING
- ;;
- ;; LOCATIONS 23-2F NOT ASSIGNED
- ;;
- ;; INTERNAL ADDRESS SPACE
- ;;
- HCP EQU 30H ; (30-3F) STORAGE FOR HOST COMMAND PACKET
- SOS EQU 40H ; (40-4F) START OF STACK-SYSTEM STACK
- ICP EQU 09H ; (09-0F) STORAGE FOR IMMEDIATE COM PACKET
- BOQ EQU 50H ; (50-7F) BEGINING OF THE TASK QUEUE
- STAT EQU 51H ; STATUS REGIS OF TASK ON QUEUE
- EOQ EQU 7FH ; END OF TASK QUEUE
- ;;
- ;; EXTERNAL ADDRESS SPACE
- ;;
- UDR EQU 00H ; USART DATA REGISTER
- UCR EQU 01H ; USART CONTROL REGISTER
- UDRL EQU 40H ; LOCAL USART DATA REGISTER
- UCRL EQU 41H ; LOCAL USART CONTROL REGISTER
- TAS EQU 21H ; DIAG/ADDRESS DIPSWITCH, (READ)
- ; BIT 7 6
- ; 0 0 NO DIAGNOSTICS
- ;
- ; 0 1 SEND TAS TO HOST
- ; (SWTH)
- ; 1 0 HOST TO P1,P2,LED
- ; (HTPT)
- ; 1 1 ECHO TO HOST
- ; (ECHO)
- LED EQU 21H ; LED/BUZZER LATCH, (WRITE)
- ; BIT 0 =0 LED ON
- ; BIT 1 =0 BUZZER ON
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ORG 00H
- ;
- ; VECTOR LOCATION FOLLOWING A RESET
- ;
- BEGIN: AJMP START ; JUMP TO THE START OF THE PROGRAM
- ;
- ; VECTOR LOCATION FOLLOWING EXTERNAL INTERRUPT #0
- ;
- ORG 03H
- INTR0: RETI ; ONLY USING SERIAL PORT INTERRUPT
- ;
- ORG 0BH
- TYMER0: NOP ; TIME-OUT ROUTINE (ACTIVIATED BY SENSR.3)
- ; PAUSE/RESUME (ACTIVATED BY SWD.1)
- AJMP TIM0INT ; JUMP TO TIMER 0 SERVICE ROUTINE
- ;
- ; VECTOR LOCATION FOLLOWING EXTERNAL INTERRUPT #1
- ;
- ORG 13H
- INTR1: RETI ; NOT CURRENTLY IMPLEMENTED
- ;
- ; VECTOR LOCATION FOLLOWING TIMER INTERRUPT #1
- ;
- ORG 1BH
- TYMER1: RETI ; NOT CURRENTLY IMPLEMENTED
- ;
- ; VECTOR LOCATION FOR SERIAL PORT INTERRUPT
- ;
- ORG 23H
- SERPRT: CLR EA ; TURN OFF INTERRUPTS
- ;
- ; CHECK IF TI
- ;
- JNB TI,RINT ; JUMP IF NOT TI
- SETB SENSR.2 ; SET TRANSMIT READY FLAG
- CLR TI ; CLEAR TI
- SETB EA ; ENABLE INTERRUPTS
- RETI
- ;
- ; IT MUST BE A RECEIVER INTERRUPT
- ;
- RINT: CLR EA ; DISABLE ALL INTERRPTS
- PUSH ACC ; PUT ACC ON STACK
- PUSH PSW ; PUT PSW ON STACK
- MOV PSW,#RB3 ; USE RB3 FOR INTERRUPT SERVICE
- MOV A,R4 ; GET THE PTR TO HCP
- MOV R1,A ; SET UP R1 AS PTR TO HCP AREA
- ACALL GETCHRI ; GET THE CHAR
- LJMP CHECK ; SERVICE THE CHARACTER
- ;
- TIM0INT: NOP
- ;
- ; TIMER SERVICE ROUTINE
- ;
- CLR EA ; DISABLE ALL INTERRUPTS
- CLR TR0 ; TURN OFF THE TIMER
- PUSH ACC ; PUT ACC ON STACK
- PUSH PSW ; PUT PSW ON STACK
- MOV PSW,#RB2 ; USE RB2 FOR TIMEOUT FUNCTIONS
- ACALL DUMMY ; CLEAR THE INTERRUPT LATCH
- ;
- ; CHECK FOR A PAUSE
- ;
- TR00: JNB SWD.1,TR01; JUMP IF NO PAUSE
- SETB EA ; ALLOW INTERRUPT TO CLEAR PAUSE BIT
- NOP ; WAIT
- NOP
- CLR EA ; DISABLE THE INTERRUPTS
- AJMP TR00 ; GO BACK AND TEST AGAIN
- ;
- ; CHECK FOR A TIMEOUT
- ;
- TR01: JNB SENSR.3,TR02 ; JUMP IF TIMEOUT NOT ACTIVE
- CLR C ; CLEAR THE CARRY BIT
- MOV A,R4 ; GET LOW BYTE OF COUNTER
- ADDC A,#01H ; INC THE COUNT
- MOV R4,A ; RESTORE THE LOW COUNT
- MOV A,R3 ; GET THE MID BYTE
- ADDC A,#00H ; CONSIDER THE CARRY
- MOV R3,A ; RESTORE THE MID BYTE COUNT
- MOV A,R2 ; GET THE HIGH BYTE OF COUNT
- ADDC A,#00 ; CONSIDER THE CARRY
- MOV R2,A ; RESTORE THE HIGH COUNT
- JNC TR02 ; JMP IF NO TIMEOUT (C <> 1)
- MOV SP,#SOS+2 ; RESET THE SP
- CLR EA ; DISABLE INTERRUPTS
- CLR ET0 ; DISABLE TIME-OUT INTERRUPT
- RETI ; START AFRESH
- ;
- ; RESET COUNTER 0 AND RETURN
- ;
- TR02: MOV TH0,#10H ; RESET HIGH BYTE OF TIMER 0
- MOV TL0,#00H ; RESET LOW BYTE OF TIMER 0
- SETB TR0 ; START TIMER 0
- POP PSW ;
- POP ACC ;
- SETB EA ; ENABLE INTERRUPTS AGAIN
- RETI ;
- ;
- ;
- ; START OF THE PROGRAM
- ;
- START: CLR EA ; DISABLE ALL INTERRUPTS
- MOV SWD,#00H ; CLEAR THE STATUS WORD
- MOV PSW,#RB3 ; USE RB3 FOR THE OP SYS
- MOV SP,#SOS ; INITIALIZE THE SP
- ;;
- ;; THIS SECTION INITIALIZES THE OPERATING SYSTEM AND THE USART
- ;;
- MOV P2,#0FFH ; SELECT THE I/O PORTS
- LCALL TASK15 ; FRIENDLY BLINK
- START1: CLR EA ; MASTER INT DISABLE
- MOV SWD,#00H ; CLEAR THE STATUS WORD
- MOV TCON,#00H ; STOP TIMER/EDGE TRIGGER INTERRUPTS
- MOV PSW,#RB3 ; USE RB3 FOR OP SYSTEM
- MOV SP,#SOS ; INITIALIZE THE STACK PTR
- LCALL INIT ; CLEAR QUEUE AND MEMORY
- ;;
- DIAG: NOP ; CHECK IF DIAG REQUESTED
- ;;
- ;; THIS IS A DIAGNOSTICS ROUTINE. IT CHECKS TO SEE IF THE
- ;; USER HAS REQUESTED ANY DIAGNOSTICS BY SETTING THE
- ;; DIAGNOSTICS SWITCH.
- ;;
- MOV P2,#0FFH ; UPPER AD BYTE FOR I/O PORTS
- MOV R0,#TAS ; ADDRESS OF THE DIAGNOS SWITCH
- MOVX A,@R0 ; GET THE SWITCH CONTENTS
- ANL A,#0C0H ; GET THE LEADING 2 BITS
- JZ BATCH ; IF NO DIAG REQUESTED, GO ON
- CJNE A,#40H,DG1; SEE IF "01" CODE, SEND SWITCH
- LCALL SWTH ; TASK TO SEND TAS
- SJMP DIAG ; GO BACK AGAIN
- DG1 CJNE A,#80H,DG2; SEE IF "10" CODE HOST DATA TO PORTS
- LCALL SWTI ; USE LOCAL USART
- SJMP DIAG ; GO BACK AGAIN
- DG2 CJNE A,#0C0H,DG3; SEE OF "11" CODE, ECHO
- LCALL ECHO ; ECHO THE RECEIVED DATA
- DG3 SJMP DIAG ; GO BACK AGAIN
- ;;
- ;; DIAGNOSTIC SUBROUTINES, CALLED WITH DIAGNOSTIC SWITCH
- ;;
- SWTH: NOP ;SEND THE ADDRESS/DIAG SWITCH TO THE HOST
- ;;
- ;;
- MOV PSW,#RB0
- MOV R7,#00 ; SET UP DELAY
- MOV R6,#00 ; SET UP DELAY
- T31: DJNZ R7,T31 ; GO BACK AGAIN
- DJNZ R6,T31 ; BACK AGAIN
- MOV R1,#TAS ; PTR TO THE SWITCH REGISTER
- MOVX A,@R1 ; READ THE SWITCH REGISTER
- ANL A,#3FH ; GET RID OF LEADING BITS
- LCALL OUTCHAR ; SEND TO THE USART
- RET
- ;;
- SWTI: NOP ;SWITCH REGISTER SENT USING LOCAL USART PORT
- ;;
- MOV IE,#00H ; ALL INTS OFF
- MOV R7,#00 ; SET UP DELAY
- MOV TMOD,#21H ; COUNTER 1 FOR UART
- MOV TH1,#0FEH ; 9600 BAUD
- MOV TL1,#0FEH ; 9600 BAUD
- MOV TCON,#40H ; START TIMER #1
- MOV SCON,#52H ; REC &TRAN ENABLED, SET TRANS FLAG
- MOV R6,#00 ; SET UP DELAY
- T31I: DJNZ R7,T31I ; GO BACK AGAIN
- DJNZ R6,T31I ; BACK AGAIN
- MOV R1,#TAS ; PTR TO THE SWITCH REGISTER
- MOVX A,@R1 ; READ THE SWITCH REGISTER
- ANL A,#3FH ; GET RID OF LEADING BITS
- MOV SBUF,A ; SEND TO THE LOCAL USART
- CLR TI ; CLEAR THE TRANS FLAG
- RET
- ;;
- ECHO: NOP ; ACCEPT AN ASCII CHARACTER FROM THE HOST,
- ;; RETURNS THE CHARACTER TO THE HOST
- ;;
- MOV IE,#00H ; DISABLE ALL INTERRUPTS
- EO1: JNB RI,EO1 ; WAIT FOR RECEIVER CHARACTER
- MOV A,SBUF ; GET THE CHARACTER
- EO2: JNB TI,EO2 ; WAIT FOR TRANSMITTER FLAG
- MOV SBUF,A ; TRANSMIT THE CHARACTER
- CLR RI ; CLEAR THE RECEIVER FLAG
- CLR TI ; CLEAR THE TRANSMITTER FLAG
- SJMP EO1 ; GO BACK AGAIN
- ;;
- BATCH: NOP
- ;;
- ;; THIS SECTION CONTAINS COMMANDS PREPROGRAMMED INTO THE
- ;; PROGRAM ROM MEMORY
- ;;
- BAUD: NOP
- ;
- ; THIS SECTION AUTOMATICALLY SETS THE BAUD RATE BY DETECTING A "{"
- ;
- MOV R2,#0FEH ; COUNTER CODE FOR 9600 BAUD
- CLR RI ; CLEAR THE RECEIVER INT BIT
- SETBD: JNB RI,SETBD ; WAIT FOR A CHARACTER
- MOV A,SBUF ; GET THE CHARACTER
- CLR RI ; CLEAR THE RECEIVER INT
- CJNE A,#"{",BD48; JUMP IF NOT A "{"
- SETB SWD.2 ; SET THE PIP BIT
- MOV R4,#HCP ; RESET THE HCP PTR
- AJMP BTCHLOOP ; BAUD RATE CORRECT
- BD48: CJNE A,#9EH,BD24 ; CHECK FOR 4800 BAUD
- CLR TR1 ; STOP TIMER
- MOV TL1,#0FCH ; CONST FOR 4800 BAUD
- MOV TH1,#0FCH ;
- SETB SWD.2 ; SET PIP BIT
- MOV R4,#HCP ; RESET HCP PTR
- MOV R6,#04H ; WAITING CONSTANT
- WT1: DJNZ R6,WT1 ; WAIT FOR END OF CURRENT CHAR
- CLR RI ; CLEAR THE REC FLAG
- AJMP BTCHLOOP ; ENTER THE WAIT LOOP
- BD24: NOP
- BD1: CLR TR1 ; STOP THE TIMER
- CLR C ; CLEAR THE CARRY BIT
- MOV A,R2 ; GET THE COUNT CONSTANT
- RLC A ; DIVIDE BY 2
- MOV R2,A ; RESTORE A
- MOV TL1,A ; RESTORE TL1
- MOV TH1,A ; RESTORE TH1
- MOV R7,#80H
- MOV R6,#00H ; INITIALIZE R6
- BD2: DJNZ R6,BD2 ; TIME DELAY
- DJNZ R7,BD2
- SETB TR1 ; START TIMER 1
- CJNE A,#080H,SETBD ; GO BACK AND TRY AGAIN
- CLR TR1 ; STOP TIMER 1
- MOV TL1,#0FEH ; SET UP FOR 9600 BAUD
- MOV TH1,#0FEH ;
- MOV R2,#0FEH ; SET UP R2
- SETB TR1 ; START TIMER 1
- AJMP SETBD
- ;
- BTCHLOOP: NOP
- ;;
- ;; THESE COMMAND ARE EXECUTED BEFORE EVERY QUEUED TASK
- ;;
- MOV P2,#0FFH ; SELECT THE I/O PORTS
- OPWIND: CLR TR0 ; STOP TIMER 0
- CLR ET0 ; DISABLE TIMER INT
- SETB ES ; ENABLE SERIAL INT
- SETB EA ; ENABLE ALL INTS
- NOP
- NOP
- CLWIND: CLR EA ; DISABLE THE INTERRUPTS
- CLR TR0 ; STOP TIMER
- ;;
- ;; THIS SECTION CONTAINS COMMANDS WHICH ARE INCLUDED IN THE
- ;; TASK SERVICE LOOP
- ;;
- ;;
- SOFKEY: NOP
- NOP
- ;;
- ;; THIS SECTION CHECKS TO SEE IF A SOFTKEY HAS BEEN
- ;; DEPRESSED (NOT IMPLEMENTED)
- ;;
- GTASK: NOP ;
- ;;
- ;; THIS SECTION GETS THE FIRST TASK ON THE QUEUE AND
- ;; EXECUTES IT
- ;;
- MOV A,#BOQ ; GET BOQ POINTER
- XRL A,R3 ; COMPARE TO EOQ PTR
- JZ BTCHLOOP ; IF NO TASK, GO BACK
- ;;
- ;; CHECK TO SEE IF ACTION IS "PAUSED"
- ;;
- JB SWD.1,BTCHLOOP ; IF PAUSED, GO BACK
- ;;
- ;; SET UP RB0 REGISTERS
- ;;
- MOV 02H,#BOQ ; SET POINTER FOR R2 OF RB0
- MOV 03H,BOQ+2 ; MOVE ARG #1 TO R3 OF RB0
- MOV 04H,BOQ+3 ; MOVE ARG #2 TO R4 OF RB0
- MOV 05H,BOQ+4 ; MOVE ARG #3 TO R5 OF RB0
- MOV 06H,BOQ+5 ; MOVE ARG #4 TO R6 OF RB0
- MOV 07H,BOQ+6 ; MOVE ARG #5 TO R7 OF RB0
- ;;
- ;; SEE IF TASK READY TO RUN
- ;;
- MOV R1,#STAT ; SET PTR TO STATUS BYTE
- MOV A,@R1 ; GET THE STATUS
- ANL A,#80H ; GET MSBIT
- JZ GK2 ; NO WAIT, A ";" COMMAND
- ;;
- ;; ADJUST STATUS TO "10" (WAITING)
- ;;
- MOV A,@R1 ; GET STATUS BYTE
- ANL A,#30H ; GET BITS 5,4
- XRL A,#10H ; CHECK IF BITS 0,1
- JZ GK2 ; GO ON, READY TO RUN
- MOV A,@R1 ; GET STATUS
- ANL A,#0CFH ; PUT 0,0 IN POS 5,4
- ORL A,#20H ; PUT IN BLOCKED CODE
- MOV @R1,A ; PUT STATUS WORD BACK
- AJMP BTCHLOOP ; BLOCKED, GO BACK
- ;;
- ;; ADJUST STATUS TO "01" (BEGUN)
- ;;
- GK2: MOV A,@R1 ; GET THE STATUS WORD
- ANL A,#0CFH ; 0 BITS 5,4
- ORL A,#10H ; PUT 0,1 IN POS 5,4
- MOV @R1,A ; STORE STATUS
- ;;
- ;; ADJUST SYSTEM STATUS TO "TASK RUNNING"
- ;;
- SETB SWD.5 ; INDICATE A QUEUE TASK RUNNING
- MOV A,BOQ ; GET THE TASK NUMBER
- ;;
- ;; SERVICE THE QUEUED TASK
- ;;
- LCALL QVECTOR ; SERVICE THE TASK
- ;;
- ENTSK: CLR TR0 ; STOP TIMER 0
- ;;
- ;; THIS SECTION ADJUSTS THE STATUS WORD AND PTRS AT THE
- ;; END OF A TASK
- ;;
- CLR EA ; DISABLE THE INTERRUPTS
- CLR ET0 ; CLEAR TIMER INTERRUPT
- MOV P2,#0FFH ; SELECT THE I/O PORT
- MOV PSW,#RB3 ; MAKE SURE WE'RE IN RB3
- ;;
- ;; ADJUST SYSTEM STATUS TO "TASK DONE"
- ;;
- CLR SWD.5 ; INDICATE QUEUE TASK NOT RUNNING
- ;;
- ;; TRAP OUT THE CLEAR QUEUE CONDITION (FROM TASK1)
- ;;
- CJNE R3,#BOQ,EK0 ; IF PTR NOT RESET, GO ON
- AJMP BTCHLOOP ; GO BACK TO IDLE LOOP
- ;;
- ;; GET COUNT OF BYTES IN 1ST TASK
- ;;
- EK0: MOV A,STAT ; GET THE STATUS WORD
- ANL A,#07H ; GET BYTE COUNT IN STAT
- ADD A,#02H ; ADJUST COUNT
- MOV R6,A ; STORE COUNT
- ;;
- ;; ADVANCE BOQ PTR
- ;;
- MOV A,#BOQ ; ORIGINAL BOQ
- ADD A,R6 ; TEMP BOQ
- MOV R2,A ; STORE BOQ
- ;;
- ;; SEE IF RE-QUEUEING IS NECESSARY
- ;;
- MOV R0,#STAT ; SET PTR TO STAT REG
- MOV A,@R0 ; GET STATUS WORD
- ANL A,#40H ; GET "RE-QUEUE" BIT
- JZ EK2 ; NO RE-QUEUE NECESSARY
- ;;
- ;; RESET STATUS REGISTER OF TASK TO BE REQUEUED
- ;;
- MOV A,@R0 ; GET THE STATUS REGISTER
- ANL A,#0CFH ; PUT 0,0 IN BITS 5,4
- MOV @R0,A ; RESTORE THE STATUS
- ;;
- ;; DO THE REQUEUEING
- ;;
- MOV R0,#BOQ ; SET UP SRCE PTR IN R0
- MOV A,R6 ; GET THE BYTE COUNT IN PACK 1
- MOV R7,A ; STORE BYTE COUNT IN R7
- MOV A,R3 ; GET THE EOQ
- MOV R1,A ; SET UP DEST PTR IN R1
- EK1: MOV A,@R0 ; GET THE DATA
- MOV @R1,A ; STORE ON QUEUE
- INC R0 ; INC THE PTR
- INC R1 ; INC THE PTR
- DJNZ R7,EK1 ; GO BACK IF NOT DONE
- ;;
- ;; ADJUST EOQ
- ;;
- MOV A,R3 ; GET OLD EOQ
- ADD A,R6 ; COMPUTE NEW EOQ
- MOV R3,A ; STORE TEMP EOQ
- ;;
- ;; CALCULATE NEW EOQ (AFTER SHIFT)
- ;;
- EK2: MOV A,R6 ; GET BYTE COUNT OF 1ST PACKET
- CPL A ; NEGATE
- INC A ;
- ADD A,R3 ; COMPUTE NEW EOQ
- MOV R3,A ; STORE NEW EOQ
- XRL A,#BOQ ; CHECK FOR NO QUEUE
- JNZ EK6 ; SHIFT NECESSARY
- AJMP EK4 ; NO QUEUE TO SHIFT
- ;;
- ;; CALCULATE NUMBER OF BYTES TO SHIFT
- ;;
- EK6: MOV A,#BOQ ; ADDRESS OF BOQ
- CPL A ; NEGATE
- INC A ;
- ADD A,R3 ; THIS GIVES LENGTH OF QUEUE
- MOV R7,A ; STORE LENGTH OF QUEUE
- ;;
- ;; SHIFT THE QUEUE
- ;;
- MOV A,R2 ; TEMP BOQ PTR
- MOV R0,A ; SOURCE PTR
- MOV R1,#BOQ ; DEST PTR
- EK3: MOV A,@R0 ; GET THE DATA
- MOV @R1,A ; STORE THE DATA
- INC R0 ; INC THE PTR
- INC R1 ; INC THE PTR
- DJNZ R7,EK3 ; GO BACK TILL DONE
- ;;
- ;; CLEAR THE UNUSED PART OF QUEUE (FOR DISPLAY PURPOSES)
- ;;
- EK4: MOV A,R3 ; GET EOQ PTR
- MOV R0,A ; STORE THE PTR
- EK5: MOV @R0,#00H ; CLEAR THE LOCATION
- INC R0 ; INC THE PTR
- DJNZ R6,EK5 ; GO BACK TIL DONE
- MOV R2,#BOQ ; RESET THE BOQ PTR
- AJMP BTCHLOOP ; GO BACK AGAIN
- ;;
- ;
- ; THIS IS THE COMMON SECTION WHICH SERVICES ALL INTERRUPTS FROM
- ; THE SERIAL PORT
- ;
- CHECK ANL A,#7FH ; STRIP OFF LEADING BIT
- MOV R6,A ; STORE THE CHAR
- ;;
- ;; CHECK FOR BEGINNING OF PACKET "{"
- ;;
- CJNE R6,#"{",SR0B ; JUMP IF NOT "{"
- ;;
- ;; SET STATUS TO SHOW PACKET IN PROGRESS
- ;;
- SETB SWD.2 ; SHOW PACKET IN PROGRESS
- MOV R4,#HCP ; RESET THE PACKET PTR
- POP PSW
- POP ACC
- SETB EA ; ENABLE INTERRUPTS
- RETI
- ;;
- ;; CHECK FOR PACKET IN PROGRESS
- ;;
- SR0B: JB SWD.2,SR0A; JUMP IF PACKET IN PROGRESS
- ;;
- ;; CHECK IF LOCAL ASYNC PORT IS SENSITIZED
- ;;
- SR1: JNB SENSR.7,SR0C ; JUMP IF SER PORT NOT SENSITIZED
- ;;
- ;; SEND CHAR OUT ASYNC PORT (NO READY CHECK)
- ;;
- MOV A,R6 ; GET THE CHARACTER
- MOV R0,#UDRL ; ADDRESS OF LOC ASYNC PORT
- MOVX @R0,A ; SEND THE CHARACTER
- ;;
- ;; CHECK IF PARALLEL PORT IS SENSITIZED
- ;;
- SR0C: JNB SENSR.5,SR2 ; JUMP IF PAR PORT NOT SENSITIZED
- ;;
- ;; SEND CHAR OUT PAR PORT (NO READY CHECK)
- ;;
- MOV A,R6 ; GET THE CHARACTER
- MOV P1,A ; SEND CHAR TO THE PORT
- ANL P2,#0DFH ; SET THE STROBE
- ORL P2,#20H ; CLEAR THE STROBE
- ;;
- ;; RESTORE AC AND RETURN
- ;;
- SR2: POP PSW
- POP ACC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI
- ;;
- ;; CHECK FOR DATA LOCKOUT, ADDRESS 00H
- ;;
- ;SR0: MOV R0,#TAS ; ADDRESS OF ADDRESS SWITCH
- ; MOVX A,@R0 ; GET DEVICE ADDRESS
- ; JNZ SR0A ; JUMP IF NOT 00 ADDRESS
- ; POP PSW
- ; POP ACC ; POP THE AC STACK
- ; SETB EA ; ENABLE THE INTERRUPT ***
- ; RETI
- ;;
- ;; CHECK FOR A BLANK AND IGNORE IT
- ;;
- SR0A: CJNE R6,#" ",SE0 ; JUMP IF NOT A BLANK
- POP PSW
- POP ACC ; POP THE AC STACK
- SETB EA ; ENABLE SER INT/TIMER0 INT
- RETI
- ;;
- ;; CHECK FOR A "%" . THIS IS A RESTART COMMAND
- ;;
- SE0: CJNE R6,#"%",SE1 ; JUMP IF NOT A "%"
- AJMP START ; A RESTART, GO TO BEGINNING
- ;;
- ;; CHECK FOR A "$". THIS IS AN ADVANCE/SYNC COMMAND
- ;;
- SE1: CJNE R6,#"$",SE2 ; JUMP IF NOT A "$"
- MOV R4,#HCP ; RESET POINTER
- MOV R1,#STAT ; GET THE BOQ PTR
- MOV A,@R1 ; GET THE STATUS WORD
- ANL A,#0CFH ; PUT 0,0 IN BITS 5,4
- ORL A,#10H ; PUT 0,1 IN BITS 5,4
- MOV @R1,A ; RESTORE THE STATUS WORD
- POP PSW
- POP ACC ; RESTORE THE AC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI ; GO BACK
- ;;
- ;; CHECK FOR A "&". THIS IS AN ABORT COMMAND
- ;;
- SE2: CJNE R6,#"&",SE5C ; JUMP IF NOT A "&"
- LCALL TASK2 ; ACALL THE ABORT TASK
- ;;
- ;; CHECK FOR A "/" ACK ECHO REQUIRED
- ;;
- SE5C: CJNE R6,#"/",SE4 ; JUMP IF NOT A "/"
- SETB SWD.7 ; SET ECHO BIT IN STATUS WORD
- POP PSW
- POP ACC ; POP THE AC STACK
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI
- ;;
- ;; CHECK FOR A "}". END OF PACK, NO ECHO
- ;;
- SE4: MOV A,R6 ; GET CHAR BACK AGAIN
- XRL A,#"}" ; CHECK IF END OF A PACKET
- JZ SE5 ; AJMP IF END OF PACKET
- ;;
- ;; CHECK HERE FOR A VALID CHARACTER 0-9, A-F
- ;;
- ;; CHECK FOR PACKET TOO LONG ERROR
- ;;
- SE3D: MOV A,#ICP ; GET START ADDRESS OF ICP AREA
- XRL A,R4 ; SEE IF PTR TOO LARGE
- JNZ SE3C ; JUMP IF OK
- SE3E: SETB SWD.3 ; SET STATUS WORD ERROR BIT
- POP PSW
- POP ACC ; RESTORE THE AC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI
- ;;
- ;; THIS SECTION PUTS THE CHAR IN THE HCP AREA
- ;;
- SE3C: MOV A,R4 ; GET THE HCP PTR
- MOV R1,A ; SET UP THE PTR
- MOV A,R6 ; GET CHAR BACK AGAIN
- MOV @R1,A ; PUT CHAR IN HCP AREA
- INC R4 ; ADVANCE THE HCP PTR
- POP PSW
- POP ACC ; RESTORE THE AC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI ; GO BACK TO QUEUE TASK SERVICE
- ;
- ; HCP 20 ASCII MSB OF DEVICE ADDRESS
- ; HCP+1 21 ASCII LSB OF DEVICE ADDRESS
- ; HCP+2 22 ASCII PREFIX OF COMMAND
- ; "!" IMMEDIATE
- ; ";" PROCEED WHEN READY
- ; "?" WAIT FOR PERMISSION
- ; HCP+3 23 ASCII MSB OF TASK NUMBER
- ; HCP+4 24 ASCII LSB OF TASK NUMBER
- ; HCP+5 25 ASCII SUFFIX OF COMMAND
- ; "." DO ONCE
- ; "+" REQUEUE
- ; HCP+6 26 ASCII MSB OF ARG1
- ; HCP+7 27 ASCII LSB OF ARG1
- ; HCP+8 28 ASCII MSB OF ARG2
- ; HCP+9 29 ASCII LSB OF ARG2
- ; HCP+A 2A ASCII MSB OF ARG3
- ; HCP+B 2B ASCII LSB OF ARG3
- ; HCP+C 2C ASCII MSB OF ARG4
- ; HCP+D 2D ASCII LSB OF ARG4
- ; HCP+E 2E ASCII MSB OF ARG5
- ; HCP+F 2F ASCII MSB OF ARG5
- ;
- ;;
- ;; AT THIS POINT A COMPLETE PACKET HAS BEEN RECEIVED.
- ;; IT IS NOW SERVICED.
- ;;
- ;;
- ;; CLEAR THE PACKET IN PROGRESS BIT
- ;;
- SE5: CLR SWD.2 ; CLEAR PACKET IN PROGRESS BIT
- ;;
- ;; THIS SECTION TESTS THE ADDRESS FIELD OF THE PACKET
- ;;
- MOV R1,#HCP ; PTR TO MSB OF ADDRESS
- MOV A,@R1 ; GET PACKET ADDRESS
- ANL A,#0FH ; GET LOWER NIBBLE
- SWAP A ; SWAP NIBBLES
- MOV R7,A ; TEMP STORAGE
- INC R1 ; PTR TO LSB OF ADDRESS
- MOV A,@R1 ; GET LSB OF ADDRESS
- JB ACC.6,MS1 ; AJMP IF A-F
- AJMP MS2 ; AJMP IF 0-9
- MS1: ADD A,#09H ; CORRECT A-F
- MS2: ANL A,#0FH ; GET LOWER NIBBLE
- ORL A,R7 ; FULL ADDRESS
- ;;
- ;; CHECK IF UNIVERSAL ADDRESS
- ;;
- JNZ MS2A ; AJMP IF NOT UNIVERSAL ADDRESS
- AJMP HJ0
- MS2A: MOV R7,A ; TEMP STORE
- ;;
- ;; COMPARE TO "MY ADDRESS"
- ;;
- MOV R1,#TAS ; ADDRESS OF SWITCH REG
- MOVX A,@R1 ; GET DEVICE ADDRESS
- ANL A,#3FH ; GET LOWER 6 BITS
- XRL A,R7 ; COMPARE TO PACKET ADDRESS
- JZ MS3 ; AJMP IF "MY ADDRESS"
- POP PSW
- POP ACC ; RESTORE THE AC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI ; RETURN
- ;;
- ;; SEE IF AN "ECHO" OF PACKET IS NECESSARY
- ;;
- MS3: JNB SWD.7,HJ0 ; JUMP IF NO ECHO IS NEEDED
- CLR SWD.7 ; CLEAR THE ECHO BIT
- ;;
- ;; CONSTRUCT AND ECHO PACKET
- ;;
- MOV A,#"[" ; START OF PACKET CHAR
- ACALL OUTCHAR ; SEND FIRST CHAR
- MOV R1,#HCP ; PTR TO FIRST ASCII CHAR
- MOV A,R4 ; PTR FOR HCP
- SUBB A,#30H ; NUMBER OF BYTES ON HCP
- MOV R7,A ; SET UP COUNTER
- MS4: MOV A,@R1 ; GET THE CHAR
- ACALL OUTCHAR ; SEND THE CHAR
- INC R1 ; INCREMENT THE COUNTER
- DJNZ R7,MS4 ; GO BACK IF NOT DONE
- MS5: MOV A,#"]" ; LAST CHAR FOR PACKET
- ACALL OUTCHAR ; SEND LAST CHAR
- ;;
- ;; THIS SECTION ADJUSTS THE CODE IN THE HCP AREA SO THAT ALL
- ;; NUMERICAL DATA ARE CONVERTED FROM ASCII 0-F TO HEX 0-F.
- ;; !=1, :=A, ?=F IN LOC HCP+2
- ;; +=B, .=E IN LOC HCP+5
- ;;
- HJ0: MOV R7,#10H ; SET R7 AS A COUNTER
- MOV R1,#HCP ; SET UP R1 AS POINTER TO HCP
- HJ1: MOV A,@R1 ; GET VALUE FROM HCP AREA
- JB ACC.6,HJ1A; CHECK BIT 2
- AJMP HJ2 ; AJMP IF ALREADY 0-9 OR !,;,?,+,.
- HJ1A: ADD A,#09H ; CORRECT LOW NIBBLE IF A-F
- HJ2: ANL A,#0FH ; GET LOW NIBBLE
- MOV @R1,A ; RESTORE THE BYTE
- INC R1 ; INCREMENT THE POINTER
- DJNZ R7,HJ1 ; GO BACK IF NOT THROUGH
- ;
- ;
- ; HCP 20 HEX MSB OF DEVICE ADDRESS
- ; HCP+1 21 HEX LSB OF DEVICE ADDRESS
- ; HCP+2 22 HEX PREFIX OF COMMAND
- ; "!" IMMEDIATE
- ; ":" PROCEED WHEN READY
- ; "?" WAIT FOR PERMISSION
- ; HCP+3 23 HEX MSB OF TASK NUMBER
- ; HCP+4 24 HEX LSB OF TASK NUMBER
- ; HCP+5 25 HEX SUFFIX OF COMMAND
- ; "." DO ONCE
- ; "+" REQUEUE
- ; HCP+6 26 HEX MSB OF ARG1
- ; HCP+7 27 HEX LSB OF ARG1
- ; HCP+8 28 HEX MSB OF ARG2
- ; HCP+9 29 HEX LSB OF ARG2
- ; HCP+A 2A HEX MSB OF ARG3
- ; HCP+B 2B HEX LSB OF ARG3
- ; HCP+C 2C HEX MSB OF ARG4
- ; HCP+D 2D HEX LSB OF ARG4
- ; HCP+E 2E HEX MSB OF ARG5
- ; HCP+F 2F HEX MSB OF ARG5
- ;
- ; THIS SECTION CONSTRUCTS THE ASSEMBLED COMMAND PACKET (ACP)
- ; AND STORES IT IN THE HCP AREA. IT WILL BE TRANSFERED TO
- ; THE IMMEDIATE COMMAND PACKET (ICP) AREA OR TO THE QUEUE.
- ; LOCATION #HCP IS USED TO STORE THE PREFIX SO THAT A TEST
- ; FOR "IMMEDIATE" CAN BE MADE.
- ;
- ;
- ; STORE PREFIX FOR LATER USE TO DETERMINE IF IMMEDIATE
- ;
- SE6E: MOV R0,#HCP ; SET PTR FOR ACP
- MOV R1,#HCP+2 ; SET PTR TO PREFIX
- MOV A,@R1 ; GET PREFIX
- MOV @R0,A ; STORE PREFIX IN #HCP
- INC R0 ; INCREMENT THE ACP PTR
- ;
- ; CONSTRUCT FIRST BYTE OF ASSEMBLED PACKET, THE TASK NUM
- ;
- SE6A: MOV R1,#HCP+3 ; SET PTR TO FIRST NIB OF TASK NUM
- MOV A,@R1 ; GET THE FIRST NIBBLE
- SWAP A ; SWAP NIBBLES
- INC R1 ; INCREMENT THE HCP POINTER
- ORL A,@R1 ; APPEND THE LOWER NIB OF TASK NUM
- MOV @R0,A ; STORE FIRST BYTE OF ACP
- INC R0 ; INCREMENT ACP PTR
- ;
- ; THIS SECTION CONSTRUCTS THE STATUS WORD
- ;
- MOV R1,#HCP+2 ; SET PTR FOR FOR PREFIX
- MOV A,@R1 ; GET PREFIX; ;=0, ?=1,!=1. THE
- ; ; IMMEDIATE CONDITION (!) WILL BE
- ; ; DETECTED LATER
- ANL A,#01H ; GET LS BIT
- RR A ; PUT LSB IN MSB POS
- MOV R6,A ; TEMP STORE OF STATUS WORD
- MOV R1,#HCP+5 ; SET PTR FOR SUFFIX
- MOV A,@R1 ; GET THE SUFFIX
- ANL A,#01 ; GET THE LSB +=1, .=0
- RR A ; ROTATE
- RR A ; ROTATE AGAIN
- XRL A,R6 ; APPEND TO STATUS WORD
- MOV R6,A ; STORE TEMP
- MOV A,#HCP+6 ; GET VALUE OF START OF HCP ARGS
- CPL A ; CHANGE TO A NEG
- INC A ; NUMBER
- ADD A,R4 ; GIVES NUM OF ARG BYTES ON HCP
- MOV R4,#HCP ; RESET COUNTER
- CLR C ; CLEAR THE CARRY FLAG
- RRC A ; DIVIDE BY 2 FOR PACKING
- XRL A,R6 ; APPEND TO STATUS
- MOV @R0,A ; PUT STATUS BYTE IN ACP
- INC R0 ; INC THE ACP PTR
- ;;
- ;; PACK THE TASK ARGUMENTS
- ;;
- SE6B: MOV R1,#HCP+6 ; SET UP HCP PTR
- MOV R7,#05H ; SET UP COUNTER
- SE7: MOV A,@R1 ; GET MS BYTE OF ARG
- SWAP A ; SWAP NIBBLES
- INC R1 ; INC THE PTR
- XRL A,@R1 ; CONSTRUCT THE BYTE
- MOV @R0,A ; PUT ON ACP
- INC R1 ; INC THE HCP PTR
- INC R0 ; INC THE ACP PTR
- DJNZ R7,SE7 ; DO UNTIL PACKET FINISHED
- ;
- ; HCP 30 HEX LSB OF PREFIX
- ; HCP+1 31 HEX TASK NUMBER
- ; HCP+2 32 HEX STATUS WORD
- ; 7 =0 PROCEED WHEN READY ":"
- ; =1 WAIT FOR PERMISSION "?"
- ; 6 =0 DO ONCE "."
- ; =1 RE-QUEUE "+"
- ; 54 =00 NOT YET BEGUN
- ; =01 BEGUN
- ; =10 WAITING FOR "$" SYNC SIGNAL
- ; =11 FINISHED
- ; 3210 = NUMBER OF ARGUMENTS (0 - 5)
- ; HCP+3 33 HEX ARG1
- ; HCP+4 34 HEX ARG2
- ; HCP+5 35 HEX ARG3
- ; HCP+6 36 HEX ARG4
- ; HCP+7 37 HEX ARG5
- ;
- ;;
- ;; AT THIS POINT THE PACKET SHOULD BE ASSEMBLED AND IN
- ;; THE HCP AREA. THE FIRST BYTE IS THE PREFIX. IT WILL
- ;; BE USED TO TEST FOR IMMEDIATE.
- ;;
- ;;
- ;; TEST IF IMMEDIATE
- ;;
- SE8: MOV A,HCP ; GET THE PREFIX
- CJNE A,#01H,QUEUE ; JUMP IF NOT IMMEDIATE
- ;;
- ;; TEST HERE TO SEE IF IMMEDIATE IS ALREADY RUNNING
- ;;
- SE20: JNB SWD.6,ST1 ; JUMP IF IMMED IS NOT RUNNING
- ;;
- ;; IGNORE THE IMMEDIATE COMMAND AND RETURN
- ;;
- POP PSW ; RESTORE THE PSW
- POP ACC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI ; GO BACK
- ;;
- ;; STORE THE PACKET
- ;;
- ST1: MOV R0,#ICP ; SET PTR FOR ICP AREA
- MOV R1,#HCP+1 ; SET PTR FOR COM IN HCP
- MOV R7,#07H ; SET UP COUNT FOR TRANSFER
- ID1: MOV A,@R1 ; GET DATA FROM HCP
- MOV @R0,A ; TRANSFER DATA TO ICP
- INC R0 ; INC THE DEST PTR
- INC R1 ; INC THE SOURCE PTR
- DJNZ R7,ID1 ; REPEAT TIL PACKET TRANSFERED
- ;;
- ;; NOW PUT THE PTR TO THE HEAD OF QUEUE IN R2 OF RB1
- ;;
- MOV 0AH,#ICP ; SET START-OF-TASK POINTER
- ;
- ; R1 ICP 09 TASK NUMBER
- ; R2 ICP+1 0A PTR TO TASK ARGS
- ; R3 ICP+2 0B ARG1
- ; R4 ICP+3 0C ARG2
- ; R5 ICP+4 0D ARG3
- ; R6 ICP+5 0E ARG4
- ; R7 ICP+6 0F ARG5
- ;
- ;;
- ;; ADJUST SYSTEM STATUS TO "IMMED TASK RUNNING"
- ;;
- SETB SWD.6 ; INDICATE A IMMED TASK RUNNING
- ;;
- ;; SERVICE THE IMMEDIATE COMMAND
- ;;
- MOV A,ICP ; PUT TASK NUMBER IN AC
- LCALL IVECTOR ; SERVICE THE TASK
- ;;
- ;; ADJUST SYSTEM STATUS TO "TASK DONE"
- ;;
- CLR SWD.6 ; CLEAR IMMED TASK RUN BIT
- SETB TR0 ; START THE CLOCK AGAIN
- ;;
- ;; PREPARE TO RETURN TO QUEUED TASK/IDLE LOOP
- ;;
- POP PSW
- POP ACC ; RESTORE THE AC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI ; GO BACK
- ;;
- QUEUE: NOP
- ;;
- ;; THE QUEUE SUBROUTINE PLACES THE APPRORIATE DATA ON THE
- ;; TASK QUEUE
- ;;
- MOV R0,#HCP+2 ; SET PTR TO STATUS WORD
- MOV A,@R0 ; GET STATUS WORD
- ANL A,#07H ; GET LOWEST 3 BITS
- ADD A,#02H ; ACCOUNT FOR 1ST 2 BYTES
- MOV R6,A ; STORE COUNT IN R6
- MOV A,R3 ; GET EOQ PTR
- MOV R0,A ; PUT EOQ PTR IN R0
- MOV R1,#HCP+1 ; SET UP SOURCE PTR
- QE1: MOV A,R0 ; GET EOQ PTR
- XRL A,#EOQ+1 ; SEE IF AN OVERFLOW
- JNZ QE2 ; JUMP IF QUEUE NOT FULL
- MOV R0,#SWD ; PTR TO OS STATUS REGISTER
- MOV A,@R0 ; GET THE OS STATUS REG
- ORL A,#09H ; PUT 1 IN BIT 0,3,"QUE OVERFLOW"
- MOV @R0,A ; RESTORE
- AJMP EXIT ; GO BACK AGAIN
- QE2: MOV A,@R1 ; GET DATA
- MOV @R0,A ; PUT ON QUEUE
- INC R0 ; INC DEST PTR
- INC R1 ; INC SOURCE PTR
- DJNZ R6,QE1 ; GO BACK TIL DONE
- MOV A,R0 ; GET DEST PTR
- MOV R3,A ; STORE AS NEW EOQ
- ;;
- ;; PREPARE TO RETURN TO MAIN PROGRAM
- ;;
- EXIT: CLR SWD.0 ; CLEAR OVERFLOW ERROR BIT
- POP PSW
- POP ACC ; RESTORE THE AC
- SETB EA ; ENABLE ALL INTERRUPTS
- RETI ; GO BACK TO IDLE LOOP
- ;;
- ;; OPERATING SYSTEM SUBROUTINES
- ;;
- ;;
- OUTCHAR: NOP ; REDIRECT TO OUTCHRI, THE INTERNAL PORT
- OUTCHRI: NOP ;(A,R0,R6)
- ;;
- ;; THIS SUBROUTINE ACCEPTS A CHARACTER PASSED VIA THE AC
- ;; AND TRANSMITS IT VIA THE INTERNAL SERIAL PORT TO HOST
- ;;
- OI1: JB SENSR.2,OI2 ; CHECK THE READY FLAG
- JNB TI,OI1 ; WAIT FOR TI FLAG
- OI2: MOV SBUF,A ; SEND THE DATA
- CLR TI ; CLEAR THE TI FLAG
- CLR SENSR.2 ; CLEAR THE TRANS RDY FLAG
- OI4: RETI
- ;;
- ;;
- ;; COPYRIGHT MESSAGE FOR ROM
- ;;
- DB "COPYRIGHT 1984, J.HERZOG, J EBNER"
- RETI ; DUMMY RETURN
- ;;
- ;;
- GETCHAR: NOP ; REDIRECT FROM GETCHAR
- GETCHRI: NOP
- ;; THIS SUBROUTINE GETS A CHARACTER FROM THE INTERNAL
- ;; SERIAL PORT AND RETURNS IN IN THE AC
- ;;
- MOV A,SBUF ; GET THE CHARACTER
- CLR RI ; CLEAR THE INT FLAG
- RETI
- ;;
- INIT: NOP ;RB1:(A,R0,R2,R3,R4,R7,F0,F1)
- ;;
- ;; INITIALIZE THE RAM AND PORTS FOR THE OP SYS
- ;;
- MOV PSW,#RB3 ; SELECT REG BANK 3
- MOV IE,#00H ; DISABLE THE INTERRUPTS
- CLR A ; CLEAR THE ACC
- MOV R0,#50H
- MOV R6,#30H
- T01: MOV @R0,A ; CLEAR A MEMORY LOCATION
- INC R0 ; PT TO NEXT LOCATION
- DJNZ R6,T01 ; GO BACK TILL DONE
- MOV R2,#BOQ ; SET UP BEGIN OF QUE PTR
- MOV R3,#BOQ ; SET UP END OF QUE PTR
- MOV R4,#HCP ; SET UP COMMAND PKT PTR
- MOV R0,#LED ; LED ADDRESS
- MOV A,#00H ; PUT FF IN THE AC
- MOVX @R0,A ; TURN ON THE LED, OFF THE BUZZER
- MOV P1,#0FFH ; PUT "FF" ON PORT 1
- MOV P2,#0FFH ; PUT "FF" ON PORT 2
- ;;
- ;; INITIALIZE TIMER 0 (TIMEOUT) TIMER 1 (SERIAL BAUD RATE)
- ;; INITIALIZE INTERNAL SERIAL PORT
- ;;
- MOV TMOD,#21H ; CNTR 1 FOR UART/CNTR 0 FOR TIMEOUT
- MOV TH1,#0FEH ; 9600 BAUD
- MOV TL1,#0FEH ; 9600 BAUD
- MOV TCON,#40H ; START TIMER #1
- MOV TH0,#10H ; PRESET TIMER CONSTANT
- MOV TL0,#00H ; PRESET TIMER CONSTANT
- MOV SCON,#52H ; REC &TRAN ENABLED, SET TRANS FLAG
- CLR TI ; CLEAR THE TRANSMITTER FLAG
- SETB SENSR.2 ; SET TRAMSMIT RDY FLAG
- CLR A ; CLEAR THE ACC
- RETI
- ;;
- ;; DUMMY SUBROUTINE
- ;;
- DUMMY: RETI ; FOR CLEARING INTERRUPT
- ;;
- ;;
- HEXASC: NOP ;(A)
- ;;
- ;; CONVERTS A XEXADECIMAL CHARACTER TO ASCII
- ;;
- ANL A,#0FH ; GET LS NIBBLE
- ORL A,#30H ; CREATE ASCII
- JB ACC.3,HC4 ; TEST FOR 8 - F
- AJMP HC6 ; JUMP IF NOT 8-F
- HC4: JB ACC.2,HC5 ; CORRECTION NEEDED
- JB ACC.1,HC5 ; CORRECTION NEEDED
- AJMP HC6 ; 8 OR 9, NO CORRECTION
- HC5: ADD A,#07 ; CORRECT FOR A-F
- HC6: RET ; ALL DONE
- ;;
- SENDASC: NOP ;(A,R0,R5,R6)
- ;;
- ;;
- ;; TAKES A HEXADECIMAL CHARACTER, CONVERTS IT TO TWO
- ;; ASCII CHARACTERS AND SENDS THEM TO THE HOST
- ;;
- MOV R5,A ; TEMP STORE OF DATA
- SWAP A ; GET MS NIBBLE
- ANL A,#0FH ; GET LS NIBBLE
- ORL A,#30H ; CREATE ASCII
- JB ACC.3,HA1 ; TEST FOR 8 - F
- AJMP HA3 ; JUMP IF NOT 8-F
- HA1: JB ACC.2,HA2 ; CORRECTION NEEDED
- JB ACC.1,HA2 ; CORRECTION NEEDED
- AJMP HA3 ; 8 OR 9, NO CORRECTION
- HA2: ADD A,#07 ; CORRECT FOR A-F
- HA3: ACALL OUTCHAR ; SEND FIRST CHAR, MSB
- MOV A,R5 ; GET DATA BACK
- ANL A,#0FH ; GET LS NIBBLE
- ORL A,#30H ; CREATE ASCII
- JB ACC.3,HA4 ; TEST FOR 8 - F
- AJMP HA6 ; JUMP IF NOT 8-F
- HA4: JB ACC.2,HA5 ; CORRECTION NEEDED
- JB ACC.1,HA5 ; CORRECTION NEEDED
- AJMP HA6 ; 8 OR 9, NO CORRECTION
- HA5: ADD A,#07 ; CORRECT FOR A-F
- HA6: ACALL OUTCHAR ; SEND LSB
- RET
- ;;
- QVECTOR: NOP ;
- ;;
- ;; THIS SERVICES A QUEUED TASK
- ;; THE QVECTOR SUBROUTINE CAUSES A JUMP TO THE
- ;; PROPER TASK. IT ASSUMES THE TASK NUMBER IS IN
- ;; THE ACCUMULATOR.
- ;;
- ;; SET UP THE TIMEOUT REGISTERS (IF USED)
- ;;
- ;;
- JNB SENSR.3,VR1 ; JUMP IF TIMEOUT NOT ACTIVE
- PUSH ACC ; PUT ACC ON STACK
- MOV PSW,#RB2 ; USE RB2 FOR TIMER ACTIONS
- MOV A,R5 ; GET HI BYTE OF CONSTANT
- MOV R2,A ; SET UP HI BYTE OF COUNTER
- MOV A,R6 ; GET MID BYTE OF CONSTANT
- MOV R3,A ; SET UP MID BYTE OF COUNTER
- MOV A,R7 ; GET LO BYTE OF CONSTANT
- MOV R4,A ; SET UP LO BYTE OF COUNTER
- POP ACC ; GET ACC BACK
- MOV PSW,#RB3 ; USE RB3
- VR1: ANL A,#7FH ; MAKE SURE LEADING BIT IS A 0
- MOV R7,A ; TEMP STORE
- RL A ; MULT BY 2
- ADD A,R7 ; MULT BY 3
- MOV PSW,#RB0 ; USE RB0 FOR QUEUED TASKS
- MOV TH0,#10H ; SET UP HIGH COUNT OF COUNTER 0
- MOV TL0,#00H ; CLEAR LOW COUNT OF COUNTER 0
- SETB TR0 ; START TIMER 0
- SETB ET0 ; ENABLE TIMER 0 INTERRUPT
- SETB ES ; ENABLE SERIAL INTERRUPT
- MOV DPTR,#TABT; DISPLACEMENT FOR TASK TABLE
- JMP @A+DPTR ; VECTOR TO TASK
- ;;
- IVECTOR: NOP
- ;;
- ;; VECTOR TO THE TASK (ENTRY POINT FOR AN IMMEDIATE TASK)
- ;;
- ANL A,#7FH ; MAKE SURE LEADING BIT IS A 0
- MOV R7,A ; TEMP STORE
- RL A ; MULT BY 2
- ADD A,R7 ; MULT BY 3
- MOV PSW,#RB1 ; USE RB1 FOR IMMED TASK
- SETB ES ; ENABLE SERIAL INTERRUPT
- MOV DPTR,#TABT; DISPLACEMENT FOR TASK TABLE
- JMP @A+DPTR ; VECTOR TO TASK
- ;;
- ;; MEMORY BANK 0 TASKS
- ;;
- ;; VOLUME I: QUEUE MANAGEMENT AND UTILITY TASKS
- ;;
- TABT: LJMP TASK0 ; RSET :RESET THE TASK-MASTER
- LJMP TASK1 ; CLRQ :CLEAR THE QUEUE
- LJMP TASK2 ; ABRT :ABORT THE CURRENT TASK
- LJMP TASK3 ; SYNC :START A SYNC TASK FROM QUEUE
- LJMP TASK4 ; PAUS :PAUSE IN THE CURRENT TASK
- LJMP TASK5 ; RESM :RESUME A PAUSED TASK
- LJMP TASK6 ; TIME :SET THE TIMEOUT REGISTER
- LJMP TASK7 ; NULL :NULL TASK
- LJMP TASK8 ; INFT :TASK WITH INFINITE LOOP
- LJMP TASK9 ; DUMP :CONTENTS OF TASK QUE TO HOST
- LJMP TASKA ; POLL :POLL THE UNITS
- LJMP TASKB ; HTOM :HOST TO DATA MEM TRANSFER
- LJMP TASKC ; MTOH :DATA MEM TO HOST TRANSFER
- LJMP TASKD ; HTOX :HOST TO EXTERNAL MEM
- LJMP TASKE ; XTOH :EXTERNAL MEM TO HOST
- LJMP TASKF ; SLAP :SENSTITZE ASYNC PORT
- LJMP TASK10 ; DLAP :DESENSITIZE ASYNC PORT
- LJMP TASK11 ; SLPP :SENSITIZE PARALLEL PORT
- LJMP TASK12 ; DLPP :DESENSITIZE PARALLEL PORT
- LJMP TASK13 ; DLAY :TIME DELAY
- LJMP TASK14 ; BEEP :AUDIO SIGNAL
- LJMP TASK15 ; BLNK :FRIENDLY BLINK OF LED
- LJMP TASK16 ; KLIK :CLICKING NOISE
- LJMP TASK17 ; P1TH :PORT 1 TO HOST DATA TRANS
- LJMP TASK18 ; HTP1 :HOST TO PORT 1 DATA TRANS
- LJMP TASK19 ; P2TH :PORT 2 TO HOST DATA TRANS
- LJMP TASK1A ; HTP2 :HOST TO PORT 2 DATA TRANS
- LJMP TASK1B ; INT0 :T0 TO HOST TRANSFER
- LJMP TASK1C ; INT1 :T1 TO HOST TRANSFER
- LJMP TASK1D ; ASPT :ACTIVE STIM PROGRAM
- LJMP TASK1E ; SPARE
- LJMP TASK1F ; SPARE
- ;;
- ;; VOLUME II : INPUT/OUTPUT TASKS
- ;;
- LJMP TASK20 ; PARP :PARALLEL PORT
- LJMP TASK21 ; DPT1 ;8 BIT DATA PORT #1
- LJMP TASK22 ; DPT2 :8 BIT DATA PORT #2
- LJMP TASK23 ; DPT3 ;4 BIT DATA PORT #3
- LJMP TASK24 ; DPT4 ;4 BIT DATA PORT #4
- LJMP TASK25 ; SSPT :4 BIT SWITCH SENSE PORT
- LJMP TASK26 ; RLPT :4 BIT RELAY PORT
- LJMP TASK27 ; HTOQ :HOST TO DATA QUEUE
- LJMP TASK28 ; QTOH :DATA QUEUE TO HOST
- LJMP TASK29 ; BEEP :BEEP (REPEAT)
- LJMP TASK2A ; BLNK :BLINK (REPEAT)
- LJMP TASK2B ; SPARE
- LJMP TASK2C ; SPARE
- LJMP TASK2D ; LPTH :LOCAL ASYNC PORT TO HOST
- LJMP TASK2E ; SERP :SERIAL PORT
- LJMP TASK2F ; DECP :DECREMENT LOC AND PAUSE ON 0
- LJMP TASK30 ; PRAR :POLL,REPORT AND RESUME
- LJMP TASK31 ; :SPARE
- LJMP TASK32 ; :SPARE
- LJMP TASK33 ; :SPARE
- LJMP TASK34 ; :SPARE
- LJMP TASK35 ; :SPARE
- LJMP TASK36 ; :SPARE
- LJMP TASK37 ; :SPARE
- ;;
- ;; VOLUME III : APPLICATION TASKS
- ;;
- LJMP TASK38 ; EVNT :UPDATE THE EVENT REGISTER
- LJMP TASK39 ; WFEV :WAIT FOR EVENT, THEN ABORT
- LJMP TASK3A ; :SPARE
- LJMP TASK3B ; :SPARE
- LJMP TASK3C ; :SPARE
- LJMP TASK3D ; :SPARE
- LJMP TASK3E ; :SPARE
- LJMP TASK3F ; :SPARE
- ;
- ;; VOLUME IV : APPLICATION TASKS FOR SPECIALIZED HARDWARE
- ;;
- LJMP TASK40 ; TALK :DIGITALK SUPPORT
- LJMP TASK41 ; :SPARE
- LJMP TASK42 ; :SPARE
- LJMP TASK43 ; :SPARE
- LJMP TASK44 ; :SPARE
- LJMP TASK45 ; :SPARE
- LJMP TASK46 ; :SPARE
- LJMP TASK47 ; :SPARE
- LJMP TASK48 ; :SPARE
- LJMP TASK49 ; :SPARE
- LJMP TASK4A ; :SPARE
- LJMP TASK4B ; :SPARE
- LJMP TASK4C ; :SPARE
- LJMP TASK4D ; :SPARE
- LJMP TASK4E ; :SPARE
- LJMP TASK4F ; :SPARE
- ;;
- ;;
- TASK0: CLR EA ; DISABLE THE INTERRUPTS
- ;;
- ;; RSET :SYSTEM RESET
- ;;
- MOV R0,#SWD ; ADDRESS OF STATUS WORD
- MOV @R0,#00H ; CLEAR THE STATUS WORD
- CLR TR0 ; STOP TIME-OUT CLOCK
- CLR ET0 ; DISABLE TIME-OUT INTERRUPT
- LJMP START ; GO BACK TO STARTUP PROCEEDURE
- RETI ; DUMMY SUBROUTINE RETURN
- ;;
- TASK1: NOP
- ;;
- ;; CLRQ :
- ;;
- MOV PSW,#RB3 ; USE OP SYSTEM REG BANK
- JB SWD.5,T11 ; JUMP IF SOMETHING ON THE QUEUE
- RETI ; RETURN IF NO TASK RUNNING
- T11: MOV SWD,#00H ; CLEAR THE STATUS WORD
- MOV A,R3 ; GET EOQ
- SUBB A,#BOQ ; GET LENGTH OF QUEUE
- MOV R3,A ; SET UP A COUNTER
- MOV A,#00H ; CLEAR THE ACC
- MOV R0,#BOQ ; SET UP A PTR TO QUEUE
- T12: MOV @R0,A ; CLEAR A LOCATION
- INC R0 ; INCREMENT THE POINTER
- DJNZ R3,T12 ; GO BACK TIL DONE
- MOV R2,#BOQ ; RESET START OF QUE
- MOV R3,#BOQ ; RESET END OF QUEUE
- MOV R4,#HCP ; RESET THE HCP POINTER
- MOV SP,#SOS+2 ; ALTER THE SP
- CLR TR0 ; STOP TIME-OUT CLOCK
- CLR ET0 ; DISABLE TIME-OUT INTERRUPT
- RETI ; GO BACK
- ;;
- TASK2: NOP
- ;;
- ;; ABRT : AN ADDRESSED ABORT
- ;;
- MOV PSW,#RB3 ; USE REG BANK 3
- JB SWD.5,T101; JUMP IF QUEUED TASK IS RUNNING
- RETI ; RETURN
- T101: CLR SWD.5 ; CLEAR QUEUED TASK RUN BIT
- CLR SWD.6 ; CLEAR IMMED TASK RUN BIT
- MOV R4,#HCP ; RESET POINTER
- MOV SP,#SOS+2 ; RESET THE SP
- CLR TR0 ; STOP TIME-OUT CLOCK
- CLR ET0 ; DISABLE TIME-OUT INTERRUPT
- RETI ; GO BACK
- ;;
- TASK3: NOP
- ;;
- ;; SYNC :ADVANCE/SYNCHRONIZE
- ;;
- MOV PSW,#RB3 ; USE RB3
- MOV A,R2 ; GET THE BOQ PTR
- INC A ; PT TO THE STATUS WORD
- MOV R1,A ; SET UP R1 AS PTR
- MOV A,@R1 ; GET THE STATUS WORD
- ANL A,#0CFH ; PUT 00 IN BITS 5,4
- ORL A,#10H ; PUT 01 IN BITS 5,4
- MOV @R1,A ; RESTORE THE STATUS WORD
- RETI ; GO BACK
- ;;
- TASK4: NOP
- ;;
- ;; PAUS :PAUSE THE TASK (IMMEDIATE ONLY)
- ;;
- SETB SWD.1 ; SET THE PAUSE BIT
- RETI
- ;;
- TASK5: NOP
- ;;
- ;; RESM :RESUME THE TASK (IMMEDIATE ONLY)
- ;;
- CLR SWD.1 ; CLEAR THE PAUSE BIT
- RETI ; GO BACK
- TASK6: NOP
- ;;
- ;; TIME :LOAD THE TIME OUT REGISTERS
- ;;
- CLR TR0 ; STOP THE CLOCK
- MOV A,R2 ; GET THE BOQ PTR
- ADD A,#02H ; POINT TO 1ST ARG (HI BYTE)
- MOV R0,A ; SET UP THE POINTER
- MOV R1,#15H ; POINTER TO HIGH TIME OUT CONSTANT
- MOV R6,#03H ; SET UP COUNTER
- CLR SENSR.3 ; DISABLE TIMEOUT
- TE1: MOV A,@R0 ; GET THE DATA
- CJNE A,#00H,TE3 ; CHECK IF NOT 0
- AJMP TE4 ;
- TE3: SETB SENSR.3 ; THERE IS A NON ZERO VALUE
- TE4: CPL A ; COMPLEMENT THE COUNT
- MOV @R1,A ; STORE THE DATA IN TOC
- INC R0 ; INC THE POINTER
- INC R1 ; INC THE POINTER
- DJNZ R6,TE1 ; GO BACK IF NOT DONE
- RETI
- ;;
- TASK7: NOP
- ;;
- ;; NULL :NULL TASK
- ;;
- NOP
- RETI
- ;;
- TASK8: NOP
- ;;
- ;; INFT : NON-TERMINIATING TASK
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- T81: AJMP T81 ; STAY IN JUMP LOOP
- CLR EA ; DISABLE THE INTERRUPT
- RETI
- ;;
- TASK9: NOP ;(A,R1,R4,) [GETCHAR]
- ;;
- ;; DUMP :OUTPUT THE TASK QUEUE
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV A,#"[" ; START OF PACKET CHAR
- LCALL OUTCHAR ; SEND IT
- MOV R1,#50H ; SET PTR TO START OF TASK QUEUE
- MOV R7,#30H ; SET UP COUNTER
- T82: MOV A,@R1 ; GET THE DATA
- LCALL SENDASC ; SEND TO THE HOST IN ASCII
- INC R1 ; INCREMENT THE POINTER
- DJNZ R7,T82 ; LOOP BACK TILL DONE
- MOV A,#"]" ; END OF PACKET CHARACTER
- LCALL OUTCHAR ; SEND TO HOST
- CLR EA ; DISABLE INTERRUPTS
- RETI ; GO BACK
- ;;
- TASKA: NOP
- ;;
- ;; POLL : IDENTIFY UNIT TO HOST
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV A,#"[" ; FIRST CHAR FOR PACKET
- LCALL OUTCHAR ; SEND "["
- MOV R1,#TAS ; PTR TO ADDRESS
- MOVX A,@R1 ; GET THE ADDRESS
- LCALL SENDASC ; SEND THE TWO ASCII CHARACTERS
- MOV A,#" " ; BLANK CHARACTER FOR DELIMITER
- LCALL OUTCHAR ; SEND " "
- MOV R1,#EVENT ; PTR TO EVENT REGISTER
- MOV A,@R1 ; GET EVENT REGISTER
- LCALL SENDASC ; SEND THE TWO ASCII CHARACTERS
- MOV A,#"]" ; END OF PACKET CHAR
- LCALL OUTCHAR ; SEND "]"
- CLR EA ; DISABLE INTERRUPTS
- RETI
- ;;
- ;;
- TASKB: NOP ; (A,R0,P1)
- ;;
- ;; HTOM : HOST DATA TO MEMORY: ARG 1 = ADDRESS, ARG 2 = DATA
- ;;
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV A,R2 ; GET QUEUE PTR
- ADD A,#02H ; GET PTR TO DATA DEST PTR
- MOV R0,A ; SET UP PTR TO DATA DEST PTR
- MOV A,@R0 ; GET DEST PTR
- MOV R1,A ; SET UP PTR TO DATA DEST
- INC R0 ; SET UP PTR TO DATA
- MOV A,@R0 ; GET THE DATA
- MOV @R1,A ; WRITE TO DATA MEMORY
- CLR EA
- RETI ; ALL DONE
- ;;
- ;;
- TASKC: NOP ; (A,R0,P1)
- ;;
- ;; MTOH: MEMORY DATA TO HOST, ARG1 = ADDRESS
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV A,#"[" ; START OF PACKET CHARACTER
- LCALL OUTCHAR ; SEND "["
- MOV A,R2 ; GET QUEUE PTR
- ADD A,#02 ; GET ADDRESS OF PTR
- MOV R0,A ; SET UP PTR TO DATA PTR
- MOV A,@R0 ; GET THE PTR TO DATA
- MOV R0,A ; SET UP PTR TO DATA
- MOV A,@R0 ; GET THE DATA
- LCALL SENDASC ; SEND TO THE HOST
- MOV A,#"]" ; END OF PACKET CHARACTER
- LCALL OUTCHAR ; SEND "]"
- CLR EA
- RETI ; ALL DONE
- ;;
- TASKD: NOP ; (A,R0,R1,P1)
- ;;
- ;; HTOX : WRITE DATA TO EXTERNAL ADDRESS SPACE,
- ;; ARG 1 = ADDRESS, ARG 2 = DATA
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV PSW,#RB0 ; SELECT RB0
- MOV A,R2 ; GET QUEUE PTR
- ADD A,#02H ; GET PTR TO DATA DEST PTR
- MOV R0,A ; SET UP PTR TO DATA DEST PTR
- MOV A,@R0 ; GET DEST PTR
- MOV R1,A ; SET UP PTR TO DATA DEST
- MOV A,R0 ; SET UP PTR TO DATA
- INC A
- ANL A,#0DFH ; ADJUST FOR OVERFLOW
- MOV R0,A
- MOV A,@R0 ; GET THE DATA
- MOVX @R1,A ; WRITE TO EXT ADD SPACE
- CLR EA
- RETI ; ALL DONE
- ;;
- TASKE: NOP ;
- ;;
- ;; XTOH : EXTERNAL ADDRESS SPACE TO HOST; ARG 1 = ADDRESS
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV A,#"[" ; START OF PACKET CHARACTER
- ACALL OUTCHAR ; SEND "["
- MOV A,R2 ; GET QUEUE PTR
- ADD A,#02 ; GET ADDRESS OF PTR
- MOV R0,A ; SET UP PTR TO DATA PTR
- MOV A,@R0 ; GET THE PTR TO DATA
- MOV R0,A ; SET UP PTR TO DATA
- MOVX A,@R0 ; GET THE DATA
- ACALL SENDASC ; SEND TO THE HOST
- MOV A,#"]" ; END OF PACKET CHARACTER
- ACALL OUTCHAR ; SEND "]"
- CLR EA
- RETI ; ALL DONE
- ;;
- TASKF: NOP
- ;;
- ;; SLAP : SENSITIZE THE SYSTEM SO THAT INFORMATION NOT
- ;; : WITHIN { } IS SENT TO THE ASYNC OUTPUT PORT
- ;;
- MOV R0,#SENSR ; ADDRESS OF SENS REG
- MOV A,@R0 ; GET THE STATUS
- ORL A,#80H ; SET THE SENSITIZE BIT
- MOV @R0,A ; RESTORE THE STATUS
- CLR EA
- RETI
- ;;
- TASK10: NOP ; WHY DOES THIS GET DELETED
- ;;
- ;; DLAP : DESENSITIZE THE LOCAL ASYNC PORT SO THAT IT
- ;; : NO LONGER ACCEPTS DATA
- ;;
- MOV IE,#00H ;
- MOV R0,#SENSR ; ADDRESS OF SENS REG
- MOV A,@R0 ; GET THE STATUS
- ANL A,#07FH ; CLEAR THE SENSITIZE BIT
- MOV @R0,A ; RESTORE THE STATUS
- MOV IE,#00H
- RETI
- ;;
- TASK11: NOP ;
- ;;
- ;; SLPP : SENSITIZE THE PARALLEL PRINTER PORT
- ;;
- MOV R0,#SENSR ; ADDRESS OF SENS REG
- MOV A,@R0 ; GET THE STATUS
- ORL A,#20H ; SET THE SENSITIZE BIT
- MOV @R0,A ; RESTORE THE STATUS
- MOV IE,#00H
- RETI
- ;;
- TASK12: NOP ;
- ;;
- ;; DLPP : DESENSITIZE THE PARALLEL PRINTER PORT
- ;;
- MOV R0,#SENSR ; ADDRESS OF SENS REG
- MOV A,@R0 ; GET THE STATUS
- ANL A,#0DFH ; CLEAR THE SENSITIZE BIT
- MOV @R0,A ; RESTORE THE STATUS
- RETI
- ;;
- TASK13: MOV PSW,#RB0 ; (A,R0,R5,R6,R7)
- ;;
- ;; DLAY :TIME DELAY
- ;;
- MOV IE,#92H ;ENABLE THE INTERRUPT
- MOV R6,#00 ; SET COUNT IN R6
- MOV R7,#00 ; SET COUNT IN R7
- MOV A,R2 ; GET QUEUE PTR
- ADD A,#02H ; GET ADDR OF 1ST ARG
- MOV R0,A ; SET PTR TO 1ST ARG
- MOV A,@R0 ; GET 1ST ARG
- MOV R5,A ; STORE REPITITION NUMBER
- T111: DJNZ R7,T111 ; COUNT DOWN R7
- DJNZ R6,T111 ; COUNT DOWN R6
- DJNZ R5,T111 ; COUNT DOWN R5
- MOV IE,#00H
- RETI ; ALL DONE
- ;;
- TASK14: NOP ;RB0:(A,R0,R6,R7,P1,P2,LED)
- ;;
- ;; BEEP :BEEP THE BUZZER
- ;;
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV PSW,#RB0 ; SELECT RB 0
- MOV R0,#LED ; ADDRESS OF THE LED
- MOV R5,#20H ; NUMBER OF BEEPS
- MOV A,#00H ; BEEP CHARACTER
- TFQ: MOVX @R0,A ; BEEP BUY DON'T BLINK
- MOV R6,#30H ; SET UP DELAY COUNTER
- MOV R7,#00H ; SET UP DELAY COUNTER
- TF2: DJNZ R7,TF2 ; STAY TILL 0
- DJNZ R6,TF2 ; GO BACK TILL 0
- XRL A,#02H ; TOGGLE THE BEEP CHARACTER
- DJNZ R5,TFQ
- MOV IE,#00H
- RETI ; ALL DONE
- ;;
- TASK15: NOP ;RB0:(A,R0,R6,R7,P1,P2,LED)
- ;;
- ;; BLNK :BLINK THE LED
- ;;
- BLNKN EQU 10H ; THE NUMBER OF BLINKS
- SETB EA ; ENABLE ALL INTERRUPTS
- MOV R0,#LED ; ADDRESS OF THE LED
- MOV A,#BLNKN ; GET THE BLINK NUMBER
- JZ TA3 ; GO BACK IF NO BLINKS
- MOV R5,A ; NUMBER OF BLINKS
- MOV A,#03H ; BLINK CHARACTER
- TA1: MOVX @R0,A ; BLINK BUT DON'T BEEP
- MOV R6,#50H ; SET UP DELAY COUNTER
- MOV R7,#00H ; SET UP DELAY COUNTER
- TA2: DJNZ R7,TA2 ; STAY TILL 0
- DJNZ R6,TA2 ; GO BACK TILL 0
- XRL A,#01H ; TOGGLE THE BLINK CHARACTER
- DJNZ R5,TA1
- TA3: CLR EA ; DISABLE THE INTERRUPTS
- RETI ; ALL DONE
- ;;
- TASK16: NOP
- ;;
- ;; KLIK : SHORT CLICKING SOUND
- ;;
- MOV IE,#90H ;ENABLE THE INTERRUPT
- MOV R0,#LED ; ADDRESS OF THE LED
- MOV A,#00H ; BEEP CHARACTER
- MOVX @R0,A ; BEEP BUT DON'T BLINK
- MOV R6,#50H ; SET UP DELAY COUNTER
- MOV R7,#00H ; SET UP DELAY COUNTER
- T161: DJNZ R7,T161 ; STAY TILL 0
- DJNZ R6,T161 ; GO BACK TILL 0
- XRL A,#02H ; TOGGLE THE BEEP CHARACTER
- MOVX @R0,A ; TURN OFF BEEP
- MOV IE,#00H
- RETI ; ALL DONE
- ;;
- TASK17: NOP
- ;;
- ;; P1TH : PORT 1 TO HOST
- ;;
- MOV IE,#90H ;ENABLE THE INTERRUPT
- MOV A,#"[" ; START BRACKET
- ACALL OUTCHAR ; SEND BRACKET
- MOV A,P1 ; GET THE PORT DATA
- ACALL SENDASC ; SEND DATA TO THE HOST
- MOV A,#"]" ; ENDING BRACKET
- ACALL OUTCHAR ; SEND END BRACKET
- MOV IE,#00H
- RETI ; ALL DONE
- ;;
- TASK18: NOP
- ;;
- ;; HTP1 : HOST TO P1
- ;;
- ;;
- MOV IE,#90H ;ENABLE THE INTERRUPT
- MOV A,R2 ; GET QUEUE PTR
- ADD A,#02H ; PT TO ARG 1
- MOV R0,A ; SET UP R0 PTR
- MOV A,@R0 ; GET THE DATA BYTE
- MOV P1,A ; LATCH DATA BYTE TO PORT
- MOV IE,#00H
- RETI ; ALL DONE
- ;;
- TASK19: NOP
- ;;
- ;; P2TH : PORT 2 TO HOST
- ;;
- MOV IE,#90H ;ENABLE THE INTERRUPT
- MOV A,#"[" ; START BRACKET
- ACALL OUTCHAR ; SEND START BRACKET
- MOV A,P2 ; GET THE PORT DATA
- ACALL SENDASC ; SEND DATA TO HOST
- MOV A,#"]" ; END BRACKET
- ACALL OUTCHAR ; SEND END BRACKET
- MOV IE,#00H
- RETI ; ALL DONE
- ;;
- TASK1A: NOP
- ;;
- ;; HTP2 : HOST TO P2
- ;;
- ;;
- MOV IE,#90H ;ENABLE THE INTERRUPT
- MOV A,R2 ; GET QUEUE PTR
- ADD A,#02H ; PT TO ARG 1
- MOV R0,A ; SET UP R0 PTR
- MOV A,@R0 ; GET THE DATA BYTE
- MOV P2,A ; LATCH DATA BYTE TO PORT
- MOV IE,#00H
- RETI ; ALL DONE
- ;;
- TASK1B: NOP
- ;;
- ;; INT0 : VALUE OF T0 TO HOST
- ;;
- MOV IE,#90H ;ENABLE THE INTERRUPT
- CLR A ; CLEAR THE AC
- JNB TCON.1,T241 ; SKIP IF NOT T0
- INC A ; INC AC IF T0=1
- T241: MOV R7,A ; STORE THE VALUE
- MOV A,#"[" ; AC GETS "["
- ACALL OUTCHAR ; SEND "[" TO HOST
- MOV A,R7 ; GET THE DATA BACK
- ACALL SENDASC ; SEND DATA TO HOST
- MOV A,#"]" ; AC GETS "]"
- ACALL OUTCHAR ; SEND "]" TO HOST
- MOV IE,#00H
- RETI
- ;;
- TASK1C: NOP
- ;;
- ;; INT1 : VALUE OF T1 TO HOST
- ;;
- MOV IE,#90H ;ENABLE THE INTERRUPT
- CLR A
- JNB TCON.3,T251 ; SKIP IF NOT T1
- INC A ; INC IF T1=1
- T251: MOV R7,A ; STORE THE VALUE
- MOV A,#"[" ; AC GETS "["
- ACALL OUTCHAR ; SEND "[" TO HOST
- MOV A,R7 ; GET THE DATA BACK
- ACALL SENDASC ; SEND DATA TO HOST
- MOV A,#"]" ; AC GETS "]"
- ACALL OUTCHAR ; SEND "]" TO HOST
- MOV IE,#00H
- RETI
- TASK1D: RETI
- ;
- TASK1E: NOP
- ;
- ; TMOF : TIMEOUT OFF
- ;
- CLR SENSR.3 ; TURN OFF TIMEOUT BIT
- RETI
- ;
- TASK1F: NOP
- ;
- ; TMON : TIMEOUT ON
- ;
- SETB SENSR.3 ; TURN ON THE TIMEOUT BIT
- RETI
- ;
- TASK20 RETI
- TASK21 RETI
- TASK22 RETI
- TASK23 RETI
- TASK24 RETI
- TASK25 RETI
- TASK26 RETI
- TASK27 RETI
- TASK28 RETI
- TASK29 RETI
- TASK2A RETI
- TASK2B RETI
- TASK2C RETI
- TASK2D RETI
- TASK2E RETI
- TASK2F RETI
- TASK30 RETI
- TASK31 RETI
- TASK32 RETI
- TASK33 RETI
- TASK34 RETI
- TASK35 RETI
- TASK36 RETI
- TASK37 RETI
- TASK38 RETI
- TASK39 RETI
- TASK3A RETI
- TASK3B RETI
- TASK3C RETI
- TASK3D RETI
- TASK3E RETI
- TASK3F RETI
- TASK40 RETI
- TASK41 RETI
- TASK42 RETI
- TASK43 RETI
- TASK44 RETI
- TASK45 RETI
- TASK46 RETI
- TASK47 RETI
- TASK48 RETI
- TASK49 RETI
- TASK4A RETI
- TASK4B RETI
- TASK4C RETI
- TASK4D RETI
- TASK4E RETI
- TASK4F RETI
- END