IMD 1.17: 29/05/2011 18:19:32 non-disk drivers  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   S6NIT MACPAUSE COMSSLOAD MAC ijSSLOAD RELkSSMPINITMAC lmSSMPINITRELnqu 09h ;ctc channel 1 register ctcch2 equ 0ah ;ctc channel 2 register ctcch3 equ 0bh ;ctc channel 3 register ; fdccsr SQCON REL,SQSERIALMAC-./0123456789:;<SQSERIALMAC=SQSERIALREL >?; name ('S6NIT') ;module id ; include DREQUATE.LIB ;driver symbolic equivalences ; sioadr equ 00h ;sio port a data reS6NIT RELHDWINIT MACHDWINIT RELLSTCTS MAC SSPIO MACopqSSPIO RELrSSRESET MACsSSRESET RELtequ 0ch ;fdc command/status register fdctrk equ 0dh ;fdc track register fdcsec equ 0eh ;fdc sector register fdcdat equ SQPIO MAC@ABSQPIO RELCS6RTC MACDES6RTC RELFgister sioacr equ 01h ;sio port a control register siobdr equ 02h ;sio port b data register siobcr equ 03h ;sio port b LSTCTS REL LSTETX MAC LSTETX RELLSTPAR MAC SSRTC MACuSSRTC RELvSSSIO MACXwxyz{|}~SSSIO REL0fh ;fdc data register ; dmactl equ 10h ;dma control register ; fdcdsr equ 14h ;fdc drive select register tssojr equ S6SIO MACGHIJKLMNOPQRSTUVS6SIO REL WXSSBOOT MAC$YZ[\]SSBOOT REL^control register ; pioadr equ 04h ;pio port a data register piobdr equ 05h ;pio port b data register pioacr equ 06h ;pLSTPAR RELLSTXON MACLSTXON RELMCDSS MACv !"# title TURBODOS OPERATING SYSTEM - SUPER SIX HARDWARE INITIALIZATION subttl copyright 1983, software 2000, inc. .Z80 ; ; cSSSOM MACSSSOM RELUSERID SYSPAUSE MAC15h ;two-sided status/option jumper reg extadr equ 15h ;extended address register ; memcr1 equ 16h ;memory control regiSSCKTDR MAC_`abSSCKTDR RELcSSINT MACdefgSSINT RELhio port a control register piobcr equ 07h ;pio port b control register ; ctcch0 equ 08h ;ctc channel 0 register ctcch1 eMCDSS REL $%S6CON MAC&'(S6CON REL)SQCON MAC*+opyright 1983, software 2000, inc. ; converted to MICROSOFT M80 format by ; Advanced Digital Corp. ; ; version: 07/01/83  ster ##1 memcr2 equ 17h ;memory control register ##2 ; siobrr equ 18h ;sio baud rate generator register ; aseg org 0nitialize circuit driver a call cktinb## ;initialize circuit driver b call cktinc## ;initialize circuit driver c jp cktirrupt page register im 2 ;set interrupt mode 2 ld a,LOW ctcvec ;get ctc interrupt vector out (ctcch0),a ;initialize ctT͓U d5D5dT8M%=YPIOVEC0cC!]9%RP,K%`8%9%P^>w\d@;aaai6! i`arity error latch out (memcr1),a ld a,0efh ;enable parity error detection out (memcr1),a ld a,18h out (sioacr),a ;rSERIAL MULTIPLEX DRIVER SPIAMD ;SERIAL/PARALLEL DRIVERS FOR ADVANCED MICRO DIGITAL RTCAMD ;REAL TIME CLOCK DRIVER FO ;locate in base page ; intpag: ;im2 interrupt page ds 8 ;(reserved for turbodos) ctcvec:: ds 4 ;ctc interrupt nd## ;initialize circuit driver d ; end c interrupt vector call bnknit## ;initialize banked tpa driver call sionit## ;initialize serial i/o call parnit## ;initii^`h4f 3@h d$HڰCKTINAd4D(CKTINCd4DH@CTCVECdE4hDSKeset sio port a out (siobcr),a ;reset sio port b ld a,03h out (ctcch0),a ;reset ctc channel 0 out (ctcch1),a ;reset cR ADVANCED MICRO DIGITAL MNDN80 ;MASTER NETWORK DRIVER FOR NET/80 MNDN82 ;MASTER NETWORK DRIVER FOR NET/82 IVER FOvector siovec:: ds 8 ;sio interrupt vector piovec:: ds 2 ;pio interrupt vector ; common /?init?/ ;locate in init-cNTROLLER ;CONREM ;REMOTE CONSOLE DRIVER (ANY SLAVE) CON96 ;CONSOLE DRIVER FOR 9600 BAUD TERMINAL LSTCTS ;LISTialize parallel i/o call rtcnit## ;initialize real time clock call dskina## ;initialize disk driver a call dskinb## ;inINBdE48ژDSKINDdEtH PARNIT edT88RTCNITe4H`SIOVEC@;aaai6! i`tc channel 1 out (ctcch2),a ;reset ctc channel 2 out (ctcch3),a ;reset ctc channel 3 ld a,07h out (pioacr),a ;reset pode area ; hdwnit:: LD a,0efh ;disable prom/power on jump out (memcr1),a xor a ;disable second memory bank out (me DRIVER FOR A 9600 BAUD PRINTER (CTS HANDSHAKE) ;LSTETX ;LIST DRIVER FOR 1200 BAUD PRINTER (ETX/ACK HANDSHAKE) ;LSTPAR itialize disk driver b call dskinc## ;initialize disk driver c call dskind## ;initialize disk driver d call cktina## ;i ;AMOUNT OF DYNAMIC SPACE BELOW THE O.S. AUTUSR = 080 ;DEFAULT TO PRIVLEGED, USER 0 NMBUFS = 14 ;DEFAULT io port a interrupts out (piobcr),a ;reset pio port b interrupts ld a,HIGH intpag ;get interrupt page ld i,a ;set intemcr2),a ld (iobyte),a ;set i/o byte=0 ld hl,0 ;initialize memory parity ld de,0 ld bc,0 ldir ld a,6fh ;reset p ;LIST DRIVER FOR PARALLEL PORT DSKAMD ;DISK DRIVER FOR ADVANCED MICRO DIGITAL DISK CONTROLLER SERIAL ;STANDARD  NUMBER OF BUFFERS BUFSIZ = 03 ;DEFAULT BUFFER SIZE (LOG2(SIZE/128)) NMBSLV = 10 ;TOTAL NUMBER OF SLAVES SUPPORTEii)10 Ȋii)q *@ ɪ*  Ji*p (ʪjJ Hsver a call cktinb## ;initialize circuit driver b call cktinc## ;initialize circuit driver c call cktind## ;initialize cATE IN PROGRAM AREA ; PUBLIC CTSBR,CTSFF ; LSTDR@:: ; LD A,E ;GET FUNCTION NUMBER CP 2 ;FUNCTION NUMBER=2? JR Z, ; ; common /?init?/ ;put into initialization area ; ; hdwnit:: call mpenit## ;initialize memory parity circuits calD NMBN80 = 08 ;NUMBER OF NET/80 SLAVES SUPPORTED NMBN82 = 08 ;NUMBER OF NET/82 SLAVES SUPPORTED NETAST+08 = 10, DISK CONTROLLER SERIAL ;STANDARD SERIAL MULTIPLEX DRIVER SPIAMD ;SERIAL/PARALLEL DRIVERS FOR ADVANCED MICRO DIGITALircuit driver d call usrprc## ;initialize user process ret ; end LSTOUT ;IF SO, CONTINUE CP 7 ;FUNCTION NUMBER=7? JR Z,LSTWSR ;IF SO, CONTINUE RET ;ELSE, DONE ; LSTWSR: CTSFF El intnit## ;initialize interrupt controller call sernit## ;initialize serial i/o call parnit## ;initialize parallel i/o 11,12,13,14,15,16,17 ;SET UP ASSIGNMENT TABLE FOR ABOVE SLVTBL = " 22222222" ;SET UP SLAVE TYPE TABLE (OSSLAVEx.SY ;RTCNUL ;NULL REAL TIME CLOCK DRIVER RTCAMD ;REAL TIME CLOCK DRIVER FOR ADVANCED MICRO DIGITAL CED MICRO DIGITALQU $+1 LD C,AFF ;FORM FEED CHARACTER TO C-REG ;(FORM FEED CHARACTER) ; LD E,2 ;SET FUNCTION NUMBER=2 ; LSTOUT:  call rtcnit## ;initialize real time clock call dskina## ;initialize disk device a call dskinb## ;initialize disk device  TITLE TurboDOS OPERATING SYSTEM - DATA TERMINAL READY PRINTER DRIVER .Z80 ; NAME ('LSTCTS') ;MODULE ID ; INCLUDE DREQUS) N80PAT = 60,62,64,66,68,6A,6C,6E ;NET/80 PORT ADDRESSES N82PAT = 70,72,74,76,78,7A,7C,7E ;NET/82 PORT ADDRESSES SOSb`%9%PHDWNITA)*h4f 3@h4f ij)1 "ij)qP LD HL,INITC ;GET INITIALIZATION COMPLETE FLAG LD A,(HL) OR A ;INITIALIZATION COMPLETE FLAG SET? JR NZ,..CDRV ;IF SO, Sb call dskinc## ;initialize disk device c call dskind## ;initialize disk device d call cktina## ;initialize circuit driATE.LIB ;DRIVER SYMBOLIC EQUIVALENCES ; DSEG ;LOCATE IN DATA AREA INITC:: DB 0 ;INIT COMPLETE FLAG ; CSEG ;LOC title TurboDOS operating system - hardware initialization .z80 ; ; name ('HDWINI') ;module id ; include DREQUATE.LIB  KIP CONSOLE INITIALIZATION ; DEC (HL) ;SET INITIALIZATION COMPLETE FLAG PUSH DE ;SAVE FUNCTION NUMBER PUSH BC ;SAVE,0,0,0,0,0,0 SEQCNT: DB 0,0,0,0,0,0,0,0 ;SEQUENCE COUNT DB 0,0,0,0,0,0,0,0 INITC:: DB 0 ;INIT COMPLETE FLAG ; CSEG TORE OF 0C9H WAS IGNORED. ; MVI H,0F0H ;ASSUME PAGE ZERO PROM MVI L,INIT-START ;POINT TO PROM INITIALIZATION CODE PCHL ARACTER COUNT OUTSTANDING? JR C,..OUT ;IF NOT, CONTINUE CALL ..GSCA ;ELSE, GET SEQUENCE COUNT ADDRESS LD A,(HL) ;GETALLOW Z80 OP CODES ; START: DI ;DISABLE INTERRUPTS LXI H,04100H ;POINT TO PRESUMED RAM SPHL ;SET UP AS STACK MVI A,0NITIALIZATION ; DEC (HL) ;SET INITIALIZATION COMPLETE FLAG PUSH DE ;SAVE FUNCTION NUMBER PUSH BC ;SAVE CHANNEL NUMB CHANNEL NUMBER/CHARACTER LD E,3 ;GET SET BAUD RATE FUNCTION CTSBR EQU $+1 LD C,06EH ;SET DEFAULT PRINTER BAUD RATE (96;LOCATE IN PROGRAM AREA ; PUBLIC EXTBR ; LSTDR@:: ; LD A,E ;GET FUNCTION NUMBER CP 2 ;FUNCTION NUMBER=2? JR Z,LS TITLE TURBODOS OPERATING SYSTEM - ETX/ACK PRINTER DRIVER .Z80 ; NAME ('LSTETX') ;MODULE ID ; INCLUDE DREQUATE.LIB ;DR SEQUENCE COUNT OR A ;IN ESCAPE SEQUENCE? JR NZ,..OUT ;IF SO, CONTINUE PUSH BC ;ELSE, SAVE OUTPUT CHARACTER LD C,AEC9H ;PUT RETURN AT 010H STA 010H RST 2 ;CALL 010H ; ; IF WE GET CONTROL HERE AGAIN, WE EXECUTED THE ; RETURN AT 010H. ER/CHARACTER LD E,3 ;GET SET BAUD RATE FUNCTION EXTBR EQU $+1 LD C,07H ;SET DEFAULT PRINTER BAUD RATE (1200) CALL SERTD8 QM JCTSFF% R@ pZ{Pd`ժhhtl))GB*24x$!@2b"d)TOUT ;IF SO, CONTINUE CP 7 ;FUNCTION NUMBER=7? JR Z,LSTWSR ;IF SO, CONTINUE RET ;ELSE, DONE ; LSTWSR: LD A,(ETXFFIVER SYMBOLIC EQUIVALENCES ; DSEG ;LOCATE IN DATA AREA ; ETXLEN:: DB 140 ;CHARACTER COUNT BETWEEN ETX'S ETXSEQ:: TX ;GET ETX CHARACTER CALL ..SOUT ;OUTPUT ETX CHARACTER ..WAIT: CALL ..SIN ;ELSE, GET SERIAL INPUT AND 7FH ;STRIP STHE PAGE ADDRESS OF THE PROM ; IS NOW AT 040FFH, DUE TO THE STACK OPERATION. ; DCX H ;POINT TO PROM PAGE MOV H,M ;GET ITIAL## ;AND DO IT POP BC ;RESTORE CHANNEL NUMBER/CHARACTER POP DE ;RESTORE FUNCTION NUMBER ..CDRV: CALL ..GCCA ;GET C$N) ;GET FORM FEED CHARACTER LD C,A ;FORM FEED CHARACTER TO C-REG LD E,2 ;SET FUNCTION NUMBER=2 ; LSTOUT: LD HL,INITC DB 4 ;MAX ESCAPE SEQUENCE LENGTH ETXFF:: DB AFF ;FORM FEED CHARACTER CHRCNT: DB 0,0,0,0,0,0,0,0 ;CHARACTER COUNT DB 0,0IGN BIT SUB AACK ;CHARACTER=ACK? JR NZ,..WAIT ;IF NOT, WAIT CALL ..GCCA ;ELSE, GET CHARACTER COUNT ADDRESS LD (HL), IN H JR GO ;GO TO COMMON ROUTINE NOP ;(FILLER) ; ; IF WE GET CONTROL HERE, THE PROM IS RUNNING AT ; 00000H, AND THE SHARACTER COUNT ADDRESS LD A,(HL) ;GET CHARACTER COUNT LD HL,ETXLEN ;GET CHARACTER COUNT BETWEEN ETX'S CP (HL) ;MAX CHMOVE ;MODULE ID ; ; .LOC .PROG.# ;LOCATE IN PROGRAM AREA ; ORG 0100H ;WE BUILD THE .COM VERSION FIRST ; MACLIB Z80 ;;GET INITIALIZATION COMPLETE FLAG LD A,(HL) OR A ;INITIALIZATION COMPLETE FLAG SET? JR NZ,..CDRV ;IF SO, SKIP CONSOLE I A ;RESET CHARACTER COUNT POP BC ;RESTORE OUTPUT CHARACTER ..OUT: LD A,C ;GET OUTPUT CHARACTER AND 7FH ;STRIP SIGN BjC0p0Z,~6ͯ@帀(ٵY@fP?b;6ݛ[@hͯ@Wђj,>Z`D8 00`, Y1 FORM FEED? JR NZ,..XIT ;NO, SKIP SAFE RETURN ..XIT1: LD C,0 ;FORCE CHAR TO NULL AS FLAG JR ..XIT2 ;AND LEAVE ..XIT: LD ASAVE CHANNEL NUMBER/CHARACTER PUSH DE ;SAVE FUNCTION NUMBER LD E,1 ;SET FUNCTION NUMBER=1 CALL SERIAL## ;GET SERIAL IREA FOR PARALLEL PORT PARMX: DW 1 ;MUTUAL EXCLUSION SEMAPHORE ..MX: DW ..MX DW ..MX ; CSEG ;LOCATE IN PROGRAM AREA ; IT CP AESC ;CHARACTER=ESCAPE? JR NZ,..NESC ;IF NOT, CONTINUE CALL ..GSCA ;ELSE, GET SEQUENCE COUNT ADDRESS LD A,(ETȪ   JQ0 ɊjH 8 o8` xx!`帀5,C ;GET THIS CHARACTER LD (LAST),A ;SAVE IT FOR NEXT TIME ..XIT2: LD HL,PARDAT ;POINT TO DATA AREA JP PARAO## ;CONTINUE NPUT JR ..SIOC ;CONTINUE ..SOUT: PUSH BC ;SAVE CHANNEL NUMBER/CHARACTER PUSH DE ;SAVE FUNCTION NUMBER CALL SERIAL## LSTDR@:: PUSH BC ;SAVE REGISTERS PUSH DE LD HL,PARMX ;MUTUAL EXCLUSION CALL WAIT## POP DE ;RESTORE REGISTERS POP XSEQ) ;GET MAX ESCAPE SEQUENCE LENGTH LD (HL),A ;SET SEQUENCE COUNT ..NESC: CALL ..SOUT ;OUTPUT CHARACTER CALL ..GCCA SG = 0D,0A,0A,"ADV. MICRO DIGITAL running:" SOMSG+1F = 0D,0A,"TurboDOS ver: 1.16 $"  ;DEFAULT TO 04 1K BYTE BUFFERS SOM; END  ;OUTPUT CHARACTER ..SIOC: POP DE ;RESTORE FUNCTION NUMBER POP BC ;RESTORE CHANNEL NUMBER/CHARACTER RET ;DONE ..GCBC LD A,E ;GET FUNCTION CODE CP 2 ;OUTPUT CHARACTER? JR Z,..XIT ;YES, GO DO IT CP 7 ;CONDITIONAL FORM FEED? JR NZ, ;GET CHARACTER COUNT ADDRESS INC (HL) ;INCREMENT CHARACTER COUNT CALL ..GSCA ;GET SEQUENCE COUNT ADDRESS DEC (HL)  TITLE TURBO-DOS OPERATING SYSTEM PARALLEL LIST DRIVER .Z80 ; NAME ('LSTPAR') ;MODULE ID ; INCLUDE DREQUATE.LIB ;O/S SY, RETURN TO CALLER ; LOGMES: .BYTE 0,0DH,0AH,0AH,0 ;LOG ON MESSAGE .ASCII \Booting.....\ .BYTE 0DH,0AH,0AH,0,0,0,0,0 .BYU dUETQaMFETXFFRSUTUD%(1MQIPH5# o8` xx!`帀5..XIT1 ;NO, EXIT SAFELY TEST: LD C,0CH ;YES, MAKE IT A REAL FORM FEED LD A,(LAST) ;GET LAST CHARACTER OUT CP C ;WAS IT A ;DECREMENT SEQUENCE COUNT RET P ;IF POSITIVE, DONE INC (HL) ;ELSE, RESTORE COUNT TO 0 RET ;DONE ..SIN: PUSH BC ;MBOLIC EQUIVALENCES ; DSEG ;LOCATE IN DATA AREA ; LAST: DB 00CH ;LAST CHARACTER SENT OUT ; PARDAT: DS 8 ;DUMMY DATA A TE "$" ; .XSYM .END GMES: .BYTE 0,0DH,0AH,0AH,0 ;LOG ON MESSAGE .ASCII \Booting.....\ .BYTE 0DH,0AH,0AH,0,0,0,0,0 .BY SERIAL## ;AND DO IT POP BC ;RESTORE CHANNEL NUMBER/CHARACTER POP DE ;RESTORE FUNCTION NUMBER ..CDRV: CALL ..SST ;GE,AFF ;GET FORM FEED CHARACTER LD C,A ;FORM FEED CHARACTER TO C-REG LD E,2 ;SET FUNCTION NUMBER=2 ; LSTOUT: LD HL,INI TITLE TurboDOS OPERATING SYSTEM - XON/XOFF PRINTER DRIVER .Z80 ; NAME ('LSTXON') ;MODULE ID ; INCLUDE DREQUATE.LIB ;DT SERIAL STATUS OR A ;CHARACTER AVAILABLE? JR Z,..OUT ;IF NOT, CONTINUE CALL ..SIN ;ELSE, GET SERIAL INPUT AND 7FHTd5DE$ @xԤ\ @,K@Q f  q  `ȀɊjHp )*TC ;GET INITIALIZATION COMPLETE FLAG LD A,(HL) OR A ;INITIALIZATION COMPLETE FLAG SET? JR NZ,..CDRV ;IF SO, SKIP CONSORIVER SYMBOLIC EQUIVALENCES ; DSEG ;LOCATE IN DATA AREA INITC:: DB 0 ;INIT COMPLETE FLAG ; CSEG ;LOCATE IN PR ;STRIP SIGN BIT CP ADC3 ;CHARACTER=DC3 (XOFF)? JR NZ,LSTOUT ;IF NOT, WAIT ..WAIT: CALL ..SIN ;GET SERIAL INPUT ANg p4 pLE INITIALIZATION ; DEC (HL) ;SET INITIALIZATION COMPLETE FLAG PUSH DE ;SAVE FUNCTION NUMBER PUSH BC ;SAVE CHANNEL OGRAM AREA ; PUBLIC XONBR,XONFF ; LSTDR@:: LD A,E ;GET FUNCTION NUMBER CP 2 ;FUNCTION NUMBER=2? JR Z,LSTOUT ;IF D 7FH ;STRIP SIGN BIT CP ADC1 ;CHARACTER=DC1 (XON)? JR NZ,..WAIT ;IF NOT, WAIT ..OUT: JP SERIAL## ;OUTPUT CHARACTER NUMBER/CHARACTER LD E,3 ;GET SET BAUD RATE FUNCTION XONBR EQU $+1 LD C,07H ;SET DEFAULT CONSOLE BAUD RATE (1200) CALLSO, CONTINUE CP 7 ;FUNCTION NUMBER=7? JR Z,LSTWSR ;IF SO, CONTINUE RET ;ELSE, DONE ; LSTWSR: XONFF EQU $+1 LD A ; ..SST: PUSH BC ;SAVE CHANNEL NUMBER/CHARACTER PUSH DE ;SAVE FUNCTION NUMBER LD E,0 ;SET FUNCTION NUMBER=0 CALL SEEQUATE.LIB ;system equates ; false equ 0 ;logical equates true equ not false ; sprsix equ false ;true if using SUPER-6NOT READY, CONTINUE CALL SEEK ;ELSE, SEEK TO REQUESTED TRACK ; LDED CSEC ;SET DE TO FIRST SECTOR NUMBER EXX ;SWAP TO ALT jp p,rcver1 ;leave if not inc DE ;else bump pointer to message header inc DE inc DE inc DE ld A,(DE) ;get lengxͨ@  &<RSU1MQI2TPS#a=9 J:Vӑold equ 1 ;write hold rdhold equ 2 ;read hold overrun equ 4 ;overrun error svcrqt equ 8 ;slave service request resetRIAL## ;GET SERIAL STATUS JR ..SSIC ;CONTINUE ; ..SIN: PUSH BC ;SAVE CHANNEL NUMBER/CHARACTER PUSH DE ;SAVE FUNCTIO with 4MHZ slaves ; ; Signal table flag equates ; shrtmsg equ 7 ;short message sent sysldd equ 6 ;system loaded to slavERNATE REGISTERS MVI B,08CH ;SET INITIAL HEAD LOAD FLAG ;(READ+HEAD LOAD) MVI C,FDWAIT;SET WAIT/SYNC I/O PORT LDED CDMth of message ld (tranlng),A ;and save it push DE ;save pointer to message header rcvl: ld DE,rcvpol ;link slave polNTRQ STAX D ;STORE AT DMA ADDRESS INX D ;INCREMENT DMA ADDRESS INP A ;WAIT FOR DRQ OR INTRQ JM ..L ;GOT DRQ, LOOP TO REA equ 1 ;slave reset bit slvclr equ 8 ;slave clear slvatn equ 2 ;slave atten. int ; cseg ;put into code segment ; N NUMBER LD E,1 ;SET FUNCTION NUMBER=1 CALL SERIAL## ;GET SERIAL STATUS ..SSIC: POP DE ;RESTORE FUNCTION NUMBER POP e systry equ 5 ;tried to load system to slave sndpolf equ 4 ;send poll flag on timeout sndwt equ 3 ;send message waitinA ;SET CURRENT DMA ADDRESS EXX ;SWAP BACK TO REGULAR REGISTERS ; LHLD CXLTBL ;GET CURRENT XLATE TABLE MOV A,H ;TRANSLATIl routine call lnkpol## ld HL,rcvsmph ;and wait for response call wait## call rcvsetup bit slvrdyf,(HL) ;is slave alD NEXT BYTE ..LX: IN DSTAT ;GOT INTRQ, GET 1797 STATUS EXX ;SWAP BACK TO NORMAL REGISTERS ; ANI 9DH ;MASK ERROR BITS RZ cktdr@:: ld A,C ;get operation code or A ; = 0 jr z,rcvmsg ;receive message dec A ; = 1 jp z,sndmsg ;send meBC ;RESTORE CHANNEL NUMBER/CHARACTER RET ;DONE ; END g rcvpolf equ 2 ;poll for receive slvrqst equ 1 ;slave request bit set slvrdyf equ 0 ;slave ready for transfer ; ; Sl title TurboDOS operating system - master circuit driver for super slaves .z80 ; name ('mcdss') ;module id ; include DRready ready pop HL ;get pointer to message back jr nz,rcvm0 ;leave if flag was set call slvtest ;is slave okay jr c ;IF NOT, DONE CALL TRYAGN ;ELSE, TRY AGAIN JMPR ..AGN ;CONTINUE ; SETUP: CALL SELDSK ;SELECT DISK JNZ FATAL ;IF DRIVE ssage ret ;if here bad command so return rcvmsg: ld A,(slvctr) ;get service counter dec A ;counted down to zero yetӠTD8a=9 JXONFF% U pZ{PdCq0jb`;4`Yn( 3j0 ڌ?"1Z6Vave control port bits ; svcrqst equ 3 ;slave service request wrhld equ 0 ;slave write hold status ; ; and masks ; wrh  ,rcver2 ;leave if error push AF ;save slave request bit dec C ;point to slave data port ld A,15h ;send response to not res sndwt,(HL) ;else clear send pending bit ld HL,sndsmph ;and signal send message routine jp signal## sndmsg: ex Dr),A ;update slave service counter ld (rcvdev),A ;and receive device no. rcver2: call chkstrt ;setup timout for future sl snd1: call slvtest ;test if slave is there jp c,slver1 ;skip out if not jr nz,slvreq ;skip out if slave request bit setsys wants to receive cp (HL) ;is it same as slave wants to send jr c,rcver2 ld B,(HL) ;get amount to receive inc HL ;init regs bit rcvpolf,(HL) ;do we have a receive poll request jp nz,sndwait ;leave if so bit systry,(HL) ;have we loadslave out (C),A inc C pop AF ;get request bit back jr nz,rcvm0 ;leave if request is set push HL ;else save pointeE,HL ;put address of message buffer into hl inc HL ;and point to message dest. id inc HL inc HL inc HL inc HL ldave check ld A,(rcvdev) ;get receive device no. jp slver3 ;and go on chkstrt: ld A,(rcvdev) ;get receive device no. dec C ;point to data port ld A,6 ;send a 6 out (C),A set slvrdyf,(HL) ;set slave ready bit res sndpolf,(HL) ;cl ;move buffer pointer up dec B ;dec receive count jr z,rcver2 ;error if no more to receive call rcvblk ;else go get ed an opsys to this slave jr z,snd1 ;if not send any length message bit sysldd,(HL) ;did opsys take jp z,cntsnd ;leaver to message header call chkstrt jr rcvl ;go back to try again rcvm0: ld A,slvclr ;clear slave control register out A,(HL) ;get dest. id dec A ;make it slave no. dec HL ;point to message length inc (HL) ;is message length 0 dec call waitnit ;init wait counter for this slave call sgnlref ;point to flag entry for slave res rcvpolf,(HL) ;clear rear send poll bit ld DE,sndpol ;link send poll routine call lnkpol## ld A,(snddev) ;init service timer call waitnit data block jr nz,rcver2 ;error if transfer didn't work call chkstrt ;setup timout for future slave check ld A,(rcvdev)  if not ex (SP),HL ld A,(HL) ;get length of message to send ex (SP),HL cp 8bh ;is it max length jr z,snd1 ;proce (C),A ld B,1 ;set up to receive 1 byte call rcvblk ;go get it jr nz,rcver2 ;leave if error dec HL ;point back at (HL) jp z,slvlod ;leave if so push HL ;save message pointer push AF ;and slave no. ld HL,sncsmph ;wait for other eceive poll bit res slvrdyf,(HL) ;clear slave ready bit bit sndwt,(HL) ;test if send message pending ret z ;return if ld HL,sndsmph ;and wait until all is ready call wait## call sndsetup res slvrdyf,(HL) ;clear slave ready bit bit sndpo ;get slave no. call failclr ;clear table entry for this slave xor A ;and return with success ret rcver1: ld (slvctss it if so cp 0ch ;is it short message jp nz,cntsnd ;error exit if not set shrtmsg,(HL) ;else set short message flag  what we received ld A,(HL) ;get it or A ;was it 0 jr z,rcver2 ;is so error so leave ld A,(tranlng) ;get length opsends call wait## pop AF ;get slave no. back ld (snddev),A ;and update device we're working with snd0: call sndsetup  lf,(HL) ;test send poll bit jr nz,slver1 ;error out if set ld A,slvclr ;else clear slave out (C),A pop HL ;get poinlvrdyf,(HL) ; slave ready flag res slvrqst,(HL) ; slave requesting service set systry,(HL) ; tried to load opsys res sysend 15h to slave out (C),A sndwait: set sndwt,(HL) ;set send waiting status bit ld HL,sndsmph ;and wait till ok to goer ld HL,ssast ;point to slave system assignment table add HL,DE ld A,(HL) ;get down load suffix ld (ssssl##),A ;andsldd,(HL) ; opsys loaded res systry,(HL) ; tried to load opsys sndgdrtn: ld A,(snddev) ;clear falure count for this slav true push HL ;save pointer to signal table call failpt ;point to failure counter ld A,(HL) ;bump it up inc A poter to message back ld B,(HL) ;get message length dec B ;decrement it push BC ;and save it ld B,1 ;send message sldd,(HL) ; opsys loaded res shrtmsg,(HL) ; short message call failpt ;point to failure table inc (HL) ;and bump cou on call wait## jp snd0 ;now go try again syncsig: ld HL,sncsmph ;signal thru now jp signal## ; cntsnd: pop HL ; save it in system loader ld A,reset ;reset slave out (C),A ld B,0 ;and wait awhile rstwait: djnz rstwait xor A e call failclr xor A ;and return successful ret ; slvlod: ld C,A ;put slave no. into c push BC ;save it for latep HL ;get hl back ret z ;return if failure counter = 255 set sysldd,(HL) ;else set opsys loaded bit res slvrdyf,(HL) length call sndblk pop BC ;get message length back call z,sndblk ;and send message if no errors jr nz,slver2 ;skip onter for this slave slverxit: inc E ;make slave no. = ckt node no. ld A,(ssckt) ;get circuit no. ld D,A ;and put itfix stack call syncsig ;signal this run done call sndsetup ;set up registers jr slverxit ;and go on to exit slver1: ;clear reset out (C),A ld HL,lodbuf ;point to opsys request buffer ld B,0ah call rcvblk ;get slave load request rr call syslod ;try to load slave operating system pop BC ;fix stack ret z ;and exit if no errors ld A,C ;else er ;clear slave ready bit ld A,(ssckt) ;get slave circuit no. ld H,A ;make up slave default network id ld L,0 ld (ssdidut if errors in transfers call syncsig ;signal done ld A,(snddev) ;reset service timer for this slave call waitnit ca into d to return it ld A,0ffh ;set return failure flag ret ;and exit syslod: call rsstp0 ;point to signal table  pop HL ;clear stack slver2: call syncsig ld A,(snddev) slver3: call rsstp0 ;point to signal table and set flags set set nz ;return if there was an error ld A,slvclr ;else clear slave out (C),A ld HL,ssload## ;get address of 1st boot loror out jr slver3 ; slvreq: set slvrqst,(HL) ;set slave request status bit dec C ;point to data port ld A,15h ;and ##),HL ;and save in system loader ld A,E ;now make up slave id inc A ld L,A ld (sssid##),HL ;and save in system loadll sgnlref bit shrtmsg,(HL) ;was it short message jr z,sndgdrtn ;skip if not res shrtmsg,(HL) ;else clear bits res sy ld A,(HL) ;get flags for this slave and 40H ;have we already loaded an opsys to this slave xor 40H ret z ;return if  ader ld B,80h call sndblk ;and send it ret nz ;return if it didn't work ld HL,ssblod## ;send load address and size de linkage ; sndpol: dw 0 dw 0 call sndsetup ;set up registers in A,(C) ;get slave status bit svcrqst,A ;is slave  in A,(C) ;read slave status bit svcrqst,A ;is request bit set jr z,rcvp1 ;skip if not rcvp0: res slvrqst,(HL) ;elsel ready ret nz dec C ;point to data port sndb0: if sprsix nop ;extra wait time for fast master and slow slave noof slaves or A ;make sure we have some out there ret z ;return if not dec A ;else make it no. of last slave and 0fst1 ;skip out if so djnz slvtst0 ;go back if not timed out yet scf ;else set carry flag ret ;and return in failurof 2nd loader ld B,4 call sndblk ret nz ;leave if error ld DE,(ssblen##) ;get length of 2nd loader ld B,E ;put leservice request bit set jr nz,sndp0 ;if so skip next call tmrchk ;else check if time to service anyway ret c ;exit if clear slave request set bit set slvrdyf,(HL) ;set slave ready bit jr rcvp2 ;and skip next rcvp1: call tmrchk ;checkp nop nop endif nop ;provide some extra time outi ;send byte jr nz,sndb0 ;go back if more jr blkerck ;ch ld HL,rcvdev ;point hl to receive device storage inc (HL) ;bump it up cp (HL) ;is past max jr nc,rcvprst ;skip re slvtst1: dec C ;if slave waiting point to data port in A,(C) ;get response inc C ;point back to control port cpngth to send in b ld A,E ;correct for even page length or A jr nz,syssndlp dec D syssndlp: push DE call sndblk  not set sndpolf,(HL) ;else set send poll bit sndp0: ld HL,sndpol ;unlink send poll routine call unlink## ld HL,sndsmph if time for slave check ret c ;leave if timer not timed out rcvp2: set rcvpolf,(HL) ;set receive poll flag ld HL,rcvpolheck for errors ; rcvblk: ld D,wrhold ;set mask to slave write hold call slvrdy ;and wait for slave to be ready to send teset if not ld (HL),0 rcvprst: call rcvsetup ;set up registers and point to signal table bit slvrdyf,(HL) ;is slave al 6 ;is response what we want scf ;set error flag ret nz ;and return if not in A,(C) ;else get control data and ;send first block pop DE ret nz ;exit if error in transfer dec D ;more to send? jp p,syssndlp ;go back if so xor  ;and signal send message handler jp signal## ; slvtest: ld A,slvatn ;set wrd02 bit in slave out (C),A xor A ;and  ;unlink ourselves call unlink## ld HL,rcvsmph ;and signal receive message handler jp signal## ; ;send poll routine noo us ret nz ;leave if slave not ready dec C ;point to data port rcvb0: if sprsix nop ;extra wait time for fast mready ready ret nz ;exit if so bit slvrqst,(HL) ;is slave requesting service already jr nz,rcvp0 ;then skip next test svcrqt ;keep request bit ret ;and return successfully ; sndblk: ld d,rdhold ;read hold mask call slvrdy ;wait untiA ;else return with success ret ; ;receive poll routine node linkage ; rcvpol: dw 0 dw 0 ld A,(nmbslv) ;get number clear it out (C),A ld B,0 ;set time out counter slvtst0: in A,(C) ;is slave in write hold bit wrhld,A jr nz,slvt  aster and slow slave nop nop nop endif nop ;provide some extra time ini ;get data byte from slave jr nz,rc ret ; failclr: ld E,A ;make slave no. 16 bits ld D,0 call failpt ;point to falure table ld (HL),0 ;and clear cp 3CH ;has it been long enough ret ; rcvsetup: ld A,(rcvdev) ;get receive slave no. jr rsstp0 ;and go on to pro message syncronazation semphore ; sncsmph: dw 1 dw sncsmph+2 dw sncsmph+2 ; ;send message semaphore ; sndsmph: in if not timed out xor A ;else set error return flag dec A ret ;and exit ; waitnit: ld E,A ;make device no 16  ' rcvdev: db 0 ;current receive device snddev: db 0 ;current send devece tranlng: ;receive block length db 0 slvb0 ;and go back if more blkerck: inc C ;point back to control port in A,(C) ;get status from slave and overrun  entry for this slave ret ;and return ; failpt: ld HL,flctrtbl ;point to beginning of failure table add HL,DE ;and ncess it sndsetup: ld A,(snddev) ;get send slave no. rsstp0: ld E,A ;make slave no 16 bits ld D,0 ld HL,ssadt ;get badw 0 dw sndsmph+2 dw sndsmph+2 ; ;operating system load request buffer ; lodbuf: db 0,0,0,0,0,0,0,0,0,0 ; common /?inbits ld D,0 ld HL,slvtmrtbl ;get table base add HL,DE ;point into table ld A,(ticcnt##) ;set element to tic count vctr: db 0 ;slave poll counter ; sgnltbl: ;slave device signal table db 0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0 ; slvtmr ;was there any errors in transfer ret z ;leave if not ld A,0ffh ;else set error flag ret ;and exit ; slvrdy: ld ow to entry for this slave ret ; dseg ;put into data area ; nmbslv: nmbss@:: ;number of slaves installed db 2 sse of slave port address table add HL,DE ;point to address of proper slave ld C,(HL) ;get base address for slave inc Cit?/ ;put into initialize area ; cktin@:: ld a,(nmbslv) ;get number of slaves ld (slvctr),a ;and put into service countld (HL),A ret ;and return ; tmrchk: push HL ;save hl ld HL,slvtmrtbl ;point to slave service timer table add HLtbl: ;slave service timer table db 0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0 ; flctrtbl: ;slave failure counter table db E,0 ;load time counter slvrdy0: in A,(C) ;get slave control port and D ;keep only relevant status bit xor D ;comsckt: ssckt@:: ;default slave circuit number db 0 ssadt: ssadt@:: ;slave port address, default is 70h-8eh db 70h,72 ;bump to point to control port sgnlref: ld HL,sgnltbl ;point into nuther table add HL,DE ;proper place for this slaveer ret ;no more init to do end ,DE ;and to proper entry ld A,(ticcnt##) ;get present tick count sub (HL) ;find out how much time has elapsed pop HL 0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0 ; ;receive message semaphore ; rcvsmph: dw 0 dw rcvsmph+2 dw rcvsmph+2 ; ;sendplement sense of bit ret z ;will be zero if ready dec E ;not ready so decrement time out count jr nz,slvrdy0 ;try agah,74h,76h,78h,7ah,7ch,7eh db 80h,82h,84h,86h,88h,8ah,8ch,8eh ssast: ssast@:: ;slave opsys suffix table db '  K / *M e@@G8 @ @ #n `hPh_@ H ;FORCE THE 1797 TO RESET OUT DCOM LXI H,STEPR%;ENSURE STEP RATE IS IN BOUNDS MOV A,M ANI 03H MOV M,A RET ;DONE ;>$"F#@ @ `x̀SUPUT EDIATELY IF 0 OR 1. SUB 6 ;FUNCTION NUMBER=8? JR Z,CONSO ;IF SO, ERROR SHIFT OUT DEC A ;FUNCTION NUMBER=9? JR fp&YPekfZu ^'Y< p4|vYmbfpj0 6ՁmFb0meh[eh`f# 2ۊ~ TITLE TURBODOS OPERATING SYSTEM - SUPER QUAD CONSOLE DRIVER .Z80 ; NAME ('SQCON') ;MODULE ID ; INCLUDE DREQUATE.LIB ;y@/A @pP4@P@,84&!p$? READ%:: DI ;ENSURE INTERRUPTS ARE DISABLED SSPD RETSP ;SAVE STACK POINTER SBCD CTRACK ;STORE CURRENT TRACK NUMBER SDED 2Ġ CKTDR@d4DLNKPOLd%54SIGNALe54EDSSAST@54$TSSBLODe544D̈ SSDID54H̸ SZ,CONSI ;IF SO, ERROR SHIFT IN JP SERIAL## ;ELSE, CONTINUE ; CONOUT: ;CONSOLE OUTPUT CHARACTER ROUTINE LD HL,INITC 8Y - : qpDdž!@]0 WO"3kX|vD ͫL3j[gjjEy]P{$XnD4_  PUBLIC CONBR ; DSEG ;LOCATE IN DATA AREA ; FFCHR:: DB AFF ;FORM FEED CHARACTER INITC:: DB 0 ;INIT COMPLETE FLAG SPd4DE$95 MMSSCKT@Q e545D8?INIT?S%@\)hn(YVP:Ġוm a05B7r4f`&Y iCSEC ;STORE CURRENT SECTOR NUMBER SHLD CDMA ;STORE CURRENT DMA ADDRESS MVI A,RETRYS ;GET NUMBER OF RETRIES STA TRYCNT ;SESSIDπ5554TICCNTeTĔ WAIT`x̀SU ;GET INITIALIZATION COMPLETE FLAG LD A,(HL) OR A ;INITIALIZATION COMPLETE FLAG SET? JR NZ,..CDRV ;IF SO, SKIP CONSOLE C`62Y8@ve@eFml29XR@jY|@fِ&-!L,!@ :8>;O*i vdq A10!3l CLSSTR:: ;CLEAR SCREEN STRING DB 0CH,1AH,1BH,0AAH,80H,80H,80H,80H ; CSEG ;LOCATE IN PROGRAM AREA ; CONDR@:: LD A1 9Y00ZaYn( p#6,:@ xd(3k03lh6ہ2̴3,e9:b1F~ƃVU*rT TRY COUNT ORA A ;MAKE STATUS NON-ZERO ..AGN: CZ RECAL ;FORCE RACALIBRATE ON ERROR CALL SETUP ;DO COMMON SETUP ; EXX ;TE IN PROGRAM AREA ; INIT%:: DI ;ENSURE INTERRUPTS ARE DISABLED XRA A ;CLEAR THE DRIVE SELECT LATCH OUT DCONT MVI A,0D0INITIALIZATION ; DEC (HL) ;SET INITIALIZATION COMPLETE FLAG PUSH DE ;SAVE FUNCTION NUMBER PUSH BC ;SAVE CHANNEL NUMv0,f&4Q`idxQ*^=d6 %!ՕK8_HcF_ 82Nq0e_ ldr0e.#z,E ;GET FUNCTION NO SUB 2 ;FUNCTION NUMBER = 2? JP M,SERIAL## ;NO, GO ON IMEDIATELY IF 0 OR 1. JR Z,CONOUT ;YES, OUTD9pH#,F͵`L €,ʩ.3Le U@Dh <̵0F3h3lh13m@6Ձ2̳0>;O.0jW@mFb0mSWAP TO ALTERNATE REGISTERS MOV A,B ;GET I/O COMMAND RES HLB,B ;CLEAR HEAD LOAD BIT FOR NEXT TIME MVI H,03H ;SET STATUS MA BER/CHARACTER LD E,3 ;GET SET BAUD RATE FUNCTION CONBR EQU $+1 LD C,08EH ;SET DEFAULT CONSOLE BAUD RATE CALL SERIAL##TS JRNZ ..ERR ;IF ERROR, CHECK OTHER DENSITY LHLD CLADDR ;POINT TO CURRENT LATCH ; .IFE DBLSID , [ RES TSL,M ;CLEAR TWOCALL CONSI: CALL DMS## ;POSITION TO NEXT LINE DB ACR,ALF+80H RET ;DONE ; END  JRNZ ..OSD ;JUMP IF ONE-SIDED SET TSD,C ;TWO-SIDED, SET TYPE CODE SET TSL,M ; , SET LATCH CODE ;] ..OSD: BIT DDL,M ;TESNED OR A JP Z,SERIAL## ;LEAVE IF NOT CP C ;OTHERWISE IF OUTGOING CHAR A FF JP NZ,SERIAL## ;LEAVE IF NOT LD HL,CLSS ;TEMPORARY SAVE OF DATA BYTE IN FDWAIT ;WAIT FOR NEXT BYTE ORA A ;INTRQ? JP ..XH ;YES, EXIT TO ERROR PROCESS DJNZ ..LH  ;AND DO IT POP BC ;RESTORE CHANNEL NUMBER/CHARACTER POP DE ;RESTORE FUNCTION NUMBER LD A,(FFCHR) ;GET FORM FEED CHA-SIDED DISK FLAG ; MOV A,M ;GET CURRENT LATCH VALUE SET SSL,A ;SELECT SIDE TWO OUT DCONT ; PUSH B ;SAVE SECTOR LENGTH ;JUMP IF NEITHER BUSY OR DRQ, MUST BE INTRQ MOV C,A ;TEMPORARY SAVE OF DATA BYTE IN FDWAIT ;WAIT FOR NEXT BYTE ORA A ;INTRT FOR DOUBLE DENSITY JRZ ..SDD ;NO, JUMP SET DDD,C ;YES, SET DOUBLE DENSITY TYPE ..SDD: LXI D,DSTBLS ;GET DST TABLE BASE TR ;OTHERWISE GET CLEAR SCREEN STRING ADDRESS ..CDRVL: LD A,(HL) ;GET CHAR TO SEND AND 7FH ;CLEAR PARITY BIT LD C,A ;CONTINUE UNTIL 4TH BYTE IS IN C ..LC: IN DDATA ;INPUT NEXT DATA BYTE IN FDWAIT ;SYNC ORA A ;INTRQ? JP ..XH ;YES JMPR .RACTER OR A ;FORM FEED CHARACTER=0? JP Z,SERIAL## ;IF SO, CONTINUE PUSH DE ;SAVE FUNCTION NUMBER PUSH BC ;SAVE CH MVI A,0C4H ;READ-ADDRESS WITH 15MS HLD DELAY MVI B,4 ;RECLEN IS 4TH BYTE OF HEADER MVI C,03H ;MOVE STATUS MASK TO C OUT Q? JP ..HX ;YES, EXIT TO ERROR PROCESS DJNZ ..HL ;CONTINUE UNTIL 4TH BYTE IS IN C ..CRCL: IN DDATA ;INPUT NEXT DATA BYTE  TITLE TURBODOS OPERATING SYSTEM - SUPER QUAD CONSOLE DRIVER .Z80 ; NAME ('SQCON') ;MODULE ID ; INCLUDE DREQUATE.LIB ; ;GET SET TO SEND IT PUSH BC PUSH DE PUSH HL CALL SERIAL## ;SEND CHAR POP HL POP DE POP BC LD A,(HL) ;TEST I.LC ;CONTINUE ..XH: IN DSTAT ;GET 1797 STATUS POP B ;RESTORE SECTOR SIZE IN C ANI 9DH ;MASK ERROR BITS MOV B,A ;SAVE RESUANNEL NUMBER/CHARACTER LD C,A ;FORM FEED CHARACTER TO C-REG CALL ..CDRV ;OUTPUT FORM FEED POP BC ;RESTORE CHANNEL NUTPӠT4%( !JINITCd4E$ @P|\ AR@K@m`aA4z(%0 ժm`GXnʤ V)=M-*`IN FDWAIT ;SYNC ORA A ;INTRQ? JP ..HX ;YES JMPR ..CRCL ;CONTINUE ..HX: IN DSTAT ;GET 1797 STATUS ANI 9DH ;MASK ERROR BI PUBLIC CONBR ; DSEG ;LOCATE IN DATA AREA ; FFCHR:: DB AFF ;FORM FEED CHARACTER INITC:: DB 0 ;INIT COMPLETE FLAG F LAST CHAR BIT 7,A RET NZ ;RETURN IF TRUE INC HL ;ELSE DO MORE JR ..CDRVL ; CONSO: ;ERROR MESSAGE PRE & POST LTING STATUS ; MOV A,M ;SELECT BACK TO SIDE ZERO OUT DCONT MOV A,B ;GET BACK THE STATUS ORA A ;IS THE DRIVE READY? ; MBER/CHARACTER POP DE ;RESTORE FUNCTION NUMBER JP SERIAL## ;AND EXIT ; ..CDRV: LD A,(FFCHR) ;DO WE HAVE A FF CHAR DEFI*.XTCc=rj?2aLx!))GG*zrt!") FV"jx#!)G@*JrJe4)$N  CLSSTR:: ;CLEAR SCREEN STRING DB 0CH,1AH,1BH,0AAH,80H,80H,80H,80H ; CSEG ;LOCATE IN PROGRAM AREA ; CONDR@:: CONBRSO: ;ERROR MESSAGE PRE & POST CALL CONSI: CALL DMS## ;POSITION TO NEXT LINE DB ACR,ALF+80H RET ;DONE ; END FFCHR) ;DO WE HAVE A FF CHAR DEFINED OR A JP Z,SERIAL## ;LEAVE IF NOT CP C ;OTHERWISE IF OUTGOING CHAR A FF JP NZ,SE title TurboDOS operating system - serial multiplex driver .z80 ; name ('SQSERL') ;module name false equ 0 true equ noZATION COMPLETE FLAG SET? JR NZ,..CDRV ;IF SO, SKIP CONSOLE INITIALIZATION ; DEC (HL) ;SET INITIALIZATION COMPLETE FLAG AT ;SAVE CURRENT STATUS RET ; SELDSK: LDA CDSK ;GET REQ DRIVE CPI 4 ;COMPARE WITH MAX DRIVE NUMBER JNC ..NRDY ;IF INVALI EQU $+1 LD D,08EH ;SET DEFAULT CONSOLE BAUD RATE ; LD A,E ;GET FUNCTION NO SUB 2 ;FUNCTION NUMBER = 2? JP M,SERITPӠT4%( !JINITCd4E$ @PX\ AR@K@XPB: ! 帀&5`*5Xm.`XtuXaS0RIAL## ;LEAVE IF NOT LD HL,CLSSTR ;OTHERWISE GET CLEAR SCREEN STRING ADDRESS ..CDRVL: LD A,(HL) ;GET CHAR TO SEND ANDt false ; modem equ false ;set to true to handle modem channel ; ; the following is the definition of the data structure  LD A,(FFCHR) ;GET FORM FEED CHARACTER OR A ;FORM FEED CHARACTER=0? JP Z,SERIAL## ;IF SO, CONTINUE PUSH DE ;SAVE FUD, RETURN NOT READY MOV B,A ;SAVE DRIVE NUMBER LDA FDCDRV ;GET LAST DRIVE USED CMP B ;ARE THEY THE SAME? JRZ ..TST ;YES,AL## ;NO, GO ON IMEDIATELY IF 0 OR 1. JR Z,CONOUT ;YES, OUTPUT EDIATELY IF 0 OR 1. SUB 6 ;FUNCTION NUMBER=8? JR Z,CONS?9+Uͦ?ac41 iJQ Qhq )*q@ 8 7FH ;CLEAR PARITY BIT LD C,A ;GET SET TO SEND IT PUSH BC PUSH DE PUSH HL CALL SERIAL## ;SEND CHAR POP HL POP; each serial channel has to save buffer pointers ; and channel status in. ; nitflg equ 0 ;bit 7 = initialized flag, bottomNCTION NUMBER PUSH BC ;SAVE CHANNEL NUMBER/CHARACTER LD C,A ;FORM FEED CHARACTER TO C-REG CALL ..CDRV ;OUTPUT FORM F NO NEED TO UNLOAD HEAD. ; CALL GETSTS ;GET CURRENT DRIVE STATUS ANI 0A0H ;READY AND HEAD LOADED? CPI 020H JRNZ ..TST ;O ;IF SO, ERROR SHIFT OUT DEC A ;FUNCTION NUMBER=9? JR Z,CONSI ;IF SO, ERROR SHIFT IN JP SERIAL## ;ELSE, CONTINUE L ; FDPR: IN DSTAT ;GET DRIVE STATUS ANI 1 ;1797 BUSY? JRNZ FDPR ;IF SO, LOOP RET ;DONE, RETURN TO CALLER ; GETSTS: M DE POP BC LD A,(HL) ;TEST IF LAST CHAR BIT 7,A RET NZ ;RETURN IF TRUE INC HL ;ELSE DO MORE JR ..CDRVL ; CON 5 bits ; used as counter for waiting chars. for ; output signaling purposes rcvsmph equ 1 ;receive character sigEED POP BC ;RESTORE CHANNEL NUMBER/CHARACTER POP DE ;RESTORE FUNCTION NUMBER JP SERIAL## ;AND EXIT ; ..CDRV: LD A,(NO, NO NEED TO UNLOAD. IN TRACK ;UNLOAD WITH A SEEK TO PRESENT TRACK OUT DDATA LDA STEPR% ;FORM SEEK COMMAND ORI 010H ; CONOUT: ;CONSOLE OUTPUT CHARACTER ROUTINE LD HL,INITC ;GET INITIALIZATION COMPLETE FLAG LD A,(HL) OR A ;INITIALIVI A,0D0H ;FORCE STATUS UPDATE OUT DCOM XTHL ;WAIT FOR 1797 TO SETTLE XTHL XTHL XTHL IN DSTAT ;GET STATUS STA CST nal semaphore nxtchr equ 7 ;next char received, i.e. would be returned ;on next call to input char sndsmph equ 8 ;seld A,0 ;see if chan is a valid one, 2nd byte is max chan no. sub B ld A,0 ret m ;exit if bad channel no. push IX ;finitions ; initd equ 7 ;channel initialized mdmen equ 6 ;modem enabled flag remch equ 7 ;remote channel def bit ; cs are updated di ;can't be bothered for a while ld A,(IX+inbfchrs+1) ;is there a char avail bit 7,A jr nz,nochr ;exiu 1ah ;address of driver fo channel wtcnt equ 1ch ;wait count flag for output otbfiptr equ 1dh ;output buffer input poinll z,initchn ;initialize it if not done yet ld A,E ;get command into a or A ; = 0 jr z,chravl ;character available nd character signal semaphore bdrte equ 0eh ;baud rate for channel ; bit 7 = attention detection enabled ; bit 6 else save ix and process request call procreq pop IX ret ; procreq: push BC ld L,B ;channel no. into hl for table tst equ 7 ;clear to send line status bit dcdt equ 5 ;data carrier detect status bit rit equ 4 ;ring indicator, used for t if not or (IX+inbfchrs) ;nuther check jr z,nochr ;again exit if no char ld C,(IX+nxtchr) ;this should be next char ater otbfrptr equ 1eh ;output buffer remove pointer otbfchrs equ 1fh ;number of characters in buffer outbuf equ 20h ;beg dec A ; = 1 jr z,getchr ; input a char dec A ; = 2 jp z,sndchr ;send a char dec A ; = 3 jp z,setbaud ;set ch= cts handshaking enabled ; bit 5 = output only ; bits 0-3 = baud rate rltchn equ 0fh ;relative channel within drreference ld H,0 add HL,HL ; * 2 add HL,HL ; * 4 add HL,HL ; * 8 ld B,H ;save * 8 ld C,L add HL,HL ; * 1baud rate indication txmtt equ 0 ;trans. buffer empty status bit ; public combr ; cseg ;force into code segment vail. ei bit atnd,(ix+bdrte) ;was lookahead char valid jr nz,gdxit ;skip next if so ld C,' ' ;else load a blank ' ' ining of 8 byte output buffer ; ; ; following are the baud rate bit flag diffinitions ; atnd equ 7 ;attention detection eannel baud rate dec A ; = 4 jp z,getbaud ;return channel baud rate dec A ; = 5 jp z,setmdm ;set modem controls diver inpbf equ 10h ;address of base of input buffer lngbf equ 12h ;length of input buffer inbfiptr equ 14h ;input buffe6 add HL,HL ; * 32 add HL,BC ;add in * 8, now = * 40 ld BC,(strcbase) ;get base address add HL,BC ;create entry t; comdrv:: combr equ comdrv+1 ;communications channel default baud rate ld D,5 ;preset com channel baud rate serial::  gdxit: or 0ffh ;set valid return flag ret nochr: ei xor A ;no char avail. so clear return flag ret ; getchr: pusnabled ctsd equ 6 ;clear to send handshaking enabled rcvo equ 5 ;receive only channel ; ; ; and other misc. bit flag deec A ; = 6 jp z,setmdm ;return modem status ret ;bad command so return chravl: call polser ;make sure status bitr input pointer inbfrptr equ 16h ;input buffer remove pointer inbfchrs equ 18h ;number of characters in buffer chndrvr eqo data area pop BC push HL ;and put it into ix for easy reference pop IX bit initd,(ix+nitflg) ;initialized yet? ca h IX pop HL inc HL ;point hl to recieve semaphore in case no char avail push HL di ld E,(IX+inbfchrs) ld D,(IX+inbnz,scnw ;if not skip wait inc (IX+nitflg) ;else inc no. chars waiting ei push IX ;and wait for signal pop HL ld Dld A,C ;put char to return in proper place ret ; and return as are now done ; sndchr: push BC ;save char to out put  H,(IX+chndrvr+1) ld A,(IX+rltchn) ;get relative device and 0fh ;save only relevant bits ld D,A ;put device in d ldt end of buffer cp E jr nz,gtcr1 ld A,(IX+lngbf+1) cp D jr nz,gtcr1 ld D,0 ;zero pointer if so ld E,D gtcr1: lder ld E,2 jp setmdm ;else go set control bits ; getbaud: ld A,(IX+bdrte) ;get baud from structure ret ;and retufchrs+1) dec DE ld (IX+inbfchrs),E ld (IX+inbfchrs+1),D bit 7,D jr z,gcnowt ;skip wait if data available ei push E,8 add HL,DE call wait## di scnw: pop BC ;get char to send back ld E,(ix+otbfiptr) ;get pointer to place char at in ld A,(IX+wtcnt) ;get wait flag or A ;do we want to wait jr z,scnd ;skip if not dec A ;else update flag ld (IX+wt A,E ;and command in a jp (HL) ;then go to driver ; serisi:: push IX ;save ix ld C,A ;save received char ld A, (IX+inbfrptr),E ;save pointer back ld (IX+inbfrptr+1),D add HL,DE ;point to next potential char ld A,(HL) ;get it rn with it ; initchn: set initd,(IX+nitflg) ;set initialized bit ld A,E ;is command set baud rate cp 3 ret z ;donBC call wait## ;wait for character to become available pop BC di gcnowt: ld E,(IX+inbfrptr) ;get pointer to data to re buffer ld D,0 push IX add IX,DE ;point ix at next loc ld (IX+outbuf),C ;save char in output buffer pop IX ;restocnt),A pop BC ;and delay for a while pop DE ex (SP),IX push DE push BC ld HL,0 call delay## pop BC pop DE D ;do we have a data area for this channel or E jp z,isidone ;leave if not push DE ;else put structure address into ild (IX+nxtchr),A ;save it in structure pop HL ;get address of receive semaphore back bit 7,(IX+inbfchrs+1) ;any chars lef't go on if so push BC ;else set default baud rate push DE ld C,D ld E,3 call setbaud pop DE pop BC ret ; smove ld D,(IX+inbfrptr+1) ld L,(IX+inpbf) ;get base of buffer ld H,(IX+inpbf+1) push HL add HL,DE ;point to char tore ix ld A,(IX+otbfiptr) ;update buffer input pointer inc A cp 8 jr nz,sdcr1 xor A sdcr1: ld (IX+otbfiptr),A inc (ex (SP),IX push DE push BC scnd: di ld A,(IX+otbfchrs) ;get no. of chars in output buffer cp 8 ;is buffer full jr x pop IX inc DE ;point de to recieve char semaphore if modem bit remch,(IX+0fh) ;is this channel defined as a remott in buff jr z,gcnsg ;skip signal if so push BC call signal## ;signal if no characters in buffer pop BC gcnsg: ei etbaud: ld (IX+bdrte),C ;save baud rate and fall thru to set hardware setmdm: ld L,(IX+chndrvr) ;get address of driver ld return ld C,(HL) ;get char pop HL ;restore pointer to begining of buffer inc DE ;bump pointer ld A,(IX+lngbf) ;aIX+otbfchrs) ;update counter for no. chars in buffer ld A,(IX+otbfchrs) ei cp 1 ret nz ;done if not only char in buff e channel jr z,remskp ;skip next test if not bit mdmen,(IX+00h) ;is remote channel enabled jp z,isidone ;leave if not if so ld E,D isi4: ld (IX+inbfiptr),E ;save input pointer back ld (IX+inbfiptr+1),D ld E,(IX+inbfchrs) ;update no. charjr z,isidone isi2: ld E,(IX+inbfiptr) ;point to next loc in buffer ld D,(IX+inbfiptr+1) ld L,(IX+inpbf) ld H,(IX+inpbf+1 ;go back for more if not jr iso0 ;else go on mdmact: ld A,(actchr) ;send modem activation character call sndmdm jr ;no chars in buffer ld (IX+inbfchrs+1),A ld A,(IX+inbfrptr) ;input and remove pointers equal ld (IX+inbfiptr),A ld a,(i jp z,iso0 ;skip if not res mdmen,(IX+00h) ;else clear channel enabled bit bit atnd,(IX+0eh) ;is atten detection enabledremskp: endif bit rcvo,(IX+bdrte) ;is this a send only channel jp nz,isidone ;leave if so bit atnd,(IX+bdrte) ;is s in buffer ld D,(IX+inbfchrs+1) inc DE ld (IX+inbfchrs),E ld (IX+inbfchrs+1),D isidone: pop IX ;restore ix ret ) add HL,DE ld (HL),C ;save received char ld A,(IX+inbfrptr) ;is input pointer = remove pointer cp E jr nz,isi3 lisost mdmiact: ld A,(inachr) ;send modem inactivation character call sndmdm jr iso0 sndmdm: push HL ;save registex+inbfrptr+1) ld (ix+inbfiptr+1),A isi0: ex DE,HL ;put pointer to receive semaphore into hl bit 7,(IX+inbfchrs+1) ;anythi jr z,iso0 ;skip if not ld A,(atnchr) ;get attn char cp 0ffh ;is it = 0ffh jr z,mdmiact ;skip out if so call sndattn detection enabled jr z,isi0 ;leave if not res 7,C ;else clear high bit of char call slvres## ;and check for slav ;and return ; seriso:: ld A,D ;data structure for this device or E ret z ;exit if not push IX ;save ix push d A,(IX+inbfrptr+1) cp D jr nz,isi3 ld (IX+nxtchr),C ;if so save char as next char alse isi3: inc DE ;update pointer rs push BC push IX ;put structure pointer into de pop DE call serisi ;send char pop BC ;restore regs pop HL ng in buffer already jr z,isi1 ;don't signal if so push BC call signal## pop BC isi1: ld A,(IX+lngbf) ;is input poinmdm ;else send atten to system ld HL,lgofstr ;get address of logoff string to send lgoflp: ld A,(HL) ;get char to send e reset char ld A,(atnchr##) ;get attn char sub C ;is this one jr nz,isi0 ;leave if not bit 7,(IX+inbfchrs+1) ;anytDE ;put structure address into ix pop IX if modem bit remch,(IX+0fh) ;is this a remote channel jp z,isost ;skip i ld A,E ;is pointer at edn of buffer cp (IX+lngbf) jr nz,isi4 ld A,D cp (IX+lngbf+1) jr nz,isi4 ld D,0 ;zero it ret ; and return gddcd: bit memen,(IX+00h) ;is channel enabled jr nz,isost ;if so go send char set mdmen,(IX+00h) ;ter at end of buffer cp (IX+inbfiptr) jr nz,isi2 ;not from this ld A,(IX+lngbf+1) ;high bytes = cp (IX+inbfiptr+1)  call sndmdm ;send it ld A,(HL) ;get char back inc HL ;update pointer rlca ;was char last to send jr nc,lgoflp hing already in buffer jr nz,isi0 ;no special processing if not xor A ;else clear buffer pointers ld (IX+inbfchrs),A f not bit dcdt,B ;do we have data carrier detect jr nz,gddcd ;skip if so bit mdmen,(IX+00h) ;else is channel enabled  else enable channel bit rit,B ;what is baud rate that were running at ld A,(modmhi) ;get high speed flag jr z,spdskp ;nt hl to send semaphore pop HL ld DE,8 add HL,de call signal## ;and signal more buffer space avail isodone: pop IX pop IX ;restore ix ld A,(IX+otbfrptr) ;update remove pointer inc A cp 8 jr nz,iso1 xor A iso1: ld (IX+otbfrptr),A db 2 dw serdrc## db 3 dw serdrc## db 0 dw serdrd## db 1 dw serdrd## db 2 dw serdrd## db 3 dw serdrd## ssost: endif bit txmtt,B ;is transmitter buffer emty jr z,isodone ;leave if other interrupt bit ctsd,(IX+bdrte) ;iactivation character endif ; ; common /?init?/ ;put into initialization segment serchn:: dw 2 ;number of seriaskip if high speed ld A,(modmlo) ;else get low speed flag spdskp: push BC ;save char to send ld C,a ;put baud rate in  ;restore ix ret ;and return done ; ; srlpoll: dw 0 ;this is serial poll routine and link info dw 0 polser: call ;and save it back if modem bit remch,(IX+0fh) ;is this a remote channel jr z,iso10 ;skip if not bit mdmen,(IX+00h)ernit:: ld hl,(serchn) ;get no. of serial channels supported push hl ld a,l dec a ld (serial+1),a ;save max channel s cts handshaking enabled jr z,iso0 ;skip if not bit ctst,B ;is cts line enabled jr z,isodone ;leave if not iso0: ldl channels supported serbsz:: ;default input buffer sizes for all channels dw 40h,10h,8,8,8,8,8,8,8,8,8,8,8,8,8,8 sc ld E,3 ;and load e with set baud func no. call setbaud ;go set baud rate pop BC ;get char back bit atnd,(IX+0eh) serpra## call serprb## call serprc## call serprd## ret ; ; dseg ;put into data segment strcbase: dw 0 ;a ;if remote is it enabled jr z,iso11 ;if not don't send char iso10: endif out (C),B iso11: ld A,(IX+nitflg) ;any no. for valid call check add hl,hl ;find out how much memory to reserve add hl,hl add hl,hl ld d,h ld e,l add hl,h A,(IX+otbfchrs) ;any chars in output buffer or A jr z,isodone ;leave if not dec (IX+otbfchrs) ;else decrement char couerast:: ;default serial assignment table db 0 dw serdra## db 1 dw serdra## db 2 dw serdra## db 3 dw serdra##  ;is attn detection enabled jr z,isost ;if not go handle char ld A,(atnchr) ;else get attn char cp 0ffh ;is it = 0ffddress of base of data structures for serial i/o channels if modem modmhi: db 0c7h ;1200 baud init modmlo: db 0c5h ;30chars waiting to be signaled and 3fh jr z,isodone ;leave if not dec (IX+nitflg) ;decrement signal count push IX ;poil add hl,hl add hl,de ;hl now = 40 * serchn call alloc## ;reserve memory ld (strcbase),hl ;save base address of chant ld E,(IX+otbfrptr) ;and point to char to send ld D,0 push IX add IX,DE ld B,(IX+outbuf) ;get next char to send  db 0 dw serdrb## db 1 dw serdrb## db 2 dw serdrb## db 3 dw serdrb## db 0 dw serdrc## db 1 dw serdrc## h jr z,mdmact ;if so go send modem active charater call sndmdm ;else send attn char ld A,3 ;and a ^c call sndmdm i0 baud init lgofstr: db 3,'logoff',8dh ;logoff string actchr: db 2 ;modem activation character inachr: db 3 ;modem in nnel data structures pop bc ;get no. serial channels back push ix ;save ix ld ix,serast ;point to serial assignment tsave it in the structure inc ix inc hl ld (hl),64h ;set next byte to 100d, used as wait counter inc hl ld (hl),b ; fer size pointer back pop bc ;get serial no. serial chn. back ex (sp),ix ;restore ix push de ;save buffer size pointLC TRANSLATION TABLE ADDRESS MOV E,M ;GET TRANSLATION TABLE ADDRESS INX H MOV D,M SDED CXLTBL ; LBCD SECCNT ;SET BC T buffer size ld c,a inc de ld a,(de) ;into bc ld b,a inc de push de ;save buffer size pointer push hl ;save  serina## ;do hardware init. for each driver call serinb## call serinc## call serind## ; ld de,srlpoll ;finally link able ld de,serbsz ; and serial buffer size table push de strclp: ld (hl),b ;clear initialized flag inc hl call smand clear rest of structure inc hl ;these are used as output buffer input pointer ld (hl),b ; output buffer remove pointer ld (hl),b ;clear next 3 words inc hl ;these are used as input buffer input pointer ld (hl),b ; input buffer removO SECTOR COUNT LDED CSEC ;SET DE TO FIRST SECTOR NUMBER ; ..FMT: EXX ;SWAP TO ALTERNATE REGISTERS MVI B,08CH ;SET INITIALpointer into struct. we are init'ing ld l,c ;set up to reserve buffer ld h,b push hl call alloc## ;get buffer space in serial poll routine jp lnkpol## ; smphnit: ;subroutine to init a semaphore ld (hl),b ;initialize semaphore inc hphnit ;initialize semaphore ld (hl),b ;clear next char. inc hl call smphnit ;initialize semaphore ld (hl),20h ;iner inc hl ; no. of chars in buffer ld (hl),b ; and 8 char. output buffer inc hl ld (hl),b inc hl ld (hl),b ince pointer inc hl ; and no. of chars in buffer ld (hl),b inc hl ld (hl),b inc hl ld (hl),b inc hl ld (hl),b i HEAD LOAD FLAG ;(READ+HEAD LOAD) MVI C,FDWAIT;SET WAIT/SYNC I/O PORT LDED CDMA ;SET CURRENT DMA ADDRESS EXX ;SWAP BA pop bc ;get buffer size back ex de,hl ;save buffer pointer pop hl ;get pointer to struct. back ld (hl),e ;save pl ;first word is semaphore count ld (hl),b inc hl ld d,h ld e,l ld (hl),e ;2nd & 3rd words are links to other semait. channel to output only inc hl ld a,(ix+00h) ;get relative channel no. inc ix ld (hl),a ;and save it inc hl po hl ld (hl),b inc hl ld (hl),b inc hl ld (hl),b inc hl ld (hl),b inc hl ld (hl),b inc hl ld (hl),b inc hnc hl ld a,(ix+00h) ld (hl),a inc ix inc hl ld a,(ix+00h) ;get address of driver for this device ld (hl),a ; and CK TO REGULAR REGISTERS ; RET ;DONE ; RWCOM1: LHLD CXLTBL ;GET CURRENT XLATE TABLE MOV A,H ;TRANSLATION REQUIRED? ORA ointer to buffer inc hl ld (hl),d inc hl ld (hl),c ;save buffer size inc hl ld (hl),b inc hl pop de ;get bufphores inc hl ld (hl),d inc hl ld (hl),e inc hl ld (hl),d inc hl ret ; end p de ;get pointer to buffer size back ex (sp),ix ;get old ix back push bc ;save no. serial channels ld a,(de) ;getl dec c ;decrement no. to do jr nz,strclp ;go back if haven't init'd all channels pop de ;clear stack pop ix call L MOV A,E ;GET UNTRANSLATED SECTOR IN A-REG JRZ ..NX ;NO TRANSLATION, CONTINUE DAD D ;ELSE, TRANSLATE MOV A,M ..NX: INRF NEITHER BUSY OR DRQ, MUST BE INTRQ MOV C,A ;TEMPORARY SAVE OF DATA BYTE IN FDWAIT ;WAIT FOR NEXT BYTE ORA A ;INTRQ? JPF7 6m덊'DpUi09Ypg!FpX-T#83#8ۧݺ#OtF#gFpgFpgFpD Fu ;BEGIN XMIT. CHAR BIT ; ; DSEG ;LOCATE IN DATA AREA ; P0FLAG:: DB 0 ;PARALLEL 0 OUTPUT READY FLAG P0OCHR:: DB 0 [UӸu4Ot~2[RPxͦ- %q7M6?rK6Uj\!6,na^,~ kh:"u?j TITLE TURBODOS OPERATING SYSTEM - SUPER QUAD SERIAL/PARALLEL I/O DRIVER .Z80 ; NAME ('SQPIO') ;MODULE ID ; INCLUDE DREQ A ;MAKE BASE 1 OUT SECTP ;OUTPUT TO 1797 SECTOR REGISTER RET ;DONE ; RWCOM2: LXI H,RWERR ;GET READ/WRITE ERROR ACCUMULAT ..HX ;YES, EXIT TO ERROR PROCESS DJNZ ..HL ;CONTINUE UNTIL 4TH BYTE IS IN C ..CRCL: IN DDATA ;INPUT NEXT DATA BYTE IN FDWA4fl3]9B3#d* bbze '!)G@@*zjt!)+Fu*"*b o&'%'GȀ2* |)!)G2*Btl)") ;PARALLEL 0 OUTPUT CHARACTER P0CHAN:: DB 0 ;PARALLEL 0 CHANNEL NUMBER P0ADDR:: DW 0 ;PARALLEL 0 DATA AREA ADDRESS ; C0;[tnӸUeO€+o-I  M  QV M"8Oe؀?Bt ۫znbXZnӐU^ 7Jtn- $dUATE.LIB ;O/S SYMBOLIC EQUIVALENCES ; ; IVEC1 EQU 40H ;PARALLEL PORT A INTERRUPT VECTOR NUMBER ; IOBASE EQU 00H ;PARALLELTT T4%( =5IZSERIALTT`e4U$4 ?INIT?Te4U$%5MIMRSERNITMQ`( +67\,)LE$BhR v%IT ;SYNC ORA A ;INTRQ? JP ..HX ;YES JMPR ..CRCL ;CONTINUE ..HX: IN DSTAT ;GET 1797 STATUS EI ;ENABLE INTERRUPTS AGAIN 2*"m)")!2*"$t)$F2*Jr o)$!F2*Jro)$"GRr*JLw)$Ԁ2*rJd )() O*e )OMMON /?INIT?/ ;PUT INTO INITIALIZATION COMMON AREA ; PARNIT:: LD A,IVEC1 ;SET UP PRINTER INTERRUPT VECTOR OUT (PIO1C),A 7\V녖@۬qPe> ۣPt VeF7\-xx*< O0P n@ +"Y8d4f 2e~/ I/O PORT BASE ; PIO0D EQU IOBASE+04H ;PARALLEL PORT 0 DATA PORT PIO0C EQU IOBASE+06H PIO1D EQU IOBASE+05H ;PARALLEL PORT 1 n[IOkq@`z(YWzʦ#U NY,tn,([8n {?/{%pܯ6x0+CmӘar B;/6x,+ۦt ANI 9DH ;MASK ERROR BITS JRNZ ..ERR ;IF ERROR, CHECK OTHER DENSITY LHLD CLADDR ;POINT TO CURRENT LATCH ; .IFE DBLSID , ()!Q*$d ) FYrb*g+N '!)G@@*zjt!)+Fu*"*b o&'%'GȀ2* |)!)G2*Btl)")  LD HL,P0TISR LD (IVEC1),HL LD A,00FH ;PUT PORT A IN OUTPUT MODE OUT (PIO0C),A LD A,0CFH ;PUT PORT B IN BIT MODE OU@@@0/s 5v>=Ҁ}4Uʁ E"tR) @`\" DATA PORT PIO1C EQU IOBASE+07H ; RDY EQU 7 ;OUTPUT CHAR READY TO SEND BIT OPA EQU 6 ;OUTPUT PORT AVAILABLE BIT BXC EQU 5 rIt]-Mt ,9'n'@/%?‰w0Z-U!qX6>ѠrB ealx:7\t n[ RES TSL,M ;CLEAR TWO-SIDED DISK FLAG ; MOV A,M ;GET CURRENT LATCH VALUE SET SSL,A ;SELECT SIDE TWO OUT DCONT ; PUS T (PIO1C),A LD A,01FH ;BITS 0-4 INPUT, BITS 5-7 OUTPUT OUT (PIO1C),A LD A,0B7H ;ENABLE PORT B INTERRUPT OUT (PIO1C),A  TSL,M ;TWO-SIDED DISK? JRZ ..OSD ;NO, JUMP SRLR B ;YES, DIVIDE TRACK BY TWO JRC ..TSD ;JUMP IF SIDE ONE ;] JMPR ..OSD ,80H ;STROBE IT OUT (PIO1D),A XOR A OUT (PIO1D),A RES OPA,(HL) ;CLEAR THE OUTPUT PORT READY FLAG ; P0TSB2: LD HL,(P0AL# ;SIGNAL PROCESS AS READY ; WTSEEK: LXI D,FDPOLL ;GET POLL ROUTINE ADDRESS CALL LNKPOL# ;CREATE POLL ROUTINUE CALL FDPRT LD HL,P0FLAG ;POINT TO OUTPUT READY FLAG SET RDY,(HL) ;SET OUTPUT READY INDICATION DI ;DISABLE INTERRUPTS SET BXC,(Hvca%R2RS# %9QMQ.< Q@@ !:< Q @= !J: Tԣ@QM:B P@AI>>TU#(M%92p LD A,0FEH ;ONLY BUSY SIGNAL OUT (PIO1C),A LD HL,P0FLAG ;SET OUTPUT PORT AVAILABLE SET OPA,(HL) RET ; CSEG ;PUT I;MUST BE SIDE ZERO ; ..FMT: MVI C,010H+HLAB ;NO VERIFY ON FORMATS ; .IFE DBLSID , [ BIT 7,PDRSEC+1(X) ;TEST FOR SIDE TWDDR) ;POINT TO OUTPUT SEMAPHORE LD DE,8 ADD HL,DE CALL SIGNAL## ;SIGNAL PROCESS AS READY ; ??XIT:: LD HL,P0FLAG ;POINT T ;EXECUTE POLL ROUTINE LXI H,FDSPH ;GET SEMAPHORE JMP WAIT# ;DISPATCH IF NECESSARY ; GETSTS: MVI A,0D0H ;FORCE STATUS UPDAL) ;SET BEGIN XMIT. CHARACTER FLAG ; P0TSUB:: ; BIT OPA,(HL) ;TRANSMITTER AVAILABLE? JR Z,??XIT ;NO, EXIT ; P0TSB1:: `qݦ?`qe2iV+U! `&"`q[w2 ,(ì`AWA4YTj%`]NTO CODE SEGMENT ; P0TISR:: LD (INTSP##),SP ;SAVE STACK POINTER LD SP,INTSTK## ;SET UP AUX STACK POINTER PUSH AF ;SAVE O JRZ ..OSD ;NOT SIDE TWO, GO TO COMMON CODE ; ..TSD: MOV A,M ;GET THE CURRENT LATCH VALUE SET SSL,A ;SET SIDE ONE (2ND SIO FLAG BYTE BIT BXC,(HL) ;BEGIN XMIT. CHARACTER? JP Z,INTXIT## ;NO, MUST BE AN INTERRUPT RES BXC,(HL) ;YES, CLEAR FLAG E title TURBODOS OPERATING SYSTEM - SUPER SIX REAL TIME CLOCK DRIVER subttl copyright 1983 by software 2000, inc. .z80 ; ;  BIT RDY,(HL) ;IS A CHARACTER READY TO SEND? JR Z,??XIT ;NO, EXIT RES RDY,(HL) ;YES, CLEAR THE FLAG ; LD A,(P0OCHR) ;GET;TRY AGAIN ; FDPOLL: .WORD 0 ;POLL ROUTINE .WORD 0 ; FDPR: IN DSTAT ;GET DRIVE STATUS ANI 1 ;1797 BUSY? RNZ ;IF SO, DPSW PUSH BC ;SAVE REMAINING REGISTERS PUSH DE PUSH HL LD HL,P0FLAG ;SET OUTPUT PORT AVAILABLE BIT SET OPA,(HL) JR PTTSedx@= !JP0CHAN Q%9%PPARNIT TԠeE4#AI>P0TSUBOU%U p Cxh`aI ;ENABLE INTERRUPTS AGAIN RET ;RETURN TO CALLER ; END copyright 1983 by software 2000, inc. ; converted to MICROSOFT M80 format by ; Advanced Digital Corp. ; ; version: 07/01/8 PARALLEL 0 OUTPUT CHARACTER OR A ;CHARACTER A NUL JR Z,P0TSB2 ;YES, DON'T SEND IT OUT (PIO0D),A ;OUTPUT CHARACTER LD AONE LXI H,FDPOLL ;ELSE, GET POLL ROUTINE ADDRESS CALL UNLINK# ;UNLINK POLL ROUTINE LXI H,FDSPH ;GET SEMAPHORE JMP SIGNA0TSB1 ; PARAO:: LD (P0ADDR),HL ;SAVE PARALLEL 0 ADDRESS LD HL,P0OCHR ;GET PARALLEL 0 OUTPUT CHARACTER LD (HL),C ;SAVE I=`qݦ?`qe2iV+U! `&"`q[w2 ,(ì`AWA4YTj%`] 3 ; name ('S6RTC') ;module id ; include DREQUATE.LIB ;driver symbolic equivalences ; ctcch0 equ 08h ;ctc channel 0 r IN TRACK ;GET 1797 TRACK REGISTER MOV M,A ;SAVE IN TRACK TABLE ..UND: MOV A,PDRDRV(X) ;GET REQ DRIVE STA FDCDRV ;UPDATE F,0 ;else, reset tick counter call rtcsec## ;service real time clock manager ..nsec: call dlytic## ;service dispatcher del title TURBODOS OPERATING SYSTEM - SUPER SIX SERIAL I/O DRIVER subttl copyright 1983, software 2000, inc. .z80 ; ; copyrigt (ctcch1),a ;initialize ctc channel 1 ld a,100 ;get time constant value out (ctcch1),a ;set ctc channel 1 time constant(1<4) ;NUMBER OF BLOCKS .BYTE 4 ;NUMBER OF DIRECTORY BLOCKS .BYTE 3 ;PHYSICAL SECTOR SIZE (2^N*128) .WORD 8 ;PHYSICAL SECTegister ctcch1 equ 09h ;ctc channel 1 register ; dseg ;locate in data area ; ticctr: db 0 ;tick counter ; COMMONT͔%9%PRTCNITTԥ Rp p?INIT?hH0@0HeӘ1VCp4pX/i0ay manager pop hl ;restore registers pop de pop bc pop af ld sp,(intsp##) ;restore stack pointer jp isrxit## ;coht 1983, software 2000, inc. ; converted to MICROSOFT M80 format by ; Advanced Digital Corp. ; ; version: 07/01/83 ; na ret ;done ; cseg ;locate in program area ; rtcisr:: ld (intsp##),SP ;save stack pointer ld sp,intstk## ;set ORS PER TRACK .WORD 2*77 ;PHYSICAL TRACKS PER DISK .WORD 0 ;RESERVED TRACKS .WORD 0 ;TRANSLATION TABLE ADDRESS .BYTE 3!1 /?init?/ ;locate in initialization area ; rtcnit:: ld hl,rtcisr ;get interrupt service address ld (ctcvec##+2),hl ;s CTCVECdDŕD8INTSPdE5D(ISRXITe%D45(RTCNITe%D54T9ntinue ; end me ('S6SIO') ;module id ; include DREQUATE.LIB ;driver symbolic equivalences ; sioadr equ 00h ;sio port a data registerup aux stack pointer push af ;save registers push bc push de push hl ld hl,ticctr ;get tick counter inc (hl) ;i-EX 8F`[.ҐY(;Jx3@5*Ũ>+bV&?b@ ld a,c ;get requested baud rate code add a,a ;shift baud rate code to msn add a,a add a,a add a,a or b ;combin vector bit cts,d ;cts set? jr z,..ncts2 ;if not, continue set 7,a ;else, set cts bit ..ncts2: bit dcd,d ;dcd se or a ;channel number=0? jr z,..com1 ;if so, continue ld hl,s1br ;else, get serial 1 baud rate code ..com1: ld (hl);get write register 5 di ;disable interrupts out (c),a ;select write register 5 out (c),d ;output control word eisersmc: ld a,0eah ;get write register 5 control word and not 82h ;strip rts/cts control bits bit 7,c ;rts requested? +v%R%iO>"T4mh 3O qxC6!f !€ Parf۰+8h8 63hX3n0o|i[`Y]! ne with baud rate register jr ..com2 ;continue ..ch0: and 0f0h ;strip lower four bits or c ;combine with baud rate reet? ret z ;if not, done set 5,a ;else, set dcd bit ret ;done ; end ,c ;save baud rate code ld a,c ;get requested baud rate code and 0fh ;extract relevant bits ld c,a ;update request ;enable interrupts ret ;done ; serrmc: ld c,sioacr ;get sio port a control register ld a,b ;get channel number  jr z,..nrts set 1,a ;if so, set rts bit ..nrts: bit 6,c ;dtr requested? jr z,..ndtr set 7,a ;if so, set dtr bit .7X0h!€ ;L,e6Y:` 0o0( @f԰mpX/iݤGd670 (\gister ..com2: out (siobrr),a ;set baud rate generator register ld (baudrt),a ;update baud rate register value ret ;doT͔Se3%5L% Mj(SUe4HM%=%MJSERIALQW)pÀ1x/ed baud rate code ld a,b ;get channel number or a ;channel number=0? ld a,(baudrt) ;get baud rate register value jr or a ;channel number=0? jr z,..com5 ;if so, continue ld c,siobcr ;get sio port b control register ..com5: ld a,10h ;.ndtr: ld d,a ;requested modem controls to d-reg ld c,sioacr ;get sio port a control register ld a,b ;get channel numbeȀ*,!X$U@[JMiO (F`[.ҐY(;Jx#88C f Gd6BX70 (\ @ b@&,P*ne ; serrbr: ld hl,s0br ;get serial 0 baud rate ld a,b ;get channel number or a ;channel number=0? jr z,..com3 ;i151;SU2^" x]1<n՘3@`Pbo!b $b`H`Dl@P.A z,..ch0 ;if channel number=0, continue and 0fh ;else, strip upper four bits ld b,a ;baud rate register value to b-regget reset external status command out (c),a ;reset external status in d,(c) ;get sio modem status xor a ;clear retur ( ݥ&ôX#uK@iH`,p4#L0> 4/ `>41 dec HL ;correct for +1 ex DE,HL ;put source and dest in proper regs lddr ;move what we just got to execution addr ;TRY AGAIN ; FDPOLL: .WORD 0 ;POLL ROUTINE .WORD 0 ; FDPR: IN DSTAT ;GET DRIVE STATUS ANI 1 ;1797 BUSY? RNZ ;IF SO, k jr reqdta ;and go do more ; ; got all of operating system, now put where it belongs and execute it ; done: dec HL msgdid: dw 0 ;gets patched to network default id db 0 msgsid: dw 0 ;gets patched to slave network id dw 0 db 0,0,0  push AF ;save psw ld A,6 ;send acknowledgement out (dta),A in A,(dta) ;get masters response cp 6 ;was it rigJ]1 _2‡f@.FvL ( Z`imrՃ/2p uEnj&*`DH 0l>L 60:]Yo inc DE ;make de point to start of code ld HL,(msgsid) ;get slave source id ld (80h),HL ;and save it in default bufferDONE LXI H,FDPOLL ;ELSE, GET POLL ROUTINE ADDRESS CALL UNLINK# ;UNLINK POLL ROUTINE LXI H,FDSPH ;GET SEMAPHORE JMP SIGN ;get last char we just received ld A,(HL) ld HL,lodbuf ;point to begining of receive buffer ld E,(HL) ;get starting  msgssl: db ' ' ;gets patched with slave operating system ;down load suffix ; rcvhdr: ds 0bh rcvbuf: ds 80h ;temp r }I0%pSSBLENe54$HSSDIDU554HXSSSSL0R T@@>p4#L0> 4/ `>4MSG ;EXIT IF NOT RES 6,(HL) ; OTHERWISE CLEAR SEND MESSAGE FLAG LD HL,SDMSPH ; AND SIGNAL SEND MESSAGE ROUTINE CALL S ;IF WE GOT HERE MUST BE BAD COMMAND, EXIT ; ;RECEIVE MESSAGE ROUTINE ; RCVMSG: LD HL,RCVSPH ;MAKE SURE NO ONE ELSE USINSTER REQUEST INTERRUPT SERVICE ROUTINE ; ISRCKT: LD (INTSP##),SP ;SAVE STACK POINTER LD SP,INTSTK## ; AND USE INTERRUPT ST.OLD ;NO, USE OLD VALUE MOV A,B ;GET NEW DRIVE NUMBER ..OLD: OUT DCONT ;SELECT DRIVE MOV M,A ;SAVE CURRENT LATCH VALUE SHAGE LENGTH OTIR ;SEND IT EI ;CAN BE BOTHERED NOW LD HL,SDWSPH ;SAY DONE CALL SIGNAL## XOR A ;RETURN SUCCESSFUHEAD. ; CALL GETSTS ;GET CURRENT DRIVE STATUS ANI 0A0H ;READY AND HEAD LOADED? CPI 020H JRNZ ..TST ;NO, NO NEED TO UNLOIGNAL## NOMSG: XOR A ;RETURN WITH SUCCESS RET ; ;SEND MESSAGE ROUTINE ; SNDMSG: LD HL,SDWSPH ;MAKE SURE NO ONE ELG THIS ROUTINE CALL WAIT## ;AND THAT THERE IS A MESSAGE WAITING CALL SETUP ;SET UP REGISTERS IN B,(C) ;GET LENGTH OFACK PUSH AF ;SAVE ACC LD A,6 ;SEND RESPONSE TO MASTER OUT (1EH),A IN A,(1EH) ;DOES MASTER WANT TO SEND US SOMETHIN TITLE TURBODOS OPERATING SYSTEM - SUPER SLAVE CIRCUIT DRIVER .Z80 ; NAME ('SSCKTDR') ;MODULE ID ; INCLUDE DREQUATE.LIBLLY RET ; SETUP: INC DE ;POINT TO BEGINNING OF MESSAGE INC DE INC DE INC DE EX DE,HL ;PUT POINTER INTO HL LD CAD. IN TRACK ;UNLOAD WITH A SEEK TO PRESENT TRACK OUT DDATA LDA STEPR% ;FORM SEEK COMMAND ORI 010H OUT DCOM ;TELL CONTSE IS TRYING TO SEND CALL WAIT## ; MSGWAT: LD HL,SIGFLG ;GET SIGNAL FLAG ADDRESS DI ;MAKE SURE NOT BOTHERED BIT 7,(H MESSAGE LD (HL),B ;SAVE INTO MESSAGE BUFFER INC HL ;UPDATE POINTERS DEC B INIR ;GET REST OF MESSAGE EI ;RE-G CP 6 JR NZ,ISRERX ;IF NOT LEAVE PUSH BC ; OTHERWISE SIGNAL TO RECEIVE MESSAGE PROCESS PUSH DE PUSH HL LD HL,SIG ;O/S SYMBOLIC EQUATES ; IVEC0 EQU 0 ;INTERRUPT VECTOR TO RESPOND TO ; CSEG ;PUT INTO CODE SEGMENT ; CKTDR@:: ,1EH ;GET DATA PORT ADDRESS LD A,8 ;SET REQUEST BIT TO MASTER OUT (1FH),A EI SVCWAT: IN A,(1FH) ;IS MASTER LOOKING ROLLER PUSH B ;SAVE NEW DRIVE NUMBER CALL WTSEEK ;WAIT FOR COMPLETION POP B ;RESTORE NEW DRIVE NUMBER ..TST: MOV L,B ;COML) ;WAITING FOR RECEIVED MESSAGE JR Z,MSGSND ;IF NOT WE CAN GO ON EI SET 6,(HL) ;ELSE SAY WANT TO SEND LD HL,SDMSPHENABLE INTERRUPTS LD HL,SIGFLG RES 7,(HL) ;RESET RECEIVEING MESSAGE FLAG BIT 6,(HL) ;WAITING TO SEND MESSAGE JR Z,NOFLG SET 7,(HL) ;AND SET RECEIVE MESSAGE FLAG LD HL,RCVSPH CALL SIGNAL## POP HL POP DE POP BC ISRERX: POP AF ;GE LD A,C ;GET COMMAND OR A JR Z,RCVMSG ;WAS RECEIVE MESSAGE COMMAND DEC A JR Z,SNDMSG ;WAS SEND MESSAGE COMMAND RETAT US YET AND 8 JR NZ,SVCWAT ;IF NOT WAIT SOME MORE DI ;TURN INTERRUPTS OFF SO NOT BOTHERED RET ;GO DO IT ; ;MAPUTE LATCH STORAGE LOCATION MVI H,0 LXI D,LATBL DAD D MOV A,M ;GET OLD LATCH VALUE CPI 0FFH ;IS IT UNDEFINED? JRNZ . ;AND WAIT FOR CHANCE CALL WAIT## JR MSGWAT ;TRY AGAIN ; MSGSND: CALL SETUP ;SET UP REGISTERS LD B,(HL) ;GET MESS  T REGISTERS BACK LD SP,(INTSP##) ;FIX STACK POINTER JP ISRXIT## ;AND RETURN FROM INTERRUPT ; COMMON /?INIT?/ ;PUT INTͥ HL& !}`@dN`z0l<,VCof EvP SU3@G@b1 dH.WORD (2*77*(8*(1<2)))/(1<4) ;NUMBER OF BLOCKS .BYTE 3 ;NUMBER OF DIRECTORY BLOCKS .BYTE 2 ;PHYSICAL SECTOR SIZE (2^N*128) ND PORT ; ICOD EQU 18H ; 9519 DATA PORT ICOC EQU 19H ; 9519 COMMAND PORT ; IVEC EQU 10H ; INTERRUPT VECTOR BASE ADDRE NOT DIDF: DEC HL ;POINT TO LSB OF DESTINATION ID LD A,(TBUF) ;GET LSB OF PASSED DESTINATION ID LD (HL),A ;AND PUT ITSD!1pass *h " !" :d 2 2 >2 l(  Formav((  Format aborte! 4! 5 * #" * +" | |@iGeFiZ`6Lv ?Vm#[/x >X4#/i$p"n?D8ͤ`10pX/i}I )ʈ1 push HL ;save it for later ld DE,(lodlng) ;get length to load ld B,E ;preload count to load ld A,E ;is it even nta port to master ; clrpar equ 2 ;clear parity bit clrovr equ 4 ;clear overrun bit ; ssload:: .phase 1000h ;want itnot ready o  Insufficient memory to formatU  Insufficient memory to verify: O +.  Verify drive not ready :0 i  F4?A@0` `Ŧ f&1̑d3m 01`mP4`ڠ&h͵B àLqm`  Successful format Starting verify pasl  Insert disk to be verified in drive: A?  Enter to begin ve )ʉ* 6)ʋ *Q%NINTXITMP@%8%9%P^vݥ`AFrJd|iGʖd|iG`"pd o. of pages or A jr nz,readin ;skip next if not dec D ;else pre decrement repeat counter readin: inir ;read in i to execute at this address ;in slave start:: di ;can't be interrupted ld SP,start ;set up stack ld A,clrpar oQ e54HMQIRP5'y@ Y +kq*Y^Aji( 8 2[ Ҭ@dq\ ,ۜP?l` 1Y h82~?L(waX~m ;‚E@8 ̀ٷ8 ̀8turifying, (     ! " >2 l* " |eo<$: =M)"  S *Rڴ* " 2 !" " l( ٶt>z o61q`#!<&<>x lld3ma7`( 7Mf" p)fep Y@ٵ<n 27`hD egiOnfo dec D ;more to get jp p,readin ;go back if so pop HL ;else get starting address jp (HL) ;and execute what we r clrovr ;clear overrun and parity and turn off prom out (ctl),A ld C,dta ;set up data port address ld HL,lodadr ;setup Drive:: A? , Track:*   [, , <^C>] ,7( (  'd  R0x  title TurboDOS operating system - super slave initial system loader .z80 ; name ('ssload') ;module id ; lodadr equ 0100 Verifv((  Verify aborte* #" * +" |  Successful verif  Unable to execute in slave proc ;IxD[` 20ve* ũP 0s$Cp,dpjʬc-rAvh:`%Y@~>l!j  Enter density (SION CODE ; COMMON /?INIT?/ ;PUT INTO INITIALIZATION AREA ; MPENIT:: LD DE,MPEPOL ;GET ADDRESS OF DUMMY POLL ROUTINE CESSOR LINK POINTER ; LD BC,0 ;INITIALIZE THE MEMORY PARITY LD DE,0 LD HL,0 LDIR ; LD A,2 ;CLEAR THE PARITY ERROTS%9%PMPENITMJ@%@!  4 h!@ 0?INIT?h4dF2 "Jrd""'F2Jr*r l~#: : ~#* ~! " R" :c :e (2 : :g (2 % 1 i u   ] m z(zzzzzingle/Double):( _S( D(S(!c 6:l :!j  Enter number of sides (1/2):(1( 2(02d :n A!j ALL LNKPOL## ;CREATE POLL ROUTINE RET ;WAIT FOR INITIALIZATION TO COMPLETE END R LATCH OUT (SSCTL),A ; LD A,PARINT ;GET PARITY INTERRUPT NUMBER LD HL,BADINT## ;AND ADDRESS OF BAD INTERRUPT ROUTINE &'%'G2j*rJd*&$% TITLE TURBODOS OPERATING SYSTEM - SUPER SLAVE MEMORY PARITY INITIALIZATION .Z80 ; NAME ('SSMPINIT') ;MODULE ID ; SSCTL  Enter format type (TurboDOS/Cpm):( _T( C(!e 6C(44:c (4!:e _:c (+~2f !:e (+~2g :j G RN DIGITAL BASIC FORMAT MODULE FMTI8F ;INITIALIZATION FOR STANDARD 8 INCH FLOPPY FMTWD ;TRACK FORMATTING FOR WESTE CALL INTENA## ;ENABLE PARITY INTERRUPT ; LD HL,MPEPOL ;GET ADDRESS OF DUMMY POLL ROUTINE CALL UNLINK## ;UNLINK POLL ROU ; ; AUTHORS: ROANLD E. RAIKES ; MICHAEL D. BUSCH ; ; FOR MuSYS CORP.: WILLIAM A. SCHULTZ ; ; VERSION: 02/08/82 ; .IEQU 01FH ;SUPER SLAVE CONTROL PORT ADDRESS PARINT EQU 4 ;PARITY ERROR INTERRUPT ; CSEG ;LOCATE IN PROGRAM AREA ; DG;(S D 2k 1 2 2l T C 2n 6*T:to  :p :q ~#_:c |TINE ; LD HL,MPEPOL ;DEALLOCATE INITIALIZATION CODE AND RETURN JP DEALOC## ; NITLEN EQU $-MPEPOL ;LENGTH OF INITIALIZATDENT INTAMD ;MODULE ID ; IVEC = 040H ;INTERRUPT VECTOR BASE ADDRESS ; CTC0 = 008H ;CTC PORT ADDRESSES CTC1 = 009H CTC2 W NITLEN+2 ;LENGTH OF INITIALIZATION CODE ; MPEPOL: ;DUMMY POLL ROUTINE DW 0 ;PREDECESSOR LINK POINTER DW 0 ;SUCC(*! *R>! T]6:c (6N :r _:f 2 GO !s 8zw#p:e _!:c (!^#V#^#VS  !s jN#F#F#$ = 00AH CTC3 = 00BH PIOA = 005H ;PIO PORT ADDRESSES PIOB = 007H SIO1A = 001H ;SIO #1 PORT ADDRESSES SIO1B = 003H ; .LOC ;ONLY BUSY SIGNAL OUT (PIO1C),A LD HL,P0FLAG ;SET OUTPUT PORT AVAILABLE SET OPA,(HL) RET ; CSEG ;PUT INTO CODE SELLEL 0 OUTPUT CHARACTER P0CHAN: DB 0 ;PARALLEL 0 CHANNEL NUMBER P0ADDR: DW 0 ;PARALLEL 0 DATA AREA ADDRESS ; COMMON /?INI OUTPUT SEMAPHORE LD DE,8 ADD HL,DE CALL SIGNAL## ;SIGNAL PROCESS AS READY ; ??XIT: LD HL,P0FLAG ;POINT TO FLAG BYTE QUATE.LIB ;O/S SYMBOLIC EQUIVALENCES ; ; IVEC1 EQU 08H ;PARALLEL PORT A INTERRUPT VECTOR NUMBER ; IOBASE EQU 00H ;PARALLEXMIT. CHARACTER FLAG ; P0TSUB: ; BIT OPA,(HL) ;TRANSMITTER AVAILABLE? JR Z,??XIT ;NO, EXIT ; P0TSB1: BIT RDY,(HL) ; .DATA.# ;LOCATE IN DATA AREA ; INTMSK::.BYTE 000H ;INTERRUPT MASK BYTE (NOT FUNCTIONAL) ; .LOC .PROG.# ;LOCATE IN PROGRAM GMENT ; P0TISR: LD (INTSP##),SP ;SAVE STACK POINTER LD SP,INTSTK## ;SET UP AUX STACK POINTER PUSH AF ;SAVE PSW PUSH BC T?/ ;PUT INTO INITIALIZATION COMMON AREA ; PARNIT:: LD A,IVEC1 ;SET UP PRINTER INTERRUPT VECTOR OUT (PIO1C),A LD HL,P0TBIT BXC,(HL) ;BEGIN XMIT. CHARACTER? JP Z,INTXIT## ;NO, MUST BE AN INTERRUPT RES BXC,(HL) ;YES, CLEAR FLAG EI ;ENABLE INL I/O PORT BASE ; PIO0D EQU IOBASE+14H ;PARALLEL PORT 0 DATA PORT PIO0C EQU IOBASE+16H PIO1D EQU IOBASE+15H ;PARALLEL PORT 1IS A CHARACTER READY TO SEND? JR Z,??XIT ;NO, EXIT RES RDY,(HL) ;YES, CLEAR THE FLAG ; LD A,(P0OCHR) ;GET PARALLEL 0 OUTAREA ; .WORD NITLEN+2 ;INITIALIZATION CODE LENGTH ; INTNIT::XRA A ;SET INTERRUPT BASE PAGE ZERO STAI IM2 ;SET INTERRU ;SAVE REMAINING REGISTERS PUSH DE PUSH HL LD HL,P0FLAG ;SET OUTPUT PORT AVAILABLE BIT SET OPA,(HL) JR P0TSB1 ; PARAISR LD (IVEC1),HL LD A,00FH ;PUT PORT A IN OUTPUT MODE OUT (PIO0C),A LD A,0CFH ;PUT PORT B IN BIT MODE OUT (PIO1C),ATERRUPTS AGAIN RET ;RETURN TO CALLER ; END  DATA PORT PIO1C EQU IOBASE+17H ; RDY EQU 7 ;OUTPUT CHAR READY TO SEND BIT OPA EQU 6 ;OUTPUT PORT AVAILABLE BIT BXC EQU 5PUT CHARACTER OR A ;CHARACTER A NULL JR Z,P0TSB2 ;YES, DON'T SEND IT OUT (PIO0D),A ;OUTPUT CHARACTER LD A,80H ;STROBE PT MODE TWO ; LXI D,BADINT;SET DEFAULT INTERRUPT CONDITION LXI H,08H MVI B,36 ..LP: MOV M,E ;STUFF DEFAULT INTERRUPT JUMO:: LD (P0ADDR),HL ;SAVE PARALLEL 0 ADDRESS LD HL,P0OCHR ;GET PARALLEL 0 OUTPUT CHARACTER LD (HL),C ;SAVE IT LD HL,P0FL LD A,01FH ;BITS 0-4 INPUT, BITS 5-7 OUTPUT OUT (PIO1C),A LD A,0B7H ;ENABLE PORT B INTERRUPT OUT (PIO1C),A LD A,0FEH ;BEGIN XMIT. CHAR BIT ; ; DSEG ;LOCATE IN DATA AREA ; P0FLAG: DB 0 ;PARALLEL 0 OUTPUT READY FLAG P0OCHR: DB 0 ;PARAIT OUT (PIO1D),A XOR A OUT (PIO1D),A RES OPA,(HL) ;CLEAR THE OUTPUT PORT READY FLAG ; P0TSB2: LD HL,(P0ADDR) ;POINT TO TITLE TURBODOS OPERATING SYSTEM - SUPER SLAVE SERIAL/PARALLEL I/O DRIVER .Z80 ; NAME ('SSPIO') ;MODULE ID ; INCLUDE DREAG ;POINT TO OUTPUT READY FLAG SET RDY,(HL) ;SET OUTPUT READY INDICATION DI ;DISABLE INTERRUPTS SET BXC,(HL) ;SET BEGIN % GET SLAVE RESET CHARACTER CP C ;CHARACTER=SLAVE RESET CHARACTER? JR Z,..RC ;IF SO, CONTINUE LD (HL),-2 ;ELSE, RESET CHA BASE INTERRUPT VECTOR POINTER OUT CTCBAD ;(MUST BE SET IN CHANNEL ZERO) ; LXI H,RTCISR ;SET INTERRUPT VECTOR ADDRESS SHLIDENT RTCAMD ;MODULE ID ; TRUE = 0 ;DEFINE LOGICAL VALUES FALSE = # TRUE ; CHAN = 3 ;CTC CHANNEL NUMBER TO USE FOR RTC ԑT`e4$4(M1YINP5`Ƞ62F<M1YINpRACTER COUNT RET ;DONE ..RC: INC (HL) ;INCREMENT RESET CHARACTER COUNT RET NZ ;IF CHARACTER COUNT NOT=0, DONE DI ;E TITLE TURBODOS OPERATING SYSTEM - SUPER SLAVE PROCESSOR RESET .Z80 ; NAME ('SSRESET') ;MODULE ID ; INCLUDE DREQUATE.LIIVEC = 8 ;BASE INTERRUPT VECTOR FOR THE CTC ; CTCBAD = 08H ;CTC BASE AND VECTOR PORT ADDRESS CTCPAD = CTCBAD+CHAN ;CTC PORT* bzdp*)FG2Jr\d)*!O2JrJd"&,$TS℀%9%PPARNITTTSU p Cx haa=aqݦ?aqe2iV+U! `&"`qLSE, DISABLE INTERRUPTS HALT ;HALT ; END B ;DRIVER SYMBOLIC EQUIVALENCES ; DSEG ;LOCATE IN DATA AREA ; SLRCHR:: DB AUS ;SLAVE RESET CHARACTER RCCNT: DB -2 ;R ADDRESS FOR RTC ; MHZ4 = TRUE ;TRUE IF 4 MHz SYSTEM CLOCK ; .LOC .DATA.# ;LOCATE IN DATA AREA ; TICCNT: .BYTE 0 ;TICK C[w2 ,(ìaAW¬A4Y2϶Ld*)FA@2Jr\e0$*,$GD* ||( '$FQ2J:r d JZ INTXIT# ;NO, NO TICK SERVICE ;] CALL DLYTIC# ;YES, SERVICE DISPATCHER DELAY MGR. JMP INTXIT# ;SIGNAL DONE WITH INTERRUPESET CHARACTER COUNT ; CSEG ;LOCATE IN PROGRAM AREA ; SLVRES:: LD HL,RCCNT ;GET RESET CHARACTER COUNT LD A,(SLRCHR) ;OUNTER ; .LOC .PROG.# ;LOCATE IN PROGRAM AREA ; .WORD NITLEN+2 ;INITIALIZATION CODE LENGTH ; RTCNIT:: MVI A,IVEC ;SET. ; ; AUTHORS: ROANLD E. RAIKES ; MICHAEL D. BUSCH ; ; FOR MuSYS CORP.: WILLIAM A. SCHULTZ ; ; VERSION: 02/08/82 ; .T ; .XSYM .END TICK SERVICE ;] CALL DLYTIC# ;YES, SERVICE DISPATCHER DELAY MGR. JMP INTXIT# ;SIGNAL DONE WITH INTERRUP&  TITLE TurboDOS operating system - Super Slave real time clock driver .z80 ; name ('ssrtc') ;module id ; chan equ 5 ;iDR: .WORD 0 ;SERIAL 1 DATA AREA ADDRESS ; .LOC .PROG.# ;LOCATE IN PROGRAM AREA ; .WORD NITLEN+2 ;LENGTH OF INITIALIZATIONINTSPdE5DRTCISRe%D4HȸRTCSEC ;CLEAR TO SEND STATUS TRUE BIT DSR EQU 7 ;DATA SET READY STATUS BIT DSRT EQU 6 ;DATA SET READY STATUS TRUE BIT DCD EQUed notsec: call dlytic## ;signal tick has occured pop HL ;get registers back pop DE pop BC pop AF ld SP,(intsp##) PORTS 2 & 3 ; SIO0D EQU 0 ;SERIAL PORT 0 DATA SIO0C EQU 1 ;SERIAL PORT 0 CONTROL SIO1D EQU 2 ;SERIAL PORT 1 DATA SIO1nterrupt channel to use for tick int ; dseg ;put into data area ticcnt: db 0 ;seconds counter ; cseg rtcisr: CODE ; SERINA: SERIN%:: MVI C,SIO0C ;SET SIO PORT ADDRESS MVI B,SIOIL ;SET INITIALIZATION DATA LENGTH LXI H,SIOID ;SETEMAPHORE COUNT ..S1OH: .WORD ..S1OH ;SEMAPHORE P/D HEAD .WORD ..S1OH ; S0BAUD: .BYTE 0 ;SERIAL 0 BAUD RATE CODE S0OCHR: .B 3 ;DATA CARRIER DETECT STATUS BIT DCDT EQU 5 ;DATA CARRIER DETECT STATUS TRUE BIT RI EQU 4 ;RING INDICATOR STATUS BIT  ;restore stack pointer ei ;and return with interrupts on reti common /?init?/ ;initialization code rtcnit:: C EQU 3 ;SERIAL PORT 1 CONTROL ; SIO2D EQU 0CH ;SERIAL PORT 2 DATA SIO2C EQU 0DH ;SERIAL PORT 2 CONTROL SIO3D EQU 0EH : ld (intsp##),SP ;save stack pointer ld SP,intstk## ;and use interrupt stack push AF ;to save all registers push BC INITIALIZATION DATA ADDRESS OUTIR ;SEND INITIALIZATION TO SIO ; MVI C,SIO1C ;SET SIO PORT ADDRESS MVI B,SIOIL ;SET INITYTE 0 ;SERIAL 0 OUTPUT CHARACTER S0CHAN: .BYTE 0 ;SERIAL 0 CHANNEL NUMBER S0ADDR: .WORD 0 ;SERIAL 0 DATA AREA ADDRESS ; S1BARIT EQU 4 ;RING INDICATOR STATUS TRUE BIT TXMT EQU 2 ;TRANSMITTER EMPTY STATUS BIT TXMTT EQU 0 ;TRANSMITTER EMPTY STATUS ld A,CHAN ;enable interrupt ld HL,rtcisr jp intena## end  ;SERIAL PORT 3 DATA SIO3C EQU 0FH ;SERIAL PORT 3 CONTROL ; BDRATE EQU 10H ;BAUD RATE SELECT PORT (CHANNEL 0 LOW 4 BITS, push DE push HL ld HL,ticcnt ;point to tick counter inc (HL) ;bump it up ld A,(HL) ;get count cp 61 ;at 1 se TITLE TURBODOS OPERATING SYSTEM - SUPER SLAVE SERIAL DRIVERS .Z80 ; NAME ('SSSIO') ;MODULE ID ; INCLUDE DREQUATE.LIB UD: .BYTE 0 ;SERIAL 1 BAUD RATE CODE S1OCHR: .BYTE 0 ;SERIAL 1 OUTPUT CHARACTER S1CHAN: .BYTE 1 ;SERIAL 1 CHANNEL NUMBER S1AD TRUE BIT RXCHA EQU 0 ;RECIEVE CHARACTER AVAILABLE ; RSTEXT EQU 10H ;RESET EXTERNAL STATUS TO SIO RSTTX EQU 28H ;RESETTԕe%D45(@?INIT?ӒU% Rp pZ9jD8h~GQ3@ EvMSU(0DLYTICdDT 1 HIGH 4 BITS) ; SSCTL EQU 1FH ;SUPER SLAVE LOCAL COMMAND STATUS PORT ; CTS EQU 3 ;CLEAR TO SEND STATUS BIT CTST EQU 7cond yet jr C,notsec ;skip reset if not ld (HL),0 ;else reset tick counter call rtcsec## ;and signal 1 second has pass;O/S SYMBOLIC EQUIVALENCES ; IVEC0 EQU 40H ;INTERRUPT VECTOR ADDRESS PORTS 0 & 1 IVEC1 EQU 20H ;INTERRUPT VECTOR ADDRESS '  TX INT PENDING ; ; DSEG ; S0ADDR: DW 0 ;SERIAL CHAN 0 DATA AREA ADDRESS S1ADDR: DW 0 ;SERIAL CHAN 1 DATA AREA ADDRES0: DB 0,0 DB 18H ;RESET CHANNEL DB 1 ;WRITE REG 1 DB 4 ;SET STATUS AFFECTS VECTOR DB 2 ;WRITE REG 2 DB IVEC0 0 LD (IVEC0+0AH),HL ;CHANNEL 0 EXT STATUS INT. LD HL,EXTCH3 LD (IVEC1+02H),HL ;CHANNEL 3 EXT STATUS INT. LD HL,EXTCH2  OTHERWISE RETURN SBDCH0: LD (S0ADDR),IX ;SAVE DATA AREA ADDRESS LD A,C ;GET NEW BAUD RATE AND 0FH ;SAVE ONLY BAUDIN1L ; LENGTH OF INIT BLOCK LD HL,SIOIN1 ; AND ADDRESS OF BLOCK OTIR ; SEND IT LD C,SIO3C ;DO IT AGAIN FOR OTHER CH VECTOR, Tx INT, EXT INT DB 3 ;WRITE REG 3 DB 0C1H ;Rx 8 BITS, Rx ENABLE DB 4 ;WRITE REG 4 DB 4CH ;16x CLOCK, 2 S S2ADDR: DW 0 ;SERIAL CHAN 2 DATA AREA ADDRESS S3ADDR: DW 0 ;SERIAL CHAN 3 DATA AREA ADDRESS BDRT: DB 0 ;BAUD RATE STO ;INTERRUPT VECTOR DB 0 ;MAKE SURE LEAVE ON REG 0 SIOIN0L EQU $-SIOIN0 ;LENGTH OF INITIALIZATION TABLE ; SIOIN1: DB 0, LD (IVEC1+0AH),HL ;CHANNEL 2 EXT STATUS INT. LD HL,RCVCH1 LD (IVEC0+04H),HL ;CHANNEL 1 RECV INT. LD (IVEC0+06H),HL L RATE LD C,A ;PUT IT BACK LD A,(BDRT) ;GET PRESENT BAUD RATE AND 0F0H ;SAVE CHANNEL B OR C ;PUT IN NEW BAUD RATE ANNEL LD B,SIOIN1L LD HL,SIOIN1 OTIR LD HL,TBECH1 ;SAVE ADDRESSES OF INTERRUPT ROUTINES LD (IVEC0+00H),HL ;CHANNELSTOP BITS DB 5 ;WRITE REG 5 DB 0EAH ;DTR, Tx 8 BITS, Tx ENABLE, RTS DB 0 ;MAKE SURE LEFT ON REG 0 SIOTBLL EQU $-SRAGE LOC ; ; ;INITIALIZATION CODE FOR SERIAL CHANNELS PUT INTO COMMON AREA ?INIT? ; COMMON /?INIT?/ ; SERIN@:: LD C,SI0 DB 18H ;RESET CHANNEL DB 1 ;WRITE REG 1 DB 4 ;SET STATUS AFFECTS VECTOR DB 2 ;WRITE REG 2 DB IVEC1 ;INTERRD HL,RCVCH0 LD (IVEC0+0CH),HL ;CHANNEL 0 RECV INT. LD (IVEC0+0EH),HL LD HL,RCVCH3 LD (IVEC1+04H),HL ;CHANNEL 3 RECV INFOR A LD C,SIO0C ;GET CONTROL PORT ADDRESS JR INTCH SBDCH2: LD (S2ADDR),IX ;SAVE DATA AREA ADDRESS LD C,SIO2C ;G 1 TBE INT. LD HL,TBECH0 LD (IVEC0+08H),HL ;CHANNEL 0 TBE INT. LD HL,TBECH3 LD (IVEC1+00H),HL ;CHANNEL 3 TBE INT. LDIOTBL ;SIO INIT TABLE LENGTH ; ;SET BAUD RATE ; SBDRTE: LD A,D ;GET CHANNEL NO. AND 0FH ;ONLY LEAST BITS JR Z,SBDO0C ;LOAD CHANNEL TO INIT LD B,SIOIN0L ; LENGTH OF INIT BLOCK LD HL,SIOIN0 ; AND ADDRESS OF BLOCK OTIR ; SEND IT UPT VECTOR DB 0 ;MAKE SURE LEAVE ON REG 0 SIOIN1L EQU $-SIOIN1 ;LENGTH OF INITIALIZATION TABLE ; ; CSEG ; ; SIO INT. LD (IVEC1+06H),HL LD HL,RCVCH2 LD (IVEC1+0CH),HL ;CHANNEL 2 RECV INT. LD (IVEC1+0EH),HL RET ;ALL DONE ; SIOINET CONTROL PORT ADDRESS JR INITCH SBDCH3: LD (S3ADDR),IX ;SAVE DATA AREA ADDRESS LD C,SIO3C ;GET CONTROL PORT ADDRES HL,TBECH2 LD (IVEC1+08H),HL ;CHANNEL 2 TBE INT. LD HL,EXTCH1 LD (IVEC0+02H),HL ;CHANNEL 1 EXT STATUS INT. LD HL,EXTCHCH0 ;CHANNEL 0 DEC A JR Z,SBDCH1 ;CHANNEL 1 DEC A JR Z,SBDCH2 ;CHANNEL 2 DEC A JR Z,SBDCH3 ;CHANNEL 3 RET ;LD C,SIO1C ;DO IT AGAIN FOR OTHER CHANNEL LD B,SIOIN0L LD HL,SIOIN0 OTIR LD C,SIO2C ;LOAD CHANNEL TO INIT LD B,SIOITIALIZATION TABLE ; SIOTBL: DB 0,0 DB 18H ;RESET CHANNEL DB 1 ;WRITE REG 1 DB 1FH ;INT ON ALL Rx, STATUS AFFECT( S JR INITCH SBDCH1: LD (S1ADDR),IX ;SAVE DATA AREA ADDRESS LD A,C ;GET NEW BAUD RATE SLA A ;PUT BAUD RATE INTO HIT INTO BIT 7 MDMSTS: LD D,RSTEXT ;RESET EXTERNAL STATUS OUT (C),D IN D,(C) ;GET EXTERNAL STATUS LD B,0 ;CLEAR W,SIO0C ;GET CHANNEL 0 CONTROL PORT LD A,(SSCTL) ;GET DSR BITS JR MDMSTS ;GO DO IT RMDMCH2: LD C,SIO2C ;GET CHANNEL 3 OUTCH3: DI ;SAME FOR CHANNEL 3 CALL OUT3 EI RET ; ;CHANNEL 0 I/O ROUTINES ; ; RECIEVE CHAR INT ROUTINE ; RC Z,SBDRTE ; = 3 SET BAUD RATE DEC A DEC A JR Z,SMDMCTL ; = 5 SET MODEM CONTROLS DEC A JR Z,RMDMSTS ; = 6 READ MODEM A,D ;GET CHANNEL NO AND 0FH ;ONLY LEAST BITS JR Z,OUTCH0 ;CHANNEL 0 DEC A JR Z,OUTCH1 ;CHANNEL 1 DEC A JR Z,OIGH BITS SLA A SLA A SLA A LD C,A ;SAVE IT AGAIN LD A,(BDRT) ;GET PRESENT BAUD RATE AND 0FH ;SAVE CHANNEL A OORD TO BE RETURNED BIT CTS,D ;TEST CLEAR TO SEND JR Z,MDMS0 ;SKIP IF NOT TRUE SET CTST,B MDMS0: BIT DSR,A ;TEST DATEL 2 CONTROL PORT LD A,(SSCTL) ;GET DSR BITS RLCA ;PUT PROPER BIT INTO BIT 7 RLCA JR MDMSTS ;GO DO IT RMDMCH3: VCH0: LD (INTSP##),SP ;SAVE USER STACK LD SP,INTSTK## PUSH AF ;SAVE REGISTER IN A,(SIO0C) ;FIND OUT IF CHAR AVAIL  STATUS RET ; ;SET MODEM CONTROLS ; SMDMCTL: RET ;WE DON'T SET MODEM CONTROLS ; ;RETURN MODEM STATUS ; RMDMSTS: UTCH2 ;CHANNEL 2 DEC A JR Z,OUTCH3 ;CHANNEL 3 RET ;OUTPUT TO CHANNEL 0 OUTCH0: DI ;TURN OFF INTERRUPTS CALL OUTR C ;PUT IN NEW BAUD RATE FOR B LD C,SIO1C ;GET CONTROL PORT ADDRESS INTCH: LD (BDRT),A ;SAVE NEW BAUD RATE OUT (BDRA SET READY JR Z,MDMS1 SET DSRT,B MDMS1: BIT DCD,D ;TEST DATA CARRIER DETECT JR Z,MDMS2 SET DCDT,B MDMS2: BIT RI,D  LD C,SIO3C ;GET CHANNEL 3 CONTROL PORT LD A,(SSCTL) ;GET DSR BITS RLCA ;PUT PROPER BIT INTO BIT 7 RLCA RLCA JRBIT RXCHA,A IN A,(SIO0D) ;GET INPUT CHAR JR Z,RCV2 ;EXIT IF NOT HERE BECAUSE RECIEVE CHAR AVAIL. PUSH DE ;SAVE MORE R LD A,D ;GET CHANNEL NUMBER AND 0FH ;ONLY LEAST BITS JR Z,RMDMCH0 ;CHANNEL 0 DEC A JR Z,RMDMCH1 ;CHANNEL 1 DEC A0 ;PROCESS IT EI ;ALL DONE SO TURN INTS. ON RET ; AND RETURN ;OUTPUT TO CHANNEL 1 OUTCH1: DI ;SAME FOR CHANNEATE),A ;SEND NEW BAUD RATE INITCH: LD B,SIOTBLL ;GET LENGTH OF INIT TABLE LD HL,SIOTBL ;GET ADDRESS OF INIT TABLE OT ;TEST RING INDICATOR JR Z,MDMS3 SET RIT,B MDMS3: BIT TXMT,D ;TEST TX BUFFER EMPTY JR Z,MDMS4 SET TXMTT,B MDMS4: LD  MDMSTS ;GO DO IT RMDMCH1: LD C,SIO1C ;GET CHANNEL 1 CONTROL PORT LD A,(SSCTL) ;GET DSR BITS RLCA ;PUT PROPER BEGISTERS LD DE,(S0ADDR) ;GET CH0 DATA AREA ADDRESS RCV0: PUSH BC ;GO PROCESS IT PUSH HL CALL SERISI## RCV1: POP HL  JR Z,RMDMCH2 ;CHANNEL 2 DEC A JR Z,RMDMCH3 ;CHANNEL 3 XOR A ;NOT GOOD CHANNEL RET ; RETURN ; RMDMCH0: LD CL 1 CALL OUT1 EI RET ;OUTPUT TO CHANNEL 2 OUTCH2: DI ;SAME FOR CHANNEL 2 CALL OUT2 EI RET ;OUTPUT TO CHANNIR ;SEND IT RET ;ALL DONE ; ; SERIAL DRIVER ; SERDR@:: DEC A DEC A JR Z,OUTCHR ; = 2 OUTPUT CHAR DEC A JRA,B ;PUT RESULT IN A AND 0F0H ;SAVE ONLY MODEM STATUS BITS RET ;ALL DONE NOW ; ;OUTPUT CHAR IN (C) ; OUTCHR: LD) ;RETURN REGISTERS POP BC POP DE RCV2: POP AF LD SP,(INTSP##) ;RETURN STACK POINTER EI ;AND RETURN RETI ; ; EXTEP,INTSTK## PUSH AF ;SAVE REG IN A,(SIO2C) ;GET STATUS BIT RXCHA,A ;RECIEVED CHAR AVAIL. IN A,(SIO2D) ;GET INPUT DAING TBECH1: LD (INTSP##),SP ;SAVE USERS STACK LD SP,INTSTK## PUSH AF ;SAVE REG LD A,RSTTX ;RESET TX INT PENDING D (INTSP##),SP ;SAVE USER STACK LD SP,INTSTK## PUSH AF ;SAVE REG JR EXTTBE3 ;FINISH PROCESSING TBECH3: LD (INTSPRISO## ;GO PROCESS REQUEST ; ;CHANNEL 1 I/O ROUTINES ; ; RECIEVE CHAR INT ROUTINE ; RCVCH1: LD (INTSP##),SP ;SAVE USER;GET SIO STATUS LD C,SIO2D ;GET DATA PORT ADDRESS LD DE,(S2ADDR) ;GET DATA AREA ADDRESS JP SERISO## ;GO PROCESS REQUESRNAL STATUS INT ROUTINE ; EXTCH0: LD (INTSP##),SP ;SAVE USER STACK LD SP,INTSTK## PUSH AF ;SAVE REG JR EXTTBE0 ;FTA JP Z,RCV2 ; IF NOT LEAVE PUSH DE ;SAVE MORE REG LD DE,(S2ADDR) ;GET DATA AREA ADRESS JP RCV0 ;GO PROCESS IT ; OUT (SIO1C),A EXTTBE1: PUSH DE ;SAVE REGS PUSH BC PUSH HL LD HL,RCV1 ;SET UP RETURN ADDRESS PUSH HL OUT1: CA##),SP ;SAVE USERS STACK LD SP,INTSTK## PUSH AF ;SAVE REG LD A,RSTTX ;RESET TX INT PENDING OUT (SIO3C),A EXTTBE3 STACK LD SP,INTSTK## PUSH AF ;SAVE REG IN A,(SIO1C) ;GET STATUS BIT RXCHA,A ;RECIEVED CHAR AVAIL. IN A,(SIO1D) T ; ;CHANNEL 3 I/O ROUTINES ; ; RECIEVE CHAR INT ROUTINE ; RCVCH3: LD (INTSP##),SP ;SAVE USER STACK LD SP,INTSTK## INISH PROCESSING TBECH0: LD (INTSP##),SP ;SAVE USERS STACK LD SP,INTSTK## PUSH AF ;SAVE REG LD A,RSTTX ;RESET TX EXTCH2: LD (INTSP##),SP ;SAVE USER STACK LD SP,INTSTK## PUSH AF ;SAVE REG JR EXTTBE2 ;FINISH PROCESSING TBECH2LL RMDMCH1 ;GET SIO STATUS LD C,SIO1D ;GET DATA PORT ADDRESS LD DE,(S1ADDR) ;GET DATA AREA ADDRESS JP SERISO## ;GO P: PUSH DE ;SAVE REGS PUSH BC PUSH HL LD HL,RCV1 ;SET UP RETURN ADDRESS PUSH HL OUT3: CALL RMDMCH3 ;GET SIO STAT;GET INPUT DATA JR Z,RCV2 ; IF NOT LEAVE PUSH DE ;SAVE MORE REG LD DE,(S1ADDR) ;GET DATA AREA ADRESS JR RCV0 ;GO PUSH AF ;SAVE REG IN A,(SIO3C) ;GET STATUS BIT RXCHA,A ;RECIEVED CHAR AVAIL. IN A,(SIO3D) ;GET INPUT DATA JP Z,RCV INT PENDING OUT (SIO0C),A EXTTBE0: PUSH DE ;SAVE REGS PUSH BC PUSH HL LD HL,RCV1 ;SET UP RETURN ADDRESS PUSH: LD (INTSP##),SP ;SAVE USERS STACK LD SP,INTSTK## PUSH AF ;SAVE REG LD A,RSTTX ;RESET TX INT PENDING OUT (SIO2C)ROCESS REQUEST ; ;CHANNEL 2 I/O ROUTINES ; ; RECIEVE CHAR INT ROUTINE ; RCVCH2: LD (INTSP##),SP ;SAVE USER STACK LD SUS LD C,SIO3D ;GET DATA PORT ADDRESS LD DE,(S3ADDR) ;GET DATA AREA ADDRESS JP SERISO## ;GO PROCESS REQUEST ; END PROCESS IT ; EXTCH1: LD (INTSP##),SP ;SAVE USER STACK LD SP,INTSTK## PUSH AF ;SAVE REG JR EXTTBE1 ;FINISH PROCESS2 ; IF NOT LEAVE PUSH DE ;SAVE MORE REG LD DE,(S3ADDR) ;GET DATA AREA ADRESS JP RCV0 ;GO PROCESS IT ; EXTCH3: L HL OUT0: CALL RMDMCH0 ;GET SIO STATUS LD C,SIO0D ;GET DATA PORT ADDRESS LD DE,(S0ADDR) ;GET DATA AREA ADDRESS JP SE,A EXTTBE2: PUSH DE ;SAVE REGS PUSH BC PUSH HL LD HL,RCV1 ;SET UP RETURN ADDRESS PUSH HL OUT2: CALL RMDMCH2 * TS %9%PSERIN@T% P0)p?INIT? `@;V`! ՘8|fYk !"!ChDBEQUESTED SECTOR MOV H,PDRSEC+1(X) SHLD CSEC ;SET CURRENT SECTOR MOV L,PDRSC(X) ;GET SECTOR COUNT MOV H,PDRSC+1(X) SHL0AH,'Advanced Digital Corp. Super Slave up.$' end L MOV A,E ;GET UNTRANSLATED SECTOR IN A-REG JRZ ..NX ;NO TRANSLATION, CONTINUE DAD D ;ELSE, TRANSLATE MOV A,M ..NX: INR4;KxO@]:1/V5GmT8-@vCil |(iZW(Y v Nvci^{,2p U[ : 90zLC TRANSLATION TABLE ADDRESS MOV E,M ;GET TRANSLATION TABLE ADDRESS INX H MOV D,M SDED CXLTBL ; LBCD SECCNT ;SET BC T@ "6`D*i"&D!"!`D.2@ %`@+zsR=%"D SECCNT ;SET SECTOR COUNT MOV L,PDRDMA(X) ;GET REQUESTED DMA MOV H,PDRDMA+1(X) SHLD CDMA ;SET CURRENT DMA XRA A STA PUT DATA BYTE INX D ;INCREMENT DMA ADDRESS INP A ;WAIT FOR DRQ OR INTRQ JM ..WL ;LOOP IF DRQ FOUND ..WX: IN DSTAT ;GET 17 A ;MAKE BASE 1 OUT SECTP ;OUTPUT TO 1797 SECTOR REGISTER RET ;DONE ; RWCOM2: LXI H,RWERR ;GET READ/WRITE ERROR ACCUMULATӝPXQ rl8-`ԔE5HINTSTKe4U$E$SERIN@4U$4SERISOcQ^cVF5l>4mV+CB\O SECTOR COUNT LDED CSEC ;SET DE TO FIRST SECTOR NUMBER ; ..FMT: EXX ;SWAP TO ALTERNATE REGISTERS MVI B,08CH ;SET INITIAL0<:g ,mYbvX'eA1i v#=)G@z(2Y'0 A|RWERR ;CLEAR READ/WRITE ERROR CALL SELDSK ;SELECT DISK JNZ FATAL ;IF DRIVE NOT READY, CONTINUE CALL SEEK ;ELSE, SEEK TO RE97 STATUS EI ;ENABLE INTERRUPTS AGAIN EXX ;SWAP BACK TO NORMAL REGISTERS ; ANI 0E5H ;MASK ERROR BITS LXI H,RWERR ;TESSYSTEM,SECRET,0P, ONE,WON,1, TWO,TOO,2, H ;GET WRITE TRACK COMMAND MVI H,03H ;MOVE STATUS MASK TO H DI ;DISABLE INTERRUPTS OUT DCOM ;SEND COMMAND TO FDC XTHL  HEAD LOAD FLAG ;(READ+HEAD LOAD) MVI C,FDWAIT;SET WAIT/SYNC I/O PORT LDED CDMA ;SET CURRENT DMA ADDRESS EXX ;SWAP BAx>08:`( Р|2-- LC,(2 `IhPl6/6ms}^ljdٷvmYdvP jTԔ`eU5%4@Ԥ qd &sIl#S: !La;DSIʪjJi鳀T FOR ERROR ORA M RZ ;IF NOT, DONE CALL TRYAGN ;ELSE, TRY AGAIN JMPR ..AGN ;CONTINUE ; SETUP: MOV L,PDRSEC(X) ;GET RCOUNT MOV A,B ORA C ;SECTOR COUNT=0? RET ;DONE ; TRYAGN: LXI H,TRYCNT ;GET TRY COUNT MOV A,M ;GET CURRENT COUNT DC title TurboDOS operating system - super slave sign on message ; name ('usrsom') ;module id ; dseg ; USRSOM:: DB 0DH,CK TO REGULAR REGISTERS ; RET ;DONE ; RWCOM1: LHLD CXLTBL ;GET CURRENT XLATE TABLE MOV A,H ;TRANSLATION REQUIRED? ORA Kxf E=0۴9zӝѰPXQ rl8-9 %zl;l(_]X;NucQ^cVF5l>4mV+CB\ ; MOV L,PDRDST(X) ;GET PD REQUEST DST ADDRESS MOV H,PDRDST+1(X) LXI D,XLTBL ;GET OFFSET TO TRANSLATION TABLE DAD D ;CA+ R M ;DECREMENT TRY COUNT JZ FATAL ;IF EXHAUSTED, CONTINUE INR A ;ALLOW FIRST TWO FOR FREE CPI RETRYS JP ..NOB ;SKIP BELL[ RES TSL,M ;CLEAR TWO-SIDED DISK FLAG ; MOV A,M ;GET CURRENT LATCH VALUE SET SSL,A ;SELECT SIDE TWO OUT DCONT ; PUSK CP 0DH ;WAS IT CR JR NZ,START ;IF NOT START OVER RET ;ELSE EXIT ; WTMSG: DB 0DH,0AH,'Enter RETURN to Continue ' D00) CALL SERIAL## ;AND DO IT POP BC ;RESTORE CHANNEL NUMBER/CHARACTER POP DE ;RESTORE FUNCTION NUMBER ..CDRV: JP S HERE. LDA STEPR% ;FORM STEP COMMAND ORI 058H OUT DCOM ;STEP IN ONE TRACK CALL WTSEEK ;WAIT FOR COMPLETION JMPR ..RTK  JP ..XH ;YES, EXIT TO ERROR PROCESS DJNZ ..LH ;CONTINUE UNTIL 4TH BYTE IS IN C ..LC: IN DDATA ;INPUT NEXT DATA BYTE IN FD IF FIRST TWO TIMES MVI C,ABEL ;ELSE, GET ASCII BELL CALL CONOUT# ;SOUND BELL ..NOB: LDA TRYCNT ;FORCE RECAL EVERY FOURTH RB '$' CRLFMSG: DB 0DH,0AH,'$' END ERIAL## ;CONTINUE ; END  .z80 ORG 0100H OPSYS EQU 05H START: LD DE,WTMSG ;GET ADDRESS OF WAIT MESSAGE LD C,9 ;AND MESSAGE OUTPUT FUNCTION CALL WAIT ;SYNC ORA A ;INTRQ? JP ..XH ;YES JMPR ..LC ;CONTINUE ..XH: IN DSTAT ;GET 1797 STATUS EI ;ENABLE INTERRUPTS AGAIN ETRY ANI 03H RET ;DONE ; RETDST: CALL RETRDY ;GET READY STATUS ORA A ;DRIVE READY? JZ ..NRX ;IF DRIVE NOT READY, CONTIT ;SYNC ORA A ;INTRQ? JP ..HX ;YES JMPR ..CRCL ;CONTINUE ..HX: IN DSTAT ;GET 1797 STATUS EI ;ENABLE INTERRUPTS AGAIN DAD D ;CALCULATE TYPE-CODE ADDRESS MOV A,C ;GET SECLEN CMP M ;DOES TYPE-CODE MATCH SECLEN? XCHG ;DST ADDRESS TO HL JRZ OPSYS ; NOW SEND IT WTLOOP: LD C,6 ;WAIT FOR INPUT LD E,0FFH CALL OPSYS OR A ;DID WE GET INPUT JR Z,WTLOOP ;IF NOT G POP B ;RESTORE SECTOR SIZE IN C ANI 9DH ;MASK ERROR BITS MOV B,A ;SAVE RESULTING STATUS ; MOV A,M ;SELECT BACK TO SIDE INUE MVI A,RETRYS;SET RETRY COUNTER STA TRYCNT IN TRACK ;GET 1797 TRACK REGISTER INR A ;UNDEFINED? ; ..AGN: CZ RECAL ;! (=  Enter RETURN to Continue $ $ ANI 9DH ;MASK ERROR BITS JRNZ ..ERR ;IF ERROR, CHECK OTHER DENSITY LHLD CLADDR ;POINT TO CURRENT LATCH ; .IFE DBLSID , ..TFX ;YES, TYPE FOUND MOV E,M ;THREAD TO NEXT DST INX H MOV D,M MOV A,D ;END OF CHAIN? ORA E JRNZ ..TLU ;IF NOT, COO BACK AND WAIT SOMEMORE PUSH AF ;ELSE SAVE CHAR LD DE,CRLFMSG ;AND SEND CRLF LD C,9 CALL OPSYS POP AF ;GET CHAR BACZERO OUT DCONT MOV A,B ;GET BACK THE STATUS ORA A ;IS THE DRIVE READY? ; JRNZ ..OSD ;JUMP IF ONE-SIDED SET TSD,C ;TWOIF SO, RE-CALIBRATE DRIVE ..RTK: IN TRACK ;WHAT TRACK ARE WE ON? CPI 2 ;IS IT AT LEAST TRACK 2? JRNC ..RAD ;YES,OK TO DO ITMP IF NEITHER BUSY OR DRQ, MUST BE INTRQ MOV C,A ;TEMPORARY SAVE OF DATA BYTE IN FDWAIT ;WAIT FOR NEXT BYTE ORA A ;INTRQ? , NTINUE ..NRX: XRA A ;RETURN NOT-READY STATUS MOV PDRDST(X),A MOV PDRDST+1(X),A RET ;DONE ; ..ERR: LXI H,TRYCNT;DECREMENE MOV A,B ;ELSE, GET REQUESTED TRACK OUT DDATA ;OUTPUT TO 1797 DATA REGISTER LDA STEPR% ;FORM SEEK COMMAND ORA C OUT  TSL,M ;TWO-SIDED DISK? JRZ ..OSD ;NO, JUMP SRLR B ;YES, DIVIDE TRACK BY TWO JRC ..TSD ;JUMP IF SIDE ONE ;] JMPR ..OSD  MOV B,A ;SAVE DRIVE NUMBER LDA FDCDRV ;GET LAST DRIVE USED CMP B ;ARE THEY THE SAME? JRZ ..TST ;YES, NO NEED TO UNLOAD HPUSH DE ;SAVE FUNCTION NUMBER LD E,B ;CHANNEL NUMBER TO DE-REG LD D,0 ;DOUBLE LENGTH ADD HL,DE ;INDEX INTO TABLE L# ;SIGNAL PROCESS AS READY ; WTSEEK: LXI D,FDPOLL ;GET POLL ROUTINE ADDRESS CALL LNKPOL# ;CREATE POLL ROUTINUE CALL FDPRNT ERROR COUNTER DCR M JRZ ..NRX ;EXIT IF NOT READY LHLD CLADDR ;POINT TO LATCH CODE MOV A,M ;GET CURRENT VALUE XRI 1<DCOM ;SEEK WITH OR WITHOUT VERIFY CALL WTSEEK ;WAIT FOR SEEK COMPLETION IN DSTAT ;GET SEEK RETURN STATUS ANI 91H ;CHECK FO;MUST BE SIDE ZERO ; ..FMT: MVI C,010H+HLAB ;NO VERIFY ON FORMATS ; .IFE DBLSID , [ BIT 7,PDRSEC+1(X) ;TEST FOR SIDE TWEAD. ; CALL GETSTS ;GET CURRENT DRIVE STATUS ANI 0A0H ;READY AND HEAD LOADED? CPI 020H JRNZ ..TST ;NO, NO NEED TO UNLOA POP DE ;RESTORE FUNCTION NUMBER RET ;DONE ; END  ;EXECUTE POLL ROUTINE LXI H,FDSPH ;GET SEMAPHORE JMP WAIT# ;DISPATCH IF NECESSARY ; GETSTS: MVI A,0D0H ;FORCE STATUS UPDADDL ;TOGGLE TO OTHER DENSITY MOV M,A OUT DCONT ;TELL CONTROLLER XRA A ;FORCE RECALIBRATE JMP ..AGN ;TRY AGAIN ; ..TFX:R ERRORS RZ ;NO ERRORS, OKAY CALL TRYAGN ;ELSE, DECREMENT RETRY COUNT XRA A ;FORCE A RECAL AFTER SEEK ERROR JMPR ..SKL O JRZ ..OSD ;NOT SIDE TWO, GO TO COMMON CODE ; ..TSD: MOV A,M ;GET THE CURRENT LATCH VALUE SET SSL,A ;SET SIDE ONE (2ND SID. IN TRACK ;UNLOAD WITH A SEEK TO PRESENT TRACK OUT DDATA LDA STEPR% ;FORM SEEK COMMAND ORI 010H OUT DCOM ;TELL CONTRE-CALIBRATE DRIVE MOV B,PDRTRK(X) ;GET REQUESTED TRACK MVI C,014H+HLAB ;PRE-SET TO VALIDATE THE TRACK LHLD CLADDR ;POINTTE OUT DCOM XTHL ;WAIT FOR 1797 TO SETTLE XTHL XTHL XTHL IN DSTAT ;GET STATUS STA CSTAT ;SAVE CURRENT STATUS RE INX H ;INCREMENT PAST DST LINK WORD INX H ORI 0FFH ;RETURN READY & DST ADDRESS MOV PDRDST(X),L MOV PDRDST+1(X),H RET ;TRY AGAIN ; FDPOLL: .WORD 0 ;POLL ROUTINE .WORD 0 ; FDPR: IN DSTAT ;GET DRIVE STATUS ANI 1 ;1797 BUSY? RNZ ;IF SO, DDE) OUT DCONT ;TELL CONTROLLER ;] ..OSD: IN TRACK ;GET CURRENT TRACK CMP B ;ALREADY THERE? RZ ;IF REQUESTED=CURRENT, DOOLLER PUSH B ;SAVE NEW DRIVE NUMBER CALL WTSEEK ;WAIT FOR COMPLETION POP B ;RESTORE NEW DRIVE NUMBER ..TST: MOV L,B ;COMP TO CURRENT LATCH VALUE MOV A,PDRFCN(X) ;IS THIS A FORMAT FUNCTION? CPI 4 JRZ ..FMT ;YES, JUMP ; .IFE DBLSID , [ BITT ; SELDSK: MOV A,PDRDRV(X) ;GET REQ DRIVE CPI 4 ;COMPARE WITH MAX DRIVE NUMBER JNC ..NRDY ;IF INVALID, RETURN NOT READY CA: LD HL,CHRCNT ;GET CHARACTER COUNT TABLE JR INDEX ;CONTINUE ..GSCA: LD HL,SEQCNT ;GET SEQUENCE COUNT TABLE ; INDEX: ONE LXI H,FDPOLL ;ELSE, GET POLL ROUTINE ADDRESS CALL UNLINK# ;UNLINK POLL ROUTINE LXI H,FDSPH ;GET SEMAPHORE JMP SIGNA- UTE LATCH STORAGE LOCATION MVI H,0 LXI D,LATBL DAD D MOV A,M ;GET OLD LATCH VALUE CPI 0FFH ;IS IT UNDEFINED? JRNZ ..ECTOR, DOUBLE-DENSITY, TWO SIDED ; .WORD .+DSTL ;DISK SPEC TABLE LINK POINTER .BYTE 4 ;BLOCK SIZE .WORD (2*77*(8*(1<3)))/ IN TRACK ;GET 1797 TRACK REGISTER MOV M,A ;SAVE IN TRACK TABLE ..UND: MOV A,PDRDRV(X) ;GET REQ DRIVE STA FDCDRV ;UPDATE FPER DISK ; .WORD 0 ;RESERVED TRACKS ; .WORD 0 ;TRANSLATION TABLE ADDRESS ; .BYTE 3 ;DISK TYPE CODE ; .IFE DBLSID , [ ; ; VALUE OUT DCONT ;SELECT DENSITY LXI H,0 ;CLEAR TRANSLATE TABLE ADDRESS SHLD CXLTBL ; ..STS: CALL GETSTS ;GET DRIVE STATCTOR SIZE (2^N*128) .WORD 8 ;PHYSICAL SECTORS PER TRACK .WORD 77 ;PHYSICAL TRACKS PER DISK .WORD 1 ;RESERVED TRACKS .WOROLD ;NO, USE OLD VALUE MOV A,B ;GET NEW DRIVE NUMBER ..OLD: OUT DCONT ;SELECT DRIVE MOV M,A ;SAVE CURRENT LATCH VALUE SHL(1<4) ;NUMBER OF BLOCKS .BYTE 4 ;NUMBER OF DIRECTORY BLOCKS .BYTE 3 ;PHYSICAL SECTOR SIZE (2^N*128) .WORD 8 ;PHYSICAL SECTDC DRIVE MOV L,A MVI H,0 ;MAKE DOUBLE LENGTH DAD D ;CALCULATE TRACK TABLE ADDRESS MOV A,M ;GET TRACK OUT TRACK ;ELSE,  512 BYTE SECTOR, DOUBLE-DENSITY, TWO-SIDED (DELTA) ; ; .WORD .+DSTL ;DISK SPEC TABLE LINK POINTER ; .BYTE 5 ;BLOCK SIZE ; .US ANI 80H ;CHECK NOT-READY BIT JRZ ..RDY ;IS READY, JUMP CALL GETSTS ;NOT READY, GIVE IT ANOTHER CHANCE ANI 80H JRNZ D 0 ;TRANSLATION TABLE ADDRESS .BYTE 3!12S ˎ˞X ˆY ˖O >2mL >2mB >2H 2P >2K 2I C![ʖ ==!jʖ !Ö > Á>Á*}D!&!-%!\!: !ʖ : !+!.!1e#8{& #~{&~{&#~{&ͮ#{& !͔*ì'~{&͆#0Wx{&z~{&#͆#0Wx{&z{&~{&#ͮ##W8 ~{&#z{&x{&Disk FullCommand Syntax ErrorSource File Not Found Close Error04/28/80 10:25:09Page  & ????? Unexpected End of Input File*'R0 "'*4#"4!q~ (\(=\ )K x :m=(:^ 6#N#^#VG͝ Ý= 'x ͔*#y #{ #z(^ :m:(!"D!ͮ%:m(): :O!i !o 2P):m(Q: K:W!o 28HEXREL:l(22 !m{&#{&~{&#~2(! +++++ Symbol Table +++++ Errors Were Detected *****W ?Cb|58}Ie[I@ҳ?`aiaeb3HUMt">=&&)"'*4#"4͙"x: 8# w# w# wæ x ! %R8 8O:*((6(N (?((2.7 *~#"!5 &6Sl\h= 2F[*~#"(>Á0 ?w#^U%R(+Nͦ% 1.R(+ :&( x8 # q8 *.| *0|("#ì'~#^\ ͝ ͔*q#s#r!q~ (>!0>LI&!Q >(:(=Q tښ g w( ~6͙"wgʞ W ex: 3v n R8# #:2*"4=(:(G͊ :m:W:(G$͊ 6:2:2*"l:2e!!!$"D~(b8 #~+87>(0) 8"(#= { z(##~= ~# ^#V+ <(l:$*q#"!5 6Sq!F>āNV(!*q#"!5 6Sql!5<#!D/^#Vg:B:&{&>OI&e#7!8 #8W8Wv&z{&W&Wv&x{&z{&k"'e#8 {& !#"' $ PSA Macro Assembler [C12011-0102 ]- C. 1980 by Phoenix Software Associates Ltd.Directory FullFile Extension Error  # (^ :m= -& &0 "'*4#"47&x &"&x= ~ Q\ʸ =| ͔*#q#s#r0#1 k!ͮ $##~#!6#(o" $`!-N$!-N$!$~w:0 6Z!V>͑Ä:$Z!:( k!h!h!h# 0 x++~'(#w#*+~"6#"' (x G+*"+"~6[=*0"'Rs#r#p!&6Ý00,(&8 ( (0))~*R8#8 w#"&"( +~ ( (R8*8$(#(0K9*;^#VBp+qO~7#~###80##~= v n(#yȾ+~#y N#F+ ͔ 2( 2!"D>2!7#ʹ~2J8,(#2!8#27ʹʹ2!6:7> R%%O>!&ͩ x{&y{&|{&}{&!!#2 d&7!#2!d&:).&>!&!,4ͩ C;"9!-4*#6V#^S0& (͝!,5!-5 +"̝2&>!8!C"<+$!o"Z!:(Y":ʰ!%ðͱzV#^#(---W 8 OC'% 5.շ[*"R8#"6#"W*&z>!&ͩ 6 !DM>!&!&tܙ"f2&^>&v n("&! v [+S+o( n ) ( ( )&>!&!x8:m= ^&7͝"#"=*"[]>!0&%ͩ 8r+s+p+%~#G >2!%ͮ  ̦! !~ >2-.&͝ [ ͝:mjO!&:‰yj:>!&~ͩ z0"2&*0|(f *2| *.|2&7!8Y>!8Tͩ z8:m=( ^ &͟"w#++F+N#ͩ > !<x +y +z +{ !-5"> !,52"ô ͋*DM) *"#V#^#T])R*##R*&+q+p+"":)"$* X`E@I UM![ ͋͝*]&ԝ#z("'!͔*ͬ'!&͋*().&(*/.&"97[-S-w!>!&ͩ !p#q#r#s~2B~2H~2I~2G:Fj!!\w#!] 6 #:wQ!G8: x@8x0tw8nq+% x>8E,(](B( 9͝) ͝x(  )  ͝8*+͝&= >[ 00 *=‰:j:j8uN!n T]:%G: (w# (y2%2&:)y:'( *!p6 #!F6!~pɷj:j+6 ##* w"#"&R0^!^#V,͔*&R(Z(QL) )(B(<7![(ô #R0"[7͋͝*]7͝DM) :)7*"#~#ngB#*$!< 0[&ԝ͋*8 , ͋͝*[ (͝#aL"']&̝8!,(](R88o&L"'L.&"'(}o"'"'{&~ !n!#R88 8#p8TQ!.(#w͝8A. J!e8 Q!w#͝Sl\<[(>22Fô e!o>FF&ASM>*I&Ù:).^#V+"'͝] [  ; '͝; ͝ (]  /[ >;(>!8*>2+[ͩ !+6S;C996 y<2%X~(6k!!%FwO>2$2&͑Z!2$<2xwO:!)(: :' :j:(!:) ~ :'n+~6 (08[(" ͝[ ] Þ7![ !4͝ :m)~8ͩ >z*0|(f *.|*2 (~R]&ԝ07,(](>!8ͩ x###~( 2&7#oo[ !]x( 0x 0 } 7͝[ $7?] %7:8w#xP .&pʹ(*9">:82=*;"@͔*28"9&!9#";&(*>"9:=28*@";&> .|&}( ( (&2&*#~ *++"Ýw##V#^:["!"R S" ʹ["!R "S"2> {&>!&ͩ !p#q#r#s72 6+:F( !~ 6@k!nM: (-!F!$O Z! ~O8 h!>w͑yq Y" 8$4~0!%5 :)2>2%2&!n6 #= r#8Q!X(Y ͝:B:&> 7&G#.&.&͔*( 8:8 &&|<.&͔*&&|(<.&}*""? %((͢2(6 l"l"!o":"8͑!o"!m4~C"l"!$"D!~("!5"o"/"-$: =":!="!9"o":(!9"o"C"<+$!y=(7yL(7}=(|=(z&{&y6 (=6'( =6"(y6:# #6 L(*9#"9:m0!N~ '*9Deh"O:82Q:(4!R""."29+O!/8d8`*'~. 8/#~+8( #(qX~# ^#V+v n G~_!.s#rG~#N=>S7>P3>B/>A+>M$>E#>R>T>Q>U>X>Z >D>I2O!%^!n+~6?:0 !n_q<2!4 57W2'222$2 $=:)u*#~* F(@#  j:,> 0>]~2#V#^S#V#^"""|* :2)>Î+~ *w####F#&%[ $]%( .͝) -$%( ,\ G͔͝*&:OG=3>-S3= } ( <( ='%;>0%o"l":( !/"!9"o"!ni"!i"l"l"d!ͮPL- -  d|" |"|"!6:7=Z!0o"!~#N$=08K6>2MN4!R w: y()*K~w!M8 y85(5 6#6"K!N4:N:m>): :;[K!M~(5 _!A ###(++X^#V| 7~!"&tܙ"V"&v"&n !f(&#[)sS)*4#"4:(&!~6!'(4Ny 044!y z&z=(ͱ&8:7!n:%=O F2%>\> >\x&!q~ [9:8O(#V#^SG6##r#s(+~("æ~_ bDM 0[ [ UC !,4!-4>#55G S] )*##~8+͍82(l< R8 8%,(&;(" (] ,-(- $%( [ ,%͝[? ( (S? %](,($%($ y0 z($ɯ>>O["*{_z8N {8Gr#s#r#s#z{80_!Aw#w#*r+sq#w#w#w#w"#"6!N5!N~_~#%) %)!N6OW: y'H:  !"D:(>)!!ͮ%)>)+!~8B&v n("&*+#"+>>!OQ!! ##0)#8Gy(!T])))))X (y x(͝˯x *[A6:0//.&$'p#q#'G'OƐ'@'y }{&&!'NG( 0: 4N!y y(ͱ&07y2L(}=(:m82!NN!(*( (!*w":- :+!&>NF&> (*4"/Y"ðG!%~( 4_!npx ( .&͝ $%ĝ y0[~(%( 8#~(##~( %~(#>.%%[{'_z'WSZ%{Z%3%c%0%~(#%*&~#N#^#Vy#( >:B:&8+Q!X(Y( H y 8) ͝>]76&y&&}#Gx#.& > )%)%)ͮ: %):!%) > )%):*-@b)*)\ )#`)*+R#@OW!9|{ 8}_Wͩ xy!.&!-,( &, &78Q!.$%A[?a{_!64l"Z!!6:780Y":R *K7!My85(5 66"K!N4&!'NG( 0#: 4N!y y: (zS_(ͱ&0y(:8( : [!!F#N#(x8͝ ;͝] :!45(150#8[(:82/*9"/{! [ɯ>>!"0%[?RyDM*"S"O[s+r+[s+r+w+s+r+++ q++"S!%5!)~6 >>[շ[?*R0 S?W*&z&!3 {R>)_%)>*(H ~%)#F#~%)x%)# ௒%)##~#~###80$##~= ~@(W P ` ͮ###~# ^#W_vGO fW *mW KW ["W {&W "-W CW SW sW( (T]X('("(-8~(.&BD OQH. ,; (]^@>-+/*!&<)Q!.'"0:?AG?-UP T U U( v) K5*3!-x&&y( =&&:7O"7*:2=&!7 ((w&&͝',y/Ox/G{/oz/g#<28&-z,)<Vz[^YF YFQ@ J\Q@ BYFԀ YF z Y }m}V+͔*&&*7!:2827,>!8tͩ # ͝6 :& t8/ x0J*0|(!f(7^>&#(t:7(&&y27b*.| *W *ZW "[W "bcԀcup  ֚j@cdc2BCԀ OB9$  &6?LSblgHVyD_vvMvEzz@zzzz66-zg{o-zg{o*3*5x|( &&(DM-DMDM--BK-*5 DM*3*5yOxG*3{ozg-}/o|/g#,-zg{oίmԯ (8~ongN@uˀ ( ##^#VGOO:m=ę"2&!#æ*!808 :0~ ."(' "G!͝ ͝ .&eo',^ ~=O͝Q!-,~CïS[S[SVSVFF$,<Gz&:rzDKQ@W]pA6v6{ 6W6[0Wlý0 hTKT\TU-BK-x&&z/g{/o"3*1"5U,,,,---@-L-W-j--w--,,,!.F##7*5}&&*3!>=))0 >=)j    )      m8xQ@0wf,+(( :727 - #  e,@ !͝R8 8#[< !R88eo! .8+** I0&"HTGF+3HUc)PԀ@Ԁ  :Ԁ 2vTFIQ@/u+Z; C&{fS-XMXB0 O*0 ͝.8 w#"͝6(+~+"('(#y~h& A8G8-8N!A8G008"0Gy)(T]))(x Ԁ餛ZS U$ V U  SH Ui U_ & :)(*##n`͝&G&`h!.-N0>!8 ͩ x8#&"5"3}0*3*5͝æ*"1yH!- ^#VzYYC'T/iDT?7tvZx`zYFzZ4 Oa0l +XI!º"k"c"k"/#]$j@$l$ȉ$ȋ$Ȗ$ %%Y&Ș?&K'ȗ'y(Z(g):*н+@0+`Y;Y #C=i@--a,c.z.X/*/CH0&z0з142:{p3^{f46{f5678h9:1_1o15 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L