.TITLE 'BIOS FOR 48 TPI READ OF 96 TPI DRIVES' ; ; |----------------------------------------------| ; | | ; | OTRONA 500 SERIES CP/M 2.2 BIOS & BOOT | ; | | ; |----------------------------------------------| ; ; S.GRAY 10-19-1983 ; R.LINGEMANN ; R.WINTER ; .PABS .PHEX .XSYM ; TPI = \' 0 = 48 TPI, 1 = 96 TPI ' LSTDEF = \' EQUATES ' LSTCBT = \' COLD BOOT ROUTINE ' LSTINT = \' BIOS INTERFACE ' LSTDBK = \' BDOS DISK ROUTINES ' LSTDSK = \' BIOS DISK ROUTINES ' LSTFIN = \' FLOPPY INTERRUPT ' LSTIO = \' CHARACTER I/O ' LSTDSP = \' DISPLAY DRIVER CONTROL ' LSTFNC = \' DISPLAY DRIVER ESC & CNTRL ' LSTMCH = \' DISPLAY DRIVER MULTI-CHAR. ' LSTDMC = \' DISPLAY DRIVER SUPPORT ' LSTGRF = \' DISPLAY DRIVER GRAPHICS ' LSTVLE = \' VALET EXECUTIVE (SET-UP) ' LSTVLD = \' VALET DISK ROUTINES ' LSTVLM = \' VALET SUPPORT ROUTINES ' LST60H = \' 60 Hz INTERRUPT ROUTINE ' LSTTBL = \' TABLES & MESSAGES ' LSTVAR = \' VARIABLE STORAGE ' ; .IFE LSTDEF,[ .XLIST ] .PAGE ; ; SELECT DISK PARAMETERS ; LINES = 24 ; # OF LINES ON SCREEN STPRAT = 6 ; STEP RATE IN mS (MUST BE BETWEEN 2 AND 32 IN EVEN ; INCREMENTS.) SIDES = 1 ; DOUBLE SIDED ; ; CONFIGURATION ; STACK = ENDMRK+1 ; TOP OF STACK MSIZE = 56 ; CP/M VERSION MEMORY SIZE IN K-BYTES BIAS = (MSIZE-20)*1024 CCP = 3400H+BIAS; BASE OF CCP BDOS = CCP+806H ; BASE OF BDOS BIOS = CCP+1600H ; BASE OF BIOS NDISK = 2 ; NUMBER OF DISKS IN SYSTEM CDISK = 0004H ; CURRENT DISK NUMBER ADDR. MNTR = 0003H ; EPROM MONITOR ENTRY MDISKOP = 0006H ; EPROM DISKOP ENTRY SMDSPLY = 0009H ; EPROM DISPLAY DRIVER IOBYTE = 0003H ; I/O BYTE LOCATION IOINIT = 81H ; INITIAL IOBYTE VALUE KBUFLN = 16 ; KEYBOARD BUFFER SIZE FILBUF = 0FE00H ; BUFFER SPACE FOR FORMAT ; WILL BE CHANGED BY DISK ROUTINE ; .PAGE ; ; I/O CONSTANTS ; TIMCW0 = 57H ; TIMER CONTROL BYTE TIMTC0 = 02H ; 9600 BAUD TIMTC1 = 02H ; 9600 BAUD ; ; ASCII CODES ; BEL = 7H ; BELL BS = 8H ; BACKSPACE CR = 0DH ; CARRIAGE RETURN CTRLJ = 0AH ; CTRL-J CTRLJH = 0C8H ; CTRL-JH CTRLK = 0BH ; CTRL-K CTRLO = 0FH ; CTRL-O CTRLP = 10H ; CTRL-P CTRLPS = 0D3H ; CTRL-PS CTRLQ = 11H ; CTRL-Q CTRLQP = 90H ; CTRL-QP CTRLS = 13H ; CTRL-S CTRLX = 18H ; CTRL-X ESC = 1BH ; ESCAPE FF = 0CH ; FORM FEED LF = 0AH ; LINE FEED SPC = 20H ; SPACE ; ; FLOPPY CONSTANTS ; RWCODE = 40H+3 ; R/W COMMAND-2 OR 3 MTRTIM = 300 ; 5S MOTOR TIMEOUT MTRDLY = 45 ; 750MS. MOTOR START DELAY ; SRT = 16-(STPRAT/2); HEAD STEP RATE ; DHLT = 16 ; DISK HEAD LOAD TIME DHUT = 0FH ; DISK HEAD UNLOAD TIME ND = 0 ; DMA MODE ; ; CP/M DISK RETURN CODES ; WRALL = 0 ;WRITE TO ALLOCATED WRDIR = 1 ;WRITE TO DIRECTORY WRUAL = 2 ;WRITE TO UNALLOCATED ; ; DISK DRIVE PARAMETERS ; ALLTRE = 36+(40*TPI)+SIDES*(40+(42*TPI)) BLS = (TPI ! SIDES)+1 BLKSIZ = 1024*BLS; DIRECTORY BLOCK SIZE HSTSIZ = 512 ; HOST DISK SECTOR SIZE HSTSPT = 10 ; HOST SECTORS PER TRACK (CYL) ALLDSK = ALLTRK*5/BLS DSKSIZ = ALLDSK-(21-(BLS*7)+1) SYSTRK = 3 ; SYSTEM RESERVED TRACKS CNTSEC = 2 ; HSTSIZ/PHYSICAL SECTOR SIZE ; HSTBLK = HSTSIZ/128 ; CP/M SECT. PER HOST SECT. CPMSPT = HSTBLK * HSTSPT ; CP/M SECTORS PER TRACK SECMSK = HSTBLK-1 ; SECTOR MASK BADDR = CCP-HSTSIZ MAXTRK = 39+(40*TPI) DIRENT = 64*((SIDES ! TPI)+1) DIRALC = DIRENT/(BLKSIZ/32) ; .IFE DIRALC-1,[ ALOC0 = 80H ] .IFE DIRALC-2,[ ALOC0 = 0C0H ] .IFE DIRALC-4,[ ALOC0 = 0F0H ] ; TPA = 100H ; .PAGE ; ; I/O PORTS ; FPYBCA = 0E0H ;FLOPPY STATUS PORT FPYBWR = 0E1H ;FLOPPY DATA PORT DSPBCA = 0E2H ;DISPLAY BASE & CURRENT ADDRESS DSPBWR = 0E3H ;DISPLAY BASE & WORD COUNT STDBCA = 0E4H ;STD BUS BASE & CURRENT ADDRESS STDBWR = 0E5H ;STD BUS BASE & WORD COUNT SIOBCA = 0E6H ;SIO BASE & CURRENT ADDRESS SIOBWR = 0E7H ;SIO BASE & WORD COUNT DMACSR = 0E8H ;DMA COMMAND/STATUS REGISTER DMAWRR = 0E9H ;DMA WRITE R=EST REGISTER DMAWSM = 0EAH ;DMA WRITE SINGLE MASK BIT DMAWMR = 0EBH ;DMA WRITE MODE REGISTER DMACBP = 0ECH ;DMA CLEAR BYTE PNTR FLIP-FLOP DMATMP = 0EDH ;DMA TEMP REG & MASTER CLEAR SDSPY = 0EEH ;DISPLAY COMMAND/STATUS DMAWAM = 0EFH ;DMA WRITE ALL MASK REG BITS DCOMM = 0F0H ;COMM PORT DATA SCOMM = 0F1H ;COMM PORT STATUS DPRTR = 0F2H ;PRINTER PORT DATA SPRTR = 0F3H ;PRINTER PORT STATUS BAUDC = 0F4H ;BAUD TIMER FOR COMM PORT SBAUDP = 0F5H ;BAUD TIMER FOR PRINTER PORT DSPINT = 0F6H ;DISPLAY INTERRUPT (60HZ) FPYINT = 0F7H ;FLOPPY INTERRUPT TIMER DPIOA = 0F8H ;PIO PORT A DATA ; A0-7 = LATCH DATA OUT ; L0 = MOTOR ON ; L1 = GRAPHICS ENABLE ; L2 = EPROM ENABLE ; L3 7 DISPLAY BRTNS. ; A0-7 = 8910 DATA I/O ; A0-3 = 5832 D0-3 I/O ; A4-7 = 5832 A0-3 OUT ; A0-3 = 5101 D0-3 I/O ; A4-7 = 5101 A0-3 OUT DPIOB = 0FAH ;PIO PORT B DATA ; B0-1 = 5101 A4-5 ; B2-4 = OPERATION SELECT ; 0 = 8910 ADDR LOAD ; 1 = 8910 DATA LOAD ; 2 = 5832 WRITE ; 3 = 5832 READ ; 4 = 5101 WRITE ; 5 = 5101 READ ; 6 = LATCH LOAD ; 7 = NO-OP ; B5 = /'138 OPERATION STROBE ; B6 = /KEYBOARD DATA IN ; B7 = /KEYBOARD CLOCK OUT SPIOA = 0F9H ;PIO PORT A COMMAND SPIOB = 0FBH ;PIO PORT B COMMAND SFLPY = 0FCH ;FLOPPY COMMAND/STATUS DFLPY = 0FDH ;FLOPPY DATA DDSPY = 0FEH ;DISPLAY DATA DMAP = 0FFH ;RAM VIRTUAL MAP DATA ; .LIST .IFE LSTCBT,[ .XLIST ] .PAGE S; ;|----------------------------------------------| ;| BOOT - LOADED INTO FE00H BY PROM | ;|----------------------------------------------| ; ;BOOT CODE WILL BE SAVED IN SECTOR 1 OF TRACK 0 ;AND IS SET UP HERE TO ASSEMBLE ONE SECTOR LENGTH ;AHEAD OF THE CCP. THE ADDRESS OFFSET FACTOR BOFF ;IS ADDED WHERE NEEDED SO THE BOOT CODE WILL RUN ;WHEN LOADED AT IT'S STARTING ADDRESS OF 0FE00H ;THE BIOS CBOOT ROUTINE IS ALSO RUN HERE TO SAVE ;SPACE AS THE ONLY TIME THIS ROUTINE IS USED IS ;DIRECTLY FOLLOWING A SYSTEM RESET. ; MONSTK = 0FE00H ;ADDR OF MON. STACK & DISK BUFF. BTSTRT = CCP-HSTSIZ BOFF = MONSTK-BTSTRT ; .LOC BTSTRT ; ; BOOT LOADER ; JMP BOOT+BOFF ;GETSYS VECTOR .BYTE 0A7H ;INDICATES CP/M TO MONITOR ; ;|----------------------| ;| COLD BOOT | ;|----------------------| ; CBOOT: JMPR CBOOT1 ; SIGNON: .BYTE ESC,'\',ESC,'3',18H ; CLEAR GRAPHICS & RESET SCREEN .ASCII 'CP/M 2.2.5' ; .IFN TPI,[ .ASCII '/96' ] .ASCIS ' Otrona ATTACHE <56K>' ; ; CBOOT1: DI ;TURN OFF INTERRUPTS ; ; SET UP PERIPHERALS I/O VIA TABLE ; LXI H,IOTBL+BOFF ;POINT TO I/O TABLE CBL1: MOV A,M MOV C,A ;C=PORT INR A ;JUMP OUT IF DONE JRZ CBJ1 INX H ;B=COUNT MOV B,M INX H CBL2: MOV A,M ;MANUAL BLOCK OUTPUT OUTP A ; SO SLOW DEVICES INX H ; CAN KEEP UP DJNZ CBL2 JMPR CBL1 ; CBJ1: LXI H,MTRTIM SHLD MTRCNT MVI A,85H STA LSTATE ; ; INIT VARIABLES & BUFFERS ; XRA A LXI H,DSPCYC MVI B,47 CBL3: MOV M,A INX H DJNZ CBL3 ; STA OKIFLG MVI A,IOINIT; SET INITIAL IOBYTE VALUE STA IOBYTE LXI SP,STACK; SET STACK POINTER ; ; SET UP SYSTEM PARAMETERS FROM CMOS RAM ; ----- B = 0 FROM PREVIOUS OP CALL RD5101 ; MUST FIND XE,X5 IN 1ST TWO CMOS LOCATIONS CPI 0EH JRNZ STRM ; 1ST BYTE NOT XE, GO SET CMOS RAM AND BIOS VARS. MVI B,1 CALL RD5101 CPI 5 ; IF 2ND BYTE = X5 JRZ STCM ; THEN READ CMOS RAM & SET BIOS VARIABLES ; STRM: MVI A,1 ; ELSE SET CMOS RAM & BIOS VARIABLES CALL WRTTON ; SET KEYTONE MVI A,1AH CALL WRTBRT ;SET BRIGHTNESS MVI A,9 CALL WRTPNT ;SET PRINTER BAUD MVI A,9 CALL WRTCOM ;SET COMM. BAUD MVI A,0FFH CALL WRTBEL ;SET BELL TOGGLE MVI A,0FH CALL WRTVOL ;SET VOLUME LEVEL XRA A CALL WRTSLK ;SET SHIFT LOCK MVI A,0EH MVI B,0 CALL WR5101 MVI A,5 MVI B,1 CALL WR5101 MVI A,0FH MOV B,A CALL WR5101 JMPR IMPR ; STCM: MVI B,9 ; GET KEYTONE CALL RD5101 STA TONTYP ; SET BIOS VAR. CALL GTBRIT ; GET BRIGHTNESS STA BRTLEV ; SET BIOS VAR. MVI B,5 CALL RD5101 ; GET BELL TOGGLE STA CURBEL ; SET BIOS VAR. MVI B,6 CALL RD5101 ; GET VOLUME LEVEL STA VOLEVL ; SET BIOS VAR. MVI B,0EH CALL RD5101 ; GET SHIFT LOCK ORA A JRZ SLOK ; 0=OFF, 0FFH=ON MVI A,0FFH SLOK: STA SHLOCK ; SET BIOS VAR. ; IMPR: LXI H,NOTONE-15 ; SET CURRENT KEYTONE POINTER LDA TONTYP INR A MOV B,A LXI D,15 IML1: DAD D DJNZ IML1 SHLD CLIKAD ; STORE KEYTONE POINTER LDA BRTLEV ; SET PHYSICAL DEVICES: CALL BRTADJ ; BRIGHTNESS LATCH CALL ADJPNT ; PRINTER BAUD CALL ADJCOM ; COMM. BAUD LDA VOLEVL CALL VOLADJ ; VOLUME BYTES IN SOUND TABLE MVI A,0C7H STA GRFBIT+1 ; SET GRAPHICS ROUTINE TO PLOT BRIGHT ; ; CHECK FOR CLOCK CHIP TYPE ; MVI B,4 CCL4: PUSH B MVI B,0DH CALL R58174 CPI 0FH POP B JRNZ NSCK ; <> 0FH = NATIONAL SEMI CLOCK DJNZ CCL4 ; MVI A,0ACH STA W58174+14 MVI A,0A8H STA R58174+15 STA OKIFLG ; ; CHECK FOR CLOCK SET ; NSCK: MVI B,3 ; MUST FIND XE,X5 IN TWO CMOS BYTES (3 & 4) CALL RD5101 ; TO INDICATE CLOCK HAS BEEN SET CPI 0EH JRNZ SETINT ; NO MATCH, SKIP TO SET INTERRUPT MVI B,4 CALL RD5101 CPI 5 JRNZ SETINT ; NO MATCH, SKIP TO SET INTERRUPT STA CLKFLG ; ELSE SET CLKFLG <> 0 (CLOCK SET) ; ; SET UP THE INTERRUPT STRUCTURE ; SETINT: MVE A,V60HZ/25? ;SEO VECTOO AREA STAE IM2 ;MODE 2 EI ;INTERRUPTS ON ; ; SIGN ON ; LXI H,SIGNON+BOFF CALL MESSG ; ; SET UP DISK PARAMETERS ; CALL CLRFLG LXI H,SPCTBL ;SETUP SPECIFY TABLE CALL DISKOP EI XRA A STA CDISK ;SELECT DRIVE 0 STA HSTHD CALL GOCPM JMP CCP ; .PAGE ; ; ;|------------------------------| ;| I/O SETUP TABLE | ;|------------------------------| ; ; FORMAT: PORT#, # OF BYTES, BYTES ; PORT ENTRY OF 0FFH TERMINATES ; ; TIMERS ; IOTBL: .BYTE BAUDC ; COMM PORT .BYTE 4 .BYTE 3 ; RESET .BYTE (V60HZ-4) @ 256 ; INT. VECTOR .BYTE TIMCW0 ; CONTROL WORD .BYTE TIMTC0 ; COMM. BAUD (9600) ; .BYTE DSPINT ; 60 HZ. INTERRUPT .BYTE 3 .BYTE 3 ; RESET .BYTE 0D5H ; + EDGE, INT. ON .BYTE 1 ; COUNT OF 1 ; .BYTE FPYINT ; FLOPPY INTERRUPT .BYTE 3 .BYTE 3 ; RESET .BYTE 0D5H ; + EDGE, INT. ON .BYTE 1 ; ; DISABLE EPROM, TURN ON MOTOR ; .BYTE SPIOA ; SET DIRECTION OUT .BYTE 2 .BYTE 0CFH .BYTE 0 ; .BYTE DPIOA ; DATA FOR LATCH .BYTE 1 .BYTE 85H ; .BYTE DPIOB ; STROBE DATA INTO LATCH .BYTE 3 .BYTE 0FBH .BYTE 0DBH .BYTE 0FBH .BYTE 0FFH ; TERMINATOR ; ; .PAGE ; ;|------------------------------| ;| BOOT LOADER | ;|------------------------------| ; BOOT: LXI X,BOT1+BOFF ; ERROR RETURN ADDR. MVI B,10 ; 10 RETRIES BOT0: PUSH B LXI H,BRCTBL+BOFF ; HL<- START OF RECAL TABLE CALL MDISKOP ; RECAL DRIVE POP B JMPR BOT2 BOT1: POP B ; ARRIVE HERE IF RECAL ERROR DJNZ BOT0 JMPR GOMON ; IF 10 BAD TRIES, BACK TO MON. BOT2: MVI C,27 ; READ 27 SECTORS BOT3: LXI X,BOT5+BOFF ; ERROR RETURN ADDR. MVI B,10 ; 10 RETRIES BOT4: PUSH B LXI H,BRDTBL+BOFF ; HL <- START OF READ TABLE CALL MDISKOP JMPR BOT6 BOT5: POP B ; ARRIVE HERE IF READ ERROR DJNZ BOT4 JMPR GOMON ; IF 10 BAD TRIES, BACK TO MON. BOT6: POP B DCR C ; DCR SECTOR COUNTER JRZ BTOV ; IF SECTOR = 0, THEN BOOT DONE LDA BRDTBL+BOFF+2 ; ELSE INC LOAD POINTER BY 200H ADI 2 STA BRDTBL+BOFF+2 LXI H,BRREC+BOFF ; INC PHYSICAL SECTOR INR M MVI B,10 ; RESET RETRY COUNTER MOV A,C CPI 18 ; AT 1ST TRACK BOUNDARY ? JRZ BOT7 ; IF YES, GO ..BOT7 CPI 8 ; ELSE AT 2ND TRACK BOUNDARY ? JRNZ BOT4 ; IF NO THEN GO ..BOT4 BOT7: LDA BRCYL+BOFF ; INCREMENT TRACK INR A STA BRCYL+BOFF STA BSKADD+BOFF MVI A,1 ; RESET PHYSICAL SECTOR STA BRREC+BOFF LXI X,BOT9+BOFF ; ERROR RETURN ADDR. MVI B,10 ; 10 RETRIES BOT8: PUSH B LXI H,BSKTBL+BOFF ; HL <- START OF SEEK TABLE CALL MDISKOP ; SEEK TO NEXT TRACK POP B JMPR BOT3 ; GO GET NEXT SECTOR ; BTOV: DI ; SYSTEM HAS BEEN BOOTED JMP BIOS ; GOTO TO BIOS INIT ROUTINE ; BOT9: POP B ; ARRIVE HERE IF SEEK ERROR DJNZ BOT8 GOMON: JMP MNTR ; IF 10 BAD TRIES, THEN BACK TO MON. ; ;|----------------------| ;| DISK TABLES | ;|----------------------| ; ; READ A SECTOR ; BRDTBL: .BYTE 39H .WORD CCP .WORD 512-1 .BYTE 40H+6 .BYTE 0 ;UNIT BRCYL: .BYTE 0 ;C .BYTE 0 ;H BRREC: .BYTE 2 ;R .BYTE 2 ;N .BYTE 10 ;EOT .BYTE 15 ;GP2 .BYTE 0FFH ;DTL ; ; SEEK TO NEW CYLINDER ; BSKTBL: .BYTE 23H .BYTE 0FH .BYTE 0 ;HEAD & UNIT BSKADD: .BYTE 0 ;NEW CYLINDER ; ; RECALIBRATE TO CYLINDER 0 ; BRCTBL: .BYTE 22H .BYTE 7 .BYTE 0 ; .LIST .IFE LSTINT,[ .XLIST ] .PAGE S; ;|--------------------------------------| ;| | ;| BIOS | ;| | ;|--------------------------------------| ; .LOC BIOS ; ; JUMP VECTORS ; JMP CBOOT+BOFF ;COLD START WBOOTE: JMP WBOOT ;WARM START JMP CONST ;CONSOLE STATUS JMP CONIN ;CONSOLE CHAR. IN JMP CONOUT ;CONSOLE CHAR. OUT JMP LIST ;LIST CHAR. OUT JMP PUNCH ;PUNCH CHAR. OUT JMP READER ;READER CHAR. IN JMP HOME ;MOVE HEAD TO HOME POS. JMP SELDSK ;SELECT DISK JMP SETTRK ;SET TRACK # JMP SETSEC ;SET SECTOR # JMP SETDMA ;SET DMA ADDRESS JMP READ ;READ FROM DISK JMP WRITE ;WRITE TO DISK JMP LISTST ;RETURN LIST STATUS JMP SECTRA ;SECTOR TRANSLATION ; ;DISK PARAMETER TABLE ; ; DPBASE = . ; BASE OF DISK PARAMETER BLKS. ; ; DISK 00 ; XLT0 = 0 ; NO XLATION TABLE XLT1 = XLT0 .WORD XLT0,0 ; XLATE TABLE .WORD 0,0 ; SCRATCH AREA .WORD DIRBUF,DPB0 ; DIR BUFF, PARM BLOCK .WORD CSV0,ALV0 ; CHECK, ALLOC VECTORS ; ; DISK 01 ; .WORD XLT1,0 ; XLATE TABLE .WORD 0,0 ; SCRATCH AREA .WORD DIRBUF,DPB1 ; DIR BUFF, PARM BLOCK .WORD CSV1,ALV1 ; CHECK, ALLOC VECTORS ; ; DISK PARAMETER BLOCK FOR DRIVE A: ; DPB0: .WORD CPMSPT ; SEC PER TRACK .BYTE 3+BLS-1 ; BLOCK SHIFT .BYTE 7+((BLS-1)*8) ; BLOCK MASK EXM: .BYTE TPI ^ 1 .WORD DSKSIZ-1 ; DISKSIZE-1 .WORD DIRENT-1 ; DIRECTORY MAX .BYTE ALOC0 ; ALLOC0 .BYTE 0 ; ALLOC1 .WORD DIRENT/4 ; CHECK SIZE .WORD SYSTRK ; OFFSET ; ; RESERVED FOR 3 INTERRUPT VECTORS (I=0DAH) ; INT1: .BLKB 2 INT2: .BLKB 2 INT3: .BLKB 2 ; ; JUMP TABLE FOR EXTERNAL USE ; JMPTBL: JMP DISK ; VECTOR TO DISK JMP DISPLY ; VALET CRTOUT JMP TTYIST ; TEST COMM. INPUT STATUS JMP TTYIN ; INPUT FROM COMM. JMP TTYOUT ; OUTPUT TO COMM. JMP SOUND ; TABLE DRIVEN SOUND JMP PUTVAL ; EXIT VALET OVERLAY JMP LINDSP+3; FOR BASIC GRAPHICS ; ; VARIABLES FOR EXTERNAL USE ; WSFLAG: .BYTE 0 VALSTP: .BYTE 0FFH DSKFLG: .BYTE 0FFH VALPND: .BYTE 0 CLIKAD: .WORD CLICK VALCMD: .BYTE 0 VALTIM: .BYTE 0 ; ; VECTORS ; JMP OUTBLK JMP CLNVAL JMP ADJPNT ; READ CMOS & CHANGE PRINT BAUD JMP ADJCOM ; READ CMOS & CHANGE COMM. BAUD JMP DOBOOT ; DO WARM BOOT BUT DON'T GO TO CCP JMP GOCPM ; INITIALIZE ENVIRONMENT JMP CMPOFF ; RETURN HL W/PROPER LINE OFFSET WBTVEC: JMP CCP+3 ; USED TO REDIRECT WARM BOOT CCP JUMP ; ; MORE VARIABLES ; SIORG5: .BYTE 0EAH ; INITIAL STATUS OF COMM. PORT RR 5 SPOOL: .BLKB 1 ; USED IN BANKED SYSTEM FOR SPOOLER PARPNT: .WORD CURCHR LINOFS: .BYTE 0 DSPFLG: .BYTE 0 ALMWAT: .BYTE 0 ALMCNT: .BYTE 0 ; COUNTS # OF ALARM TONES BNKFLG: .BYTE 0 ; FLAG FOR BANKED OR UNBANKED ALMFLG: .WORD 600 ; BIOS VALTON: .WORD NOTONE CLKFLG: .BYTE 0 TIMFLG: .BYTE 0FFH NUMFLG: .BYTE 0 KEYADR: .WORD KEYTBL FLPTBL: .WORD FMTTBL DSTMP: .WORD 1019H ; DATE STAMP .IFN TPI,[ .BYTE 96 ] .IFE TPI,[ .BYTE 48 ] .BLKB 1 ; FREE FOR USE ; ;|-----------------------------------| ;| INTERRUPT VECTORS - MUST BE ON A | ;| BOUNDARY OF AN EVEN MULTIPLE OF 8 | ;|-----------------------------------| ; .BLKB 2 ; RESERVED FOR CTC CH. 0 .BLKB 2 ; RESERVED FOR CTC CH. 1 V60HZ: .WORD SRV60 ; 60 HZ TIMER (CTC CH. 2) .WORD SRVFPY ; FLOPPY INT. (CTC CH. 3) ; ; MORE USER INTERRUPTS ; INT4: .BLKB 2 INT5: .BLKB 2 INT6: .BLKB 2 INT7: .BLKB 2 INT8: .BLKB 2 ; DSKNO: .BYTE 2 ; N.A. USED IN CPM-128 HRDVEC: JMP 0 ; N.A. " DOHVEC: JMP 0 ; N.A. " DPBN3: .WORD 0 ; N.A. " DPBN2: .WORD 0 ; N.A. " .WORD 0 ; N.A. " ; DPB1: .WORD CPMSPT ; SEC PER TRACK .BYTE 3+BLS-1 ; BLOCK SHIFT .BYTE 7+((BLS-1)*8) ; BLOCK MASK EXMB: .BYTE TPI ^ 1 .WORD DSKSIZ-1 ; DISKSIZE-1 .WORD DIRENT-1 ; DIRECTORY MAX .BYTE ALOC0 ; ALLOC0 .BYTE 0 ; ALLOC1 .WORD DIRENT/4 ; CHECK SIZE .WORD SYSTRK ; OFFSET ; .PAGE ; ;|----------------------------------------------| ;| WARM BOOT - RE-READ UP TO THE BIOS | ;|----------------------------------------------| ; WBOOT: DI MVI A,0FFH STA VALSTP ; INHIBIT VALET AT THIS POINT LXI SP,STACK; RESET STACK POINTER EI CALL DOBOOT ORA A JRZ WB1 CALL DISK LXI H,WBTRY CALL MESSG CALL CONIN JMPR WBOOT ; WB1: CALL GOCPM ; INITIALIZE ENVIRONMENT JMP WBTVEC ; & JMP TO CCP OR CCP+3 (SEE WBTVEC) ; DOBOOT: MVI A,11 STA SECCNT ; READ 11 SECTORS STA RECNT ; RETRY 11 TIMES ; THROUGH, 10 THEREAFTER MVI A,3 ; SET COMMAND TO READ LXI B,100H ; XFER 1 SECTOR AT A TIME ; SELECT DRIVE 0 LXI D,2 ; START AT TRACK 0, SECTOR 2 LXI H,CCP ; LOAD START ADDRESS (BEGINNING OF CCP) ; RWONE: PUSH PSW ; SAVE LOAD DATA PUSH B ; ' PUSH D ; ' ; PUSH PSW MOV A,D CALL CHKSID RWJ1: POP PSW ; PUSH H ; ' CALL DISK ; LOAD SECTOR RWL1: LDA DSKCYC ORA A ; IF DSKCYC = 0 JRZ RWOK ; THEN TRACK LOADED OK ANI 0E0H ; ELSE SEE IF DISK OP DONE OR ERROR JRZ RWL1 ; IF DISK OP NOT DONE, THEN LOOP TO WAIT LXI H,RECNT ; ELSE TRY AGAIN DCR M ; DECREMENT RETRY COUNTER POP H ; RESTORE DISK COMMAND DATA POP D POP B JRZ RWNFG ; IF 10 RETRYS, THEN ERROR POP PSW JMPR RWONE ; TRY AGAIN ; RWOK: LXI H,SECCNT; DECREMENT SECTOR COUNTER DCR M POP H ; RESTORE DISK COMMAND DATA POP D POP B JRZ RWDONE ; IF SECTOR = 0 THEN GOTO CCP MVI A,10 ; ELSE SET RETRY COUNTER STA RECNT INR H ; INCREMENT LOAD POINTER BY INR H ; BY 200H (PHYSICAL SECTOR LENGTH) MOV A,E CPI 10 ; IS LAST READ SECTOR <> 10 ? JRNZ RWUPSC ; IF NOT, THEN GOT UPSC INR D MVI E,0 ; & SECTOR COUNT = 0 (NEXT INSTR. SETS TO 1) RWUPSC: INR E ; INCREMENT SECTOR COUNT POP PSW ; RESTORE DISK COMMAND JMPR RWONE ; GET NEXT SECTOR ; RWNFG: POP PSW MVI A,9 RET ; RWDONE: POP PSW ; RECTIFY SP, XRA A RET ; ; COMMON CODE FOR BOOTS ; SGOCPM: XRA A ; INITIALIZE ACT. REG. STA WSFLAG ; WORDSTR FLAG OFF STA HSTACT ; HOST BUFFER INACTIVE STA UNACNT ; CLEAR UNALLOC COUNT STA NOKEY ; CLEAR VALET INHIBIT MVI A,-3 ;TURN OFF GRAPHICS CALL LLATCH CALL SETPG0 LXI B,80H ;DEFAULT DMA ADDRESS IS 80H CALL SETDMA LXI H,WBINIT; GET ADDR OF SCREEN INITIALIZATION CHARS. CALL MESSG ; TURN OFF GRAPHICS & CLEAR TO EOS LDA CDISK ; SEND CURRENT DISK # TO CCP MOV C,A XRA A STA DSKFLG ; CLEAR DSKFLG RET ; SETPG0: MVI A,JMP ;JMP INSTRUCTION STA 0 ;STORE JMP TO WBOOT LXI H,WBOOTE ;WBOOT ENTRY POINT SHLD 1 ;STORE JMP TO BDOS0 STA 5 LXI H,BDOS ;BDOS ENTRY POINT SHLD 6 RET ; .LIST .IFE LSTDBK,[ .XLIST ] .PAGE ; SELDSK: LXI H,0 ; SET ERROR CODE MOV A,C ; GET DISK # CPI NDISK ; IF DISK DOESN'T EXIST RNC ; THEN RETURN STA SEKDSK ; ELSE STORE DISK # ADD A ; MULTIPLY BY 16 ADD A ADD A ADD A MOV L,A LXI D,DPBASE; ADD TO BASE OF DPB DAD D RET ; ;|------------------------------| ;|set track given by register BC| ;|------------------------------| ; SETTRK: SBCD SEKTRK ; TRACK TO SEEK HOME: RET ; RETURN ALSO USED BY DUMMY HOME ; ;|------------------------------| ;|set sector given by register c| ;|------------------------------| ; SETSEC: MOV A,C STA SEKSEC ;sector to seek RET ; ;|------------------------------| ;| set dma address given by BC | ;|------------------------------| ; SETDMA: SBCD DMAADR RET ; ;|------------------------------| ;| translate sector number BC | ;|------------------------------| ; SECTRA: MVI H,0 MOV L,C RET ; ;|------------------------------| ;| READ A SECTOR | ;|------------------------------| ; READ: xra a ;accum=0 sta unacnt ;unacnt=0 CMA ;DISABLE VALET INT. STA DSKFLG mvi a,1 sta readop ;read operation sta rsflag ;must read data mvi a,wrual sta wrtype ;treat as unalloc jmp rwoper ;to perform the read S; ;|------------------------------| ;| WRITE A SECTOR | ;|------------------------------| ; WRITE: xra a ;0 to accumulator sta readop ;not a read operation mov a,c ;write type in c sta wrtype cpi wrual ;write unallocated? JRNZ chkuna ;check for unalloc ; ; write to unallocated, set parameters ; mvi a,blksiz/128 ;next unalloc recs STA DSKFLG ; DISABLE VALET INT. sta unacnt lda sekdsk ;disk to seek sta unadsk ;unadsk = sekdsk lhld sektrk shld unatrk ;unatrk = sectrk lda seksec sta unasec ;unasec = seksec ; chkuna: MVI A,0FFH ;DISABLE VALET INT. STA DSKFLG ; ; check for write to unallocated sector ; lda unacnt ;any unalloc remain? ora a JRZ alloc ;skip if not ; ; more unallocated records remain ; dcr a ;unacnt = unacnt-1 sta unacnt lda sekdsk ;same disk? lxi h,unadsk cmp m ;sekdsk = unadsk? JRNZ alloc ;skip if not ; ; disks are the same ; lxi h,unatrk call sekcmp ;sektrk = unatrk? JRNZ alloc ;skip if not ; ; tracks are the same ; lda seksec ;same sector? lxi h,unasec cmp m ;seksec = unasec? JRNZ alloc ;skip if not ; ; match, move to next sector for future ref inr m ;unasec = unasec+1 mov a,m ;end of track? cpi cpmspt ;count CP/M sectors JRC noovf ;skip if no overflow ; ; overflow to next track ; mvi m,0 ;unasec = 0 S lhld unatrk inx h shld unatrk ;unatrk = unatrk+1 ; ; match found, mark as unnecessary read ; noovf: xra a ;0 to accumulator sta rsflag ;rsflag = 0 JMPR rwoper ;to perform the write ; ; not an unallocated record, requires pre-read ; alloc: xra a ;0 to accum sta unacnt ;unacnt = 0 inr a ;1 to accum sta rsflag ;rsflag = 1 ; ;|----------------------------------------------| ;| Common code for READ and WRITE follows | ;|----------------------------------------------| ; rwoper: xra a ;zero to accum sta erflag ;no errors (yet) STA DSKFLG ;ENABLE VALET INT. lda seksec ;compute host sector ORA A ;>--| RAR ;>--| ORA A ;>--|-- # OF (ORA A/RAR) DEPENDANT RAR ;>--| ON VALUE OF HSTBLK sta sekhst ;host sector to seek ; ; active host sector? ; lxi h,hstact ;host active flag mov a,m mvi m,1 ;always becomes 1 ora a ;was it already? JRZ filhst ;fill host if not ; ; host buffer active, same as seek buffer? ; lda sekdsk lxi h,hstdsk ;same disk? cmp m ;sekdsk = hstdsk? JRNZ nomatch ; ; same disk, same track? S; lxi h,hsttrk call sekcmp ;sektrk = hsttrk? JRNZ nomatch ; ; same disk, same track, same buffer? ; lda sekhst lxi h,hstsec ;sekhst = hstsec? cmp m JRZ match ;skip if match ; ; proper disk, but not correct sector ; nomatch:lda hstwrt ;host written? ora a cnz WRITEH ;clear host buff ; ; may have to fill the host buffer ; filhst: lda sekdsk sta hstdsk lhld sektrk shld hsttrk lda sekhst sta hstsec lda rsflag ;need to read? ora a cnz READHS ;yes, if 1 xra a ;0 to accum sta hstwrt ;no pending write ; ; COPY DATA TO OR FROM BUFFER ; match: lda seksec ;mask buffer number ani secmsk mov l,a ;ready to shift mvi h,0 ;double count DAD H DAD H DAD H DAD H DAD H DAD H dad h ; hl has relative host buffer address lxi d,hstbuf dad d ;hl = host address xchg ;now in DE lhld dmaadr ;get/put CP/M data ; mvi c,128 ;length of move lda readop ;which way? ora a JRNZ rwmove ;skip if read ; ; write operation, mark and switch direction ; mvi a,1 sta hstwrt ;hstwrt = 1 xchg ;source/dest swap ; ; DE is source, HL is dest, MOVE 128 BYTES ; rwmove: XCHG ; LDIR MOVES (DE)<-(HL) LXI B,128 ; MOVE 128 BYTES LDIR ; DO MOVE ; ; data has been moved to/from host buffer ; lda wrtype ;write type cpi wrdir ;to directory? lda erflag ;in case of errors rnz ;no further processing ; ; clear host buffer for directory write ; ora a ;errors? rnz ;skip if so xra a ;0 to accum sta hstwrt ;buffer written call WRITEH lda erflag ret ; ;|----------------------------------------------| ;| Utility subroutine for 16-bit compare | ;|----------------------------------------------| ; sekcmp: ;HL = .unatrk or .hsttrk, compare with sektrk xchg lxi h,sektrk ldax d ;low byte compare cmp m ;same? rnz ;return if not ; low bytes equal, test high 1s inx d inx h ldax d cmp m ;sets flags ret ; .LIST .IFE LSTDSK,[ .XLIST ] .PAGE ; ;|----------------------------------------------| ;| WRITEHST performs the physical write to | ;| the host disk, READHST reads the physical | ;| disk. | ;|----------------------------------------------| ; ;hstdsk = host disk #, hsttrk = host track #, ;hstsec = host sect #. write 'hstsiz' bytes ;from hstbuf and return error flag in erflag. ;return erflag non-zero if error WRITEH: MVI A,2 JMPR RDH1 READHS: MVI A,3 RDH1: STA DSKCMD RDH2: MVI A,10 ; SET FOR 10 RETRYS STA DSKFLG ; INHIBIT VALET HSL1: STA RECNT ; STORE RETRY CALL GSTUFF ; GET REGS. FOR DISK LDA DSKCMD ; GET COMMAND FOR DISK CALL DISK ; DO DISK OPERATION HSL2: LDA DSKCYC ; GET DSKCYC ORA A ; IF DSKCYC <> 0 JRNZ HSL3 ; THEN ..L3 LDA DSKCMD ; ELSE TEST LAST OP CPI 2 ;IF READ JUST FINISHED JRNZ HSI1 ; THEN CONTINUE ; MVI C,3 ; ELSE FORMAT OR WRITE JUST HSL5: MVI B,0CDH ; DONE SO DELAY TO GIVE TIME HSL6: DJNZ HSL6 ; FOR TUNNEL ERASE FIELD TO DCR C ; DECAY. JRNZ HSL5 ; HSI1: XRA A ; OPERATION DONE STA DSKFLG ; ENABLE VALET RET HSL3: ANI 0E0H ; IF NOT ERRONEOUS COMPLETION JRZ HSL2 ; THEN TEST DSKCYC AGAIN LDA RECNT ; ELSE DCR. RETRY RETRY DCR A ; COUNTER. IF <> 0 JRNZ HSL1 ; THEN RETRY MVI A,9 ; ELSE REPORT ERROR CALL DISK HSR1: LXI H,OPTMSG; PUT UP OPTION MESSG. CALL MESSG HSJ2: MVI C,CTRLX ; CLEAR KYBRD BUFFER CALL DISPLY CALL CONIN ; GET KEY ANI 0DFH ; MAKE UPPER CASE CPI 'W' ; IF KEY = W JRZ HSR2 ; THEN WARM BOOT CPI 'I' ; ELSE IF KEY = I JRZ HSI1 ; THEN IGNORE LAST OP. CPI 12H ; ELSE IF <> KEY = CTRL/R JNZ RDH2 ; THEN RETRY DISK OP. MVI A,8 ; ELSE REPORT FDC RESULT BYTES CALL DISK JMPR HSR1 ; LOOP TO OPTIONS AGAIN ; HSR2: LDA SETFLG ORA A ; IF IN VALET CNZ CLNVAL ; THEN RESET VALET VARIABLES JMP WBOOT ; WARM BOOT ; ; SET UP DATA FOR WRITEH & READHS ; GSTUFF: LXI H,HSTBUF; HL SET (ADDRESS) LDA HSTSEC INR A MOV E,A ; E SET (SECTOR) MVI B,1 ; B SET (# SECTORS TO XFER) LDA HSTDSK MOV C,A ; C SET (DRIVE #) ; LDA HSTTRK ; SET SIDE BIT IF NEEDED MOV D,A ; CHKSID = . ; .IFN TPI,[ ; BIT 0,C LDA EXM JRZ CHKBTH LDA EXMB CHKBTH: ORA A MOV A,D JRNZ CHK48 CPI 80 ; CHECK FOR SIDE 2 OF 48 TPI RC SUI 79+81H JMPR SIDOK ; ] .IFE TPI,[ ; JMP CHK48 .BLKB 18 ; ] ; CHK48: CPI 40 ; CHECK FOR SIDE 2 OF 96 TPI RC SUI 39+81H ; SIDOK: MOV D,A RET ; .PAGE ; ;GENERAL FLOPPY HANDLER ;STARTS MOTOR, HOMES IF NEEDED, ;SEEKS IF NEEDED, AND INITIATES ;READ, WRITE, OR FORMAT ; ;ENTRY PARAMETERS ; ; A = OPERATION CODE ; 0 = RETURN CURRENT STATUS ; 1 = FORMAT TRACK ; 2 = SECTOR WRITE ; 3 = SECTOR READ ; 8 = DISPLAY FDC RESULT BYTE ERROR MSSG. ; 9 = DISPLAY ENGLISH DISK ERROR MSSG. ; ; B = # OF SECTORS TO TRANSFER (MUST = 1) ; C = DRIVE # ; D = TRACK TO BEGIN TRANSFER (BIT 7 = SIDE) ; E = SECTOR TO BEGIN TRANSFER ; HL = ADDRESS TO TRANSFER TO/FROM ; ;DSKCYC CODES ; ; 0 = SUCCESSFUL COMPLETION ; 1 = DFM DATA FORMAT ; 2 = DWR DATA WRITE ; 3 = DRD DATA READ ; 4 = RC1 RECAL 1 ; 5 = SK1 SEEK TO 4 ; 6 = RC2 RECAL 2 ; 7 = SK2 SEEK TO TRACK ; 8 = WFR WAITING FOR READY ; ;ERROR IS INDICATED BY SETTING UPPER BIT(S) OF ;THE DSKCYC SEQUENCE CODE. ; ; BIT 7 = u765 ERRONEOUS COMPLETION ; BITS 7,6 = OPERATION TIME OUT ; BITS 7,6,5 = u765 NOT READY ; ; ;|----------------| ;| REPORT DSKYC | ;|----------------| ; DISK: ORA A ;IF ACC. <>0 JRNZ DSJ1 ; THEN GO NEXT TEST LDA DSKCYC ; ELSE TEST DSKCYC BIT 7,A RET ; ;|--------------------------------------| ;| REPORT ERROR WITH FDC RESULT BYTES | ;|--------------------------------------| ; DSJ1: CPI 8 ;IF ACC. <> 8 JRNZ DSJ2 ; THEN GO ..J2 CALL CRLF LXI H,DERMSG CALL MESSG LDA RESULT MOV B,A INR B LXI H,DSKCYC DSL1: MVI C,SPC CALL CONOUT PUSH B MOV B,M CALL DSHEX INX H POP B DJNZ DSL1 RET ; ;|-------------------------------------| ;| REPORT ERROR WITH ENGLISH MESSAGE | ;|-------------------------------------| ; DSJ2: CPI 9 JRNZ DSJ3 LXI H,VCRLF CALL MESSG LDA RWUNIT ANI 1 ADI 'A' STA DRVNUM LDA DSKCYC MOV B,A ANI 0E0H ; LXI H,TERR ; NODISK CPI 0C0H JRZ DSV1 ; CPI 0E0H JRNZ DSV2 MVI B,0 ; SYSTEM ; DSV2: MOV A,B ; ALL OTHERS ANI 0FH CPI 4 JRC DSV2A ANI 5 ; I.E. 7=5,6=4 DSV2A: INR A MOV B,A LXI H,CERR-6 LXI D,6 DSV3: DAD D DJNZ DSV3 DSV1: CALL MESSG LXI H,DERMSG JMP MESSG ; .PAGE ; ;|---------------------| ;| DO DISK OPERATION | ;|---------------------| ; ; SAVE DISK PARAMETERS ; DSJ3: STA DSKCMD ;SET UP DISK OP. TABLES MOV A,D ;--HD & UNIT ANI 80H RLC STA RWHD RLC RLC ORA C STA FMUNIT STA RWUNIT STA SDUNIT STA SKUNIT ANI 3 STA RCUNIT MOV A,D ANI 7FH STA RWCYL ; .IFN TPI,[ ; MOV D,A ; ADJUST SKCYL FOR 48/96 BIT 0,C ; CHECK DRIVE NUMBER LDA EXM JRZ CYLGN LDA EXMB CYLGN: ORA A MOV A,D JRZ OKCYL RAL ; ] .IFE TPI,[ ; JMP OKCYL .BLKB 13 ] ; OKCYL: STA SKCYL MOV A,E ;--SECTOR STA RWREC ; SHLD FMADDR ;--DATA ADDRESS SHLD RWADDR RLCR B MVI C,0 DCX B SBCD RWCNT ; DATA COUNT ; LDA DSKCMD CPI 1 JRZ DSJ5 ; IF COMMAND = FORMAT, THEN SKIP MOV C,A ; ELSE SET UP RWTBL MVI A,RWCODE ADD C STA RWCMD MVI A,39H BIT 0,C JRNZ DSJ4 ORI 40H DSJ4: STA RWTBL DSJ5: DI LHLD MTRCNT ;EXAMINE MOTOR COUNT MOV A,H ORA L ;IF MOTOR ON LXI H,MTRTIM SHLD MTRCNT JRZ STRMTR ; EI CALL SNSTAT BIT 5,A JRNZ DSJ5A LXI H,0 SHLD MTRCNT JMP NOTRDY DSJ5A: CALL GTFLGS ; EXAMINE PROPER HMFLG MOV A,M ORA A ;IF HMFLG = 0 JRZ DSJ8 MVI A,7 ; DSKCYC = 7 LXI H,SKTBL JMPR DSJ10 ; DSJ8: MVI A,4 ; DSKCYC = 4 LXI H,RCLTBL DSJ10: CALL DORCSK EI RET ; .PAGE ; ;|------------------------------| ;| MISC. DISK ROUTINES | ;|------------------------------| ; GTFLGS: LDA RWUNIT ; GET PROPER HMFLG LXI H,HMFLGS BIT 0,A RZ INX H RET ; SETDT: MVI A,60 ;SET OPERATION TIMEOUT STA DSKCNT ; (DECREMENTED BY SRV60) XRA A PUSH H MVI B,8 ; AND CLEAR RESULT BYTES LXI H,ST0 SDTL1: MOV M,A INX H DJNZ SDTL1 POP H RET ; ; START DRIVE MOTORS ; STRMTR: MVI A,40 CALL SETDT+2 ; 1/2 SECOND FOR DRIVE UP TO SPEED MVI A,8 ; DSKCYC = 8 STA DSKCYC SUI 7 CALL LLATCH EI ; ; CLEAR HOME FLAGS ; CLRFLG: LXI H,0 SHLD HMFLGS RET ; ; CLEAR ANY RESULT BYTES FROM FDC ; AND ISSUE ILLEGAL COMMAND TO RESET ; CLRFDC: MVI B,8 ; CLEAR FDC CFL1: MOV C,B CALL R765 MOV B,C DJNZ CFL1 RET ; .PAGE ; ;|----------------------------------------------| ;| BASIC FLOPPY DRIVER | ;| SETS UP BOTH FLOPPY CONTROLLER AND DMA FOR | ;| A FLOPPY OPERATION AND DELIVERS COMMAND. | ;| SEE FLOPPY COMMAND TABLES FOR TABLE FORMAT. | ;| RETURNS WITH Z FLAG SET IF A TIMEOUT OCCURS.| ;| 'A' CONTAINS ST3 ON EXIT FOR 'SENSE DRIVE | ;| STATUS' COMMANDS | ;|----------------------------------------------| ; ;---- LEAVES INTERRUPT DISABLED ---- ; SNSTAT: LXI H,SDSTBL ; SENSE DRIVE STATUS MVI A,1 JMPR DORCS1 ; DORCSK: STA DSKCYC ; SEEK OR RECALIBRATE MVI A,2 DORCS1: STA RESULT CALL SETDT ; DROP THROUGH TO DISKOP ; DISKOP: MOV D,H MOV E,L BIT 4,M JRZ DOJ3 ;Z=SKIP DMA SETUP MVI A,44H ;--SET UP DMA MODE BIT 6,M JRZ DOJ2 MVI A,48H DOJ2: OUT DMAWMR PUSH H INX H MVI C,FPYBCA OUTI OUTI MVI C,FPYBWR OUTI OUTI MVI A,0 OUT DMAWSM ;--MASK OFF DCX H XCHG POP H DOJ3: PUSH H ;SEND 765 COMMANDS MOV A,M ANI 0FH ;ISOLATE # BYTES TO SEND MOV B,A ;B=#OF BYTES MOV H,D MOV L,E DI DOL2: INX H ;DO UNTIL B=0 OR ERROR MOV C,M PUSH B CALL W765 ; SEND ONE BYTE TO FDC POP B JRZ DOJ5 ; GO ..J5 IF ERROR DJNZ DOL2 ;END DO POP H BIT 7,M ;IF READ ST3 RZ ; THEN GO ..J4 ; MVI B,1 ; READ ST3 CALL REDRES RNZ ; HAVE READ ALL BYTES PUSH H ; ELSE ERROR ; DOJ5: POP H ;KEEP SP CURRENT ; NOTRDY: CALL CLRFDC LDA DSKCYC ORI 0E0H STA DSKCYC XRA A RET ;RETURN (ERROR) ; ;This routine will wait for next byte ready then send the ;command passed in the C reg to the floppy controller ; W765: MVI B,31 ..L0: DJNZ ..L0 ; DELAY 36 US.(4 Mhz) MVI B,10 ; 10 RETRIES ..L1: IN SFLPY ; READ STATUS ANI 0C0H CPI 80H ; IF B7=1 & B6=0 JRZ ..J0 ; THEN ..J0 DJNZ ..L1 ; ELSE RETRY RET ; ..J0: ORA A MOV A,C ; CLEAR Z BIT OUT DFLPY ; SEND BYTE RET ; ;This routine will wait next byte ready then input the ;next status byte from the FDC ; R765: MVI B,31 ..L0: DJNZ ..L0 ; DELAY 36 US.(4 Mhz) MVI B,10 ; 10 RETRIES ..L1: IN SFLPY ; read status ANI 0C0H CPI 0C0H ; IF B7=B6=1 JRZ ..J0 ; THEN ..J0 DJNZ ..L1 ; ELSE RETRY RET ; ..J0: ORA A ; CLEAR Z BIT = O.K. IN DFLPY ; READ BYTE RET ; .LIST .IFE LSTFIN,[ .XLIST ] .PAGE ; ;||------------------------------------|| ;|| || ;|| FLOPPY INTERRUPT ROUTINE || ;|| || ;||------------------------------------|| ; SRVFPY: SSPD TEMSTK LXI SP,INTSTK PUSH H PUSH D PUSH B PUSH PSW IN SFLPY ANI 10H ; IF FDC NOT BUSY JRZ FPJ2 ; THEN SENSE INT. STATUS ; ;|-----------------------------------------| ;| RESULT PHASE FOR READ, WRITE OR FORMAT | ;|-----------------------------------------| ; MVI B,7 ; ELSE READ 7 RESULT BYTES CALL REDRES JRZ FPJ3 ; DIDN'T READ ALL BYTES LDA ST0 ; CHECK ST0 ANI 0F8H ; IF ST0 NOT OK LXI H,DSKCYC JRNZ FPJ5 ; THEN ERROR ; ;|-----------------------------------------------| ;| RESULT PHASE FOR SEEK, RECAL OR READY CHANGE | ;|-----------------------------------------------| ; FPJ2: MVI C,8 CALL W765 ; ISSUE SENSE INT. STATUS JRZ FPJ3 ; IF ERROR, THEN GO DERTIM CALL R765 JRZ FPJ3 ; READ 1ST RESULT BYTE MOV C,A ; SAVE ST0 CPI 80H ; IF INVALID COMMAND WAS ISSUED JRZ FPOK ; THEN WE ARE DONE LXI H,ST0 MOV M,C ; ELSE STORE ST0 CALL R765 ; READ NEXT BYTE FPJ3: JZ DERTIM ; FDC NOT READY INX H MOV M,A ; STORE ST1 MOV A,C ANI 0F8H CPI 20H ; IF SEEK OR RECAL JUST DONE JRZ FPJ2 ; THEN CHECK FOR HIDDEN INT. LXI H,DSKCYC; ELSE READY LINE HAS CHANGED STATE MOV A,M CPI 8 ; IF WAITING FOR READY FPJ4: JRZ IIEND ; THEN EXIT FPJ5: SET 7,M ; ELSE ERROR JMPR FPJ2 ; CHECK FOR HIDDEN INT. ; ;|--------------------------------------| ;| CHECK FOR NEXT OPERATION | ;|--------------------------------------| ; FPOK: XRA A STA DSKCNT ; CLEAR DSKCNT FPJ8: LXI H,DSKCYC; AND CHECK DSKCYC MOV A,M BIT 7,A ; IF BIT 7 SET JRNZ FPC7 ; THEN ERROR MVI M,0 ; ELSE CLEAR DSKCYC SUI 4 ; IF DSKCYC = 0,1,2, OR 3 JRC IIEND ; THEN EXIT JRNZ FPC1 ; ELSE IF DSKCYC <> 4 THEN ..C1 ; MVI A,4 ; DSKCYC NOW = 4 STA SKCYL ; SO DO SEEK TO TRACK 4 INR A ; NEW DSKCYC = 5 LXI H,SKTBL JMPR FPC9 ; FPC1: DCR A ; IF DSKCYC <> 5 JRNZ FPC2 ; THEN ..C2 LXI H,RCLTBL; DSKCYC NOW = 5 MVI A,6 ; SO DO 2ND RECALIBRATE JMPR FPC9 ; FPC2: DCR A ; IF DSKCYC <> 6 JRNZ FPC5 ; THEN ..C5 ; CALL GTFLGS ; DSKCYC NOW = 6 INR M ; SO SET PROPER HMFLG ; LDA RWCYL ; THEN SEEK TO DESIRED TRACK ORA A JRZ FPC6 STA SKCYL ; STORE TRACK IN SEEK TABLE LXI H,SKTBL MVI A,7 ; NEW DSKCYC = 7 FPC9: CALL DORCSK ; SEEK TO TRACK IIEND: JMP IEND ; FPC5: DCR A ; IF DSKCYC <> 7 FPC7: JRNZ DSKERR ; THEN ERROR, ARE NO OTHERS FPC6: MVI A,7 ; DSKCYC NOW = 7 STA RESULT LXI H,MTRTIM; SO RESET MOTOR TIMER SHLD MTRCNT LDA DSKCMD ; NEW DSKCYC = 1,2, OR 3 STA DSKCYC DCR A ; IF DSKCYC <> = 1 JRNZ FPC3 ; THEN ..C3 LXI H,FMTTBL; ELSE NEXT OP IS FORMAT JMPR FPC4 FPC3: LXI H,RWTBL ; NEXT OP IS READ OR WRITE FPC4: CALL SETDT ; CLEAR RESULT BYTES & RESET TIMEOUT COUNTER CALL DISKOP ; ISSUE COMMAND JMPR IIEND ; ;|------------------------------| ;| READ RESULTS (B) TIMES | ;|------------------------------| ; REDRES: LXI D,ST0 ; ELSE READ RESULTS LXI H,RESNUM RDRSL1: PUSH B CALL R765 ;READ 1 BYTE FROM FDC POP B RZ ; ERROR, Z BIT SET STAX D ; SAVE BYTE INX D INR M ; INCR COUNTER DJNZ RDRSL1 ; READ NEXT BYTE INR B ; CLEAR Z BIT RET ; ;|------------------------------| ;| DISK ERRORS | ;|------------------------------| ; WFRBAD: LXI H,0 ; -ERROR WHEN WAITING FOR READY SHLD MTRCNT ; CLEAR MTRCNT SO MOTOR IS STARTED JMP TIMOUT ; DSKCYC OR WITH 0C0H ; DSKERR: CALL CLRFDC ; NORMAL OPERATION ERROR LDA DSKCYC ; DSKCYC OR WITH 80H ORI 80H STA DSKCYC JMPR IIEND ; DERTIM: CALL NOTRDY ; u765 NOT READY ERROR JMPR IIEND ; DSKCYC OR WITH 0E0H ; .LIST .IFE LSTIO,[ .XLIST ] .PAGE S; ;|--------------------------------------| ;| I/O DRIVERS | ;|--------------------------------------| ; ;|-----------------------| ;| IOBYTE REDIRECTION | ;|-----------------------| ; CONIN: LDA IOBYTE ANI 3 JRZ TTYIN BIT 0,A JRZ LSTIN JMPR CRTIN ; CONOUT: LDA IOBYTE ANI 3 JRZ TTYOUT BIT 0,A JRZ LSTOUT JMPR CRTOUT ; READER: LDA IOBYTE RAR RAR ANI 3 JRZ TTYIN DCR A JRZ LSTIN DCR A JRZ CRTIN JMPR TTYIN ; PUNCH: LDA IOBYTE RAR RAR RAR RAR ANI 3 JRZ TTYOUT DCR A JRZ CRTOUT DCR A JRZ LSTOUT JMPR TTYOUT ; LIST: LDA IOBYTE RAL RAL RAL ANI 3 JRZ TTYOUT DCR A JRZ CRTOUT JMPR LSTOUT ; .PAGE ; ;|----------------------| ;| I/O ROUTINES | ;|----------------------| ; ; OUTPUT CHAR. TO LIST DEVICE (PRINT PORT) ; LSTOUT: CALL LSTOST JRNZ LSTOUT MOV A,C OUT DPRTR RET S; ; INPUT CHAR. FROM LIST DEVICE (PRINT PORT) ; LSTIN: CALL LSTIST JRZ LSTIN IN DPRTR RET ; ; OUTPUT CHAR. TO TTY DEVICE (COMM.PORT) ; TTYOUT: CALL TTYOST JRNZ TTYOUT MOV A,C OUT DCOMM RET ; ; INPUT CHAR. FROM TTY DEVICE (COMM. PORT) ; TTYIN: CALL TTYIST JRZ TTYIN IN DCOMM RET ; ; OUTPUT CHAR. TO CONSOLE DEVICE (CRT) ; CRTOUT: JMP DISPLY ; ; INPUT CHAR. FROM CONSOLE DEVICE (KEYBOARD) ; CRTIN: EI LDA TIMFLG ORA A CZ DSPTIM DI LDA KEYCNT ;LOOP UNTIL CHAR. ORA A JRZ CRTIN PUSH H PUSH D PUSH B LXI H,KEYBUF+1 LXI D,KEYBUF LXI B,KBUFLN-1 LDAX D LDIR LHLD KEYPNT DCX H SHLD KEYPNT LXI H,KEYCNT DCR M EI ANI 7FH ;MASK OFF BIT 7 POP B POP D POP H RET ; .PAGE ; ;|----------------------------| ;| I/O STATUS TEST ROUTINES | ;|----------------------------| ; ; TEST CONSOLE DEVICE INPUT STATUS ; CONST: LDA IOBYTE ANI 3 JRZ TTYIST BIT 0,A JRZ LSTIST LDA KEYCNT ORA A JMPR TSTGEN ; ; TEST LIST DEVICE OUTPUT STATUS ; LISTST: LDA IOBYTE RAL RAL RAL ANI 3 JRZ TTYOST DCR A JRZ TSTYGN ; LSTOST: MVI A,10H ; TEST LIST OUTPUT STATUS OUT SPRTR IN SPRTR TSTOGN: ANI 24H CPI 24H JRZ TSTYGN MVI A,0 RET ; LSTIST: MVI A,10H ; TEST LIST INPUT STATUS OUT SPRTR IN SPRTR JMPR TSTIGN ; TTYOST: MVI A,10H ; TEST TTY OUTPUT STATUS OUT SCOMM IN SCOMM JMPR TSTOGN ; TTYIST: MVI A,10H ; TEST TTY INPUT STATUS OUT SCOMM IN SCOMM TSTIGN: ANI 1 TSTGEN: RZ TSTYGN: MVI A,0FFH RET ; .PAGE ; CRLF: MVI C,0AH CALL CONOUT MVI C,0DH JMP CONOUT ; ; GENERAL MESSAGE ROUTINE ; MESSG: MOV C,M BIT 7,C RES 7,C INX H JNZ CONOUT CALL CONOUT JMPR MESSG ; ; DISPLAY H AS FOUR ASCII CHARS. ; DSADDR: MOV B,H CALL DSHEX MOV B,L ; ; DISPLAY B AS TWO ASCII CHARACTERS ; DSHEX: MOV A,B RLC RLC RLC RLC CALL DHJ1 MOV A,B DHJ1: ANI 0FH ADI 30H CPI 3AH JM DHJ2 ADI 7 DHJ2: MOV C,A JMP CONOUT ; ; CHANGE CONTROL LATCH: ENTER WITH BITS TO ; BE CHANGED IN A. IF Z IS SET, LATCH WILL ; BE ANDED WITH VALUE IN A; OTHERWISE ORED. ; DISABLES INTERRUPT. S; LLATCH: PUSH PSW MVI A,0CFH DI OUT SPIOA XRA A OUT SPIOA LDA LSTATE MOV B,A POP PSW JRZ LLJ1 ORA B JMPR LLJ2 LLJ1: ANA B LLJ2: STA LSTATE OUT DPIOA MVI A,0B8H OUT DPIOB MVI A,98H OUT DPIOB MVI A,0B8H OUT DPIOB RET ; ; MAKE THE SOUND SPECIFIED BY THE 14 BYTE TABLE ; POINTED TO BY H-L (R14 OF THE SOUND GENERATOR ; IS FIRST, R0 LAST) ; SOUND: MOV A,M STA TONPER INX H MVI A,0CFH DI OUT SPIOA S XRA A OUT SPIOA MVI A,0FFH OUT DPIOB LXI B,14*256+DPIOA SOL1: DCR B OUTP B INR B MVI A,0C3H OUT DPIOB MVI A,0E3H OUT DPIOB OUTI ;SEND THE DATA MVI A,0E7H OUT DPIOB MVI A,0C7H OUT DPIOB MVI A,0E7H OUT DPIOB JRNZ SOL1 RET ; .LIST .IFE LSTDSP,[ .XLIST ] .PAGE S; ;|--------------------------------------| ;| | ;| 500 DISPLAY & KEYBOARD DRIVER | ;| | ;|--------------------------------------| ; ;|----------------------| ;| CONTROL CODES | ;|----------------------| ; ; CTRL/G (07H) BELL ; CTRL/H (08H) BACKSPACE ; CTRL/I (09H) TAB ; CTRL/J (0AH) LINE FEED ; CTRL/K (0BH) REV. LINE FEED ; CTRL/L (0CH) RIGHT CURSOR ; CTRL/M (0DH) CARRIAGE RETURN ; CTRL/X (08H) CLEAR KEYBOARD BUFFER ; CTRL/Z (1AH) CLEAR ACTIVE REG. & HOME CURSOR ; CTRL/^ (1EH) CURSOR HOME ; ; BS (08H) BACKSPACE ; CR (0DH) CARRIAGE RETURN ; LF (0AH) LINE FEED ; ;|----------------------| ;| ESCAPE CODES | ;|----------------------| ; ; ESC 0XXYY PLOT POINT ; ESC 1XXYY PLOT VECTOR ; ESC 2XXYYXXYY BLOCK DRAW ; ESC 3 CLEAR GRAPHICS & PLOT BRIGHT ; ESC 4XXYYXXYY BLOCK FILL ; ESC 5 M1M2 SET MASKS ; ESC 6 DISABLE GRAPHIC IMAGE ; ESC 7 ENABLE GRAPHIC IMAGE ; ESC 8 SET TO PLOT BRIGHT ; ESC 9 SET TO PLOT DARK ; ESC : READ DATE ; ESC ; SET PRINTER BAUD FROM CMOS RAM ; ESC < SET COMM. BAUD FROM CMOS RAM ; ESC =LC DIRECT CURSOR MOVE ; ESC > READ TIME ; ESC ?A READ CMOS RAM ; ESC @AD WRITE TO CMOS RAM (CONSULT CMOS ALLOCATION) ; ESC A CURSOR UP ; ESC B CURSOR DOWN ; ESC C CURSOR RIGHT ; ESC D CURSOR LEFT ; ESC E -- NOT USED -- ; ESC F -- NOT USED -- ; ESC G -- NOT USED -- ; ESC H HOME ; ESC I REVERSE LINE FEED ; ESC J ERASE TO END OF SCREEN ; ESC K ERASE TO END OF LINE ; ESC L INSERT LINE ; ESC M DELETE LINE ; ESC N SET TABS ; ESC O CLEAR TABS ; ESC P DELETE CHAR. ; ESC Q INSERT CHAR. MODE ON ; ESC R INSERT CHAR. MODE OFF ; ESC SA SELECT CHAR. SIZE ; ESC TA SELECT CHAR. SET ; ESC UA SELECT ATTRIBUTE ; ESC VA SELECT ALT. LEAD-IN ; ESC WS1...S30 LOAD TONE TABLE AND EXECUTE ; ESC XTB SET ACTIVE REGION ; ESC YLC DIRECT CURSOR MOVE ; ESC Z RESET PARAMETERS ; ESC [ SAVE PARAMETERS (SYSTEM USE ONLY) ; ESC \ CLR. SCN. & RESET PAR. ; ESC ] RECALL PARAMETERS (SYSTEM USE ONLY) ; ESC ^ WORD WRAP OFF ; ESC _ WORD WRAP ON ; ESC ` WSFLAG SET (ON) ; ESC a WSFLAG RESET (OFF) ; ESC b SOUND TONE FROM TONE TABLE ; ESC c CURSOR OFF ; ESC d CURSOR ON ; .PAGE ; ;|--------------------------------------| ;| DISPLAY ENTRY (CHARACTER IN C) | ;|--------------------------------------| ; ; |---------------| ; | MASTER MODULE | ; |---------------| ; DISPLY: DI SSPD DSPSTK ; SAVE STACK POINTER LXI SP,DSPTEM ; SET STACK POINTER TO DISPLAY STACK PUSH PSW MVI A,0FFH ; SET DSPFLG TO INHIBIT VALET STA DSPFLG EI PUSH B ; SAVE REGISTERS PUSH D PUSH H ; ; ADD OFFSET TO LINE# ; LFAGN: CALL CMPOF1 ; CALCULATE LINE OFFSET ; ; CHECK CYCLE ; LDA DSPCYC ORA A ; IF DSPCYC <> 0 JNZ ESCCHK ; THEN GO CHECK DSPCYC ; ; IS CHARACTER ESCAPE ? ; RES 7,C ; ELSE MAKE SURE CHAR. IS ASCII MOV A,C CPI ESC ; IF CHAR. = ESC JRZ DSPJ1 ; THEN DSPJ1 LDA LEADIN ; ELSE CMP C ; IF CHAR. <> LEADIN JNZ DSPJ2 ; THEN OUTPUT IT TO DISPLAY DRIVER DSPJ1: MVI A,1 ; ELSE SET DSPCYC = 1 JMP EXIT3 ; AND EXIT ; ; IS CHARACTER CONTROL ? ; DSPJ2: MOV A,C ANI 60H ; IF CHAR. IS A CONTROL CHAR. JZ CTROL ; THEN GO TO CONTROL CASE ; ; TRANSLATE CHARACTER TO ALTERNATE ; SET, IF NEEDED. ; CALL CHKCHR ; ELSE XLATE TO ALTERNATE SET IF NEEDED ; ; OUTPUT CHAR. TO SCREEN AND ; INCREMENT H ACCORDINGLY ; CHRRET: CALL OUTCHR ; OUTPUT CHAR. TO SCREEN JRC DSPRET ; EXIT IF END OF LINE (EOL) CPI LF JRZ LFAGN ; ; STORE NEW H IN CHRADR+1 ; CUSTH: MOV A,H ; ELSE STORE POS. OF NEXT CHAR. STA CHRADR+1 ; ; OUTPUT CURSOR TO (H)+1,(L) ; CRSRET: CALL OUTCUR ; OUTPUT CURSOR ; ; EXIT POINTS ; EXIT2: XRA A ; CLEAR DSPCYC EXIT3: STA DSPCYC ; STORE DSPCYC DSPRET: POP H POP D ; RESTORE REGISTERS POP B XRA A DI STA DSPFLG POP PSW LSPD DSPSTK ; RESTORE STACK POINTER EI RET ; RETURN ; .PAGE ; ; |-----------------------| ; | MISC. ROUTINES FOR | ; | MASTER MODULE | ; |-----------------------| ; ; ; OUTPUT CHAR. TO HL ; OUTCHR: MOV E,A MVI D,1 LDA CURATT BIT 4,A JRZ OUTCR1 INR D OUTCR1: MOV A,L MOV B,H ORI 0E0H OUT SDSPY MVI C,DDSPY OUTP E ANI 0DFH OUT SDSPY ANI 1FH MOV L,A LDA CURATT OUTP A MOV A,H CPI 79 ; IF EOL JRZ OUTEXT ; THEN OUTEXT ; INR H ; ELSE DCR D ; IF DOUBLE CHAR. JRNZ OUTCR1 ; THEN OUTCR1 XRA A ; ELSE CLEAR CARRY (NOT EOL) RET ; AND RETURN ; OUTEXT: LDA WRPFLG ADI 1 ; IF LINE WRAP OFF RZ ; THEN RET W/CY SET ; XRA A STA CHRADR+1; COLOUMN = 0 MVI A,LF ; DO LINE FEED UPON RETURN MOV C,A RET ; ; OUTPUT CURSOR TO HL ; OUTCUR: LDA CURCTL ORA A RNZ MVI A,0ACH OUT SDSPY MOV A,H INR A OUT DDSPY MVI A,0ADH OUT SDSPY MOV A,L ANI 1FH OUT DDSPY RET ; ; ADD OFFSET TO LINE# ; CMPOF1: LHLD CHRADR CMPOFF: LDA LINOFS ADD L CPI LINES JRC CMPJ1 ADI -LINES CMPJ1: MOV L,A RET ; ; TRANSLATE ALT. CHAR. SET ; CHKCHR: MOV A,C CPI '@' RC CPI 80H RNC ANI 3FH MOV B,A LDA CURCHR ORA B RET ; .LIST .IFE LSTFNC,[ .XLIST ] .PAGE ; ;|--------------------------------------| ;| CONTROL CASE | ;|--------------------------------------| ; CTROL: MOV A,C ; ;|--------------| ;| BACK SPACE | ;|--------------| ; CTROL2: CPI BS JRNZ CLCR LDA CURATT BIT 4,A JRZ CLJ1 DCR H CLJ1: DCR H MVI A,0FFH CMP H JM CUSTH LDA WRPFLG ORA A JRNZ CLJ2 MOV A,H SUI 176 STA CHRADR+1 MOV H,A JMP REVLF ; CLJ2: MVI H,0 JMP CUSTH ; ;|-------------------| ;| CARRIAGE RETURN | ;|-------------------| ; CLCR: CPI CR JRNZ CLF MVI H,0 JMP CUSTH ; ;|-------------| ;| LINE FEED | ;|-------------| ; CLF: CPI LF JRNZ CLBL CLF1: LDA BOTACT ;IF NOT AT BOTTOM MOV B,A LDA CHRADR CMP B JRNZ CLF4 ; THEN MOVE CURSOR LDA MAGACT ; ELSE IF REGION NOT CPI LINES-1 ; FULL SCREEN JRNZ CLF3 ; THEN SOFTWARE SCROLL ; MVI L,0 CALL CMPOFF CALL LFCLR1 LDA LINOFS ;GRAPHIC SCROLL MOV D,A MVI B,1 ;CLEAR ONE LINE CALL GRFCLR+4 MVI A,0ABH ; ELSE HARDWARE SCROLL OUT SDSPY OUT DDSPY LXI H,LINOFS MOV A,M INR A CPI LINES JRNZ CLF2 XRA A CLF2: MOV M,A CALL CMPOF1 JMPR CLF5 ; END HARDWARE SCROLL ; CLF3: CALL SCRLUP ; BEGIN SOFTWARE SCROLL LDA CHRADR+1 MOV H,A JMPR CLF5 ; END SOFTWARE SCROLL ; CLF4: INR A ; BEGIN MOVE CURSOR DOWN STA CHRADR MOV L,A CALL CMPOFF CLF5: JMP CRSRET ; END MOVE CURSOR DOWN ; ;|--------| ;| BELL | ;|--------| ; CLBL: CPI BEL JRNZ CLTB LDA CURBEL BIT 0,A JRNZ CLEXT LXI H,BELLTN CALL SOUND EI CLEXT: JMP EXIT2 ; ;|-------| ;| TAB | ;|-------| ; CLTB: CPI 09H JZ MOVTAB ; ;|------------------| ;| REV. LINE FEED | ;|------------------| ; CLRV: CPI 0BH JZ REVLF ; ;|----------------| ;| CURSOR RIGHT | ;|----------------| ; CLRT: CPI 0CH JZ RITCUR ; ;|---------------| ;| CURSOR HOME | ;|---------------| ; CLHM: CPI 1EH JZ HOMCUR ; ;|-----------------------| ;| CLEAR ACTIVE REGION | ;|-----------------------| ; CLCLR: CPI 1AH JRNZ CTLX LDA TOPACT MOV L,A MVI H,0 CTRLZ: SHLD CHRADR CALL CMPOFF CALL OUTCUR CALL CLTOND CALL GRFCLR CLZ: JMP EXIT2 ; ;|-------------------------| ;| CLEAR KEYBOARD BUFFER | ;|-------------------------| ; CTLX: CPI CTRLX JRNZ CLZ LXI H,KEYBUF XRA A DI STA KEYCNT SHLD KEYPNT EI JMPR CLZ ; .PAGE ; ;|------------------------------| ;| ESCAPE CASE | ;|------------------------------| ; ESCCHK: DCR A JRZ ESCCK1 ; DCR A CPI 15H JRNC J19B PUSH H LXI H,CYCTBL JMPR ESCCK2 ; CALCULATE ADDRESS OF VECTOR FROM CHAR. ; GET VECTOR, PUSH IT AND EXECUTE (RET) ; TO JUMP TO IT. ; ESCCK1: MOV A,C ; MOVE NEXT CHAR. TO A SUI '0' ; SUBTRACT OFFSET JRC NFGESC ; IF CARRY, THEN INVALID CHAR. CPI '5' ; IF GREATER THAN 64H (NOW 34H) JRNC NFGESC ; THEN INVALID CHAR. PUSH H LXI H,ESCTBL ; ESCCK2: RLC ; ELSE MULTIPLY BY 2 MOV E,A ; MOVE TO LSB OF OFFSET MVI D,0 ; MSB OF OFFSET = 0 DAD D ; HL=(HL + DE) POINTS TO VECTOR MOV E,M ; MOVE LSB OF VECTOR TO E INX H MOV D,M ; MOVE MSB OF VECTOR TO D POP H ; RESTORE CURSOR ADDRESS PUSH D ; PUSH VECTOR ON STACK RET ; JUMP TO VECTOR ADDRESS ; NFGESC: MOV A,C ANI 7FH JMP CHRRET ; .PAGE ; ;|------------------| ;| 2 - BLOCK DRAW | ;|------------------| ; BLKDRW: MVI A,3 ; ;|------------------| ;| 0 - PLOT POINT | ;|------------------| ; PPOINT: STA GRFCMD PPNT1: MVI A,0EH ; DSPCYC = 0EH JMPR J19C ; ;|-------------------| ;| 1 - PLOT VECTOR | ;|-------------------| ; PVCTOR: MVI A,1 PVCT1: STA GRFCMD LHLD GRX SHLD GRX1 SHLD GRX12 XRA A STA GRY+1 LHLD GRY SHLD GRY1 SHLD GRY12 JMPR PPNT1 ; ;|------------------| ;| 4 - BLOCK FILL | ;|------------------| ; BLKFIL: MVI A,2 JMPR PPOINT ; ;|--------------------------| ;| 5 - SET MASKS FOR FILL | ;|--------------------------| ; SETMSK: MVI A,0DH STA GRFCMD J19C: JMP EXIT3 ; ;|-----------------------------| ;| 6 - DISABLE GRAPHIC IMAGE | ;|-----------------------------| ; DSBGRF: XRA A MVI A,-3 ; Z BIT SET ALREADY L6: CALL LLATCH EI J19B: JMP EXIT2 ; ;|----------------------------| ;| 7 - ENABLE GRAPHIC IMAGE | ;|----------------------------| ; ENBGRF: MVI A,2 ORA A ; A=2, Z BIT IS CLEAR JMPR L6 ; ;|----------------------| ;| 3 - CLEAR GRAPHICS | ;|----------------------| ; CLRGRF: CALL GRFCLR ; ;|--------------------------| ;| 8 - SET TO PLOT BRIGHT | ;|--------------------------| ; PTBRT: MVI A,0C7H PTBR1: STA GRFBIT+1 JMPR J19B ; ;|------------------------| ;| 9 - SET TO PLOT DARK | ;|------------------------| ; PTDRK: MVI A,87H JMPR PTBR1 ; ;|-----------------| ;| : - READ DATE | ;|-----------------| ; REDDAT: CALL READAT LXI H,OKIBYT LXI B,7 RDAT2: EI CPI '?' JRNZ RDAT1 LXI B,1 MOV M,A RDAT1: CALL PUSHKY JMPR J19B ; ;|--------------------------------------| ;| ; - SET PRINTER BAUD FROM CMOS RAM | ;|--------------------------------------| ; CMOSPN: CALL ADJPNT A513: EI JMP EXIT2 ; ;|------------------------------------| ;| < - SET COMM. BAUD FROM CMOS RAM | ;|------------------------------------| ; CMOSCM: CALL ADJCOM JMPR A513 ; ;|--------------------------| ;| = - DIRECT CURSOR MOVE | ;|--------------------------| ; DRCTMV: MVI A,2 JMPR J19C ; ;|-----------------| ;| > - READ TIME | ;|-----------------| ; REDTIM: CALL READTM LXI H,SCNDS LXI B,6 JMPR RDAT2 ; ;|---------------------| ;| ? - READ CMOS RAM | ;|---------------------| ; REDRAM: MVI A,12H JMPR J19C ; ;|----------------------| ;| @ - WRITE CMOS RAM | ;|----------------------| ; WRTRAM: MVI A,13H JMPR J19C ; ;|-----------------| ;| A - UP CURSOR | ;|-----------------| ; UPCUR: LDA CHRADR MOV B,A LDA TOPACT CMP B ;IF TOP OF ACT. REG. JRZ A45A ; THEN RETURN UPCUR1: DCR L ; ELSE MOVE CURSOR UP JP UPCUR2 MVI L,LINES-1 UPCUR2: DCR B MOV A,B STA CHRADR JMPR A42B ; ;|-------------------| ;| B - DOWN CURSOR | ;|-------------------| ; DWNCUR: LDA CHRADR MOV B,A LDA BOTACT CMP B ;IF BOTTOM OF ACT. REG. JZ EXIT2 ; THEN RETURN DNCUR1: INR L ; ELSE MOVE CURSOR DOWN MVI A,LINES CMP L JNZ DNCUR2 MVI L,0 DNCUR2: INR B MOV A,B STA CHRADR A42B: JMP CRSRET ; ;|--------------------| ;| C - RIGHT CURSOR | ;|--------------------| ; RITCUR: LDA CURATT BIT 4,A ;DOUBLE WIDTH MODE ? JRZ A431 INR H A431: INR H MVI A,79 CMP H ;IF NOT AT RIGHT BOUNDARY JP CUSTH ; THEN MOVE CURSOR ; LDA WRPFLG ORA A ; IF WRAP OFF JRNZ A45A ; THEN EXIT2 ; CALL OUTEXT ; ELSE CLEAR COLUMN # XRA A STA DSPCYC JMP LFAGN ; AND DO A LINE FEED ; ;|-------------------| ;| D - LEFT CURSOR | ;|-------------------| ; ; IS CTROL2+4 IN ESCTBL ; ;|----------------| ;| E - NOT USED | ;|----------------| ; ; IS EXIT2 IN TABLE ; ;|----------------| ;| F - NOT USED | ;|----------------| ; ; IS EXIT2 IN TABLE ; ;|----------------| ;| G - NOT USED | ;|----------------| ; ; IS EXIT2 IN TABLE ; ;|-------------------| ;| H - HOME CURSOR | ;|-------------------| ; HOMCUR: LDA TOPACT MOV L,A MVI H,0 SHLD CHRADR CALL CMPOFF JMPR A49A ; ;|----------------------| ;| I - REV. LINE FEED | ;|----------------------| ; REVLF: LDA CHRADR MOV B,A LDA TOPACT CMP B ;IF NOT AT TOP OF A.R. JNZ UPCUR1 ; THEN MOVE CURSOR CALL SCRLDN ; ELSE SCROLL A.R CALL CMPOF1 A49A: JMP CRSRET ; ;|-------------------------------------| ;| J - CLEAR TO END OF ACTIVE REGION | ;|-------------------------------------| ; CLREND: CALL CLTOND A45A: JMP EXIT2 ; ;|----------------------------| ;| K - CLEAR TO END OF LINE | ;|----------------------------| ; CLRELN: CALL LFCLR2 JMPR A49A ; ;|-------------------| ;| L - INSERT LINE | ;|-------------------| ; INSLIN: LDA CHRADR MOV B,A LDA BOTACT SUB B ;IF AT BOTTOM JRZ A4C1 ; THEN CLEAR LINE & EXIT CALL SCRDN1 ; ELSE INSERT BLANK LINE JMPR EXXIT2 A4C1: CALL LFCLR1 JMPR EXXIT2 ; ;|-------------------| ;| M - DELETE LINE | ;|-------------------| ; DELLIN: LDA CHRADR MOV B,A LDA BOTACT SUB B ;IF AT TOP JRZ A4C1 ; THEN CLEAR LINE AND EXIT MOV L,B ; ELSE SCROLL REGION MOV B,A ; UP & CLEAR BOTTOM LINE CALL SCRUP1 JMPR EXXIT2 ; ;|----------------| ;| N - SET TABS | ;|----------------| ; SETTAB: MVI A,0AH JMPR A51A ; ;|------------------| ;| O - CLEAR TABS | ;|------------------| ; CLRTAB: CALL CLRTBS EXXIT2: JMP EXIT2 ; ;|--------------------| ;| P - DELETE CHAR. | ;|--------------------| ; DELLCR: CALL DELCHR JMPR EXXIT2 ; ;|----------------------------| ;| Q - INSERT CHAR. MODE ON | ;|----------------------------| ; INSCON: MVI A,0CH A51A: JMP EXIT3 ; ;|-----------------------------| ;| R - INSERT CHAR. MODE OFF | ;|-----------------------------| ; ; IS EXIT2 IN ESCTBL ; ;|-------------------------| ;| S - SELECT CHAR. SIZE | ;|-------------------------| ; CHRSIZ: MVI A,9 JMPR A51A ; ;|------------------------| ;| T - SELECT CHAR. SET | ;|------------------------| ; CHRSET: MVI A,8 JMPR A51A ; ;|-------------------------| ;| U - SELECT ATTRIBUTES | ;|-------------------------| ; SELATR: MVI A,7 JMPR A51A ; ;|---------------------------| ;| V - SELECT ALT. LEAD-IN | ;|---------------------------| ; SELDIN: MVI A,0BH JMPR A51A ; ;|---------------------------------------------| ;| W - LOAD SPECIFIED REGISTER OF TONE TABLE | ;|---------------------------------------------| ; DSPSND: MVI A,16H JMPR A51A ; ;|-------------------------| ;| X - SET ACTIVE REGION | ;|-------------------------| ; SETACR: MVI A,5 JMPR A51A ; ;|--------------------------| ;| Y - DIRECT CURSOR MOVE | ;|--------------------------| ; ; IS DRCTMV IN ESCTBL ; ;|------------------------| ;| Z - RESET PARAMETERS | ;|------------------------| ; RESPAR: CALL RSTPAR JMPR EXXIT2 ; ;|-----------------------| ;| [ - SAVE PARAMETERS | ;|-----------------------| ; SAVVPR: CALL SAVPAR JMPR EXXIT2 ; ;|---------------------------------------| ;| \ - CLEAR SCREEN & RESET PARAMETERS | ;|---------------------------------------| ; ; IS CLSCRN IN ESCTBL ; ;|-------------------------| ;| ] - RECALL PARAMETERS | ;|-------------------------| ; RCLPAR: CALL RSTORP ;RESTORE PARAMETERS CALL CMPOF1 ; MOVE CURSOR TO JMP CRSRET ; PREVIOUS POSITION ; ;|----------------| ;| ^ - WRAP OFF | ;|----------------| ; WRPOFF: MVI A,0FFH JMPR WRPGEN ; ;|---------------| ;| _ - WRAP ON | ;|---------------| ; WRPON: XRA A WRPGEN: STA WRPFLG A5F0: JMP EXIT2 ; ;|-----------------------| ;| ` - WSFLAG SET (ON) | ;|-----------------------| ; SETWS: MVI A,0FFH JMPR A512 ; ;|--------------------------| ;| a - WSFLAG RESET (OFF) | ;|--------------------------| ; CLRWS: XRA A A512: STA WSFLAG JMPR A5F0 ; ;|-----------------------------| ;| b - MAKE SOUND FROM TABLE | ;|-----------------------------| ; DOSND: LXI H,SNDTBL CALL SOUND EI JMPR A5F0 ; ;|-----------------| ;| c - CURSOR OFF | ;|-----------------| ; OFFCUR: MVI H,81 CALL OUTCUR MVI A,0FFH STA CURCTL JMPR A5F0 ; ;|-----------------| ;| d - CURSOR ON | ;|-----------------| ; ONCUR: XRA A STA CURCTL JMP CRSRET ; .LIST .IFE LSTMCH,[ .XLIST ] .PAGE ; ;|--------------------------------------| ;| | ;| MULTI - CHAR. SEQUENCE HANDLERS | ;| | ;|--------------------------------------| ; ;|--------------------------------------------| ;| 02H - DIRECT CURSOR POSITION LINE NUMBER | ;|--------------------------------------------| ; LINCHK: MOV A,C SUI SPC MOV B,A LDA BOTACT CMP B JM LNCKJ3 LDA TOPACT CMP B JRZ LNCKJ1 JP LNCKJ3 LNCKJ1: MOV A,B STA CHRADR MOV L,A CALL CMPOFF MOV A,L LNCKJ2: STA TEMLIN MVI A,3 JMP EXIT3 LNCKJ3: MVI A,0FFH JMPR LNCKJ2 ; ;|----------------------------------------------| ;| 03H - DIRECT CURSOR POSITION COLUMN NUMBER | ;|----------------------------------------------| ; COLCHK: LDA TEMLIN CPI 0FFH JZ EXIT2 MOV L,A MOV A,C SUI SPC MOV H,A JMP CUSTH+1 ; ;|------------------| ;| 04H - NOT USED | ;|------------------| ; ; IS EXIT2 IN TABLE ; ;|------------------------------| ;| 05H - TOP OF ACTIVE REGION | ;|------------------------------| ; TACTCK: MOV A,C SUI SPC STA TOPACT MVI A,6 JMP EXIT3 ; ;|---------------------------------| ;| 06H - BOTTOM OF ACTIVE REGION | ;|---------------------------------| ; BACTCK: MOV A,C SUI SPC LXI H,TOPACT MOV B,M ; GET TOPACT INX H MOV M,A ; STORE BOTACT SUB B ; CALCULATE MAGACT INX H MOV M,A ; STORE MAGACT JMP HOMCUR ; ;|--------------------------| ;| 07H - SCREEN ATTRIBUTE | ;|--------------------------| ; ATTCHK: MOV A,C ADI 20H ANI 38H S RLC MOV D,A MOV A,C ANI 7H ORA D RLC MOV D,A LXI H,CURATT MOV A,M ANI 11H ORA D MOV M,A JMPR EXXT2 ; ;|-----------------------------| ;| 08H - ALTERNATE CHAR. SET | ;|-----------------------------| ; ALTCHK: MOV A,C ANI 3 MOV C,A MVI B,0 LXI H,CHRTBL DAD B MOV A,M STA CURCHR EXXT2: JMP EXIT2 ; ;|---------------------------| ;| 09H - SELECT CHAR. SIZE | ;|---------------------------| ; SIZCHK: LDA CURATT ANI 0EFH MOV B,A MOV A,C SUI '0' JRZ SZCKJ1 MVI A,10H SZCKJ1: ORA B STA CURATT JMPR EXXT2 ; ;|------------------| ;| 0AH - SET TABS | ;|------------------| ; TABCHK: MOV A,C CPI ESC JRZ EXXT2 SUI 20H JM EXIT2 CPI 50H JRNZ TBJ0 CALL CLRTBS JMP DSPRET TBJ0: JP EXIT2 MOV B,A LDA LASTAB CMP B MOV A,B JRNC TBOK STA LASTAB TBOK: ANI 7H INR A MOV B,A MVI A,80H JMPR TBJ1 TBJ2: SRLR A TBJ1: DJNZ TBJ2 MOV B,A MOV A,C CALL GTEFAD MOV A,M ORA B MOV M,A JMPR SCHK1 ; ;|---------------------------| ;| 0BH - ALTERNATE LEAD IN | ;|---------------------------| ; LEDCHK: MOV A,C STA LEADIN JMPR EXXT2 ; ;|------------------------| ;| 0CH - INSERT MODE ON | ;|------------------------| ; INSCHK: LDA LEADIN CMP C JRNZ INCKJ2 INCKJ1: MVI A,1 JMP EXIT3 INCKJ2: MVI A,ESC CMP C JRZ INCKJ1 PUSH B PUSH H CALL INSCHR POP H POP B CALL CHKCHR CALL OUTCHR JRC SCHK1 MOV A,H STA CHRADR+1 CALL OUTCUR SCHK1: JMP DSPRET ; .PAGE ; ;|------------------| ;| 0DH - GET MASK | ;|------------------| ; GRFCHK: LDA GRFCMD CPI 0DH MOV A,C JRNZ GRCK1 ;MASKS FOR FILL STA MASK XRA A STA GRFCMD JMPR SCHK1 GRCK1: STA XMASK JMPR GREXT2 ; ;|-------------------| ;| 0EH - GET X MSB | ;|-------------------| ; GRFCK1: XRA A BIT 2,C JRZ GRCK3 INR A GRCK3: STA GRX+1 MOV A,C RRC RRC ANI 0C0H STA GRX MVI A,0FH JMPR GREXT3 ; ;|-------------------| ;| 0FH - GET X LSB | ;|-------------------| ; GRFCK2: MOV A,C ANI 3FH ;REMOVE POSSIBLE OFFSET LXI H,GRX ORA M MOV M,A MVI A,10H GREXT3: JMP EXIT3 ; ;|-------------------| ;| 10H - GET Y MSB | ;|-------------------| ; GRFCK3: MOV A,C RRC RRC ANI 0C0H STA GRY MVI A,11H JMPR GREXT3 ; ;|-------------------| ;| 11H - GET Y LSB | ;|-------------------| ; GRFCK4: MOV A,C ANI 3FH ;REMOVE POSSIBLE OFFSET LXI H,GRY ORA M MOV M,A LDA GRFCMD ORA A JRNZ GRCK6 CALL PPLOT GREXT2: JMP EXIT2 GRCK6: DCR A JRNZ GRCK7 CALL VPLOT JMPR GREXT2 GRCK7: DCR A JRNZ GRDOIT MVI A,4 ;IF BLOCK FILL OR DRAW GRCK8: JMP PVCT1 ;GET SECOND POINT GRDOIT: DCR A JRNZ GROK MVI A,5 JMPR GRCK8 GROK: LXI H,EXIT2 PUSH H ;SET RETURN ADDRESS DCR A JZ FILL JMP DRWBLK ; ; .PAGE ; ;|-----------------------| ;| 12H - READ CMOS RAM | ;|-----------------------| ; GRFCK5: MOV B,C CALL RD5101 EI ANI 0FH ORI '0' LXI H,HRS10 MOV M,A LXI B,1 JMP RDAT1 ; ;|------------------------------------| ;| 13H - GET ADDRESS FOR CMOS WRITE | ;|------------------------------------| ; GRFCK6: MOV A,C STA MINS MVI A,14H EXXX3: JMP EXIT3 ; ;|------------------------| ;| 14H - WRITE CMOS RAM | ;|------------------------| ; GRFCK7: LDA MINS MOV B,A MOV A,C CALL WR5101 EI EXXX2: JMP EXIT2 ; ;|----------------------------------------------| ;| 15H - FILL SPECIFIED ADDRESS IN TONE TABLE | ;|----------------------------------------------| ; GETSND: LXI H,SNDCNT BIT 0,M XCHG LHLD SNDADR JRNZ GTSND2 GTSND1: MOV M,C JMPR GTSND3 ; GTSND2: MOV A,C RLD GTSND3: XCHG DCR M JRZ EXXX2 DS15: MVI A,15H JMPR EXXX3 ; ;|------------------------------------| ;| 16H - GET ADDRESS IN TONE TABLE | ;|------------------------------------| ; SETSND: MVI A,2EH SUB C ; NUMBER NOW = OFFSET IN TABLE JM EXXX2 ; EXIT IF NEGATIVE CPI 15 JRNC EXXX2 ; EXIT IF > 14 MVI B,0 MOV C,A LXI H,SNDTBL DAD B ; ADD TO BASE TO POINT TO REG. GOTSND: SHLD SNDADR MVI A,2 STA SNDCNT JMPR DS15 ; .LIST .IFE LSTDMC,[ .XLIST ] .PAGE ; ;|--------------------------------------| ;| DISPLAY SUBROUTINES | ;|--------------------------------------| ; READAT: LXI H,NATDAT; GET POINTERS TO TABLES LXI D,OKIDAT CALL GETCLK ; READ DATE JRNZ NOCLK ; NOCLK IF CAN'T READ OR NOT SET LXI H,OKIBYT MOV A,C ORA A ; IF NATIONAL CHIP JRZ ..J0 ; THEN ..J0 INR M ; ELSE INCREMENT DAY OF WEEK ..J0: INX H ; INCREMENT POINTER TO INX H ; AND OFF PROPER VALUE JMPR ANDIT ; READTM: LXI H,NATTIM; GET POINTERS TO TABLES LXI D,OKITIM CALL GETCLK ; READ TIME JRNZ NOCLK ; NOCLK IF CAN'T READ OR NOT SET LXI H,HRS10 ; ANDIT: MOV A,M ANI 0F3H MOV M,A RET ; NOCLK: XRA A STA CLKFLG MVI A,'?' RET ; GETCLK: PUSH D MVI B,3 ; READ NYBBLE 3 OF CMOS CALL RD5101 CPI 0EH ; IF <> 0EH JRNZ ..J0 ; THEN ..J0 MVI B,4 ; ELSE READ NYBBLE 4 OF CMOS CALL RD5101 CPI 5 ; IF <> 5 ..J0: POP D RNZ ; RETURN, CLOCK NOT SET STA CLKFLG ; SET CLKFLAG ; LDA OKIFLG ; USE PROPER TABLE ORA A MOV C,A ; SAVE OKIFLG JRZ ..J1 XCHG ; ..J1: MVI B,10 ..L0: PUSH B CALL REDCLK POP B RZ DJNZ ..L0 RET ; REDCLK: LXI D,HRS10 DCX H ..L0: INX H MOV A,M ORA A ; IF A = 0 RZ ; THEN WE'RE DONE INX H ; ELSE GET ADDRESS MOV B,M ; PUSH D ; SAVE D DCR A ; IF A > 1 JRNZ ..J0 ; THEN READ CMOS RAM ; CALL R58174 ; ELSE READ FROM CLOCK JMPR ..J1 ; ..J0: CALL RD5101 ; READ FROM CMOS RAM ..J1: POP D CPI 0FH ; IF <> 0FH JRNZ ..J2 ; THEN O.K READ ORA A ; ELSE ERROR RET ; ..J2: ORI '0' STAX D DCX D JMPR ..L0 ; .PAGE ; ; SCROLL ACTIVE REGION UP ; SCRLUP: MOV B,A ORA A JRZ LFCLR0 LDA TOPACT MOV L,A SCRUP1: CALL CMPOFF MOV E,L MOV A,L INR A CPI LINES JRNZ SCRUP2 XRA A SCRUP2: MOV D,A SCRUP3: PUSH D PUSH B CALL MOVLIN POP B POP D MOV E,D INR D MVI A,LINES CMP D JRNZ SCRUP4 MVI D,0 SCRUP4: DJNZ SCRUP3 MOV L,E JMPR LFCLR1 ; ; SCROLL ACTIVE REGION DOWN ; SCRLDN: LDA MAGACT ORA A JRZ LFCLR0 SCRDN1: MOV B,A LDA BOTACT MOV L,A CALL CMPOFF MOV E,L MOV A,L ORA A JRNZ SCRDN2 MVI A,LINES SCRDN2: DCR A MOV D,A SCRDN3: PUSH D PUSH B CALL MOVLIN POP B POP D MOV A,D MOV E,D ORA A JRNZ SCRDN4 MVI A,LINES SCRDN4: DCR A MOV D,A DJNZ SCRDN3 MOV L,E ; ;|----------------| ;| CLEAR LINE L | ;|----------------| ; LFCLR0: CALL CMPOF1 LFCLR1: MVI H,0 MOV A,L ORI 0C0H MOV L,A LXI D,SPC LXI B,79*256+SDSPY PUSH B OUTP L MVI C,DDSPY LFCL1: OUTP D DJNZ LFCL1 OUTP D POP B SET 5,L OUTP L MVI C,DDSPY LFCL2: OUTP E DJNZ LFCL2 OUTP E RET ; ; CLEAR LINE L FROM POSITION H TO END OF LINE ; LFCLR2: MOV A,L ORI 0C0H MOV L,A LXI D,SPC MOV B,H MVI A,80 LFCL3: MVI C,SDSPY CMP B RZ OUTP L ;CLEAR ATTRIBUTE MVI C,DDSPY OUTP D MVI C,SDSPY SET 5,L OUTP L ;CLEAR CHARACTER MVI C,DDSPY OUTP E RES 5,L INR B S JMPR LFCL3 ; ; MOVE LINE D TO LINE E ; MOVLIN: MOV A,D ;SET UP ORI 0C0H MOV D,A MOV A,E ORI 0C0H MOV E,A MVI B,79 PUSH H PUSH B CALL MOVLN1 ;MOVE ATTRIBUTES POP B POP H SET 5,D ;MOVE CHARACTERS SET 5,E MOVLN1: MVI C,SDSPY OUTP D LXI H,DSPBUF PUSH H PUSH B MVI C,DDSPY INIR INI POP B INR B POP H OUTP E MVI C,DDSPY OUTIR RET ; ;|----------------------------| ;| MOVE CURSOR TO NEXT TAB | ;|----------------------------| MOVTAB: LDA LASTAB CMP H JM EXIT2 JRZ TBDON PUSH H MOV B,H MOV A,H ANI 78H CALL GTEFAD+2 MOV A,B ANI 7H MOV B,A CPI 7 JRZ MOVTB3 ADI 0F8H CMA MOV D,A MOV A,M INR B MOVTB1: RLCR A DJNZ MOVTB1 MOV B,D MOVTB2: BIT 7,A JRNZ TBIT RLCR A DJNZ MOVTB2 MOVTB3: MVI A,9 CMP E JRZ TBOVR INR E INX H MOV A,M MVI B,8 JMPR MOVTB2 TBIT: MOV A,B ADI 0F7H CMA MOV B,A MOV A,E ANA A RAL RAL RAL ORA B POP H MOV H,A JMP CUSTH TBOVR: POP H TBDON: JMP EXIT2 ; GTEFAD: SUI SPC SRLR A SRLR A SRLR A MOV E,A MVI D,0 LXI H,TABS DAD D RET ; ; RESET PARAMETERS ; RSTPAR: LXI H,CURCHR MVI M,40H XRA A MVI B,4 ..L0: INX H MOV M,A DJNZ ..L0 MVI A,LINES-1 STA BOTACT STA MAGACT MVI A,ESC STA LEADIN ; ; RESET OR CLEAR TABS ; RSTABS: MVI A,4FH STA LASTAB MVI A,1 JMPR DOTABS ; CLRTBS: XRA A STA LASTAB ; DOTABS: LXI H,TABS MVI B,10 DOTBJ1: MOV M,A INX H DJNZ DOTBJ1 RET ; ; SAVE SCREEN PARAMETERS ; SAVPAR: LXI H,CURCHR LXI D,TEMPAR JMPR PARGEN ; ; RESTORE SCREEN PARAMETERS ; RSTORP: LXI H,TEMPAR LXI D,CURCHR PARGEN: LXE B,21 LDIR RET ; ; CLEAR SCREEN & RESET PARAMETERS ; CLSCRN: CALL RSTPAR XRA A STA LINOFS MVI A,0A6H OUT SDSPY MVI A,LINES-1 OUT DDSPY LXI H,0 JMP CTRLZ ; ; CLEAR TO END OF ACTIVE REGION ; CLTOND: CALL LFCLR2 LDA CHRADR MOV B,A LDA BOTACT SUB B RZ MOV B,A CLND1: MOV A,L ANI 1FH INR A CPI LINES JRNZ CLND2 XRA A CLND2: MOV L,A PUSH B CALL LFCLR1 POP B DJNZ CLND1 RET ; ; INSERT OR DELETE CHAR. ; INSCHR: PUSH H ;SET UP FOR INSERT LXI H,DSPBUF+1 SHLD MOVBEG MVI A,23H ;INX H STA MODX JMPR INSDEL ; DELCHR: PUSH H ;SET UP FOR DELETE LXI H,DSPBFL+1 SHLD MOVBEG MVI A,2BH ;DCX H STA MODX ; INSDEL: XRA A CALL FILBFF ; INSERT OR DELETE POP H PUSH H MOV A,L ORI 0C0H MOV L,A PUSH H CALL INPLIN POP H MOV A,L MOV E,H OUT SDSPY LHLD MOVBEG LDA CURATT BIT 4,A JRZ INDEL1 MODX: DCX H ;MODIFIABLE CODE INDEL1: PUSH H CALL OUTLIN MVI A,20H CALL FILBFF POP D POP H PUSH D MOV A,L ORI 0E0H MOV L,A PUSH H CALL INPLIN POP H MOV A,L MOV E,H POP H JMP OUTLIN ; FILBFF: LXI H,DSPBFL ;FILL BUFFER WITH (A) MVI B,84 FLBF1: MOV M,A INX H DJNZ FLBF1 RET ; INPLIN: OUT SDSPY ;INPUT PART OF LINE MOV A,H ;TO PART OF BUFFER DCR A MVI B,79 MVI C,DDSPY LXI H,DSPBUF INPLN1: INI CMP B JRNZ INPLN1 RET ; OUTLIN: MVI B,80 ;OUTPUT PART OF BUFFER MOV A,E ;TO PART OF LINE MVI C,DDSPY OUTLN1: OUTI CMP B JRNZ OUTLN1 RET ; .LIST .IFE LSTGRF,[ .XLIST ] .PAGE ; ; FILL COMMAND ; GRFSTR = . FILL: LDA GRY ;SET UP GRY,GRY1 MOV B,A LDA GRY1 ;AND GRX,GRX1 IN RIGHT ORDER SUB B CC SWPY XRA A ;ZERO CARRY LHLD GRX LDED GRX1 DSBC D CC SWPX LDA XMASK ;CHECK MASKS MOV B,A ;FOR BOTH = 0 LXI H,MASK MOV A,M ORA B MOV A,B STA CLFLG JRNZ FILL1 MVI A,0A2H ;ANA D STA ORAD ;PREPARE TO CLEAR BLOCK MVI A,0FFH ;MAKE MASKS 'FF' FOR NOW AND COMPLEMENT MOV M,A ;AFTER FIXING EDGES STA XMASK FILL1: INX H MOV M,A ;MASK2 INX H INX H MOV M,A ;CURMSK XRA A STA CYC ;START CYCLE AT ZERO CALL LINDSP ;CACULATE LINE LHLD GRX CALL PIX ;PIX FINDS OUT WHICH BIT THE STA PIXBT2 ;PIXEL IS IN CALL XDDR STA STRX ;START FOR X LDA GRY1 ;DO THE SAME FOR CALL LINDSP+3 LHLD GRX1 ;OTHER POINT CALL PIX MVI C,0FH ;FIX TOP PUSH H CALL FIXNIB ;FIX MASK FOR TOP EDGE POP H CALL XDDR STA STRX1 ;START FOR X2 DOMSK: LDA GRY ;START LINE HERE MOV B,A LDA GRY1 ORA A ;IF GRY1 IS AT LAST LINE JRZ LSTLIN ;THEN DO IT AND LEAVE SUB B JRC EXIT1 ;DONE IF PAST GRY CZ FIXBOT CALL LINE ;DO A LINE DOCOL: CALL COLUMN ;LOOP UNTIL ALL COLUMNS ARE DONE CALL NXTBYT ;FIND NEXT BYTE JRNZ DOCOL LDA CYC ;GET NEW MASK ORA A JRZ MSKDON ;CYCLE TELLS US WHICH ONE XRA A STA CYC XMSK: MVI A,0FFH ;MODIFIED MASK MSKOK: STA MASK2 STA CURMSK JMPR DOMSK MSKDON: INR A STA CYC LDA MASK JMPR MSKOK ; XMASK = XMSK+1 ; EXIT1: LDA PIXBIT ;WE HAVE TO MAKE SURE TO GET ANI 4 JRNZ EXIT ;LAST LINE IF NEEDED. LDA PIXBT2 ANI 4 JRZ EXIT ; LSTLIN: CALL LINE ;IF WE ARE AT THE LAST LINE CALL FIXBOT LSTLN1: CALL COLUMN ;WE DO IT AND EXIT CALL NXTBYT JRNZ LSTLN1 ;FALL INTO EXIT ; ; EXIT: LDA CLFLG ;IF WE WERE CLEARING ORA A RNZ ;A BLOCK WE NEED STA MASK STA XMASK ;TO RESTORE EVERYTHING MVI A,0B2H ;ORA D STA ORAD STA CLFLG RET ; DNLIN: MOV M,A POP PSW JMPR LSTLIN ; ; COLUMN: LDA CLFLG ;IF WE ARE ORA A ;CLEARING A BLOCK LDA MASK2 JRNZ CLMN1 CMA ;THEN COMPLEMENT THE MASK AND CLMN1: MOV D,A MVI C,DDSPY ;AND IT INSTEAD OF ORING IT INP A ORAD: ORA D ;MODIFIED TO ANA D FOR CLEAR OUTP A RET ; LINE: LDA STRX ;IF THE BLOCK IS LESS THAN MOV C,A LDA STRX1 ;4 PIXELS WIDE SUB C CPI 4 ;WE NEED TO FIX THE RIGHT EDGE CC FIXRGT LDA GRY1 ;FIND SDSPY FOR NEW LINE CALL LINDSP+3 OUT SDSPY FIXLFT: LDA PIXBIT ;FIX THE LEFT EDGE ANI 03H SUI 3 ;TAKE PIXELS OFF THE EDGES JRZ FXLFT2 NEG ;PIXBIT TELLS US HOW MANY MOV B,A LXI H,MASK2 ;PIXELS TO TAKE OFF MOV A,M MVI D,77H FXLFT1: ANA D RRCR D DJNZ FXLFT1 MOV M,A FXLFT2: LDA STRX1 ;WE NEED STRX1 IN B MOV B,A ;FOR COL RET ; ; PIX: CALL SETBIT ;SET BIT TELLS US WHICH RRCR A ;BIT IN A NIBBLE RRCR A RRCR A ;MOVE FROM BITS 3,4,5 ANI 07H ;TO 0,1,2 STA PIXBIT RET ; ; NXTBYT: LDA STRX1 ;IF WE JUST FINISHED WITH CMP B ;THE FIRST BYTE JRNZ NXBYT1 LXI H,CURMSK ;WE MUST UNFIX MOV C,M ;THE LEFT EDGE DCX H ;MMASK MOV A,M ;MMASK TELLS US IF THE TOP ANA C ;WAS FIXED OR NOT DCX H ;MASK2 MOV M,A ;MASK2 IS THE FIXED MASK MVI A,0FFH ;MAKE MMASK 'FF' INX H MOV M,A ;MMASK NXBYT1: INR B ;POINT TO NEXT BYTE LDA STRX CMP B ;COMPARE TO LAST BYTE JRZ FIXRGT ;IF EQUAL FIX RIGHT EDGE RNC ;IF LESS DO IT LXI H,GRY1 ;ELSE DECREMENT GRY1 TWICE MOV A,M ORA A ;TO GET TO NEXT LOWER BYTE RZ ;DO NOT GO BELOW ZERO DCR A ;DOWN TWO LINES JZ DNLIN DCR A MOV M,A XRA A ;SET ZERO FLAG TO START A NEW LINE RET ; ; FIXRGT: LDA PIXBT2 ;PIXBT2 IS FOR THE RIGHT EDGE ANI 03 JRZ FXRGT2 ;IF ZERO THEN NO FIXING NEEDED PUSH B ;SAVE X MOV B,A MVI D,0EEH ;TAKE OFF 'PIXBT2' BITS LXI H,MASK2 ;OFF RIGHT EDGE MOV A,M FXRGT1: ANA D RLCR D DJNU FXRGT1 MOV M,A ;SAVE IN MASK2 POP B ;GET X FXRGT2: INR A RET ; ; FIXBOT: MVI C,0F0H ;BOTTOM EDGE LDA PIXBT2 ;BIT 2 OF PIXBIT TELLS CMA ;US WHICH NIBBLE WE ARE IN FIXNIB: ANI 4 ;FIXNIB IS USED BY FIXTOP ALSO RNZ ;RETURN IF NO FIXING NEEDED LXI H,MASK2 MOV A,C ;AND MASK2 WITH F0 OR 0F ANA M ;TO TAKE OFF TOP OR BOTTOM LINE MOV M,A INX H MOV M,C ;PUT 0F OR F0 IN MMASK RET ;TO REMEMBER ; GRFEND = .-GRFSTR ; LINDSP: LDA GRY ADI 16 ;FIND OUT WHICH NIBBLE CMA LXI H,PIXBIT RES 5,M BIT 0,A JRNZ LNDSP1 SET 5,M LNDSP1: SRLR A MVI B,-1 ;AND WHICH LINE LNDSP2: INR B ADI -5 JRC LNDSP2 ADI 5 RRC RRC RRC MOV C,A LDA LINOFS PUSH PSW ;SAVE LINOFS ADD B CPI LINES JRC LNDSP3 ADI -LINES LNDSP3: ORA C POP B ;IN B FOR EXTERNAL USE RET ; XDDR: MOV A,L ;X COORDINATE IN [HL] ANI 0FCH ORA H RRC RRC RET ; SETBIT: MOV A,L ;FIND OUT WHICH BIT RLC RLC ;IN THE NIBBLE RLC ANI 18H MOV B,A LDA PIXBIT ANI 0E7H ORA B XRI 18H RET ; ; ; ;PLOT POINT SPECIFIED BY GRX,GRY ; PPLOT: LDA GRFBIT+1 STA PIXBIT CALL LINDSP ;INVERT Y OUT SDSPY LHLD GRX CALL SETBIT ;GET X STA GRFBIT+1 CALL XDDR ;SET X ADDRESS MOV B,A MVI C,DDSPY INP A GRFBIT: SET 0,A ;MODIFIED BIT SET OUTP A RET ; ; CMPH: STA GRMODE MOV A,L CMA MOV L,A MOV A,H CMA MOV H,A INX H RET ; ; SWPX: LHLD GRX ;EXCHANGE GRX & GRX1 LDED GRX1 SHLD GRX1 SDED GRX RET ; SWPY: LHLD GRY ;EXCHANGE GRY & GRY1 LBCD GRY1 SHLD GRY1 SBCD GRY RET ; DRWBLK: LHLD GRX PUSH H SHLD GRX1 CALL VPLOT LHLD GRX12 PUSH H SHLD GRX1 CALL VPLOT POP H SHLD GRX SHLD GRX1 CALL PPLOT LDA GRY12 STA GRY CALL VPLOT POP H SHLD GRX ; ;PLOT VECTOR FROM X1,Y1 TO X,Y ; ;CALCULATE DELTA X VPLOT: CALL SWPX PUSH H XRA A ;CLEAR CARRY & A STA GRMODE ;INITIALIZE DELTA SIGNS DSBC D JRNC VPLOT1 INR A ;HANDLE -X CALL CMPH ;COMPLEMENT H VPLOT1: XCHG ;LEAVE DELTA X IN D ; CALCULATE DELTA Y CALL SWPY PUSH H XRA A ;CLEAR CARRY LDA GRMODE S DSBC B JRNC VPLOT2 SET 1,A ;HANDLE -Y CALL CMPH ; HL = DELTA Y ; COMPARE DELTA X AND DELTA Y VPLOT2: PUSH H XRA A ;CLEAR CARRY LDA GRMODE DSBC D POP H JRC VPLOT3 XCHG ;SET UP FOR DELTA Y >= DELTA X VPLOT3: MOV B,D ;SET UP FOR DELTA X > DELTA Y MOV C,E SDED GDELL SHLD GDELS LXI H,GRX LXI D,GRY JRC VPLOT4 XCHG BIT 0,A ;SWAP BITS 1 & 0 RAR RES 1,A JRZ VPLOT4 SET 1,A VPLOT4: SHLD GLL SHLD GLS XCHG SHLD GSL SHLD GSS BIT 1,A PUSH PSW MVI A,13H ;INX H JRZ VPLOT5 MVI A,1BH ;DCX H VPLOT5: STA GSI ;SET LONG DIMENSION INCREMENT POP PSW BIT 0,A MVI A,23H JRZ VPLOT6 MVI A,2BH SVPLOT6: STA GLI ; PLOT ACTUAL VECTOR MOV H,B ;GRK=GDELL/2 MOV L,C SRLR H RARR L SHLD GRK VPLOT7: MOV A,B ORA C JRZ VPLOT9 PUSH B GLL1: LHLD GRX ;MODIFIABLE CODE GLI: INX H ;MODIFIABLE CODE SHLD GRX ;MODIFIABLE CODE LHLD GRK LDED GDELS ORA A DSBC D JRNC VPLOT8 LDED GDELL DAD D LDED GRY ;MODIFIABLE CODE INX D ;MODIFIABLE CODE SDED GRY ;MODIFIABLE CODE VPLOT8: SHLD GRK CALL PPLOT POP B DCX B JMPR VPLOT7 VPLOT9: POP H ;RESTORE GRX & GRY SHLD GRY POP H SHLD GRX RET ; GLL = GLL1+1 GLS = GLL+4 GSL = GLL+25 GSI = GLL+27 GSS = GLL+30 ; ;CLEAR GRAPHIC MEMORY ; GRFCLR: MVI B,LINES MVI D,0 GRFCL1: PUSH B ;--LOOP LINES LINES MVI B,5 GRFCL2: PUSH B ;----LOOP 5 SCAN PAIRS MOV A,D OUT SDSPY LXI B,79*256+DDSPY XRA A GRFCL3: OUTP A ;------LOOP 80 CHAR POS. DJNZ GRFCL3 ;------END LOOP OUTP A MOV A,D ADI 20H MOV D,A POP B DJNZ GRFCL2 ;----END LOOP MOV A,D INR A ANI 1FH MOV D,A POP B DJNZ GRFCL1 ;--END LOOP RET ; .LIST .IFE LSTVLE,[ .XLIST ] .PAGE S; ;|------------------------------| ;| VALET | ;|------------------------------| ; VALCHK: LHLD TEMSTK SHLD VALPNT POP PSW POP B POP D POP H LXI SP,VALSTK PUSH H PUSH D PUSH B PUSH PSW LXI H,NUMFLG MOV A,M MVI M,0 STA NUMSAV LXI H,WSFLAG MOV A,M MVI M,0 STA WSSAVE LXI H,VALENT PUSH H RETI ; CLNVAL: DI XRA A ; 00H TELLS OUTBLK TO READ CALL OUTBLK LXI H,VALCLN LDA LSAVE BIT 1,A JRNZ CLNVL1 INX H INX H CLNVL1: CALL VALMSG XRA A STA VALSTP STA VALTIM STA SETFLG STA NOKEY CMA STA TIMFLG LDA NUMSAV STA NUMFLG LDA WSSAVE STA WSFLAG ; RSTALM: LXI H,600 RSTAL1: XRA A RSTAL2: STA ALMCNT SHLD ALMFLG RET ; VALEXT: CALL CLNVAL DI LXI SP,VALSTK-8 POP PSW POP B POP D POP H LSPD VALPNT EI RET ; VALENT: MVI A,0FFH STA SETFLG EI CALL OUTBLK ;0FFH TELLS OUTBLK TO SAVE LDA LSTATE STA LSAVE LXI H,VALPAR CALL VALMSG VALRTN: MVI A,0FFH STA VALTIM LXI H,2037H CALL POSCUR LXI B,5020H VLLOOP: CALL DISPLY DJNZ VLLOOP CALL BRTDSP ;DISPLAY CURRENT CALL VOLDSP ;PARAMETERS CALL KEYDSP CALL COMUP CALL PNTUP CALL BELDSP VLVEX1: EI ;POSITION CURSOR LDA VALCMD CPI '!' ; IF VALCMD IS ! JRZ VLV2 ; THEN GOTO OVERLAY CALL CONIN ; ELSE GET KEY ORA A ; IF = CTRL/ESC JRZ VLV0 ; THEN EXIT SET-UP MODE CPI 9 ; ELSE IF = ASCII TAB JRZ VLV2 ; THEN GOTO OVERLAY CPI 3AH ; ELSE IF > ASCII 9 JRNC VLV1 ; THEN ..V1 CPI 29H ; ELSE IF > ASCII 0 JRNC VLV3 ; THEN ..V3 VLV0: JMP VALEXT ; ELSE EXIT SET-UP MODE VLV1: ANI 0DFH ; CHANGE TO UPPER CASE CPI 'A' ; IF < ASCII 'A' JRC VLV0 ; THEN EXIT SET UP MODE CPI 'Z'+1 ; ELSE IF > ASCII 'Z' JRNC VLV0 ; THEN EXIT SET-UP MODE STA VALCMD ; ELSE STORE CHARACTER VLV2: JMP GETVAL ; GOTO OVERLAY VLV3: SUI 30H ; SET ASCII NUMERIC TO 0 OFFSET LXI H,VLVEX1 PUSH H ; JRNZ VLBRIT ;0 - BELL TOGGLE LDA CURBEL ;COMPLEMENT CURBEL CMA CALL WRTBEL ;SAVE IN CMOS RAM JMP BELDSP ;DISPLAY CURRENT STATE ; VLBRIT: DCR A ;1 - BRIGHT UP LXI H,BRTLEV JRNZ VLBTDN MOV A,M ;CHECK CURRENT BRIGHTNESS CPI 1FH ;FOR MAX RZ ;IF MAX-GET KEY INR A ;ELSE INCREASE BRIGHTNESS JMPR VLDOBT VLBTDN: DCR A ;2 - BRIGHT DOWN JRNZ VLVLUP MOV A,M ;CHECK CURRENT BRIGHTNESS ORA A ;FOR MINIMUM RZ ;IF MIN-GET KEY DCR A ;ELSE DECREASE BRIGHTNESS VLDOBT: PUSH PSW CALL WRTBRT POP PSW PUSH PSW CALL BRTADJ ;ADJUST BRIGHTNESS TO NEW VALUE POP PSW JMP BRTDSP VLVLUP: DCR A LXI H,VOLEVL JRNZ VLVLDN MOV A,M ;READ CURRENT VOLUME CPI 0FH ;MAX? RZ ;YES-GET KEY INR A ;ELSE INCREASE JMPR VLDOVL ;AND ADJUST VLVLDN: DCR A ;4 - VOLUME DOWN JRNZ VLCLKS MOV A,M ;READ CURRENT VOLUME ORA A ;MIN? RZ ;YES-GET KEY DCR A ;ELSE DECREASE VLDOVL: PUSH PSW CALL WRTVOL POP PSW PUSH PSW CALL VOLADJ ;ADJUST VOLUME TO NEW VALUE LXI H,MIDA CALL SOUND ;OUTPUT SOUND POP PSW JMP VOLDSP ;AND DISPLAY NEW VALUE VLCLKS: DCR A ;5 - CHANGE CLICK JRNZ VLCOM LDA TONTYP ;READ CURRENT CLICK LHLD CLIKAD ;POINT TO CLICK TABLE LXI B,15 ;POINT TO NEXT CLICK DAD B INR A CPI 5 ;IF PAST END OF TABLE JRNZ VLCLK1 ;RESET POINTER LXI H,NOTONE;TO START OF TABLE XRA A VLCLK1: PUSH PSW PUSH H CALL WRTTON ;WRITE CURRENT CLICK TO POP H ;CMOS RAM SHLD CLIKAD CALL SOUND ;OUTPUT A CLICK POP PSW JMP KEYDSP+3;DISPLAY NEW VALUE VLCOM: DCR A JRNZ VLCMDN CALL REDCOM CPI 10 RZ INR A JMPR VLDOCM VLCMDN: DCR A JRNZ VLPTUP CALL REDCOM ORA A RZ DCR A VLDOCM: CALL WRTCOM CALL COMUP JMP ADJCOM ; VLPTUP: DCR A JRNZ VLPTDN CALL REDPNT CPI 10 RZ INR A JMPR VLDOPT VLPTDN: CALL REDPNT ORA A RZ DCR A VLDOPT: CALL WRTPNT CALL PNTUP JMP ADJPNT ; .PAGE ; DSPTM1: LXI H,2037H CALL POSCUR LXI H,NOTSET CALL VALMSG JMP DSPTMX ; DSPTIM: PUSH H PUSH D PUSH B LHLD CHRADR ; SAVE CURSOR POSITION LXI D,2020H DAD D PUSH H ; CALL READTM ; READ TIME EI CPI '?' ; IF READ ERROR JRZ DSPTM1 ; THEN DISPLAY ERROR ; LXI H,2037H ; POSITION CURSOR CALL POSCUR ; LXI H,HRS10 ; DISPLAY HOURS MOV A,M CPI '0' ; SUPPRESS LEADING 0 JRNZ ..J0 MVI A,SPC ..J0: MOV C,A CALL DISPLY DCX H MOV C,M CALL DISPLY ; MVI E,2 ; DISPLAY MINS. & SECS. ..L0: LXI B,3*256+':' ..L1: CALL DISPLY DCX H MOV C,M DJNZ ..L1 INX H DCR E JRNZ ..L0 ; CALL READAT ; READ DATE EI CPI '?' ; IF ERROR JRZ DSPTM1 ; THEN ERROR MESSAGE ; MVI C,SPC CALL DISPLY LXI H,MINS10; ELSE DISPLAY DATE MOV A,M ANI 0F3H ; ?????????? CPI '0' ; SUPPRESS LEADING 0 JRNZ ..J1 MVI A,SPC ..J1: MOV C,A ; DISPLAY DAY CALL DISPLY DCX H MOV C,M CALL DISPLY ; LXI B,3*256+'/' ..L3: CALL DISPLY DCX H MOV C,M DJNZ ..L3 ; DSPTMX: POP H CALL POSCUR ;CURSOR TO LOWER RIGHT CORNER MVI A,0FFH STA TIMFLG ;SET FLAGS FOR SRV60 & CONIN STA VALTIM POP B POP D POP H RET ; .PAGE ; ADJPNT: CALL REDPNT MVI E,BAUDP JMPR BAUDGN ; ADJCOM: CALL REDCOM MVI E,BAUDC ; BAUDGN: RLC ;OUTPUT TWO BYTES MOV C,A ;FROM BAUD MVI B,0 ;TABLE LXI H,BTABL DAD B ;CONTROL WORD AND TIME CONSTANT WORD DI MOV C,E MOV A,M ;MASK OUT INT. ENAB. BIT ANI 70H ORI 7 OUTP A INX H OUTI RET ; BRTADJ: ANI 1FH ;SHIFT LEVEL INTO RLC ; CORRECT POSITION RLC ; FOR LATCH RLC MOV D,A ; SAVE NEW LEVEL XRA A MVI A,7 CALL LLATCH ; CLEAR PRESENT LEVEL ORA A MOV A,D JMP LLATCH ; OR IN NEW LEVEL ; GTBRIT: MVI B,0AH ;GET MSB AND LSB CALL RD5101 ;OF BRIGHTNESS LEVEL PUSH PSW ;FROM CMOS RAM MVI B,0BH CALL RD5101 POP B JMP PACK ;PACK INTO ONE BYTE ; VOLADJ: LXI H,NOTONE+4 MVI B,5 ;CHANGE VOLUME BY CHANGING VOL1: PUSH B ;3 BYTES IN EACH MVI B,3 ;OF 5 SOUNDS VOL2: MOV M,A INX H DJNZ VOL2 LXI D,000CH DAD D POP B DJNZ VOL1 RET ; OUTBLK: MVI B,2 LXI H,22 LXI D,DSPBFL ORA A JRZ ..L1 ; ..L0: PUSH B PUSH H MVI C,0C0H CALL OTLIN POP H PUSH H MVI C,0E0H CALL OTLIN POP H POP B INR L DJNZ ..L0 RET ; ..L1: PUSH B PUSH H MVI C,0C0H CALL INLIN POP H PUSH H MVI C,0E0H CALL INLIN POP H POP B INR L DJNZ ..L1 RET ; OTLIN: CALL CMPOFF MOV A,L ORA C OUT SDSPY LXI B,79*256+DDSPY XCHG INIR INI XCHG RET ; INLIN: CALL CMPOFF MOV A,L ORA C OUT SDSPY LXI B,80*256+DDSPY XCHG OUTIR XCHG RET ; VALMSG: JMP MESSG ; BELDSP: LDA CURBEL ;SET HL TO CURSOR POSITION ANI 1 LXI H,6937H ;DE POINTS TO BELL TABLE LXI D,BELTBL JMPR BAUD1 ; KEYDSP: LDA TONTYP LXI H,4637H ;DE POINTS TO CLICK TABBBLE LXI D,KNMTBL JMPR BAUD1 ; COMUP: CALL REDCOM ; GET COMM. BAUD RATE LXI H,5137H ;DE POINTS TO BAUD TABLE JMPR BAUD0 ; PNTUP: CALL REDPNT ; GET PRINTER BAUD RATE LXI H,6037H ;DE POINTS TO BAUD TABLE BAUD0: LXE D,BNMTBL BAUD1: ORA A PUSH PSW CALL POSCUR ;POSITION CURSOR POP PSW JRZ BAUD2 MOV B,A ;ADD INDEX TO TABLE POINTER RLC RLC ADD B BAUD2: MOV C,A MVI B,0 XCHG DAD B JMP VALMSG ;DISPLAY CURRENT PARAMETER ; POSCUR: SET 7,H ;POSITION CURSOR TO SHLD POSITN LXI H,GOPOS JMP VALMSG ; VOLDSP: LXI H,3F37H ;DISPLAY CURRENT VOLUME CALL POSCUR LDA VOLEVL JMPR BTDSP1 ; BRTDSP: LXI H,3437H ;POSITION CURSOR CALL POSCUR LDA BRTLEV BTDSP1: INR A ;CONVERT NUMBER IN A MVI C,'0' BTDSP2: SUI 10 ;TO ASCII JM BTDSP3 INR C ;MOST SIGNIFICANT DIGIT IN C JMPR BTDSP2 BTDSP3: ADI '9'+1 ;LEAST SIGNIFICANT DIGIT IN A MOV B,A MOV A,C ;IN MSD IS 0 CPI '0' ;THEN SUPPRESS IT JRNZ BTDSP4 MVI C,SPC BTDSP4: CALL DISPLY ;DISPLAY MOV C,B JMP DISPLY ; .LIST .IFE LSTVLD,[ .XLIST ] .PAGE ; ;|-------------------------| ;| VALET DISK I/O | ;|-------------------------| ; ; ************ I M P O R T A N T ****************** ; * * ; * THIS MODULE IS COMPANY CONFIDENTIAL AND IS * ; * NOT TO BE SUPPLIED TO ANYONE OUTSIDE THE * ; * COMPANY REGARDLESS OF ANY CIRCUMSTANCES. * ; ************************************************* ; ; ; THESE ROUTINES SAVE THE HOST BUFFER, AND FIND THE VALET.VL2 ; FILE. ; VALSTR = 2000H ;VALET ENTRY POINT ; GETVAL: DI XRA A STA VALTIM CMA STA TIMFLG STA NOKEY EI LXI D,20AH ;SAVE HOST BUFFER CALL WRTSEC CALL SCHDIR ;FIND AU'S FOR VALET.VL2 MVI B,0 ;SAVE TPA MVI A,2 CALL RWVAL JNZ BWTERR ; MVI B,3 ; START AT A.U. 3 MOV A,B ; READ CALL RWVAL JNZ BRDERR LXI H,SAVAUS ;ALLOCATION UNIT TABLE LDA EXM JMP VALSTR ;VALET ENTRY POINT ; COMPAR: LXI D,HSTBUF MVI C,HSTSIZ/32 ;# OF POSSIBLE FCB'S CL3: LXI H,VALMOD ;COMPARE WITH VALET.VL2 FCB CL2: MVI B,12 ; CL1: LDAX D ANI 7FH RES 7,M CMP M JRNZ INCBUF ;NO MATCH HERE INX H INX D DJNZ CL1 LXI H,4 DAD D ;HL=AU'S FOR VALET.VL2 LDA EXM ;IF 48 TPI ORA A MVI A,0 RNZ ;WE ARE DONE LDA SNDAU ;IF 96 TPI ORA A MVI A,0 ;RETURN IF SECOND FCB RNZ ; PUSH B CALL GOTVLY ;SAVE THE FIRST POP B ;16 AU'S ;AND SEARCH FOR MORE ; INCBUF: LXI H,32 ;MOVE TO NEXT FCB PUSH B MVI A,12 SUB B MOV C,A MVI B,0 ;SUBTRACT THE CHARACTERS DSBC B ;THAT MATCHED DAD D ;AND ADD 32 XCHG ;GET RESULT IN DE POP B DCR C ;FCB COUNTER MVI A,1 ;FLAG FOR NO MATCH RZ ;END OF HSTBUF JMPR CL3 ; ; PUTVAL: MVI B,0 ;RESTORE TPA MVI A,3 CALL RWVAL JRNZ BRDERR ; PTVAL1: LXI D,20AH ;RESTORE HOST BUFFER CALL REDSEC JMP VALEXT ; ; SEARCH DIRECTORY FOR VALET.VL2 FILE ; SCHDIR: XRA A STA SNDAU LXI D,301H ;TRACK 3 - SECTOR 1 RWLOP: LXI B,100H ;1 SECTOR - DRIVE 0 RWLP1: MVI A,3 ;READ LXI H,SECCNT MVI M,1 ;1 SECTOR LXI H,HSTBUF ;READ INTO HOST BUFFER CALL RWONE ORA A JNZ BWTERR ;READ ERROR PUSH D ;SAVE SECTOR & TRACK # CALL COMPAR POP D ORA A JRZ GOTVLY ;FOUND IT INR E MOV A,E ;8 SECTORS MAX. CPI 9 ;FOR DIRECTORY JRNZ RWLOP JMPR BWTERR ;VALET NOT FOUND ; GOTVLY: PUSH D ;SAVE TRACK & SECTOR & LXI D,SAVAUS+16 LDA SNDAU ORA A JRNZ LL1 LXI D,SAVAUS LL1: LXI B,16 LDIR MVI A,1 STA SNDAU POP D RET ; BRDERR: CALL VLERRR LXI H,OPTV1 CALL MESSG CALL CONIN CALL CLNVAL JMP WBOOT ; BWTERR: CALL VLERRR LXI H,OPTV2 CALL MESSG CALL CONIN JMPR PTVAL1 ; VLERRR: MVI A,'A' STA DRVNUM LXI H,VALLER JMP MESSG ; WRTSEC: MVI A,2 JMPR SECTIN REDSEC: MVI A,3 SECTIN: PUSH PSW MVI A,10 STA RECNT MVI A,1 STA SECCNT POP PSW LXI B,100H LXI H,HSTBUF JMP RWONE ; ; B=START A.U. # ; A=R/W COMMAND 2=WRITE 3=READ ; RWVAL: LXI H,VALSTR ; START AT VALET .LOC STA VALOP ; STORE R/W COMMAND MVI A,3 STA VALCNT ; DO 3 A.U.'S ; RWVAL1: PUSH B PUSH H CALL GTRKSC ; GET STARTING TRACK & SECTOR OF A.U. POP H PUSH H MVI A,4 STA SECCNT ; READ 4 SECTORS (1 A.U.) MVI A,10 STA RECNT LXI B,100H ; 1 SECTOR AT A TME, DRIVE 0 LDA VALOP ; GET RWCMD CALL RWONE ; DO DISK OP POP H POP B ORA A ; IF ERROR RNZ ; THEN RETURN INR B ; ELSE INC A.U. XCHG LXI H,VALCNT DCR M ; IF ALL A.U.S READ RZ ; THEN RETURN XCHG ; ELSE CALC. NEW DMA ADDR. LXI D,800H DAD D JMPR RWVAL1 ; GTRKSC: LXI H,SAVAUS ;ALLOCATION UNITS FOR MOV A,B ;VALET.VL2 FILE ORA A LDA EXM JRZ GTRKS2 ORA A JRNZ GTRKS1 SLAR B GTRKS1: INX H DJNZ GTRKS1 GTRKS2: MOV C,M INX H MOV B,M ORA A JRZ GTRKS3 MVI B,0 GTRKS3: MOV H,B MOV L,C DAD H ; MLPY BY 4 DAD H MOV B,H ; SAVE MOV C,L LXI D,10 XRA A GTRKS4: INR A ANA A DSBC D JP GTRKS4 DAD D ADI 2 INR L MOV D,A MOV E,L RET ; .LIST .IFE LSTVLM,[ .XLIST ] .PAGE ; ;|----------------------------------------------| ;| CLOCK AND BACKUP RAM I/O ROUTINES | ;|----------------------------------------------| ; WRTBRT: STA BRTLEV PUSH PSW RLC RLC RLC RLC MVI B,0AH CALL WR5101 POP PSW MVI B,0BH JMPR WR5101 ; WRTBEL: STA CURBEL MVI B,5 JMPR WR5101 ; WRTVOL: STA VOLEVL MVI B,6 JMPR WR5101 ; WRTTON: STA TONTYP MVI B,9 JMPR WR5101 ; WRTPNT: MVI B,7 JMPR WR5101 ; WRTCOM: MVI B,8 JMPR WR5101 ; WRTSLK: STA SHLOCK MVI B,0EH ; WR5101: CALL SU5101 XRA A CALL RWPORT MOV A,D OUT DPIOA MVI C,DPIOB MOV A,E ORI 0B0H JMP WCOMON ; W58174: CALL PACK MOV D,A XRA A CALL RWPORT MOV A,D OUT DPIOA MVI C,DPIOB MVI A,0A8H JMPR WCOMON ; REDCOM: MVI B,8 JMPR RD5101 ; REDPNT: MVI B,7 ; RD5101: CALL SU5101 MVI A,0FH CALL RWPORT MOV A,D OUT DPIOA MVI C,DPIOB MOV A,E ORI 0B4H JMPR RCOMON ; R58174: CALL PACK MOV D,A MVI A,0FH CALL RWPORT MOV A,D OUT DPIOA MVI C,DPIOB MVI A,0ACH ; RCOMON: OUTP A ANI 0DFH OUTP A IN DPIOA MOV B,A JMPR DSLC ; RWPORT: MVI C,SPIOA MVI B,0CFH DI OUTP B OUTP A RET ; WCOMON: OUTP A ANI 0DFH OUTP A DSLC: MVI A,0A0H OUTP A MOV A,B ANI 0FH RET ; SU5101: CALL PACK MOV D,A MOV A,C ANI 30H RRC RRC RRC RRC MOV E,A RET ; PACK: MOV C,B ANI 0FH MOV D,A MOV A,B ANI 0FH RLC RLC RLC RLC ORA D RET ; .LIST .IFE LST60H,[ .XLIST ] .PAGE ; ;|--------------------------------------| ;| | ;| 60 HZ INTERRUPT ROUTINE | ;| | ;|--------------------------------------| ; SRV60: SSPD TEMSTK LXI SP,INTSTK PUSH H ;SAVE REGISTERS PUSH D PUSH B PUSH PSW ;|------------------------------| ;| CHECK KEYCLICK SHUTDOWN | ;|------------------------------| LXI H,TONPER MOV A,M ORA A JRZ SRV60A DCR M JRNZ SRV60A INX H CALL SOUND ;|------------------------------| ;| HANDLE KEYBOARD | ;|------------------------------| SRV60A: IN DPIOB ;CHECK FOR KEY BIT 6,A JZ CHKALM ; NO KEY PRESENT LDA TONTYP ;IF KEYCLICK OFF ORA A ;DO NOT CHANGE SOUND JRZ NOSND LHLD CLIKAD ;SOUND THE KEY CALL SOUND NOSND: MVI B,9 SRV60B: IN DPIOB ;BIT INTO CARRY RLC RLC CMC RARR L MVI A,7FH ;CLOCK DOWN OUT DPIOB MVI A,0FFH ;CLOCK UP OUT DPIOB DJNZ SRV60B ; ;|------------------------------| ;| TRANSLATE KEYCODE | ;|------------------------------| ; MVI H,0 MOV C,L LXI D,KEYTBL DAD D MOV B,M ; ;|------------------------------| ;| EVALUATE KEYCODE | ;|------------------------------| ; LDA WSFLAG ORA A JRZ CHKCTL ; NOT IN WORDSTAR ; ; CHANGE NORMAL CODES TO WS CODES ; MOV A,C CPI 50H ; 1EH -> 0A8H (CTRL/SHFT/^) JRNZ WSCOD0 ; (HIDE) MVI B,0A8H WSCOD0: CPI 7EH ; 1FH -> 0CH (CTRL/SHFT/_) JRNZ WSCOD1 ; (FIND/REPLACE AGAIN) MVI B,0CH WSCOD1: CPI 8CH ; 08H -> 13H (LEFT ARROW) JRNZ WSCOD2 ; (CURSOR LEFT) MVI B,13H WSCOD2: CPI 8DH ; 0CH -> 04H (RIGHT ARROW) JRNZ WSCOD3 ; (CURSOR RIGHT) MVI B,4 WSCOD3: CPI 8EH ; 0BH -> 05H (UP ARROW) JRNZ WSCOD4 ; (CURSOR UP) MVI B,5 WSCOD4: CPI 8FH ; 0AH -> 18H (DOWN ARROW) JRNZ CHKCTL ; (CURSOR DOWN) MVI B,18H ; ; CONTROL CODE ? ; CHKCTL: BIT 7,B JRNZ CHKSPL ; CONTROL CODE ; ; KEYPAD MODE ? ; LDA NUMFLG ORA A JRZ CHKCAP ; NOT 10 KEY PAD ; ;|------------------------------| ;| 10 KEY PAD TRANSLATION | ;|------------------------------| ; MOV A,C SUI 9BH JM CHKCAP CPI ESC JRNC CHKCAP LXI H,PADTBL MOV E,A MVI D,0 DAD D MOV A,M JMPR NOCAP ; ; NOT A CONTROL CHARACTER ; CHKCAP: LDA SHLOCK ;CAPITALIZE IF NEEDED ORA A MOV A,B JRZ NOCAP ; ;|------------------------------| ;| CAPITALIZE IF SHIFT LOCKED | ;|------------------------------| ; CPI 61H ;AFTER SMALL-A? JRC NOCAP CPI 7BH ;BEFORE SMALL-Z? JP NOCAP ANI 0DFH ;CAPITALIZE NOCAP: JMP GOADDK ;ADD TO BUFFER ; ;|------------------------------| ;| HANDLE CONTROL CODES | ;|------------------------------| ; ; HANDLE KEYPAD KEY ; CHKSPL: MOV A,B CPI 0FDH JRNZ CKSPL3 LDA NUMFLG ORA A JRZ CKSPL2 CKSPL1: CMA STA NUMFLG JMPR CKSPL4 CKSPL2: XRA A STA SHLOCK JMPR CKSPL1 ; ; HANDLE CAPS LOCK KEY ; CKSPL3: CPI 0FEH JRNZ CKVLKY XRA A STA NUMFLG LDA SHLOCK CMA STA SHLOCK CKSPL4: MVI B,0EH CALL WR5101 JMP CHKALM ; ; HANDLE SET-UP KEY ; CKVLKY: CPI 0FFH JRNZ ALMDLY CKVLK1: LDA NOKEY ORA A ; IF IN VALET OVERLAY JNZ CHKMTR ; THEN IGNORE CTRL/ESC LDA VALSTP ; ELSE MOV B,A ; IF NOT IN W OR C BOOT OR DISK OPERATION LDA DSKFLG ; OR DISPLAY DRIVER ORA B MOV B,A LDA DSPFLG ORA B MOV B,A LDA DSPCYC ORA B JRZ DOVLKY ; MVI A,0FFH ; ELSE SET VALET PENDING FLAG TO WAIT STA VALPND ; FOR OK TIME TO ENTER OR EXIT VALET JMP CHKMTR ; DOVLKY: XRA A STA VALPND LDA SETFLG CMA ORA A JZ GOADDK CALL RSTALM JMP VALCHK ; ; ALARM DELAY (5 MINUTES) ; ALMDLY: CPI 0FCH JRNZ CHKBRK MVI A,0FFH STA ALMWAT LXI H,BELLTN CALL SOUND JMPR CHKALM ; ; ALL OTHER CONTROL CHARACTERS ; CHKBRK: CPI 0FBH JRNZ CKWSFL MVI A,5 OUT SCOMM LDA SIORG5 ORI 10H OUT SCOMM MVI A,32 STA BRKCNT JMPR CHKALM ; CKWSFL: MOV B,A LDA WSFLAG ORA A ; IF NOT IN WS MOV A,B JRZ GOADDK ; THEN DON'T DO XLATION ; ; WORDSTAR SPECIAL TRANSLATION ; STA CTLCOD ; ELSE XLATE TO WS SEQUENCE ANI 60H ; WHICH PREFIX? JRNZ WSCOD7 MVI A,CTRLQ ;CTRL-Q WSCOD6: CALL WSCODB JMPR CHKALM ; WSCOD7: CPI 20H JRNZ WSCOD8 MVI A,CTRLK ;CTRL-K CALL WSCODB CPI CTRLS JRNZ CHKALM MVI A,CTRLQP ;CTRL-KSQP JMPR CKWSFL ; WSCOD8: CPI 40H JRNZ CHKALM LDA CTLCOD ;CTRL-J, O, OR P CPI CTRLJH JRNZ WSCOD9 MVI A,CTRLJ ;CTRL-JH JMPR WSCOD6 ; WSCOD9: CPI CTRLPS JRNZ WSCODA MVI A,CTRLP ;CTRL-PS JMPR WSCOD6 ; WSCODA: MVI A,CTRLO ;CTRL-O CALL WSCODB JMPR CHKALM ; WSCODB: CALL ADDKEY LDA CTLCOD S ANI 1FH JMP ADDKEY ; GOADDK: CALL ADDKEY ; ;|------------------------------| ;| CHECK ALARMS | ;|------------------------------| ; CHKALM: LHLD ALMFLG DCX H SHLD ALMFLG MOV A,H ORA L JRNZ VALP ; LDA ALMCNT ; SEE IF ALMCNT SHOULD BE RESET BIT 6,A CZ RSTALM ; MVE B,0FE > CMOO RAI MONTH CALL RD5101 CPI 0FH JRZ VALP PUSH PSW CALL READAT CPI '?' POP B JRZ VALP LXI H,MINS10 MOV A,M ; 10'S OF MONTH ANI 0FH DCX H MOV A,M ;UNITS OF MONTH JRZ CKALM1 ADI 0AH CKALM1: ANI 0FH CMP B JRZ CKALM2 JNC ALARM JMPR VALP CKALM2: DCX H LXI B,1012H ; CMOS RAM DAY10 CALL CHKMOS JC ALARM JRNZ VALP CALL READTM LXI B,1216H ; CMOS RAM HRS. & MINS. LXI H,HRS10 CALL CHKMOS JRZ ALARM JRC ALARM ; ;|------------------------------| ;| VALET PENDING ? | ;|------------------------------| ; VALP: LDA VALPND ORA A JNZ CKVLK1 ; ; DISPLAY TIME AND DATE ? ; LDA VALTIM ORA A JRZ CHKMTR XRA A STA TIMFLG STA VALTIM ; ;|------------------------------| ;| FLOPPY MOTOR SHUT-DOWN | ;|------------------------------| ; CHKMTR: LHLD MTRCNT ;GET MOTOR TIMER MOV A,H ;TEST FOR ZERO ORA L JRNZ CKMTR1 ;IF <>0 ,THEN DECREMENT MVI A,-2 ; (Z BIT ALREADY SET) CALL LLATCH ; ELSE SHUT OFF MOTORS INX H CKMTR1: DCX H SHLD MTRCNT ; ;|------------------------------| ;| HANDLE DISK TIME OUT | ;|------------------------------| ; LDA DSKCNT ORA A JRZ BREAK ; DSKCNT ALREADY = 0 DCR A STA DSKCNT JRNZ BREAK ; DSKCNT <> 0 LDA DSKCYC CPI 8 ; IF NOT WAITING FOR READY JRNZ TIMOUT ; THEN ERROR ; CALL SNSTAT ; ELSE SENSE DRIVE STATUS BIT 5,A ; IF DRIVE NOT OK JZ WFRBAD ; THEN WAITING FOR READY ERROR LXI H,RCLTBL; ELSE START 1ST RECAL MVI A,4 ; NEW DSKCYC = 4 CALL DORCSK JMPR BREAK ; ; TIMOUT: CALL CLRFDC ; -ALL OTHER TIMEOUT ERRORS LDA DSKCYC ; CLEAR OUT FDC ORI 0C0H ; DSKCYC OR WITH 0C0H STA DSKCYC ; BREAK: LDA BRKCNT ORA A JRZ IEND DCR A STA BRKCNT JRNZ IEND MVI A,5 OUT SCOMM LDA SIORG5 OUT SCOMM ; ;|----------------------------------------------| ;| EXIT SRV60 (ALSO USED BY SRVFPY) | ;|----------------------------------------------| ; IEND: POP PSW POP B POP D POP H LSPD TEMSTK EI RETI ; .PAGE ; ;|--------------------------------------| ;| | ;| MISC. SRV60 SUBROUTINES | ;| | ;|--------------------------------------| ; ;|---------------------| ;| SOUND VALET ALARM | ;|---------------------| ; ALARM: LDA ALMCNT ORI 40H CPI 40H JRNZ ALJ3 LXI H,ALMWAT MVI M,0 ; ALJ0: INR A LXI H,120 ; ALJ1: CALL RSTAL2 MVI A,'!' STA VALCMD ALJ2: LXI H,ALMSND CALL SOUND JMP VALP ; ALJ3: CPI 42H JRC ALJ0 ; LDA ALMWAT ORA A JRNZ ALJ4 MVI B,17H CALL RD5101 ANI 2 JRZ ALJ4 MVI A,0FFH STA VALPND LDA NOKEY ORA A JRZ ALJ2 ; ALJ4: LXI H,14400 MOV A,L ; L=40H JMPR ALJ1 ; ;|----------------------------------------| ;| COMPARE CMOS RAM TIME WITH REAL TIME | ;|----------------------------------------| ; CHKMOS: PUSH B CALL RD5101 POP B ORI 30H CMP M DCX H RNZ INR B MOV A,B CMP C JRNZ CHKMOS RET ; ;|--------------------------------------| ;| ADD KEY TO END OF KEYBOARD BUFFER | ;|--------------------------------------| ; ADDKEY: MOV B,A LDA KEYCNT S CPI KBUFLN ;IF BUFFER FULL LXI H,BELLTN JZ SOUND ; SOUND BELL, BUFFER FULL INR A ; ELSE ADD KEY STA KEYCNT LHLD KEYPNT MOV A,B MOV M,A INX H SHLD KEYPNT RET ; ;|-----------------------------------| ;| PUSH KEY(S) INTO KEYBOARD BUFER | ;|-----------------------------------| ; PUSHKY: PUSH H PUSH B MVI A,16 SUB C LXI H,KEYBUF PUSH H DI JRZ PSHKY1 ; IF PUSHING 16, THEN PSHKY1 ; MOV C,A ; ELSE MOVE OLD KEYS UP MVI B,0 DAD B ; HL = (KEYBUF+(16-KEYS TO PUSH-1)) DCX H LXI D,KEYBUF+15 LDDR ; MOVE UP KEYS IN BUFFER ; PSHKY1: POP D POP B ; LDA KEYCNT ; UPDATE KEYCNT & KEYPNT LHLD KEYPNT DAD B ADD C CPI 16 JRC PSHKY2 MVI A,16 LXI H,KEYBUF+16 PSHKY2: STA KEYCNT SHLD KEYPNT ; POP H LDIR ; ADD KEYS TO BUFFER EI RET ; .LIST .IFE LSTTBL,[ .XLIST ] .PAGE S; ;|------------------------------| ;| CLOCK READ TABLES | ;|------------------------------| ; ; FORMAT OF TABLES ; ; 1ST BYTE = OPERATION ; 0 = TABLE TERMINATOR ; 1 = READ FROM CLOCK CHIP ; 2 = READ FROM CMOS RAM ; 2ND BYTE = ADDRESS TO READ FROM ; NATTIM: .BYTE 1,07 ; TIME FROM NATIONAL CHIP .BYTE 1,06 .BYTE 1,05 .BYTE 1,04 .BYTE 1,03 .BYTE 1,02 .BYTE 0 ; OKITIM: .BYTE 1,05 ; TIME FROM OKI CHIP .BYTE 1,04 .BYTE 1,03 .BYTE 1,02 .BYTE 1,01 .BYTE 1,00 .BYTE 0 ; NATDAT: .BYTE 2,13 ; DATE FROM NATIONAL CHIP .BYTE 2,12 .BYTE 1,12 .BYTE 1,11 .BYTE 1,09 .BYTE 1,08 .BYTE 1,10 .BYTE 0 ; OKIDAT: .BYTE 1,12 ; DATE FROM OKI CHIP .BYTE 1,11 .BYTE 1,10 .BYTE 1,09 .BYTE 1,08 .BYTE 1,07 .BYTE 1,06 .BYTE 0 ; .PAGE .RADIX 16 ; ;|-------------------------------------| ;| BAUD TABLE | ;|-------------------------------------| ; BTABL: .BYTE 37,0D,57,0AF,57,8F .BYTE 57,80,57,40,57,20 .BYTE 57,10,57,08,57,04 .BYTE 57,02,57,01 BNMTBL: .ASCIS ' 75' .ASCIS ' 110' .ASCIS '134.5' .ASCIS ' 150' .ASCIS ' 300' .ASCIS ' 600' .ASCIS ' 1200' .ASCIS ' 2400' .ASCIS ' 4800' .ASCIS ' 9600' .ASCIS '19200' BELTBL: .ASCIS ' ON ' KNMTBL: .ASCIS ' OFF ' .ASCIS 'CLICK' .ASCIS ' DINK' .ASCIS 'BEEP1' .ASCIS 'BEEP2' ; ;|------------------------------| ;| SOUND TABLES | ;|------------------------------| ; ALMSND: .BYTE 00,03,20,20,1F,00,00,0F8 .BYTE 00,41,87 ; TONPER: .BYTE 0 ; LENGTH OF SOUND IN 1/60ths SEC. ; NOTONE: .BYTE 00,00,00,00,0F,0F,0F,0FF; NULL .BYTE 00,00,00,00,00,00,00 CLICK: .BYTE 01,04,00,00,0F,0F,0F,00 ; CLICK .BYTE 80,47,1D,20,0F6,0AF,0ED BEEP: .BYTE 02,02,00,00,0F,0F,0F,32 ; DINK .BYTE 54,20,32,56,20,3E,25 MIDA: .BYTE 02,00,00,00,0F,0F,0F,0F8; BEEP1 .BYTE 1F,00,0FE,00,00,00,00 AUP3O: .BYTE 02,00,00,00,0F,0F,0F,0F8; BEEP2 .BYTE 1F,02,0FA,00,00,00,00 BELLTN: .BYTE 02,02,00,00,0F,0F,0F,32 ; BELL .BYTE 54,20,32,56,20,3E,25 ; ;|----------------------------------------------| ;| ALTERNATE CHARACTER SET TRANSLATION TABLE | ;|----------------------------------------------| ; CHRTBL: .BYTE 40 ;0 = STANDARD SET .BYTE 00 ;1 = FORMS RULING .BYTE 80 ;2 = GREEK & LANGUAGES .BYTE 0C0 ;3 = MATH & WORD PROCESSING S; ;|-----------------------------------------------| ;| KEYCODE TRANSLATION TABLE (WORDSTAR VERSION) | ;|-----------------------------------------------| ; ; NO CTRL, SHIFT ; KEYTBL: .BYTE 08,09,0A,00,00,0D,00,0FE ; BS TAB LF NA NA CR NA LOCK .BYTE 20,00,00,1B,01,06,1A,17 ; SP NA NA ESC LFT RT UP DN .BYTE 5E,21,40,23,24,25,26,2A ; ^!@#$%&* .BYTE 28,29,22,3A,3C,2B,3E,3F ; ()":<+>? .BYTE 7E,41,42,43,44,45,46,47 ; ~ABCDEFG .BYTE 48,49,4A,4B,4C,4D,4E,4F ; HIJKLMNO .BYTE 50,51,52,53,54,55,56,57 ; PQRSTUVW .BYTE 58,59,5A,7B,7C,7D,5F,07 ; XYZ{|}_DEL ; ; CTRL, SHIFT ; .BYTE 08,09,0A,00,00,0D,00,0FD ; BS TAB LF NA NA CR NA LOCK .BYTE 20,00,00,0FF,93,84,92,83 ; SP NA NA ESC LFT RT UP DN .BYTE 1E,85,0C8,0D3,0B3,0B0,0A2,0AB ;^!@#$%&* .BYTE 0B6,0A3,27,3B,2C,0C,2E,2F; ()":<+>? .BYTE 00,01,02,03,04,05,06,07 ; CTRL-~ABCDEFG .BYTE 08,09,0A,0B,0C,0D,0E,0F ; CTRL-HIJKLMNO S .BYTE 10,11,12,13,14,15,16,17 ; CTRL-PQRSTUVW .BYTE 18,19,1A,1B,1C,1D,1F,19 ; CTRL-XYZ{|}_DEL ; ; NO SHIFT OR CTRL ; .BYTE 08,09,0A,00,00,0D,00,0FE ; BS TAB LF NA NA CR NA LOCK .BYTE 20,00,00,1B,08,0C,0B,0A ; SP NA NA ESC LFT RT UP DN .BYTE 30,31,32,33,34,35,36,37 ; 01234567 .BYTE 38,39,27,3B,2C,3D,2E,2F ; 89';,=./ .BYTE 60,61,62,63,64,65,66,67 ; `abcdefg .BYTE 68,69,6A,6B,6C,6D,6E,6F ; hijklmno .BYTE 70,71,72,73,74,75,76,77 ; pqrstuvw .BYTE 78,79,7A,5B,5C,5D,2D,7F ; xyz[\]-DEL ; ; CTRL, NO SHIFT ; .BYTE 0FC,09,0FB,00,00,0D,00,0FD ; BS TAB LF NA NA CR NA LOCK .BYTE 20,00,00,0FF,01,06,12,03 ; SP NA NA ESC LFT RT UP DN .BYTE 0CE,11,0A,0F,10,0B,16,02 ; 01234567 .BYTE 0D8,0C9,27,3B,2C,81,2E,2F ; 89';,=./ .BYTE 00,01,02,03,04,05,06,07 ; CTRL-`abcdefg .BYTE 08,09,0A,0B,0C,0D,0E,0F ; CTRL-hijklmno .BYTE 10,11,12,13,14,15,16,17 ; CTRL-pqrstuvw .BYTE 18,19,1A,1B,1C,1D,86,14 ; CTRL-xyz[\]-DEL ; ; KEYPAD TABLE ; PADTBL: .BYTE 2A,2C,3D,2E,2F ; *,=./ .BYTE 60,61,62,63,64,65,66,67 ; `abcdefg .BYTE 68,35,31,32,33,30,6E,36 ; h51230n6 .BYTE 2B,71,72,73,74,34 ; +qrst4 ; .RADIX 10 ; .PAGE ; ;|------------------------------| ;| ESCAPE SEQUENCE VECTOR TABLE | ;|------------------------------| ; ESCTBL: .WORD PPOINT ; PLOT POINT .WORD PVCTOR ; PLOT VECTOR .WORD BLKDRW ; BLOCK DRAW .WORD CLRGRF ; CLEAR GRAPHICS MEM. .WORD BLKFIL ; BLOCK FILL .WORD SETMSK ; SET MASK FOR BLOCK FILL .WORD DSBGRF ; DISABLE GRAPHICS .WORD ENBGRF ; ENABLE GRAPHICS .WORD PTBRT ; SET TO PLOT BRIGHT .WORD PTDRK ; SET TO PLOT DARK .WORD REDDAT ; READ DATE FROM CLOCK CHIP .WORD CMOSPN ; SET PRINTER BAUD FROM CMOS RAM .WORD CMOSCM ; SET COMM. BAUD FROM CMOS RAM .WORD DRCTMV ; DIRECT CURSOR MOVEMENT .WORD REDTIM ; READ TIME FROM CLOCK CHIP .WORD REDRAM ; READ CMOS RAM .WORD WRTRAM ; WRITE CMOS RAM .WORD UPCUR ; CURSOR UP .WORD DWNCUR ; CURSOR DOWN .WORD RITCUR ; CURSOR RIGHT .WORD CTROL2+4; CURSOR LEFT .WORD NFGESC ; -- NOT USED -- .WORD NFGESC ; -- NOT USED -- .WORD NFGESC ; -- NOT USED -- .WORD HOMCUR ; CURSOR HOME .WORD REVLF ; REVERSE LINE FEED .WORD CLREND ; CLEAR TO END OF ACTIVE REGION .WORD CLRELN ; CLAR TO END OF LINE .WORD INSLIN ; INSERT LINE .WORD DELLIN ; DELETE LINE .WORD SETTAB ; SET TAB .WORD CLRTAB ; CLEAR TAB .WORD DELLCR ; DELETE CHARACTER .WORD INSCON ; INSERT CHAR. MODE ON .WORD EXIT2 ; INSERT CHAR. MODE OFF .WORD CHRSIZ ; SELECT CHAR. SIZE .WORD CHRSET ; SELECT CHAR. SET .WORD SELATR ; SELECT CHAR. ATTRIBUTE .WORD SELDIN ; SELECT ALT. LEAD-IN .WORD DSPSND ; SOUND GENERATOR .WORD SETACR ; SET ACTIVE REGION .WORD DRCTMV ; DIRECT CURSOR MOVE .WORD RESPAR ; RESET PARAMETERS .WORD SAVVPR ; SAVE PARAMETERS (SYSTEM USE ONLY) .WORD CLSCRN ; CLEAR SCREEN & RESET PARAMETERS .WORD RCLPAR ; RECALL PARAMETERS (SYSTEM USE ONLY) .WORD WRPOFF ; WORD WRAP OFF .WORD WRPON ; WORD WRAP ON .WORD SETWS ; SET WSFLAG (ON) .WORD CLRWS ; RESET WSFLAG (OFF) .WORD DOSND ; SOUND TONE FROM TONE TABLE .WORD OFFCUR ; CURSOR OFF .WORD ONCUR ; CURSOR ON ; .PAGE ; ;|-----------------------| ;| DSPCYC VECTOR TABLE | ;|-----------------------| ; CYCTBL: .WORD LINCHK ; LINE NUMBER FOR DIRECT CURSOR .WORD COLCHK ; COLUMN NUMBER FOR ' ' .WORD EXIT2 ;-- NOT USED -- .WORD TACTCK ; TOP OF ACTIVE REGION .WORD BACTCK ; BOTTOM OF ACTIVE REGION .WORD ATTCHK ; NEW ATTRIBUTE .WORD ALTCHK ; ALTERNATE CHAR. SET .WORD SIZCHK ; NEW SIZE .WORD TABCHK ; NEW TAB .WORD LEDCHK ; SOFT ESCAPE CHAR. .WORD INSCHK ; INSERT MODE ON .WORD GRFCHK ; GET MASK .WORD GRFCK1 ; GET X MSB .WORD GRFCK2 ; GET X LSB .WORD GRFCK3 ; GET Y MSB .WORD GRFCK4 ; GET Y LSB .WORD GRFCK5 ; GET ADDR. FOR CMOS READ .WORD GRFCK6 ; GET ADDR. FOR CMOS WRITE .WORD GRFCK7 ; GET DATA FOR CMOS WRITE .WORD GETSND ; GET SOUND BYTES AFTER 1ST ONE .WORD SETSND ; GET 1ST SOUND BYTE ; S .PAGE ; ;|------------------------------| ;| FLOPPY COMMAND TABLES | ;|------------------------------| ; ;FORMAT... ; COMMAND INFO ; NNNNNNNN ; |||||||| ; ||||BYTES TO 765 ; |||0=NO, 1=YES FOR DMA ; ||0=NO, 1=YES FOR INT ; |0=RD, 1=WR TO DISK ; 0=NO, 1=YES TO READ ST3 ; ADDR TO START DATA XFER (IF NEEDED) ; BYTE COUNT-1 (IF NEEDED) ; COMMAND TO 765 ; UNIT # + 4*HEAD ; CYLINDER ; HEAD ; RECORD ; BYTES/SECTOR ; SECTORS/TRACK ; GAP 2 LENGTH ; DATA LENGTH ; ;-------- FORMAT -------- ; FMTTBL: .BYTE 76H FMADDR: .WORD FILBUF FMCNT: .WORD 40-1 .BYTE 40H+0DH FMUNIT: .BYTE 0 .BYTE 2 .BYTE HSTSPT .BYTE 30 .BYTE 0E5H ; ;-------- RECALIBRATE -------- ; RCLTBL: .BYTE 22H .BYTE 7 RCUNIT: .BYTE 0 ; ;-------- READ OR WRITE -------- ; RWTBL: .BYTE 39H RWADDR: .WORD HSTBUF RWCNT: .WORD HSTSIZ - 1 RWCMD: .BYTE 40H+6H RWUNIT: .BYTE 0 RWCYL: .BYTE 0 RWHD: .BYTE 0 RWREC: .BYTE 1 .BYTE 2 .BYTE HSTSPT .BYTE 15 ;GP2 .BYTE 0FFH ; ;-------- SENSE DRIVE STATUS -------- ; SDSTBL: .BYTE 82H .BYTE 4 SDUNIT: .BYTE 0 ; ;-------- SPECIFY -------- ; SPCTBL: .BYTE 3 .BYTE 3 .BYTE SRT*16+DHUT .BYTE DHLT*2+ND ; ;-------- SEEK & RECALIBRATE -------- ; SKTBL: .BYTE 23H .BYTE 0FH SKUNIT: .BYTE 0 ;UNIT+HD*4 SKCYL: .BYTE 0 ;NCN ; .PAGE ; VALMOD: .BYTE 0 .ASCII 'VALET VL2' ; ; GRAPHICS VARIABLES (INITIALIZED VALUES) ; MASK: .BYTE 0FFH ;THESE MUST MASK2: .BYTE 00H ;STAY IN MMASK: .BYTE 0FFH ;ORDER CURMSK: .BLKB 1 ;TO HERE CLFLG: .BYTE 0FFH CYC: .BYTE 0 ; ; MESSAGES ; GOPOS: .BYTE ESC,'=' ; FOR DIRECT CURSOR MOVE POSITN: .BLKB 2 ; IN VALET ; VALCLN: .BYTE ESC,'7',ESC,']'+80H VALPAR: .BYTE ESC,'6',ESC,'[',ESC,'Z',ESC,'c',ESC,'^' .BYTE ESC,'X',36H,037H,ESC,'U',22H ;CURSOR HOME,REV. VIDEO .ASCII ' TIME DATE BRIGHTNESS VOLUME' .ASCII ' KEY COMMUNICATIONS PRINTER' .ASCIS ' BELL ' NOTSET: .ASCIS ' CLOCK NOT SET' WBINIT: .BYTE ESC,'Z',ESC,'J'+80H WBTRY: .BYTE CR,LF .ASCIS 'RESET OR ANY KEY TO RETRY' OPTMSG: .BYTE CR,LF .ASCIS 'OPTIONS: (R)ETRY,(W)ARM BOOT,(I)GNORE' VALLER: .BYTE 1AH ; HOME & CLEAR ACTIVE .ASCII 'FATAL' DERMSG: .ASCII ' ERROR ON DISK ' DRVNUM: .BLKB 1 .ASCIS ':' VCRLF: .BYTE CR,LF+80H TERR: .ASCIS 'NO DISK' CERR: .ASCIS 'SYSTEM' WERR: .ASCIS ' WRITE' RERR: .ASCIS ' READ' RLERR? .ASCIS ' HOME' SKERR: .ASCIS ' SEEK' ; OPTV1: .BYTE CR,LF .ASCIS 'CR TO WARM BOOT' OPTV2: .BYTE CR,LF .ASCIS 'CR TO ABORT' ; .LIST .IFE LSTVAR,[ .XLIST ] .PAGE S; ;|------------------------------| ;| VARIABLES & BUFFERS | ;|------------------------------| ; ; DISPLAY VARIABLES & BUFFERS ; ; NEXT 4 ITEMS MUST STAY IN ORDER ; DSPBFL: .BLKB 2 DSPBUF: .BLKB 82 ; BUFFER FOR MOVING LINES BUFPNT: .BLKB 2 ; USED BY SCROLL ROUTINES BYTBUF: .BLKB 320-86 ; VALET SCREEN SAVE ; MOVBEG: .BLKB 2 ; USED BY INSDEL CHRPNT: .BLKB 1 ; CHARACTER POINTER GRFCMD: .BLKB 1 ; GRAPHICS COMMAND GDELS: .BLKB 2 ; VECTOR SHORT DELTA GDELL: .BLKB 2 ; VECTOR LONG DELTA GRK: .BLKB 2 ; VECTOR ERROR ACCUMULATOR GRMODE: .BLKB 1 ; VECTOR DIRECTION POINTERS GRX: .BLKB 2 ; X COORDINATE GRX1: .BLKB 2 ; VECTOR X START POINT GRY: .BLKB 2 ; Y COORDINATE GRY1: .BLKB 2 ; VECTOR Y START POINT ; NEXT 47 BYTES MUST STAY AS A BLOCK W/DSPCYC FIRST DSPCYC: .BLKB 1 ; DISPLAY CYCLE COUNTER ; 0 = NORMAL CHAR ; 1 = ESC PENDING ; 2 = LINE # PNDG. DIR. CUR. ; 3 = CHAR # PNDG. ' ' ; 4 = SCROLL FILL PENDING ; 5 = LINE # PENDING; TOP ACT. ; 6 = ' ' ' BOT. ACT. ; 7 = ATTRIBUTE PENDING ; 8 = CHAR. SET PENDING ; 9 = CHAR. SIZE PENDING ; A = NEW TABS PENDING ; B = ALT. LEAD IN PENDING ; C = INSERT CHAR. PENDING ; D = BRIGHTNESS CHAR. PENDING KEYCNT: .BLKB 1 ; # OF KEYS IN BUFFER SETFLG: .BLKB 1 ; SETUP MODE FLAG .BLKB 1 ; ---------- NOT CURRENTLY USED ---------- BRKCNT: .BLKB 1 ; COUNTER FOR BREAK DURATION ; ; NEXT 21 BYTES MUST REMAIN IN THIS ORDER ; CURCHR: .BLKB 1 ; CURRENT CHARACTER SET CURATT: .BLKB 1 ; CURRENT ATTRIBUTE CODE WRPFLG: .BLKB 1 ; WRAP 0=ON, 0FFH=OFF CURCTL: .BLKB 1 ; CURSOR 0=ON, 0FFH=OFF TOPACT: .BLKB 1 ; TOP OF ACTIVE REGION BOTACT: .BLKB 1 ; BOTTOM OF ACTIVE REGION MAGACT: .BLKB 1 ; LINES IN ACTIVE REGION-1 LEADIN: .BLKB 1 ; SOFT ESCAPE CHARACTER CHRADR: .BLKB 2 ; CHARACTER ADDRESS ; H=CHAR POSITION (0=LEFT) ; L=LINE# (0=TOP, 23=BOTTOM) LASTAB: .BLKB 1 ; LAST TAB POSITION TABS: .BLKB 10 ; TAB KEY TEMPAR: .BLKB 21 ; SAVE PARAMETERS HERE TEMLIN: .BLKB 1 ; TEMPORARY STORAGE FOR LINE# ; ; KEYBOARD VARIABLES ; CTLCOD: .BLKB 1 ; CONTROL KEY CODE KEYBUF: .BLKB KBUFLN ; KEYBOARD BUFFER KEYPNT? .BLKB 2 ; POINTEO TI KEYBUF ; ;MISC. VARIABLES ; LSAVE: .BLKB 1 ; SAVE LSTATE IN VALET SECCNT: .BLKB 1 ; SECTOR COUNTER FOR WBOOT SNDADR: .BLKB 2 ; POINTER TO SOUND TABLE SNDCNT? .BLKB ? ; COUNTEO FOO SOUND TABLA INPUT NUMSAV: .BLKB 1 ; SPACE TO SAVE NUMFLG WSSAVE: .BLKB 1 ; SPACE TO SAVE WSFLAG LSTATE: .BLKB 1 ; L0-7 STATE VALPNT: .BLKB 2 ; SAVE SP IN VALET TEMSTK: .BLKB 2 ; SAVE SP IN SRV60 DSPSTK: .BLKB 2 ; SAVE SP IN DISPLY OKIFLG: .BLKB 1 ; 0=NAT., <>0 = OKI TONTYP: .BLKB 1 ; KEYTONE BRTLEV? .BLKB ? ; BRIGHTNESO LEVEL CURBEL: .BLKB 1 ; BELL TOGGLE VOLEVL: .BLKB 1 ; VOLUME LEVEL SHLOCK: .BLKB 1 ; SHIFT LOCK NOKEY: .BLKB 1 ; VALET INHIBIT FLAG SNDTBL: .BLKB 15 ; SOUND TABLE FOR USER TONES VALOP: .BLKB 1 ; R/W COMMAND FOR VALET DISK IO VALCNT: .BLKB 1 ; # OF A.U.'S TO READ IN VALET DISK IO ; ; GRAPHICS VARIABLES ; GRX12: .BLKB 2 GRY12: .BLKB 2 STRX1: .BLKB 1 ; USED IN FILL ROUTINE STRX: .BLKB 1 PIXBIT: .BLKB 1 PIXBT2: .BLKB 1 ; ; FLOPPY VARIABLES ; ; ALL VARIABLES FROM HERE TO THE END MUST REMAIN AS THEY ; ARE NOW. THIER RELATIVE POSITIONS MUST NOT CHANGE. ; MTRCNT: .BLKB 2 ; MOTOR TIMER RESULT: .BLKB 1 ; # OF BYTES TO GET FROM u765 DSKCMD: .BLKB 1 ; DISK COMMAND unacnt: .BLKB 1 ; unalloc rec cnt unadsk: .BLKB 1 ; last unalloc disk unatrk: .BLKB 2 ; last unalloc track unasec: .BLKB 1 ; last unalloc sector hmflgs: .BLKB ndisk ; home been here before flag savech: .BLKB 1 sekdsk: .BLKB 1 ; seek disk number sektrk: .BLKB 2 ; seek track number seksec: .BLKB 1 ; seek sector number hstdsk: .BLKB 1 ; host disk number hsttrk: .BLKB 2 ; host track number hstsec: .BLKB 1 ; host sector number sekhst: .BLKB 1 ; seek shr secshf hstact: .BLKB 1 ; host active flag hstwrt: .BLKB 1 ; host written flag Shsthd: .BLKB 1 ; host hd (side) flag erflag: .BLKB 1 ; error reporting rsflag: .BLKB 1 ; read sector flag readop: .BLKB 1 ; 1 if read operation wrtype: .BLKB 1 ; write operation type DMAADR: .BLKB 2 ; CPM DMA ADDRESS DIRBUF: .BLKB 128 ; SCRATCH DIRECTORY AREA RECNT: .BLKB 1 ; RETRY COUNT ALV0: .BLKB DSKSIZ/8+2 ; ALLOCATION VECTORS CSV0: .BLKB DIRENT/4 ; CHECK VECTORS ALV1: .BLKB DSKSIZ/8+2 CSV1: .BLKB DIRENT/4 ; ; THE NEXT 9 ITEMS MUST STAY IN THIS ORDER ; DSKCYC: .BLKB 1 ; DISK CYCLE st0: .BLKB 1 ; status 0 st1: .BLKB 1 ; status 1 st2: .BLKB 1 ; status 2 cstat: .BLKB 1 ; cyl at status time hstat: .BLKB 1 ; head at status time rstat: .BLKB 1 ; sector at status time nstat: .BLKB 1 ; # of data bytes at status time RESNUM: .BLKB 1 ; NUMBER OF RESULT BYTES ACTUALLY READ ; SAVAUS: .BLKB 32 ; ALLOCATION UNITS FOR VALET.VL2 CURREC: .BLKB 4 ; FOR RANDOM ACCESS ; DSKCNT: .BLKB 1 ; DISKOP TIMEOUT COUNTER OKIBYT: .BLKB 1 ; STORAGE FOR CLOCK SCNDS: .BLKB 1 ; ' SECS10: .BLKB 1 ; ' MINS: .BLKB 1 ; ' MINS10: .BLKB 1 ; ' HRS: .BLKB 1 ; ' HRS10: .BLKB 1 ; ' ; hstbuf: .BLKB hstsiz ; host buffer SNDAU: .BLKB 1 ENDRAM = . ; ; STACK AREA ; .LOC CCP+3B60H ; .BLKB 61 VALSTK: .BLKB 1 .BLKB 36 INTSTK: .BLKB 1 .BLKB 39 DSPTEM: .BLKB 1 .BLKB 20 ENDMRK = . ; .END