IMD 1.17: 25/11/2014 13:13:56 82VKXBVERDOS D* BT23:0 68K VERSADOS/RMS68K OBJECT 4.5 (DS,DD 96 tpi 5.1/4" DISK) REVISED: 04/22/86 DISK 23 OF 24  BT23 82VKXBVERDOS 0420²`-`Dh7p7x8€@ˆ<�>˜E 0¨8°6¸À<È:Ð]Ø4à7è:ð2øC86 *K***************************************************************************K***************************************************************************K***************************************************************************K***************************************************************************‰PAGE‰OPT�CRE,PCS,BRS**‰MISC�EQUATES*4DRIVESƒEQU‡12’Total�number�of�drives�on�our�channel. **ƒXREF'S�from�DISKLIB*ŠXREF…DISK_INITŠXREF…DISK_COMMANDŠXREF…CHAN_DONE **‚Equate�files�included:* *‰INCLUDE‚9995.&.TCB.EQ*‰INCLUDE‚9995.&.CCB.EQ*‰INCLUDE‚9995.&.LV5.EQ*‰INCLUDE‚9995.&.IOE.EQ*‰INCLUDE‚9995.&.NIO.EQ*‰INCLUDE‚9995.&.DISKCCB.EQ*‰INCLUDE‚9995.&.DISKMEM.EQ*‰INCLUDE‚9995.&.DISK.EQ*‰INCLUDE‚9995.&.UTILITY.MC*ŠNOLIST*$*‰Include�the�standard�equate�files:*‰INCLUDE‚9995.&.TCB.EQ‰INCLUDE‚9995.&.CCB.EQ‰INCLUDE‚9995.&.LV5.EQ‰INCLUDE‚9995.&.IOE.EQ‰INCLUDE‚9995.&.NIO.EQ‰INCLUDE‚9995.&.UTILITY.MC ‰TTL†DISK.EQ‰LIST‰INCLUDE‚9995.&.DISK.EQ‰TTL†DISKCCB.EQ‰INCLUDE‚9995.&.DISKCCB.EQ‰TTL†VM22DRV.SA‰PAGE/‰OFFSETƒDCCBDDP�Continue�with�channel-dependent*¦CCB�variable�space.  M*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* *%%%Å%%%*B*%%%„Device-dependent,�channel�related,�variables�start�here.‰%%%* *%%%Å%%%**%%%™(CCB�SPACE)¡%%%* *%%%Å%%%*M*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*  NN2SAVECAP‚DS.L…1–We�use�this�variable�for�saving�the'*¦Command�Address�Pointer�returned�from(*¦the�Trap�#1�call�for�memory�allocation)*¦during�initialization.�This�is�the�base"*¦address�from�which�the�CAP�for�a'*¦particular�command�will�be�determined*¦based�on�the�LUN.  M*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* *%%%Å%%%*>*%%%„End�of�device�dependent,�channel�related,�variables.�%%%* *%%%Å%%%**%%%•END�OF�CCB�SPACE %%%* *%%%Å%%%*M*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*  3CCBSIZEB�EQU†*–CCBSIZEB�defines�the�size�(in�bytes)(*¦of�a�complete�CCB�for�the�VM22�driver. %*¨CCBSIZE�defines�the�size�(in�pages)?L0080„EQU†CCBSIZEB+PAGESIZE-1‚of�a�CCB�for�the�VM22�driver,�andBCCBSIZE‚EQU†L0080/PAGESIZE‡EXTCCBSZ�defines�the�size�(in�pages)�of*ƒ15‚14‚13‚12ƒ11‚10ƒ9ƒ8„in�the�parameters�mask�are�not�used�byI*‚+---+---+---+---++---+---+---+---+‚the�VM22�driver,�but�all�of�the�bits8*‚|‹|ƒ||ƒ|ƒ|ƒ|ƒ|‚that�are�defined�for�any�disk�drive�are;*‚+---+---+---+---++---+---+---+---+‚shown�in�the�diagrams.*„^ƒ^ƒ^ƒ^„^ƒ^ƒ^ƒ^*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ|/*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ----�1�=�IOSSOF�is�significant.*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|1*„|ƒ|ƒ|ƒ|„|ƒ|ƒ--------�1�=�IOSPSM�is�significant. *„|ƒ|ƒ|ƒ|„|ƒ|3*„|ƒ|ƒ|ƒ|„|ƒ------------�1�=�IOSSHD�is�significant. *„|ƒ|ƒ|ƒ|„|6*„|ƒ|ƒ|ƒ|„----------------�1�=�IOSTRKD�is�significant. *„|ƒ|ƒ|ƒ|9*„|ƒ|ƒ|ƒ---------------------�1�=�IOSPCOM�is�significant.*„|ƒ|ƒ|D*„|ƒ|ƒ-------------------------�1�=�IOSSPTD�is�not�used�by�the�VM22.*„|ƒ|<*„|ƒ-----------------------------�1�=�IOSSRB�is�significant.*„|I*„---------------------------------�1�=�IOSRWCCB�is�not�used�by�the�VM22.* **„7ƒ6ƒ5ƒ4„3ƒ2ƒ1ƒ0$*‚+---+---+---+---++---+---+---+---+*‚|ƒ|ƒ|ƒ|ƒ||ƒ|ƒ|ƒ|ƒ|$*‚+---+---+---+---++---+---+---+---+*„^ƒ^ƒ^ƒ^„^ƒ^ƒ^ƒ^*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ|/*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ----�1�=�IOSREC�is�significant.*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|1*„|ƒ|ƒ|ƒ|„|ƒ|ƒ--------�1�=�IOSRSZ�is�significant. *„|ƒ|ƒ|ƒ|„|ƒ|<*„|ƒ|ƒ|ƒ|„|ƒ------------�1�=�IOSWTO�is�not�used�by�the�VM22. *„|ƒ|ƒ|ƒ|„|>*„|ƒ|ƒ|ƒ|„----------------�1�=�IOSRTO�is�not�used�by�the�VM22. *„|ƒ|ƒ|ƒ|8*„|ƒ|ƒ|ƒ---------------------�1�=�IOSSPT�is�significant.*„|ƒ|ƒ|:*„|ƒ|ƒ-------------------------�1�=�IOSHDS�is�significant.*„|ƒ|<*„|ƒ-----------------------------�1�=�IOSTRK�is�significant.*„|>*„---------------------------------�1�=�IOSILV�is�significant.‰PAGE*%*ˆATTRIBUTES�MASK�FOR�THE�VM22�DRIVER* **ƒ15‚14‚13‚12ƒ11‚10ƒ9ƒ8$*‚+---+---+---+---++---+---+---+---+*‚| |$*‚+---+---+---+---++---+---+---+---+*„^ƒ^ƒ^ƒ^„^ƒ^ƒ^ƒ^*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ|;*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ----�1�=�Post-read/pre-write�precomp�req'd.*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|=*„|ƒ|ƒ|ƒ|„|ƒ|ƒ--------�1�=�8�"�floppy�disk;�0�=�5-1/4�"�disk. *„|ƒ|ƒ|ƒ|„|ƒ|8*„|ƒ|ƒ|ƒ|„|ƒ------------�1�=�Alternate�Sector�Capability *„|ƒ|ƒ|ƒ|„|-*„---------------------------------…Not�used.* **„7ƒ6ƒ5ƒ4„3ƒ2ƒ1ƒ0$*‚+---+---+---+---++---+---+---+---+*‚|‹|ƒ||ƒ|ƒ|ƒ|ƒ|$*‚+---+---+---+---++---+---+---+---+*„^ƒ^ƒ^ƒ^„^ƒ^ƒ^ƒ^*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ|<*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|ƒ----�1�=�Double�data-density�(MFM)�on�media.*„|ƒ|ƒ|ƒ|„|ƒ|ƒ|9*„|ƒ|ƒ|ƒ|„|ƒ|ƒ--------�1�=�Double�track-density�on�media. *„|ƒ|ƒ|ƒ|„|ƒ|6*„|ƒ|ƒ|ƒ|„|ƒ------------�1�=�Double-sided�floppy�disk. *„|ƒ|ƒ|ƒ|„|?*„|ƒ|ƒ|ƒ|„----------------�1�=�IBM�format;�0�=�Motorola�format. *„|ƒ|ƒ|ƒ|>*„|ƒ|ƒ|ƒ---------------------�1�=�Rigid�disk;�0�=�floppy�disk.*„|ƒ|ƒ|G*„|ƒ|ƒ-------------------------�1�=�Double�data-density�(MFM)�on�drive.*„|ƒ|D*„|ƒ-----------------------------�1�=�Double�track-density�on�drive.*„|C*„---------------------------------�1�=�Seek�required�on�SMD�drive. PAGEC*‰The�following�section�defines�the�variables�that�are�contained�inE*‚the�VM22‚command�packet.‚Each‚individual‚command‚processing�routineK*‚builds�a�command�packet�in�global�memory�as�defined�by�the�command.�ThereH*‚are‚five‚interpretations�of�the�command�packet�for�the�eleven�commandsI*‚supported�by�the�VM22.‚The�format�of�each�command�packet�types�is�shown J*‚in�the�following�diagrams.‚Not�all�are�supported�by�the�VERSAdos�driver. SPC 2H*ˆThe�TYPE�0�command�packet�is�used�for�the�Read�Sectors,�Write�Sectors,*ˆand�Check�Sectors�commands.**�TYPE�0�PACKET*�BYTE�0¤BYTE�3;*‰+-------------+-------------+-------------+-------------+.*‡0�!‚COMMAND„!�COMMAND�OPT�!…LUN…!‚ADDR�MODƒ!;*‰+-------------+-------------+-------------+-------------+0*‡4�!‚INT�LEVEL‚!‚INT�VECTOR�!„RETRY„!ƒMISCTRLƒ!;*‰+-------------+-------------+-------------+-------------+&*‡8�!ŒSTARTING�LOGICAL�SECTOR�NUMBER�!;*‰+-------------+-------------+-------------+-------------+&*†12�!�NUMBER�OF�SECTORS�TO�TRANSFER�!;*‰+-------------+-------------+-------------+-------------+*†16�!•BUFFER�ADDRESS”!;*‰+-------------+-------------+-------------+-------------+'*†20�!ŒPOINTER�TO�NEXT�COMMAND�PACKET�!;*‰+-------------+-------------+-------------+-------------+**%*‰COMMAND�OPTIONS�=�|CRR|CWV|ƒ|ƒ|‡|‡|* SPC 2A*ˆThe�TYPE�1�command�packet�is�used�for�the�Recalibrate�and�Check4*ˆUnit�Status,�and�Return�Self-Test�Status�commands.**�TYPE�1�PACKET*�BYTE�0¤BYTE�3;*‰+-------------+-------------+-------------+-------------+*‡0�!‚COMMAND„!�!…LUN…!�!;*‰+-------------+-------------+-------------+-------------+"*‡4�!‚INT.�LEVEL�!�INT.�VECTOR�!›!;*‰+-------------+-------------+-------------+-------------+*‡8�!·!;*‰+-------------+-------------+-------------+-------------+*†12�!·!;*‰+-------------+-------------+-------------+-------------+*†16�!·!;*‰+-------------+-------------+-------------+-------------+'*†20�!ŒPOINTER�TO�NEXT�COMMAND�PACKET�!;*‰+-------------+-------------+-------------+-------------+* PAGED*ˆThe�TYPE�2�command�packet�is�used�for�the�Seek�Track,�Format-Unit,.*ˆFormat-Track,�and�Format-Track-Bad�commands.**�TYPE�2�PACKET*�BYTE�0¤BYTE�3;*‰+-------------+-------------+-------------+-------------+0*‡0�!‚COMMAND„!�COMMAND�OPT�!…LUN…!�*ADDR�MOD*‚!;*‰+-------------+-------------+-------------+-------------+2*‡4�!‚INT�LEVEL‚!‚INT�VECTOR�!ƒ*RETRY*ƒ!ƒMISCTRLƒ!;*‰+-------------+-------------+-------------+-------------+ *‡8�!�LOGICAL�SECTOR�NUMBER(1)�!;*‰+-------------+-------------+-------------+-------------+#*†12�!�ALTERNATE�SECTOR�NUMBER(2)Ž!;*‰+-------------+-------------+-------------+-------------+$*†16�!INTERLEAVE(3)!SPI�OFFSET(3)!›!;*‰+-------------+-------------+-------------+-------------+'*†20�!ŒPOINTER�TO�NEXT�COMMAND�PACKET�!;*‰+-------------+-------------+-------------+-------------+*-*‰COMMAND�OPTIONS�=�|ƒ|CWV|ƒ|CFMTBAD|ƒ|ƒ|ƒ|ƒ|**‰*�*�=�Ignored�by�this�command**‰(1)�=�Used�by�format-track�and�seek�only%*‰(2)�=�Used�by�format-track-bad�only(*‰(3)�=�Used�by�all�format�commands�only* SPC 2?*ˆThe�TYPE�3�commmand�packet�is�used�for�the�Configure�command.**�TYPE�3�PACKET*�BYTE�0¤BYTE�3;*‰+-------------+-------------+-------------+-------------+0*‡0�!‚COMMAND„!*COMMAND�OPT*!…LUN…!�*ADDR�MOD*‚!;*‰+-------------+-------------+-------------+-------------+4*‡4�!‚INT�LEVEL‚!‚INT�VECTOR�!ƒ*RETRY*ƒ!‚*MISCTRL*‚!;*‰+-------------+-------------+-------------+-------------+7*‡8�!STARTING�HD#�!NUMBER�OF�HDS!‚NUMBER�OF�CYLINDERS†!;*‰+-------------+-------------+-------------+-------------+7*†12�!…WRITE-PRECOMP�CYL#„!SECTORS/TRACK!STEPPING�RATE!;*‰+-------------+-------------+-------------+-------------+*†16�!·!;*‰+-------------+-------------+-------------+-------------+'*†20�!ŒPOINTER�TO�NEXT�COMMAND�PACKET�!;*‰+-------------+-------------+-------------+-------------+***‰*�*�=�Ignored�by�this�command* PAGE1*ˆThese�variables�define�the�VM22�command�packet. .‰OFFSETƒ0•This�OFFSET�statement�is�included�so**¦that�the�variables�in�the�command-status#*¦packet�will�be�defined�as�offsets'*¦relative�to�the�start�of�each�packet. 6CMDCODE‚DS.B…1•The�CMDCODE�field�of�the�command�packet)*¦contains�the�opcode�that�tells�the�VM22'*¦controller�what�operation�to�perform. CMDSTAT‚EQU‡0“CHECK�UNIT�STATUSCMDRCAL‚EQU‡1“RECALIBRATE CMDFRMU‚EQU‡2“FORMAT�UNITCMDFRMT‚EQU‡3“FORMAT�TRACKCMDREAD‚EQU‡4“READ�SECTORSCMDWRIT‚EQU‡5“WRITE�SECTORSCMDCHCK‚EQU‡6“CHECK�SECTORSCMDSEEK‚EQU‡7“SEEK�TRACKCMDCNFG‚EQU‡8“CONFIGURE�UNITCMDLOAD‚EQU‡9“DOWNLOAD%CMDREQƒEQU†10“RETURN�SELF-TEST�STATUS 2CMDOPTƒDS.B…1–The�CMDOPT�field�of�a�command�packet&*¦contains�the�8-bit�options�field�for*¦the�command�being�processed. 7CDIAG„EQU†7‘Bit�equate�for�CMDOPT�to�enable�diagnostics*¦0�=�disable�diagnostics*¦1�=�enable�diagnostics -CWV†EQU†6•Bit�equate�for�CMDOPT�to�enable�CRC(*¦0�=�inhibit�read-after-write�CRC�check'*¦1�=�enable�read-after-write�CRC�check 1CECC…EQU†5•Bit�equate�for�CMDOPT�to�report�errors%*¦0�=�don't�report�correctable�errors*¦1�=�report�correctable�errors 5CFMTBAD‚EQU†4”Bit�equate�for�CMDOPT�to�format�a�track*¦as�bad*¦0�=�don't�format�it�as�bad(*¦1�=�format�the�track�as�bad�and�assign*¦the�alternate�track�in�CMDNST*¦as�the�alternate ;OPTCDIAG�EQU†0<N�on�both�sides)*¦1�=�Motorola�format .FMF†EQU‡5•Bit�equate�for�MISCTRL�to�define�the$*¦recording�method�of�a�floppy�disk:*¦0�=�FM‚(single�data-density)*¦1�=�MFM�(double�data-density)‰PAGE.FDS†EQU‡2•Bit�equate�for�MISCTRL�to�define�the#*¦number�of�sides�on�a�floppy�disk:*¦0�=�Single-sided*¦1�=�Double-sided .FDR†EQU‡1•Bit�equate�for�MISCTRL�to�define�the*¦floppy�disk�data-rate�(size):*¦0�=�5-1/4�"�floppy�disk*¦1�=�8�"�floppy�disk -IBS†EQU‡0•Bit�equate�for�MISCTRL�to�define�if(*¦seek�is�required�when�a�head�switch�is*¦performed�(SMD�drives�only):#*¦0�=�Drive�does�not�require�a�seek*¦1�=�Drive�requires�a�seek -STARTHD‚DS.B†1•The�STARTHD�field�contains�the%*¦starting�head�number�on�a�drive�for*¦a�Configure�command. 4NUMHEAD‚DS.B†1•The�NUMHEAD�field�contains�the�number%*¦of�heads�on�a�drive�for�a�Configure *¦command. 2NUMCYLƒDS.W†1•The�NUMCYL�field�contains�the�number*¦of�cylinders�on�a�drive�for�a*¦Configure�command. 8CMDLSNƒEQU‡STARTHD�The�CMDLSN�field�is�a�long-word�field)*¦beginning�at�STARTHD�which�contains�the$*¦starting�logical�sector�number�for'*¦read,�write,�check�and�seek�commands. -PRECOMP‚DS.W†1•The�PRECOMP�field�contains�the&*¦write-precompensation�cylinder�value (*¦for�the�drive�for�a�Configure�command. 8CMDNSTƒEQU‡PRECOMP�The�CMDNST�field�is�a�long-word�field)*¦beginning�at�PRECOMP�which�contains�the'*¦number�of�logical�sectors�to�transfer%*¦for�read,�write�and�check�commands. 4SECTORS‚DS.B†1•The�SECTORS�field�contains�the�number&*¦of�physical�sectors�per�track�on�the *¦media�for�a�Configure�command. 4STEPRATE�DS.B†1•The�STEPRATE�field�contains�the�code(*¦for�the�stepping�rate�of�the�drive�for*¦a�Configure�command.‰PAGE2ILEAVEƒDS.B†1•The�ILEAVE�field�contains�the�inter-#*¦leave�factor�for�format�commands. 2SPIRALƒDS.B†1•The�SPIRAL�field�contains�the�spiral*¦offset�for�format�commands. &‰DS.B†2•Reserve�space�for�long-word... 6CMDBUFƒEQU‡ILEAVE�The�CMDBUF�field�contains�the�Buffer&*¦Address�for�data�transfers�for�read,*¦write�and�check�commands. 2CMDPNTR‚DS.L†1•The�CMDPNTR�field�is�the�last�long-'*¦word�in�the�command�packet.‚It�points)*¦to�the�next�command�packet�when�command#*¦chaining�is�used.‚Otherwise,�this*¦field�must�be�zero. 0CMDENDƒEQU†*–The�label�CMDEND�is�attached�to�the;CMDLENƒEQU†CMDEND-CMDCODE‡byte�that�immediately�follows�the&*¦command�packet�in�memory,�and�CMDLEN(*¦specifies�the�length�(in�bytes)�of�the*¦command�packet. PAGED*ˆDuring�or�at�the�completion�of�a�command,�the�VM22�will�convey�theG*‚status�of�the‚command�by�way�of�a‚Status�Packet.‚The�packet�is�placedE*‚into‚memory‚immediately�following�the‚command�packet.‚The‚interruptH*‚generated�for�command‚completion�also�indicates�that�the�status‚packet*‚is�available. SPC 3C*ˆThe�Command�Status�Packet�is�returned�for�all�commands�except�the$*ˆ"Return�Self-Test�Status"�command.**˜COMMAND�STATUS�PACKET*�BYTE�0¤BYTE�3;*‰+-------------+-------------+-------------+-------------+<*‡0�!STATUS�COMPL.!�CMD�STATUS‚!�RETRY�COUNT�!DRIVE�STATUS�!;*‰+-------------+-------------+-------------+-------------+%*‡4�!�CURRENT�LOGICAL�SECTOR�NUMBER�!;*‰+-------------+-------------+-------------+-------------+*‡8�!‘CURRENT�SECTOR�COUNT’!;*‰+-------------+-------------+-------------+-------------+*†12�!�CURRENT�BUFFER�ADDRESS‘!;*‰+-------------+-------------+-------------+-------------+ SPC 3<*ˆThe�Self-Test�Status�Packet�is�returned�in�response�to�the$*ˆ"Return�Self-Test�Status"�command.**™SELF-TEST�STATUS�PACKET*�BYTE�0¤BYTE�3;*‰+-------------+-------------+-------------+-------------+7*‡0�!STATUS�COMPL.!�CMD�STATUS‚!�S-T�STATUS‚!ƒF/W�REVƒ!;*‰+-------------+-------------+-------------+-------------+=*‡4�!�LUN�0�STATUS!�LUN�1�STATUS!�LUN�2�STATUS!�LUN�3�STATUS!;*‰+-------------+-------------+-------------+-------------+=*‡8�!�LUN�4�STATUS!�LUN�5�STATUS!�LUN�6�STATUS!�LUN�7�STATUS!;*‰+-------------+-------------+-------------+-------------+>*†12�!�LUN�8�STATUS!�LUN�9�STATUS!LUN�10�STATUS!LUN�11�STATUS!;*‰+-------------+-------------+-------------+-------------+ PAGE0*ˆThese�variables�define�the�VM22�status�packet. /S_COMPƒDS.B†1•The�S_COMP�field�will�contain�the'*¦status�complete�code�for�the�command.(*¦This�is�the�last�byte�written�into�the)*¦status�packet�and�can�be�used�as�a�flag'*¦for�'status�complete'�when�interrupts*¦are�not�used. =S_CHOMP‚EQU‡S_COMP+CMDLEN‰The�S_CHOMP�field�is�the�equivalent"*¦to�the�S_COMP�field�when�command*¦chaining�is�used. 3CMDCOMP‚EQU‡$80“The�S_COMP�will�be�equal�to�CMDCOMP!*¦at�the�completion�of�a�command. 2S_STATƒDS.B†1•The�S_STAT�field�contains�the�status(*¦code�for�the�command�just�completed.�A'*¦successful�completion�will�store�a�00(*¦in�this�byte.�Otherwise�the�error�code*¦will�be�stored�in�this�byte. 4S_RETRY‚DS.B†1•The�S_RETRY�field�contains�the�number%*¦of�retries�required�to�complete�the *¦command. 3S_DRIVE‚DS.B†1•The�S_DRIVE�field�contains�the�8-bit(*¦status�of�the�LUN�after�completing�the*¦command.‚The�bit�equates�are*¦defined�below: 0DRDY…EQU‡7•Bit�equate�for�S_DRIVE�that�indicates*¦the�LUN�is�ready�when�set. 0DCYL…EQU‡6•Bit�equate�for�S_DRIVE�that�indicates **¦the�LUN�returned�"on-cylinder"�when�set. /DWP†EQU‡5•Bit�equate�for�S_DRIVE�that�indicates&*¦the�LUN�is�write-protected�when�set. 6S_SELFƒEQU‡S_RETRY�The�S_SELF�field�contains�the�self-&*¦test�status�in�response�to�a�request*¦self-test�status�command. 2S_FWREV‚EQU‡S_DRIVE�The�S_FWREV�field�contains�the)*¦firmware�revision�number�in�response�to%*¦a�request�self-test�status�command.‰PAGE1S_LSN„DS.L†1•The�S_LSN�field�contains�the�logical(*¦sector�number�of�the�error�sector�when#*¦an�error�has�occured�and�the�next%*¦logical�sector�number�when�no�error*¦has�occured. 3S_CNT„DS.L†1•The�S_CNT�field�contains�the�number�of(*¦sectors�left�to�transfer�when�an�error'*¦has�occured�and�is�zero�when�no�error*¦has�occured. 3S_ADDRƒDS.L†1•The�S_ADDR�field�contains�the�address(*¦of�the�last�byte�read�+1�or�written�+1(*¦with�and�without�errors.�This�field�is'*¦used�to�determine�the�number�of�bytes(*¦transferred�on�data�transfer�commands. 5S_CADDR‚DS.L†1•The�S_CADDR�field�contains�the�address%*¦of�the�command�packet�for�which�the'*¦error�occured�for�errors�when�command)*¦chaining�is�used.�Otherwise,�this�field *¦is�zero. 2STATEND‚EQU‡*•The�label�STATEND�is�attached�to�theBPKTLENƒEQU‡STATEND+CMDLEN†byte�that�immediately�follows�the�status8PKTLONG‚EQU‡PKTLEN/4Œpacket�in�memory,�and�specifies�the&*¦length�of�one�command/status�packet.)*¦PKTLEN�defines�the�length�of�a�command/$*¦command/status�packet�which�is�the)*¦length�reserved�for�one�drive�in�global'*¦memory.�PKTLONG�defines�the�length�in *¦long�words. 6EQ095„EQU‡PKTLEN*DRIVES‰The�label�PAGES�is�used�by�the@EQ096„EQU‡EQ095+PAGESIZE-1„initializer�to�allocate�global�memory9PAGES„EQU‡EQ096/PAGESIZE†to�be�used�for�the�VM22�command-&*¦status�packets.�There�are�$100�bytes'*¦per�page�of�memory,�and�the�memory�is(*¦allocated�as�an�integral�no.�of�pages. /TIMEOUT‚EQU‡1000’The�TIMEOUT�equate�defines�the(*¦number�of�times�we'll�read�the�QUE�bit)*¦of�the�status�register�before�reporting"*¦a�controller�error�if�not�ready. PAGE/‰OFFSETƒ0–This�OFFSET�block�defines�the�memory-&*¦mapped�I/O�space�for�a�VM22�channel.&*¦The�VM22�driver�communicates�through*¦this�memory-mapped�I/O�space.************** *ƒBYTE�1ƒ*************** 5CONTROL‚DS.B†1*2“The�Control�Register�is�a�WRITE�only#*¦register�used�to�initiate�control&*¦functions�to�the�VM22.�Below�are�the*¦bit�defintions�for�CONTROL. 0CRQUE„EQU‡7•Setting�the�CRQUE�bit�tells�the�VM22'*¦that�a�command�packet�has�been�placed(*¦in�memory�and�is�ready�to�be�executed."*¦This�should�be�set�only�if�it�is*¦currently�zero. 2CRRST„EQU‡6•Setting�the�CRRST�bit�sets�the�VM22�to'*¦a�hard�reset�state.‚The�board�remains'*¦in�this�state�until�CRRST�is�cleared. 0CRIST„EQU‡5•When�the�CRIST�bit�is�set,�the�self-)*¦test�is�bypassed�when�CRRST�goes�from�1(*¦to�0.‚When�the�CRIST�bit�is�clear,�the(*¦self-test�is�performed�when�CRRST�goes*¦from�1�to�0. *CRISF„EQU‡4•Setting�the�CRISF�bit�inhibits(*¦SYSFAIL�from�being�sourced�by�the�VM22**¦in�case�of�a�self-test�detected�failure. 4STATUSƒEQU‡CONTROL�The�Controller�Status�register�is)*¦a�READ�only�mapped�to�the�same�location%*¦as�the�WRITE�only�Control�Register.**¦Below�are�the�bit�defintions�for�STATUS. 1CSQUE„EQU‡7•When�the�CSQUE�bit�is�clear,�the�VM22(*¦is�ready�for�a�queue�command.‚When�the$*¦CSQUE�bit�is�set,�the�VM22�has�not'*¦completed�queuing�the�last�command.‚A**¦command�may�not�be�queued�until�this�bit*¦goes�to�zero. 2CSFLT„EQU‡6•When�the�CSFLT�bit�is�clear,�no�errors%*¦were�detected�during�the�self-test.)*¦When�the�CSFLT�bit�is�set,�an�error�was$*¦detected�by�the�self-test�routine. 1CSRDY„EQU‡5•When�the�CSRDY�bit�is�clear,�the�VM22(*¦is�performing�the�self-test/initialize'*¦routines.‚Communication�should�not�be(*¦attempted�at�this�time.�When�the�CSRDY!*¦bit�is�set,�the�VM22�self-test/*¦initialization�is�complete. PAGE*******************‚BYTES�3�&�5ƒ******************* ‰DS.B†1*2“Byte�3�is�reserved. ‰DS.B†1*2“Byte�5�is�reserved. ************** *ƒBYTE�7ƒ*************** 1CAAM…DS.B†1*2“The�Command�Access�Address�Modifier&*¦is�the�address�modifier�code�used�to(*¦access�the�command�packet�by�the�VM22. $*¨The�following�is�a�list�of�equates*¦used�to�define�to�codes:*BIT16UƒEQU‡$11‘16-bit�User�I/O$BIT16SƒEQU‡$15‘16-bit�Supervisor�I/O BIT24UD‚EQU‡$01‘24-bit�User�Data#BIT24UP‚EQU‡$02‘24-bit�User�Program&BIT24SD‚EQU‡$05‘24-bit�Supervisor�Data)BIT24SP‚EQU‡$06‘24-bit�Supervisor�Program BIT32UD‚EQU‡$F1‘32-bit�User�Data#BIT32UP‚EQU‡$F2‘32-bit�User�Program&BIT32SD‚EQU‡$F5‘32-bit�Supervisor�Data)BIT32SP‚EQU‡$F6‘32-bit�Supervisor�Program ***************************ƒBYTES�9,�11,�13,�15‚*************************** )CAP†DS.B†1*2‘Command�Address�Pointer-�MSB(‰DS.B†1*2‘Command�Address�Pointer-Byte�2(‰DS.B†1*2‘Command�Address�Pointer-Byte�1&‰DS.B†1*2‘Command�Address�Pointer-�LSB‰PAGEO********************************************************************************1*ˆSERVICE�VECTOR�TABLE,�PARAMETERS,�REVISION�INFO*@*ˆThe�first‚several‚locations�of�every‚I/O�driver�must�contain�aB*ˆservice�vector�table�to�contain�the‚long-word�relative�addressesB*ˆof�the�three�driver�subroutines�that�CMR�uses.‚The�CMR�parameterC*ˆtable�immediately�follows�the�service�vector�table�and�includes�aA*ˆfield�telling‚CMR‚how�many�extra�pages‚to�allocate�for�the�CCB.E*ˆThe�revision�table�immediately�follows�the�the�CMR�parameter�table.*O*******************************************************************************O******************************************************************************* ‰SECTION‚0 VM22DRV: *D*‚Service�vector�table.‚Notice�that�these�values�are�relative�to�theC*‚beginning�of�the�driver�so�the�mechanism�is�position-independent!* <‰DC.L…INTERUPT-VM22DRV…Address�of�interrupt�service�routine.:‰DC.L…COMMANDS-VM22DRV…Address�of�command�service�routine.5‰DC.L…INIT-VM22DRV‰Address�of�initialization�routine.‰DC.L…0”Reserved. **‚Other�CMR�parameters.*3‰DC.B…EXTCCBSZ�#�of�extra�pages�in�the�CCB.‚The�CCB(*§may�be�any�size�from�1�to�256�pages�(a&*§page�is�256�bytes):‚if�this�field�is*§0,�it�will�be�1�page,�etc.‰DC.B…0,0,0�Reserved.‰DC.L…0,0,0�Reserved. **‚Revision�info:*/‰DC.B…'021286'�Date�of�last�assembly�as�MMDDYY.1‰DC.B…'�'’Space�indicates�no�patches�to�.LO�file.)‰DC.B…'4'’Major�VERSAdos�revision�number.‰PAGEO********************************************************************************7*ˆJump�table�for�use�by�the�generic�disk�driver�DISKLIB*O******************************************************************************* ‰BRA.L„SET_CNFG‰BRA.L„SET_CODE‰BRA.L„CHK_FLOPPY‰BRA.L„CHK_LSN‰BRA.L„BLD_PACKET‰BRA.L„DISK_START‰BRA.L„CHK_PARAM‰PAGEO*******************************************************************************O*********************************************************************************ˆINITIALIZATION�ROUTINE*B*ˆThis‚subroutine�is�called�from�CMR‚when�CMR�is�invoked�by�a�taskB*ˆ(normally�IOI)�to‚allocate�a�channel.‚Its�purpose�is�to�give�theD*ˆdriver�a�chance�to�set�up�things�for�command�service�and�interrupt-*ˆservice.‚The�basic�functions�performed�are:*5*ˆ1.‚Put�the�start�address�of�the�driver�into�the�CCB*Œvariable�DRV_ADDR.2*ˆ2.‚Put�the�total�number�of�drives�on�our�channel!*Œinto�the�CCB�variable�MAX_DRVS.8*ˆ3.‚Put�the�size�in�bytes�of�the�drive's�variable�block!*Œinto�the�CCB�variable�DRV_SIZE.?*ˆ4.‚Device-Independent�initialization�in�the�call�to�DISK_INIT"*Žto�initialize�the�CCB�variables.?*ˆ5.‚Device-Dependent�initialization�in�the�call�to�DO_INIT�for"*Ždevice�dependent�initialization.*B*ˆThis�subroutine�is�entered�through�a�JSR�from�CMR,�and�will�exit7*ˆwith�an�RTS.‚The�processor�is�in�the�supervisor�mode.*%*ˆEntry:„A6�=�physical�address�of�TCB*’A5�=�physical�address�of�CCB*5*ˆInterrupt�level�is�0.‚Registers�may�be�used�freely.*.*ˆRegisters�used�in�DISK_INIT:…0�1�2�3�4�5�6�7 *¦D‚**¦A‚*‰P**ˆExits�to:�CMR�via�RTS*O*******************************************************************************O*******************************************************************************ŠPAGEINIT: *)*‚Get�address�of�start�of�driver�into�CCB*ŠLEA‡VM22DRV(PC),A0ŠMOVE.L„A0,DRV_ADDR(A5)*9*‚Get�the�number�of�drives�supported�by�the�VM22�channel.*ŠMOVE.W„#DRIVES,MAX_DRVS(A5)*5*‚Get�the�size�in�bytes�of�the�drive's�variable�block*ŠMOVE.W„#DRVBLKSZ,DRV_SIZE(A5)*>*‚Perform�the�device-independent�initialization�by�calling�the'*‚generic�routine�DISK_INIT�in�DISKLIB.*/‰JSR†DISK_INITŒDo�the�device-independent�stuff.4‰IF‚‚THEN.SŽSomething�went�wrong�with�DISK_INIT.‹RTS™The�channel�is�down�!!‰ENDI*8*‚Perform�any�device-dependent�initialization�in�DO_INIT*/‰BSR.L„DO_INITŽDevice�dependent�initialization.‰RTS‰PAGEO*******************************************************************************O*********************************************************************************ˆCOMMAND�SERVICE�ROUTINE*C*ˆThis�subroutine�is�called�from�CMR�when�CMR�receives�a�command�toA*ˆinitiate�an‚I/O�transaction‚with�a�device�that�is�controlled�by?*ˆthis�driver.‚Its�function�is�to‚process�the‚given�command‚andB*ˆqueue�the�command�to�the�controller.‚These�functions�are�handled%*ˆby�the�generic�disk�driver�DISKLIB.*5*ˆEntry:„A2�=�physical�address�of�CMR�parameter�block*’A5�=�physical�address�of�CCB/*’A6�=�physical�address�of�TCB�of�attached�task*5*ˆInterrupt�level�is�0.‚Registers�may�be�used�freely.*1*ˆRegisters�used�by�DISK_COMMAND:†0�1�2�3�4�5�6�7*ªD‚*�*�*�*�*�*�**ªA‚*�*�*�*�*�P**ˆExits�to:�CMR�via�RTS*O*******************************************************************************O******************************************************************************* COMMANDS: *,*‚Perform�any�device-dependent�stuff�here...* =*‚We�have�received�a�command,�so�we�know�there�is�someone�out**‚there�to�talk�to.‚Let�DISKLIB�handle�it.*&‰JSR†DISK_COMMAND‹Perform�the�command.‰RTS�Return�to�CMR.‰PAGE‰TTL‡VM22�INTERRUPT�HANDLERO*******************************************************************************O**********************************************************************************ˆVM22�INTERRUPT�HANDLER*A*ˆThis�is�the�VM22�Interrupt�Handler�Routine.‚It�is�called�by�CMRB*ˆwhen�CMR�has‚received�an�interrupt�for�the�VM22�disk�controller.A*ˆThe�VM22�disk�controller‚is�an�intelligent�periphial�controllerA*ˆwhich�maintains�its�own�queue�of�commands�to�be�processed.‚ThisB*ˆsimplifies�the�work�the�interrupt�handler�has�to�do,�but�it�alsoF*ˆmeans�we�do�not�immediately�know�which�device�the�command�completionD*ˆinterrupt�is�for.�It�is�possible�for�the�command�handler�to�'send'?*ˆseveral�commands�to�the‚controller‚before�receiving‚a‚commandC*ˆcompletion�interrupt�for�any�one�of�them.�This�routine�determinesA*ˆwhich�device�the‚command�completion�interrupt‚is�for�by�polling@*ˆthe�status�byte�of�the‚status�packet‚belonging‚to‚each�device.C*ˆEach�time�an�interrupt�is�received,�the�status�byte�of�the�statusB*ˆpacket�is�checked�starting�at�the�status�packet�for�drive�0.‚TheB*ˆinterrupt�is�claimed‚when�a�non-zero�status�byte�is�found�beforeB*ˆreaching�the�end�of�the�chain.‚The�interrupt�is�not�claimed�when<*ˆthe�end�is�reached�without�finding�a�non-zero�status�byte.**O*******************************************************************************O******************************************************************************* PAGE O*********************************************************************************ˆPolling�time�calculations:**‹TimeˆInstruction!*‰-------‡-----------------------*‰12(3/0)‡MOVE.LƒSAVECAP(A5),A0*‰12(3/0)‡MOVE.LƒDVBPTR(A5),A1*‰12(3/0)‡MOVEQ.L‚#0,D0*Š8(2/0)‡MOVE.WƒMAX_DRVS(A5),D0*Š4(1/0)‡SUB.W„#1,D0**Š4(1/0)‡TST.L„CMDPNTR(A0) *‰10(2/0)‡BEQ.S„INT100*Š4(1/0)‡TST.B„S_CHOMP(A0)*Š8(1/0)‡BEQ.S„INT150*Š6(1/0)‡ADDA.Lƒ#CMDLEN,A0*‰10(2/0)‡BNE.S„INT200*Š4(1/0)‡TST.B„S_COMP(A0)*‰10(2/0)‡BNE.S„INT200*Š6(1/0)‡ADDA.Lƒ#PKTLEN,A0*Š6(1/0)‡ADDA.Lƒ#DRVBLKSZ,A1*‰12(2/0)‡DBRA…D0,INT050**K*„The�EXORmacs�typically�requires�3‚wait�cycles�for�a�read�cycle�and�1�waitL*„cycle�for�a�write�cycle,�and�the�microprocessor�in�a�standard�EXORmacs�run:*„at�8.0�megahertz�for�a�cycle�time�of�0.125�microseconds.*O******************************************************************************* PAGEO*********************************************************************************ˆINTERRUPT�SERVICE�ROUTINE**ˆEntry:„JSR�from�ISR*’A5�=�Physical�address�of�CCB*!*ˆRegister�usage:…0�1�2�3�4�5�6�7'*™D‚*�#�#�#�#�=�Saved�to�use�as�working#*™A‚*�*ƒ#�#�*�registers�throughout.**ˆCalls:„CHAN_DONE**ˆExit:…RTS�to�CMR*O******************************************************************************* INTERUPT: ;‰MOVE.LƒSAVECAP(A5),A0‰Point�A0�to�the�first�command�packet<‰MOVE.LƒDVBPTR(A5),A1ˆin�the�chain�of�command/status�packets0‰MOVEQ.L‚#0,D0�to�be�polled.�I�usually�use�A2�to=‰MOVE.WƒMAX_DRVS(A5),D0†point�to�the�command�packet�but�it�is3‰SUB.W„#1,D0�not�one�of�the�registers�saved�by�CMR.&*¦Point�A1�to�the�first�drive�variable*¦block. ?INT050ƒTST.L„CMDPNTR(A0)ŒWe�must�find�which�drive�the�interrupt5‰BEQ.S„INT100�was�for:‚In�the�command�handler,�we�set6‰TST.B„S_CHOMP(A0)Šthe�byte�S_COMP�to�zero�just�before4‰BEQ.S„INT150�queueing�a�command�packet�to�the�VM22.7‰ADDA.Lƒ#CMDLEN,A0‹Upon�completion�of�the�commmand,�the3‰BNE.S„INT200�VM22�places�a�command�complete�status>INT100ƒTST.B„S_COMP(A0)‹code�into�the�S_COMP�byte�and�proceeds6‰BNE.S„INT200�to�interrupt�us.�We�scan�the�S_COMP�byte=INT150ƒADDA.Lƒ#PKTLEN,A0‹of�the�status�packet�until�S_COMP�is:‰ADDA.Lƒ#DRVBLKSZ,A1‰non-zero.�When�we've�found�the�drive,8‰DBRA…D0,INT050Œthat�is�the�drive�the�command�completion$*¦interrupt�is�for.�If�we�test�every)*¦status�packet�and�have�not�found�a�non-(*¦zero�S_COMP�byte,�the�interrupt�is�not*¦claimed�by�the�VM22. '*¦A0�<--�1st�packet�without�chaining�OR*©<--�2nd�packet�with�chaining.%*¦This�works�so�long�as�we�access�the*¦status�packet�portion�only.**¦A1�<--�Address�of�drives�variable�block. )*§We�depend�on�the�status�byte�being�non-(*¦zero�as�the�ONLY�indication�as�to�what**¦drive�we're�receiving�the�interrupt�for.#*¦When�the�drive�has�been�found,�D0$*¦contains�a�value�from�which�we�can(*¦determine�the�drive�number,�but�is�not*¦equal�to�the�drive�number. PAGE*¦THE�INTERRUPT�ISN'T�FOR�ME2CLEAR„EQU†0<<0“We�return�with�SR.C�=�0�to�indicate8‰AND.B„#CLEAR,CCR‹that�the�interrupt�isn't�mine.�The�RTS‰RTS›is�to�CMR. *¦THE�INTERRUPT�IS�FOR�ME=INT200ƒMOVE.BƒS_COMP(A0),D0ŠSave�and�clear�the�status�byte�to:‰MOVE.Bƒ#0,S_COMP(A0)ˆindicate�I've�accepted�the�interrupt =EQ600„REG†A4/A3/D3/D2/D1‰A5,�A1,�A0,�and�D0�have�already�been;‰MOVEM.L‚EQ600,-(SP)Šsaved�by�CMR.‚Here�we�save�the�rest�of'*¦the�registers�that�we�need�to�use.‚We(*¦save�only�the�registers�that�we�really%*¦need�because�we�don't�want�to�waste(*¦time�or�stack�space.‚Time,�especially,'*¦is�important�in�an�interrupt�handler. 8CHKSTAT‚MOVEQ.L‚#0,D2’We�have�accepted�the�interrupt�and7‰MOVE.BƒS_STAT(A0),D2ˆmust�check�status.‚If�the�command5‰BNE.S„STATERRŽstatus�byte�returned�is�not�zero,�then*¦an�error�has�occured. 8‰MOVE.BƒEOVFLAG(A1),D1‰Return�the�EOVFLAG�value�from�the&*¦drive�variable�block�for�the�current**¦command�completion�interrupt.The�EOVFLAG'*¦value�that�we�get�into�D1.B�here�will#*¦be�returned�to�the�user�as�an�I/O&*¦status�code.‚If�the�I/O�transfer�was'*¦truncated�to�avoid�running�beyond�the(*¦end�of�the�disk,�we�return�the�ISTAEOV'*¦status�code.‚Otherwise,�we�return�the)*¦ISTAOK�status�code�to�indicate�that�the!*¦entire�operation�went�smoothly. PAGE@VM22ERR‚MOVE.LƒS_ADDR(A0),D0ŠGet�the�pointer�to�the�next�byte�in :‰MOVE.LƒD0,IOBUFPTR(A1)†the�I/O�buffer.‚This�value�will�beNNNNNNN#*¦used�to�calculate�number�of�bytes*¦transferred.Š**�02/12/86‚** ‰JSR†CHAN_DONE >EQ640„REG†D1/D2/D3/A3/A4‡Restore�the�registers�that�were�saved;‰MOVEM.L‚(SP)+,EQ640Šat�the�start�of�the�interrupt�routine. 4CARRY„EQU†1<<0“Finally,�set�the�SR.C�bit,�and�return5‰OR.B…#CARRY,CCR‹control�to�CMR.‚Setting�the�SR.C�bit)‰RTS›indicates�that�we�have�processed�the *¦interrupt. !*¨Notice�that�we�don't�change�the(*¦interrupt�mask�level,�so�the�interrupt$*¦mask�level�is�the�same�level�as�it%*¦was�when�the�VM22�interrupt�handler*¦was�invoked. CTRLERR‚ST.B…CHANDOWN(A5)‹Down�the�VM22�channel�by�setting�the"*¦variable�that�indicates�that�the#*¦controller�is�down.‚If�the�system(*¦tries�to�access�the�VM22�channel�again#*¦without�resetting�it�first,�we'll%*¦report�an�error�indicating�that�the$*¦channel�is�down.‚The�system�really"*¦shouldn't�try�to�access�the�VM22'*¦channel�again�without�first�resetting$*¦the�controller.‚Even�resetting�the)*¦controller�may�not�correct�the�problem,'*¦but�we'll�let�the�system�try�as�often*¦as�it�wishes. 5‰MOVEQIƒISTACNT,D1�Set�up�D1.B�for�reporting�a�status4‰BRA†VM22ERRŽcode�that�indicates�a�controller�error,%*¦and�go�terminate�processing�for�the*¦current�command.  PAGE O********************************************************************************=*ˆTABLE�TO�TRANSLATE�VM22�ERROR�CODES�TO�VERSADOS�ERROR�CODES*O******************************************************************************* %*“---------------‚VERSAdos�Error�Code*’|*’|”----‚VM22�Error�Code*’|“|*’|“|%*’V“V†VM22�Definition�and�Explanation!*­------------------------------- "ERRCODE‚DC.B…ISTADMA‡$00„No�error. .‰DC.B…ISTAUNR‡$01„No�index/sector�pulse�signal)*¦from�the�drive.�VERSAdos�doesn't�really)*¦have�an�error�code�to�describe�this,�so#*¦we�simply�report�an�unrecoverable *¦disk�error. 8‰DC.B…ISTARES‡$02„No�track�000�on�a�RECALIBRATE�command.* 3‰DC.B…ISTASAˆ$03„Invalid�sector�number�-�the�LSN�is*¦out�of�bounds !‰DC.B…ISTANRˆ$04„Drive�not�ready.* 2‰DC.B…ISTASEK‡$05„No�'ON-CYLINDER'�from�the�drive.* &‰DC.B…ISTADME‡$06„ID�header�not�found.* 7‰DC.B…ISTADME‡$07„Data�mark�not�found.�This�is�reported$*¦as�ID�not�found�and�not�a�"DELETED*¦DATA�MARK�DETECT". 2‰DC.B…ISTAILU‡$08„LUN�is�greater�than�maximum�LUN.* 4‰DC.B…ISTAILU‡$09„The�LUN�requested�is�already�busy.* PAGE ‰DC.B…ISTADMC‡$0A„DMA�error.* '‰DC.B…ISTAICE‡$0B„Undefined�error�code.* &‰DC.B…ISTAIFˆ$0C„Invalid�command�code.* 9‰DC.B…ISTATOˆ$0D„H/W�error;�timeout�for�an�unknown�cause.* :‰DC.B…ISTAILU‡$0E„Inconsistent�LUN�within�a�command�chain.* (‰DC.B…ISTACFG‡$0F„Illegal�configuration.* '‰DC.B…ISTAICE‡$10„Undefined�error�code.'‰DC.B…ISTAICE‡$11„Undefined�error�code. 7‰DC.B…ISTACRC‡$12„CRC�error�or�uncorrectable�ECC�error.* )‰DC.B…ISTACRC‡$13„Correctable�data�error.* (‰DC.B…ISTAWPˆ$14„Write�protected�device.* -‰DC.B…ISTAUNR‡$15„Hard�disk�controller�fault.* /‰DC.B…ISTAUNR‡$16„Floppy�disk�controller�fault.* -‰DC.B…ISTACNF‡$17„Invalid�floppy�disk�format.* +‰DC.B…ISTACFG‡$18„Drive/Media�incompatible.* '‰DC.B…ISTAICE‡$19„Undefined�error�code.'‰DC.B…ISTAICE‡$1A„Undefined�error�code.'‰DC.B…ISTAICE‡$1B„Undefined�error�code.'‰DC.B…ISTAICE‡$1C„Undefined�error�code.'‰DC.B…ISTAICE‡$1D„Undefined�error�code.'‰DC.B…ISTAICE‡$1E„Undefined�error�code. "‰DC.B…ISTAUNR‡$1F„Self-test�error.* PAGE  '‰DC.B…ISTAICE‡$20„Undefined�error�code.'‰DC.B…ISTAICE‡$21„Undefined�error�code.'‰DC.B…ISTAICE‡$22„Undefined�error�code.'‰DC.B…ISTAICE‡$23„Undefined�error�code.'‰DC.B…ISTAICE‡$24„Undefined�error�code.'‰DC.B…ISTAICE‡$25„Undefined�error�code.'‰DC.B…ISTAICE‡$26„Undefined�error�code.'‰DC.B…ISTAICE‡$27„Undefined�error�code.'‰DC.B…ISTAICE‡$28„Undefined�error�code.'‰DC.B…ISTAICE‡$29„Undefined�error�code.'‰DC.B…ISTAICE‡$2A„Undefined�error�code.'‰DC.B…ISTAICE‡$2B„Undefined�error�code.'‰DC.B…ISTAICE‡$2C„Undefined�error�code.'‰DC.B…ISTAICE‡$2D„Undefined�error�code.'‰DC.B…ISTAICE‡$2E„Undefined�error�code.'‰DC.B…ISTAICE‡$2F„Undefined�error�code. '‰DC.B…ISTAICE‡$30„Undefined�error�code.'‰DC.B…ISTAICE‡$31„Undefined�error�code.'‰DC.B…ISTAICE‡$32„Undefined�error�code.'‰DC.B…ISTAICE‡$33„Undefined�error�code.'‰DC.B…ISTAICE‡$34„Undefined�error�code.'‰DC.B…ISTAICE‡$35„Undefined�error�code.'‰DC.B…ISTAICE‡$36„Undefined�error�code.'‰DC.B…ISTAICE‡$37„Undefined�error�code.'‰DC.B…ISTAICE‡$38„Undefined�error�code.'‰DC.B…ISTAICE‡$39„Undefined�error�code.'‰DC.B…ISTAICE‡$3A„Undefined�error�code.'‰DC.B…ISTAICE‡$3B„Undefined�error�code.'‰DC.B…ISTAICE‡$3C„Undefined�error�code.'‰DC.B…ISTAICE‡$3D„Undefined�error�code.'‰DC.B…ISTAICE‡$3E„Undefined�error�code.'‰DC.B…ISTAICE‡$3F„Undefined�error�code.'‰DC.B…ISTAICE‡$40„Undefined�error�code.‰DS.W…0ERRCEND‚EQU†*-ERRCODE D*ˆError�codes�in�the�range�$40�through�$80�are�reported�as�"ISTAICE"A*ˆand�are�not�shown�in�the�table.�Error�code�$1F�is�the�self-test?*ˆerror�code�and�is�reported�as�"ISTAUNR".‚The�checks�for�these;*ˆerror�conditions�are�made�in�the�above�routine�'STATERR'.‰PAGE‰TTL‡ROUTINES�CALLED�BY�DISKLIBO********************************************************************************!*’R�O�U�T�I�N�E�SƒC�A�L�L�E�DƒB�Y**œD�I�S�K�L�I�B**O*******************************************************************************‰PAGEN*******************************************************************************)*ˆSET_CNFG…SET�UP�FOR�A�CONFIGURE�COMMAND*C*ˆThis‚is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toD*ˆset�the�fields's�in�the�drive's�variable�block,�device-independent#*ˆportion,�for�a�configure�command.**A*ˆEntry:�A1�=�pointer�to�Drive's�Variable�Block�in�global�memory.#*�A5�=�physical�address�of�the�CCB.* *�Interrupt�level�on�entry�is�0.*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D *™A„P�*…P* *ˆCalls:�none*/*ˆExit:‚RTS�to�caller�with�condition�codes�set:7*�‚Drive/controller�supports�the�configure�request.?*�‚Drive/controller�does�not�support�the�configure�request.4*•D1.B�=�VERSAdos�error�code�for�the�error�detected.*F*ˆThe�interrupt�level�upon�exit�must�be�the�same�as�it�was�upon�entry.*N****************************************************************************** SET_CNFG:0‰MOVE.L„A2,-(SP)ŽSave�the�registers�we�will�use.=‰MOVE.L„IOCAPTR(A1),A2ˆA2�<--�address�of�this�command�packet. >EQ410„EQU†CONFGBLK+IOSSHD+1†Copy�the�starting�head�number�from@‰MOVE.BƒEQ410(A1),STARTHD(A2)‚the�drive�block�to�command�packet. ;EQ420„EQU†CONFGBLK+IOSHDSˆCopy�the�number�of�heads�from�the@‰MOVE.BƒEQ420(A1),NUMHEAD(A2)‚drive�block�to�the�command�packet. @EQ430„EQU†CONFGBLK+IOSTRKD‡Copy�the�number�of�cylinders�from�the?‰MOVE.WƒEQ430(A1),NUMCYL(A2)ƒdrive�block�to�the�command�packet. >EQ440„EQU†CONFGBLK+IOSPCOM‡Copy�the�precompensation�cylinder�#A‰MOVE.WƒEQ440(A1),PRECOMP(A2)‚from�drive�block�to�command�packet. =EQ450„EQU†CONFGBLK+IOSSPTˆCopy�the�sectors-per-track�from�the@‰MOVE.BƒEQ450(A1),SECTORS(A2)‚drive�block�to�the�command�packet. ?EQ455„EQU†CONFGBLK+IOSSRTD‡Copy�the�stepping-rate�code�from�theA‰MOVE.BƒEQ455(A1),STEPRATE(A2)�drive�block�to�the�command�packet. /‰MOVE.Lƒ(SP)+,A2�Restore�the�registers�we�used.'‰CMP.B„D0,D0’Set�good�status�on�return.‰RTS ‰PAGEN******************************************************************************* *ˆSET_CODE*F*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installed�atE*ˆthe�beginning�of�the�driver.‚The�function�of�this�routine�is�to�setD*ˆany�media‚and/or‚drive�related�codes�in�the�drive's�variable�blockC*ˆ(device-dependent�portion)‚required�by‚the�particular‚controller.>*ˆIt�is�called�by�configure,�read,�write,�and�format�commands.**A*ˆEntry:„A1�=�pointer�to�Drive's�Variable�Block�in�global�memory.#*’A5�=�physical�address�of�the�CCB.* *’Interrupt�level�on�entry�is�0.*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D‚*�* *™A„P�*…P* *ˆCalls:�none**ˆExit:‚RTS�to�caller.*F*ˆThe�interrupt�level�upon�exit�must�be�the�same�as�it�was�upon�entry.*N****************************************************************************** SET_CODE: 7‰MOVEM.LƒD0/D1/A2,-(SP)ˆSave�the�registers�we�will�use. =EQ460„EQU†CONFGBLK+IOSPSMˆGet�the�sectors-per-track�value�for;‰MOVE.WƒEQ460(A1),D1‰the�media�into�D1�(this�is�our�working2‰MOVEQ.L‚#0,D0�register).‚Clear�D0�to�use�to�store*¦the�results. :COM10„SUB.W„#128,D1�For�each�multiple�of�128�bytes,�we�add2‰BEQ.S„COM20�one�to�the�sector�size�code,�starting-‰ADD.B„#1,D0�with�128�bytes/sector�equal�to�a2‰BRA†COM10�sector�size�code�of�00.‚The�sector�size:COM20„LSL.B„#3,D0�code�is�assigned�to�bits�3-4�of�MISCTRL. >EQ470„EQU†CONFGBLK+IOSATWˆGet�the�attribute�word�for�the�media4‰MOVE.WƒEQ470(A1),D1‰into�D1�(our�working�register). 8‰BTST…#IOARDISC,D1‹If�this�is�a�floppy�disk,�go�right�to'‰BEQ.S„COM30�the�floppy�bit�attributes. 5‰BTST…#IOARIBS,D1ŒDefine�a�required�seek�for�a�rigid-/‰BEQ.S„COM90�SMD�drive.‚We�set�the�IBS�bit�if�a5‰BSET…#IBS,D0Žseek�is�required�with�a�head�change�and0‰BRA.S„COM90�leave�that�bit�as�zero�if�a�seek�is"*¦not�required�with�a�head�change.‰PAGE=COM30„BTST…#IOATDEN,D1ŒDefine�the�track�density�of�the�media.5‰BNE.S„COM40�We�set�the�FTD�bit�when�the�media�TPI�is5‰BSET…#FTD,D0Žone-half�of�the�drive�TPI.�We�leave�the?COM40„BTST…#IOATDEND,D1‰bit�as�zero�when�the�media�TPI�is�equal‰BNE.S„COM50�to�the�drive�TPI.‰BCLR…#FTD,D0Ž* ;COM50„BTST…#IOAFRMT,D1ŒDefine�the�format-type�of�the�media.3‰BNE.S„COM60�We�set�the�FSN�bit�for�Motorola�format1‰BSET…#FSN,D0Žand�leave�that�bit�as�zero�for�IBM. 9COM60„BTST…#IOADDEN,D1ŒDefine�the�recording-method�(data-2‰BEQ.S„COM70�density)�of�the�media.‚We�set�bit�FMF4‰BSET…#FMF,D0Žfor�MFM�encoding�(double�data-density)#*¦and�leave�that�bit�as�zero�for‚FM!*¦encoding�(single�data-density). 7COM70„BTST…#IOADSIDE,D1‹Define�the�number�of�sides�on�a.‰BEQ.S„COM80�floppy�disk.‚We�set�bit�FDS�for�a5‰BSET…#FDS,D0Ždouble-sided�disk�and�leave�that�bit�as"*¦as�zero�for�a�single-sided�disk. 7COM80„BTST…#IOASIZE,D1ŒDefine�the�floppy�disk�data�rate2‰BEQ.S„COM90�(size).‚We�set�bit�FDR�for�500k�bits/5‰BSET…#FDR,D0Žsec�(8")�and�leave�that�bit�as�zero�for*¦250k�bits/sec�(5-1/4"). ACOM90„MOVE.BƒD0,MEDCODE(A1)‰Save�the�defined�control�code�for�the(*¦current�drive�into�the�variable�block. 8‰MOVE.LƒSAVECAP(A5),A2‰Set�up�A2�to�point�to�the�command;‰MOVEQ.L‚#PKTLEN,D0‹packet�for�the�disk�drive�that�is�to�be5‰MOVEQ.L‚#0,D1�accessed�for�this�command.�Get�address<‰MOVE.BƒDRIVENUM(A1),D1†of�packet�for�drive�0,�then�multiply1‰MULU…D1,D0�the�length�of�one�packet�by�the�drive&‰ADD.L„D0,A2�number�to�get�the�offset. ;‰MOVEQ.L‚#PKTLONG-1,D0ŠWe�must�clear�out�the�command�packet8‰ADD.L„#PKTLEN,A2‹we're�about�to�use.‚Set�up�D0�with�the;CLRPKTƒCLR.L„-(A2)�length�in�long�words�minus�one�and�point3‰DBRA…D0,CLRPKTŒA2�to�the�start�of�the�next�packet. ;‰MOVE.LƒA2,IOCAPTR(A1)‰Save�address�of�this�command�packet. 6‰MOVEM.L‚(SP)+,D0/D1/A2‰Restore�the�registers�we�used.‰RTS‰PAGEN********************************************************************************ˆCHK_FLOPPY�ROUTINE*C*ˆThis�is�a‚device�dependent‚routine�whose‚offset�must‚be�installed D*ˆat�the�beginning�of�the�driver.�The‚function�of‚this�routine‚is�toF*ˆcheck�that�the�bytes�per�sector,‚sectors�per�track,�and�data-densityG*ˆdensity�values�are�consistent�with�each�other.�This�routine�is�called?*ˆafter�the‚user's‚configuration‚block‚has‚been‚filled‚with‚theG*ˆproposed�configuration.�Therefore,�A0�points�to�the�end�of�the�user's*ˆconfiguration�block.*0*ˆEntry:�A0�=�end�of�user's�configuration�block.* *�Interrupt�level�on�entry�is�0.*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D*™A‚P* *ˆCalls:�none*/*ˆExit:‚RTS�to�caller�with�condition�codes�set:-*��no�errors�in�this�configuration�check.*��an�error�was�found.*F*ˆThe�interrupt�level�upon�exit�must�be�the�same�as�it�was�upon�entry.*N****************************************************************************** CHK_FLOPPY: ‰CMP.B�D0,D0‰RTS‰PAGEN******************************************************************************* *ˆCHK_LSN*C*ˆThis�is�a�device�dependent�routine�whose�offset�must‚be‚installedD*ˆat�the�beginning�of�the‚driver.�The�function�of�this�routine�is�toC*ˆcheck�that‚the�requested�starting�logical‚sector�number�(in�D2.L)E*ˆis�less�than�or�same�as�the�largest�logical�sector�number�supported$*ˆby�the�particular�disk�controller.**-*ˆEntry:�D2�=�starting�logical�sector�number.* *�Interrupt�level�on�entry�is�0.*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D†P*™A* *ˆCalls:�none*/*ˆExit:‚RTS�to�caller�with�condition�codes�set:3*��=�starting�logical�sector�number�is�invalid.1*��=�starting�logical�sector�number�is�valid.*F*ˆThe�interrupt�level�upon�exit�must�be�the�same�as�it�was�upon�entry.*N****************************************************************************** CHK_LSN: ‰CMP.B�D0,D0‰RTS‰PAGEN******************************************************************************* *ˆBLD_PACKET*C*ˆThis�is�a�device-dependent�routine�whose‚offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toC*ˆbuild�any�or�all‚parts�of�the�command�packet�that�can�be�built�at=*ˆinterrupt‚level�0‚which‚will�be‚used‚by�the‚particular‚disk,*ˆcontroller�to�process�the�current�command.*A*ˆEntry:„A1�=�pointer�to�Drive's�Variable�Block�in�global�memory.#*’A5�=�physical�address�of�the�CCB.* *’Interrupt�level�on�entry�is�0.*!*ˆRegister�usage:…0�1�2�3�4�5�6�7 *™D‚*�*‹* *™A„P�*…P* *ˆCalls:„none*/*ˆExit:‚RTS�to�caller�with�condition�codes�set:3*�‚No�errors�were�found�in�building�the�packet.4*�‚An�error�was�detected�in�building�the�packet.4*•D1.B�=�VERSAdos�error�code�for�the�error�detected.*F*ˆThe�interrupt�level�upon�exit�must�be�the�same�as�it�was�upon�entry.*N****************************************************************************** BLD_PACKET:*>*ˆThis�routine�completes�the�command�packet.‚It�fills�in�those?*ˆfields�that�are�common�to�all�commands�as�well�as�some�fields?*ˆwhich�are�unique�to�a�particular�command.�Command�chaining�is<*ˆrequired�for�read�and�write�commands�when�the�I/O�transfer>*ˆcrosses�the�track�zero�to�track�one�boundary.�For�this�case,$*ˆtwo�command�packets�are�processed.* :‰MOVEM.LƒD0/D1/D7/A2,-(SP)ƒSave�the�registers�we�will�use. *.*‚Get�the�pointer�to�the�first�command�packet.*=‰MOVE.L„IOCAPTR(A1),A2†A2�<--�address�of�this�command�packet.7‰MOVEQ.Lƒ#0,D7�D7�<--�pointer�to�second�command�packet.0EQATTRƒEQU‡CONFGBLK+IOSATW…For�easy�reference...‰PAGE*F*‚Determine�if�this�is�a�read�or�write�command.‚If�it�is,�complete�theJ*‚sector�address�and�buffer�fields�of�this�command�packet.�If�this�commandK*‚requests�crossing�the�track�zero/track�one�boundary�on�a�256�bytes/sectorD*‚floppy�disk,�then�set�up�D7�to�point�to�the�second�command�packet.*<‰CMP.B…#READFUNC,IOFUNCT(A1)ƒDo�the�following�for�read/write‰BEQ.S…RW_PROC‘operations�only.‰CMP.B…#WRTFUNC,IOFUNCT(A1)‰BEQ.S…RW_PROC ‰BRA.S…NOT_RW  HRW_PROCƒMOVE.LƒIOSECTOR(A1),CMDLSN(A2)ƒStore�the�starting�sector�number.;ŠMOVE.LƒIOSCTCNT(A1),CMDNST(A2)ƒStore�the�count�of�sectors.9ŠMOVE.LƒIOBUFPTR(A1),CMDBUF(A2)ƒStore�the�buffer�address. 1ŠTST.L„HALFSCTS(A1)ŠIf�HALFSCTS�is�zero,�skip�any!ŠBEQ.S„PKT_LOOPŒcommand�chaining. 8ŠMOVE.LƒIOSCTCNT(A1),D0‡If�there's�a�track-zero�crossing>ŠSUB.L„HALFSCTS(A1),D0…on�a�256�bytes/sector�floppy�disk,�then3ŠIF��THEN‘command�chaining�must�be�used.‚Set�up5‹MOVE.L‚A2,D7�D7�to�point�to�the�next�command�packet.‹ADD.Lƒ#CMDLEN,D7ŠENDINOT_RW *G*‚This�section�of�code�fills�in�the�first�8�bytes�of�the�command�packetF*‚which�are�common�to�most�commands.‚If�two�packets�are�required,�thisF*‚code�is�entered�a�second�time�with�A2�pointing�to�the�second�command *‚packet.* PKT_LOOP***¤RETRY�COUNT<‰BTSTW„#IOPRTYB,IOOPTS(A1)‚Is�the�option�for�no�retries�set?.‰IF��THEN’If�set,�no�retries�is�requested.6ŠMOVE.Bƒ#0,D0�Use�a�retry�count�of�zero�for�all�disks.)‰ELSEšIf�clear,�set�retry�count�for�disk. 6‰MOVE.Bƒ#HRTRYCNT,D0‰Default�to�hard�disk�retry�count.2‰BTSTW„#IOARDISC,EQATTR(A1)�Is�this�a�floppy�disk?‰IF��THEN’Yes.7ŠMOVE.Bƒ#FRTRYCNT,D0ˆReplace�D0�with�floppy�disk�count.‰ENDI‰ENDI8‰MOVE.B„D0,RETRY(A2)ˆCopy�correct�retry�count�to�packet.‰PAGE***¤MISC�CONTROL�CODEA‰MOVE.BƒMEDCODE(A1),MISCTRL(A2)�Copy�the�media/misc�control�code.2‰BTSTW„#IOARDISC,EQATTR(A1)�Check�for�floppy�disk.‰IF��THEN’If�yes,3ŠMOVEQ.L‚#0,D0�If�we�access�track�0,�modify�MISCTRLDŠMOVE.BƒCONFGBLK+IOSSPT(A1),D0�for�a�sector�size�code�of�00�equal�to8ŠCMP.L„IOSECTOR(A1),D0…128�bytes/sector�and�FM�recording2ŠIF��THEN‘density.�This�really�only�applies�to>‹AND.Bƒ#$C7,MISCTRL(A2)„MFM�disks�but�we�do�it�for�FM�as�well.ŠENDI‰ENDI ***¤VECTOR�NUMBER�AND�LEVEL@‰MOVE.BƒCCBVECT(A5),INTNUM(A2)‚Copy�the�interrupt�vector�number.9‰MOVE.BƒCCBPPRIO(A5),INTLEV(A2)�Copy�the�interrupt�level. ***¤COMMAND�OPTIONS,�ETC.:‰MOVE.Bƒ#AMCODE,CMDAMC(A2)ƒCopy�the�address�modifier�code.6‰MOVE.BƒDRIVENUM(A1),CMDLUN(A2)�Copy�the�drive�number.C‰MOVE.Bƒ#OPTDFLT,CMDOPT(A2)‚Copy�the�command�options�default�value. ***¤COMMAND�CODE/‰MOVE.BƒIOFUNCT(A1),D0‡D0�<--�I/O�function�code ‰EXT.W„D0“*B‰MOVE.BƒOPTBL(PC,D0),CMDCODE(A2)�Use�table�to�set�code�in�the�ECA. ‰BRA†SKIP_TBL O*********************************************************************************ˆVM22�COMMAND�CODE�TABLE*@*ˆThis�table�contains�the�VM22�defined�command�codes�for�the�I/O!*ˆoperations�currently�supported.*O******************************************************************************* .‰DC.B…CMDWRITŽWrite�command:‚IOFUNCT�equals�-13OPTBL„DC.B…CMDFRMTŽFormat�command:�IOFUNCT�equals‚0.‰DC.B…CMDCNFGŽConfigure-seek:�IOFUNCT�equals‚1,‰DC.B…CMDREADŽRead�command:ƒIOFUNCT�equals‚2SKIP_TBL�DS.W†0“End�of�table*8‰CMP.B…#FMTFUNC,IOFUNCT(A1)‚If�this�is�a�FORMAT�command,‰IF��THEN’do�the�following: =EQ510„EQU†CONFGBLK+IOSILV†Copy�the�interleave�factor�from�the?‰MOVE.BƒEQ510(A1),ILEAVE(A2)�drive�block�to�the�command�packet. �THEN•change�the�VM22�command�code�to)‹MOVE.B‚#CMDFRMU,CMDCODE(A2)„format-unit.#ŠELSE�Else�it�must�be�format�track. @ŠMOVE.L�IOSECTOR(A1),CMDLSN(A2)ƒCopy�starting�logical�sector�no. 9ŠCMP.W„#IOPBAD,IOOPTS(A1)†If�this�is�a�format�w/alternate1ŠIF��THEN•command,�store�the�alternate�sectorB‹MOVE.L�IOALTSEC(A1),CMDNST(A2)‚no.�in�the�command�packet.�Set�the<‹BSETƒ#CFMTBAD,CMDOPT(A2)†option�bit�for�format�w/alternate.ŠENDIŠENDI ‰ENDI CPKT_TWO‚MOVE.Bƒ#0,S_COMP(A2)ˆClear�the�status�byte�in�first�command9‰MOVE.LƒD7,CMDPNTR(A2)‡packet�and�copy�the�chain�pointer.*J*‚The�command�chaining�pointer�is�zero�if�this�is�the�last�or�only�packet.  '6>!;)!194AJ*‚The�command�chaining�pointer�is�not�zero�if�a�second�packet�is�required.*+‰IF��THEN’If�the�pointer�is�not�zero... 4‰MOVE.L„HALFSCTS(A1),D1…D1�<--�sectors�in�track�zero=‰MOVE.L„D1,CMDNST(A2)‡Copy�the�number�of�sectors�to�transfer.,‰MOVE.L„D7,A2�Point�A2�to�command�packet�#2. 5‰MOVE.L„IOSECTOR(A1),D0…D0�<--�starting�sector�number5‰ADD.L…D1,D0�Add�to�find�next�starting�sector�number.0‰MOVE.L„D0,CMDLSN(A2)‡Copy�to�command�packet�#2.;‰MOVE.L„D0,IOSECTOR(A1)…Copy�here�so�that�we�set�up�MISCTRL"*§for�command�packet�#2�correctly. +‰MOVE.L„IOSCTCNT(A1),D0…D0�<--�sector�count4‰SUB.L…D1,D0�Subtract�to�find�next�count�of�sectors.0‰MOVE.L„D0,CMDNST(A2)‡Copy�to�command�packet�#2. -‰MOVE.L„IOBUFPTR(A1),D0…D0�<--�buffer�address5‰MULU†#128,D1�Calculate�next�buffer�address�by�adding'‰ADD.L…D1,D0�to�current�buffer�address.0‰MOVE.L„D0,CMDBUF(A2)‡Copy�to�command�packet�#2. 7‰MOVEQ.Lƒ#0,D7�D7�<--�0�indicating�last�command�packet..‰BRA†PKT_LOOP�Loop�back�to�complete�packet�#2. ‰ENDI 9‰MOVEM.Lƒ(SP)+,D0/D1/D7/A2ƒRestore�the�registers�we�used.'‰CMP.B…D0,D0�Set�good�status�on�return.‰RTS‰PAGEN******************************************************************************* *ˆDISK_START*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedE*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�to:*.*Š1.‚Set�up�the�device-dependent�fields�in�the*Ždrive's�variable�block.B*Š2.‚If�the�drive�is�not�busy,�tell�the�command�to�the�controller.**D*ˆEntry:�A1�=�address�of�the�drives�variable�block�in�global�memory.#*�A5�=�physical�address�of�the�CCB.*=*�Interrupt�level�on�entry�is�at�our�hardware�level�(masked).*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D‚* *™A‚*�P‡P* *ˆCalls:�none**ˆExit:‚RTS�to�caller.*N****************************************************************************** DISK_START:4‰MOVEM.LƒD0/A0,-(SP)‹Save�the�registers�we�will�use. 9‰MOVE.L„CCBCHB(A5),A0‰Assure�that�the�controller�is�ready<‰MOVE.L„#TIMEOUT,D0‰to�receive�the�command�that�we've�placed9SEND10ƒSUBQ.L„#1,D0�into�global�memory.�The�controller�is0‰BEQ‡CTRLERR�ready�when�the�CSQUE�bit�is�off.‚We=‰BTST†#CSQUE,STATUS(A0)ƒmay�timeout�in�this�loop�indicating�a&‰BNE‡SEND10Žprobable�controller�error. 1‰MOVE.B„#0,CAAM(A0)‹Initialize�the�Command�Access*¦Address�Modifier�code. 9‰MOVE.L„IOCAPTR(A1),D0ˆSend�the�CAP�address�through�write&‰MOVEP.LƒD0,CAP(A0)Šregisters�WR4-WR7. =‰BSET†#CRQUE,CONTROL(A0)„Set�the�CRQUE�bit�to�inform�the�VM22'*¦that�a�command�packet�has�been�placed(*¦in�memory�and�is�ready�to�be�executed."*¦Acceptance�test�is�not�neccesary*¦because�it�happens�so�fast. 3‰MOVEM.Lƒ(SP)+,D0/A0‹Restore�the�registers�we�used.‰RTS‰PAGEN********************************************************************************ˆCHK_PARAM�ROUTINE*C*ˆThis�is�a‚device�dependent‚routine�whose‚offset�must‚be�installedD*ˆat�the�beginning�of�the�driver.�The‚function�of‚this�routine‚is�toB*ˆvalidate‚any‚device‚dependent‚parameters.‚This�routine�is�called?*ˆafter�the‚user's‚configuration‚block‚has‚been‚filled‚with‚theG*ˆproposed�configuration.�Therefore,�A0�points�to�the�end�of�the�user's*ˆconfiguration�block.*/*ˆEntry:�A0�=�end�of�user's�configuration�block* *�Interrupt�level�on�entry�is�0.*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™DˆR*™A‚P* *ˆCalls:�none*$*ˆExit:‚RTS�back�to�calling�routine.>*�CONDITION�CODES:��no�errors�in�this�configuration�check.* �an�error�was�found./*�D3.B�=�Returned�error�code�if�error�is�found.*F*ˆThe�interrupt�level�upon�exit�must�be�the�same�as�it�was�upon�entry.*N**************************************************************  **************** CHK_PARAM: ‰CMP.B…D0,D0�Set�condition�codes ‰RTS›Return.‰PAGEN********************************************************************************‰FINISH�OFF�THE�INITIALIZATION*2*‰These�other�device-dependent�things�MUST�be�done>*‰before�we�can�handle�commands.‚They�probably�could�have�been?*‰done�in�INIT�at�the�start�of�the�driver�but�are�handled�here.*3*‰1.‚Allocate�global�memory�for�the�Command�Packets-*‰2.‚Check�that�the�VM22�board�is�functional.**‰Entry:�A5�=�address�of�CCB.**‰Calls:�REQSTAT*N****************************************************************************** DO_INIT:*4*‚Allocate�memory�for�the�command�and�status�packets*7‰MOVE.Lƒ#PAGES,A0ŽAllocate�global�memory�for�a�command/5‰MOVE.Lƒ#4,D0�status�packet�for�each�possible�device..‰TRAP…#0“The�address�for�the�memory�segment�is*¦returned�in�A0.‰BRA.S„INIT20�Good�return!‰BRA.S„INITERRŽBad�return. EINIT20ƒMOVE.LƒA0,SAVECAP(A5)‡Save�the�base�address�of�the�CAP�pointer8‰MOVEQ.L‚#DRIVES,D1‹**‚01/03/86‚Clear�the�packet�memory.‰MULU…#PKTLONG,D13‰SUBQ.Lƒ#1,D1�D1�<--�number�of�long�words�to�clear.INIT25ƒCLR.L„(A0)+‰DBRA…D1,INIT25 7‰MOVE.LƒSAVECAP(A5),A0‡Restore�the�CAP�pointer�into�A0.NNN6‰MOVE.LƒA0,A2�Copy�it�into�A2�for�the�next�subroutine,>‰MOVE.LƒCCBCHB(A5),A0ˆand�get�the�VM22�channel's�memory-mapped*¦I/O�area�into�A0. :‰MOVE.Lƒ#TIMEOUT*2000,D1‡Assure�that�the�controller�is�not7INIT30ƒSUBQ.Lƒ#1,D1�performing�the�self-test/initialize2‰BEQ†INITERRŽroutines.‚Communication�should�not�be=‰BTST…#CSRDY,STATUS(A0)„attempted�while�the�bit�is�set.�Then,2‰BEQ†INIT30�assure�the�controller�has�not�detected?‰BTST…#CSFLT,STATUS(A0)„a�fault.�Allow�approximately�15�seconds‰BEQ.S„INITDONE�for�timeout. >‰MOVE.Bƒ#$40,CONTROL(A0)‡If�the�fault�bit�is�set,�try�reseting=‰MOVE.Bƒ#$00,CONTROL(A0)…the�VM22�controller.‚Set�the�bits�to'*¦perform�a�self-test�and�allow�SYSFAIL*¦when�coming�out�of�reset. 5‰BSR.S„REQSTATŽRequest�the�status�of�the�latest�self-5‰BEQ.S„INITDONE�test.‚If�an�error�was�again�detected,?INITERR‚SNE.B„CHANDOWN(A5)‰shut�the�channel�down�by�setting�the+INITDONE�RTS›variable�CHANDOWN�to�non-zero. PAGEO********************************************************************************3*ˆREQUEST�SELF-TEST�STATUS�FROM�THE�VM22�CONTROLLER*NN  NC*ˆThis�subroutine�requests�status�about�the�last�self-test�from�theA*ˆVM22�Controller.�It�sends�a�request�self-test�status‚command‚toF*ˆthe�controller�and�then�moves�the�status�byte�from�the�status�packet?*ˆto�register�D0.�The�request�is�made�using�the�polling�method.*=*ˆEntry:„A0�=�Physical�address�of�VM22�Memory-mapped�I/O�area)*’A2�=�Command�packet�address�for�drive�0*!*ˆRegister�usage:‰0�1�2�3�4�5�6�7*œDƒR�**œAƒPƒP*4*ˆExits�to:�Caller�via�RTS�with�condition�codes�set:*’‚Self-test�passed.4*’‚Self-test�failed�or�cannot�perform�self-test.*O******************************************************************************* REQSTAT:8‰MOVE.L„#TIMEOUT*10,D1ˆAssure�that�the�controller�is�not7REQ100ƒSUBQ.L„#1,D1�performing�the�self-test/initialize1‰BEQ‡REQERRŽroutines.‚Communication�should�not�be7‰BTST†#CSRDY,STATUS(A0)ƒattempted�while�the�bit�is�set.1‰BEQ‡REQ100Žassure�no�errors�were�detected�during ?‰MOVE.B„#CMDREQ,CMDCODE(A2)ƒSet�up�a�type�1�command�packet�with>‰MOVE.W„#0,INTLEV(A2)‡the�REQUEST�command�opcode�and�interrupt&*¦level�and�vector�number�set�to�zero. 7‰MOVE.L„#TIMEOUT,D1‹Assure�that�the�controller�is�ready�status.‰ENDNNNNN  N' VMES10 CRTINIT AFUU  EDITMODEAF^^  FEEDER AFgg  INCHAR AFpp  OUTCHS AFyy  PAGEMODEAF‚‚  POUTCHS AF‹‹  TERMDRV AF””  CRTINIT SA��ó  EDITMODESAÆÆv  FEEDER SAOO'"  INCHAR SA€€¥  OUTCHS SA¡¡ÐÙ  PAGEMODESAzzs  POUTCHS SA“„ó   TERMDRV SA•†Ìw  =/*=/*†VMES10.CRTINIT.AF=/*8=/* Chain file to assemble VME/10 screen/keyboard driver=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to VMES10.CRTINIT.LS=/*=/IFC \1ƒ=ARG�VMES10.CRTINIT.LS=/ENDIF=/*2=ASM VMES10.CRTINIT.SA,VMES10.CRTINIT.RO,\1;RZ=140=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNNNM=/*=/*†VMES10.EDITMODE.AF=/*8=/* Chain file to assemble VME/10 screen/keyboard driver=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to VMES10.EDITMODE.LS=/*=/IFC \1ƒ=ARG�VMES10.EDITMODE.LS=/ENDIF=/*4=ASM VMES10.EDITMODE.SA,VMES10.EDITMODE.RO,\1;RZ=140=/*{ Included files are:=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.VMES10.TERMDRV.EQ=/*}=/*=END  NNNNNNV=/*=/*†VMES10.FEEDER.AF=/*M=/* Chain file to assemble VMES10.FEEDER.SA for VME/10 screen/keyboard driver=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to VMES10.FEEDER.LS=/*=/IFC \1ƒ=ARG�VMES10.FEEDER.LS=/ENDIF=/*0=ASM VMES10.FEEDER.SA,VMES10.FEEDER.RO,\1;RZ=100=/*{ Included files are:=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.VMES10.TERMDRV.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNNNN_  =/*=/*†VMES10.INCHAR.AF=/*M=/* Chain file to assemble VMES10.INCHAR.SA for VME/10 screen/keyboard driver=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to VMES10.INCHAR.LS=/*=/IFC \1ƒ=ARG�VMES10.INCHAR.LS=/ENDIF=/*0=ASM VMES10.INCHAR.SA,VMES10.INCHAR.RO,\1;RZ=140=/*{ Included files are:=/*ƒ9995.&.UTILITY.MC=/*}=/*=ENDNNNNNNh=/*=/*†VMES10.OUTCHS.AF=/*M=/* Chain file to assemble VMES10.OUTCHS.SA for VME/10 screen/keyboard driver=/*:=/* If no output argument is specified for the listing the/=/* chain file will default to VMES10.OUTCHS.LS=/*=/IFC \1ƒ=ARG�VMES10.OUTCHS.LS=/ENDIF=/*0=ASM VMES10.OUTCHS.SA,VMES10.OUTCHS.RO,\1;RZ=140=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNN  Nq=/*=/*†VMES10.PAGEMODE.AF=/*B=/* Chain file to assemble VMES10.PAGEMODE.SA for VME/10 page mode=/* input handler=/*:=/* If no output argument is specified for the listing the1=/* chain file will default to VMES10.PAGEMODE.LS=/*=/IFC \1ƒ=ARG�VMES10.PAGEMODE.LS=/ENDIF=/*4=ASM VMES10.PAGEMODE.SA,VMES10.PAGEMODE.RO,\1;RZ=140=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNNNz=/*=/*†VMES10.POUTCHS.AF=/*N=/* Chain file to assemble VMES10.POUTCHS.SA for VME/10 screen/keyboard driver=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to VMES10.POUTCHS.LS=/*=/IFC \1ƒ=ARG�VMES10.POUTCHS.LS=/ENDIF=/*2=ASM VMES10.POUTCHS.SA,VMES10.POUTCHS.RO,\1;RZ=140=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNN  NNNƒ=/*=/*†VMES10.TERMDRV.AF=/*N=/* Chain file to assemble VMES10.TERMDRV.SA for VME/10 screen/keyboard driver=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to VMES10.TERMDRV.LS=/*=/IFC \1ƒ=ARG�VMES10.TERMDRV.LS=/ENDIF=/*2=ASM VMES10.TERMDRV.SA,VMES10.TERMDRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.VMES10.TERMDRV.EQ=/*}=/*=ENDNNNNNŒ4CRTINIT‚IDNT†45,0†Configure�the�virtual�display�area0‰TTL‡CRTINIT:‚Configure�the�virtual�display�areaNN  NNNNN•ž=¦F®E¶*<*************************************************************º**�Routine�name:ŽCRTINIT—*<*----------------------------------------------------------*-*�Current�revision.....................1.00�*1*�Date�written.........................12-21-82Œ*2*�Written�by...........................S.Pri-Tal‹*)*�Date�changed.........................”*)*�Changed�by...........................”**º**�Description�of�change:£**º**º**º**º**º**º*<************************************************************.*�Function:�Initialize�all�the�CRT�constants�*<*----------------------------------------------------------**�Input�parameters:�none£*<*----------------------------------------------------------**�Registers�affected:�none¡*<*----------------------------------------------------------* *�External�routines�used:�none�*<************************************************************‰PAGE ‰XDEF†CRTINIT‰XDEF†SCRNINIT *‰XDEF†FACS�Field�Attribute�Codes�in�effect 5‰XDEF†CPERLINEŒNumber�of�characters�per�absolute�line+‰XDEF†BPERLINEŒNumber�of�bytes�per�RAM�line2‰XDEF†LPERSCRNŒNumber�of�lines�per�absolute�screen "‰XDEF†S.SCRNŽVirtual�home�position*‰XDEF†E.SCRNŽEnd�address�of�virtual�screen 3‰XDEF†C.LINEŽNumber�of�characters�in�a�virtual�line.‰XDEF†B.LINEŽNumber�of�bytes�in�a�virtual�line/‰XDEF†PB.LINE�Number�of�blanked�bytes�in�a�line2‰XDEF†S.LINEŽStart�address�of�virtual�current�line0‰XDEF†E.LINEŽEnd�address�of�virtual�current�line0‰XDEF†L.SCRNŽNumber�of�lines�in�a�virtual�screen (‰XDEF†SCREENŽBase�address�of�display�RAM<‰XDEF†CRTCADD,CRTCREG…Addresses�of�CRT�controller�registers. +‰XDEF†LEFTCOL�Left�column�of�virtual�screen-‰XDEF†RIGHTCOLŒRight�column�of�virtual�screen*$*Š0<=�LEFTCOL/RIGHTCOL�<=�CPERLINE-1*(‰XDEF†TOPLINE�Top�line�of�virtual�screen+‰XDEF†BOTLINE�Bottom�line�of�virtual�screen*#*Š0<=�TOPLINE/BOTLINE�<=�LPERSCRN-1*#‰XDEF†PAGEFLAGŒ0=scroll;�$FFFF=page .SCREENƒEQU‡$F17000�Base�address�of�display�RAM(CRTCADD‚EQU‡$F1A021�Base�address�of�CRTC1CRTCREG‚EQU‡$F1A023�Address�of�CRTC�register�file‰PAGE ‰SECTIONƒ16CPERLINE�DC.W†80’Number�of�characters�in�absolute�line3LPERSCRN�DC.W†25’Number�of�lines�in�absolute�screen6BPERLINE�DC.L†160‘Number�of�bytes�in�absolute�RAM�line*G* The following 4 constants can be changed by using escape sequences or* their eqivalents.*,LEFTCOL‚DC.W†0“Default�value�for�left�column/RIGHTCOL�DC.W†79’Default�value�f  or�right�column)TOPLINE‚DC.W†0“Default�value�for�top�line-BOTLINE‚DC.W†23’Default�value�for�bottom�line 7S.SCRNƒDC.L†$F17000�Init�to�be�the�same�as�start�of�RAM7E.SCRNƒDC.L†$F17F00�End�address�of�virtual�display�area&C.LINEƒDC.W†79’Adjusted�for�DBRA�loopsB.LINEƒDC.L†160)S.LINEƒDC.L†$F17000�Start�of�current�line'E.LINEƒDC.L†$F170A0�End�of�current�linePB.LINE‚DC.W†00&L.SCRNƒDC.W†23’Adjusted�for�DBRA�loops)*C.SCRNƒDC.L†1919�Adjusted�for�DBRA�loopsFACS…DC.W†$4400#PAGEFLAG�DC.W†0“Init�to�scroll�mode‰PAGE‰SECTIONƒ11’Program�areaSCRNINIT�DS.W†0-‰MOVE.W„#80,CPERLINEˆ80�characters�per�screen1‰MOVE.W„#25,LPERSCRNˆ24�lines�in�the�display�area‰CLR.W…TOPLINE‰MOVE.W„#23,BOTLINE‰CLR.W…LEFTCOL‰MOVE.W„#79,RIGHTCOL‰CLR.W…PAGEFLAG SPC 1 CRTINIT‚EQU‡*'‰MOVEM.LƒD0/A0,-(A7)‰Save�user's�values‰CLR.L…D0’HSKP ** Init the FACs register*‰MOVE.W„#$4400,FACS**ˆD15†cleared�for�unprotect*ˆD14†set�for�display*ˆD13†cleared�for�non-blink*ˆD12†cleared�for�no�underline$*ˆD11†cleared�for�non�inverted�video<*ˆD10-D08‚set�for�half�brightness�(111�=�maximum�brightness)*ˆD07†cleared�for�no�TAB*ˆD06-D00‚null�character* *9* Init number of RAM bytes required for one absolute line**’BPERLINE�=�CPERLINE*2*:‰MOVE.W„CPERLINE,D0‰Maximum�number�of�characters�in�a�line‰LSL.L…#1,D0Ž*2,‰MOVE.L„D0,BPERLINEˆ=Bytes�per�absolute�line *M* Init the number of character per line in the virtual display area - C.LINE.*!*’C.LINE�=�RIGHTCOL�-�LEFTCOL�+�1*>* (adjusted for DBRA loops, expressed in characters on screen)* ‰CLR.L…D0;‰MOVE.W„RIGHTCOL,D0‰Requested�last�column�in�virtual�screen;‰SUB.W…LEFTCOL,D0‰-Requested�first�column�in�virtual�screen9‰MOVE.W„D0,C.LINEŠ=Number�of�characters�in�a�virtual�line*¦-1�to�adjust�for�DBRA�loops ‰ADD.W…#1,D0 ‰LSL.W…#1,D0-‰MOVE.L„D0,B.LINE‹Init�bytes�per�virtual�line *1* Init the number of blanked bytes in a RAM line.* *’PB.LINE�=[CPERLINE�-�C.LINE]*2* ‰CLR.L…D0<‰MOVE.W„CPERLINE,D0‰Number�of�characters�in�an�absolute�line8‰SUB.W…C.LINE,D0Š-Number�of�characters�in�a�virtual�line)‰SUB.W…#1,D0�To�adjust�for�the�DBRA�value‰LSL.W…#1,D0�Times�29‰MOVE.W„D0,PB.LINE‰=Number�of�blanked�bytes�in�a�RAM�line *@* Init the number of lines in the virtual display area - L.SCRN.**’L.SCRN�=�BOTLINE�-�TOPLINE�+1** Adjusted for DBRA loops* ‰CLR.L…D0(‰MOVE.W„BOTLINE,D0ŠRequested�bottom�line%‰SUB.W…TOPLINE,D0‰-Requested�top�line6‰MOVE.W„D0,L.SCRNŠ=Number�of�lines�in�a�virtual�screen *D* Init the number of character in the virtual display area - C.SCRN.*#*’C.SCRN�=�[C.LINE�+1]�*�[L.SCRN+1]*H* (adjusted for DBRA loops, expressed in number of characters in screen)* *ˆCLR.L…D09*ˆMOVE.W„C.LINE,D0‹Number�of�characters�in�a�virtual�line$*ˆADD.W…#1,D0�To�adjust�for�the�DBRA*ˆMOVE.W„D0,C.SCRN6*ˆMOVE.W„L.SCRN,D0‹Number�of�lines�in�a�virtual�screen$*ˆADD.W…#1,D0�To�adjust�for�the�DBRA<*ˆMULU.W„C.SCRN,D0Š=Number�of�characters�in�a�virtual�screen*ˆMOVE.W„D0,C.SCRN-*ˆSUB.W…#1,C.SCRNŠ-1�to�adjust�for�DBRA�loops *H* Init the absolute address of home position in the virtual display area*0*ˆS.SCRN�=�SCREEN�+�TOPLINE*BPERLINE�+�LEFTCOL*2* ,‰MOVE.L„BPERLINE,D0ˆ=Bytes�per�absolute�line0‰MULU.W„TOPLINE,D0‰=Unused�area�on�top�of�screen‰ADD.W…LEFTCOL,D00‰ADD.W…LEFTCOL,D0‰+Unused�bytes�at�start�of�line.‰ADD.L…#SCREEN,D0‰+Base�address�of�display�RAM+‰MOVE.L„D0,S.SCRNŠ=Virtual�home�RAM�address *B* Init the absolute address of the end of the virtual display area*1*ˆE.SCRN�=�SCREEN�+�BOTLINE*BPERLINE�+�RIGHTCOL*2*,‰MOVE.L„BPERLINE,D0ˆ=Bytes�per�absolute�line9‰MULU.W„BOTLINE,D0‰=Number�of�bytes�to�start�of�last�line‰ADD.W…RIGHTCOL,D07‰ADD.W…RIGHTCOL,D0ˆ=Number�of�bytes�to�end�of�last�line&‰ADD.L…#SCREEN,D0‰=Base�address�of�RAM ‰ADD.L…#2,D01‰MOVE.L„D0,E.SCRNŠ=End�of�virtual�screen�in�RAM+1 *?* Init S.LINE to point to start address of cursor virtual line.=* Init E.LINE to p oint to end address of cursor virtual line.*‰CLR.L…D0’HSKP ‰MOVE.B„#$E,CRTCADD‰Point�to�R14‰MOVE.B„CRTCREG,D0 ‰LSL.W…#8,D0‰MOVE.B„#$F,CRTCADD2‰MOVE.B„CRTCREG,D0ŠD0.W=absolute�address�of�cursor ‰LSL.W…#1,D0 ‰MOVE.L„D0,A02‰ADD.L…#SCREEN,A0ŠA0.L=address�of�cursor�on�screen ‰LSR.W…#1,D0‰DIVU†CPERLINE,D0‰D0.L=00cc00ll‰SWAP†D0’D0.W=00cc7‰SUB.W…LEFTCOL,D0ŠD0.W=number�of�spots�to�start�of�line‰LSL.W…#1,D0�To�make�it�bytes ‰SUB.W…D0,A0‰MOVE.L„A0,S.LINE ‰ADD.W…C.LINE,A0‰ADD.W…C.LINE,A0 ‰ADD.W…#2,A0‰MOVE.L„A0,E.LINE‰MOVEM.Lƒ(A7)+,D0/A0‰RTS‰END NNN:EDITMODE‚IDNTƒ45,0‡VME/10�edit�mode�emulation�for�TERMDRV.6ŠTTL„EDITMODE:‚VME/10�edit�mode�emulation�for�TERMDRV.NNNNNNN ¾Ç7Ï?×Fß:ç3ï*÷)ÿ,)'1>'G/O7@?8O*v*****************************************************************************O*******************************************************************************O**********************************************************************************É*** =***†FILENAME:‚EDITMODE�--�EDIT�MODE�EMULATION�FOR�TERMDRV�******É***8***†ENVIRONMENT:‚Linked�into�TERMDRV�for�the�VME/10.’******É***E***†FUNCTION:‚When�the�keyboard/screen�is�put�into�edit�mode,�any…***?***‰characters�received�from�the�keyboard�are�sent�here�for‰******‰special�interpretation.©******É***B***†NOTES:‚Only�RETURN�COMMAND�mode�is�implemented;�NON-RETURNˆ***D***‰COMMAND�mode�is�not�since�the�VERSAdos�editor�(E.LO)�doesn't„******‰use�it.¹******É***,***†EXTERNAL�DATA�STRUCTURES�REFERENCED:Ÿ*** ***‰CCB�for�terminal�driver.¨***(***‰Various�parameters�from�CRTINIT. ******É***)***†EXTERNAL�ENTRY�POINTS�REFERENCED:¢******‰OUTCHSº******É***"***†SERVICES�CALLED�VIA�TRAPS:©******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------;*†1/30/85‚Mike�Duh‡Set�RING_BELL�flag�when�$07�is�detected.2*†7/19/83‚Steve�FranckƒSeparated�out�FEEDER�stuff.'*†4/31/83‚Steve�FranckƒInitial�writing.*ŠPAGE* *‚XDEF's.*:ŠXDEFƒEDITMODE‹Entry�pt.�for�char's�received�in�edit�mode.5ŠXDEFƒKB_LOCKŒFlag�indicating�whether�the�keyboard�is(*§locked�(from�having�sent�a�termination*§packet�in�edit�mode).7ŠXDEFƒDUP_CHAR‹This�is�a�word�field,�$FFFF�if�there�was%*§no�DUPLICATE�CHAR�specified�when�we'*§got�put�into�command�mode,�else�$00dd%*§($dd=the�DUPLICATE�CHAR)�if�one�was *§specified.    *0*‚XREF's�(indicate�where�the�XDEF�is,�if�known).*8ŠXREFƒOUTCHS�Routine�in�OUTCHS�to�output�char�on�screen./*ž(All�of�the�following�are�XDEF'ed�in�CRTINIT)9ŠXREFƒBPERLINE‹#�of�bytes�per�absolute�display�line�(.L).$*§Note�that�since�this�is�a�longword#*§the�address�BPERLINE+2�is�used�in%*§DIVU�instructions�(which�use�only�a"*§word�for�the�divisor).‚The�upper*§word�is�always�0.3ŠXREFƒC.LINE�#�of�char's�per�virtual�line�-�1�(.W).DŠXREFƒS.LINE,E.LINE�Start/end�addr�+�1�of�current�virtual�line�(.L).>ŠXREFƒS.SCRN,E.SCRN†Start/end�addr�+�1�of�virtual�screen�(.L).4ŠXREFƒSCREEN�Base�address�of�screen�RAM�(an�equate).?ŠXREFƒCRTCADD,CRTCREG„Addr's�of�CRT�controller�reg's�(equates)..*ž(All�of�the�following�are�XDEF'ed�in�FEEDER)3ŠXREFƒFEEDER�Entry�point�and�some�variables�for�the>ŠXREFƒFEEDER_ADDRESS…FEEDER�module�which�takes�our�packets�and)ŠXREFƒFEEDER_COUNT‡gives�them�to�TERMDRV. 0ŠXREFƒRING_BELL‹Flag�set�when�$07�is�detected�in&*žorder�to�ring�the�bell�in�KEYBRD.AG.ŠPAGEO*********************************************************************************‰INCLUDE�FILES�AND�EQUATES*O******************************************************************************* *=*‚Define�the�environment�as�EXORMACS/S�in�a�switch�to�control*‚conditional�assemblies.*2ENVIRONMENT�EQU‚'EX/S'�This�is�for�the�EXORMACS/S.  **‚Include�files:5*‰UTILITY.MC‹General�purpose�macros�(e.g.�PUSH,�POP).,*‰IOE.SA�Equates�for�IOS-related�structures.7*‰EQUCCB.EQŒEquates�for�device-independent�part�of�CCB.9*‰TERMDRV.EQ‹Equates�for�the�generalized�terminal�driver.*ŠNOLISTŠINCLUDE‚9995.&.UTILITY.MCŠINCLUDE‚9995.&.IOE.EQŠINCLUDE‚9995.&.CCB.EQŠINCLUDE‚9995.VMES10.TERMDRV.EQŠLIST  .FALSE…EQU„$00�Value�FALSE�for�a�flag�variable.,TRUE†EQU„$FF�Value�TRUE‚for�a�flag�variable.  4BSˆEQU„$08�Definitions�for�certain�ASCII�characters. LFˆEQU„$0A�* CRˆEQU„$0D�*SPACE…EQU„$20�*DELETE„EQU„$7F�*  5HOME†EQU„$C0�Definitions�for�certain�characters�which7UPARROWƒEQU„$C1�are�recognized�by�the�EXORTERM�155�(and4DOWNARROW�EQU„$C2�hence�OUTCHS)�as�special�commands.ERASE_EOL�EQU„$D5�*DEL_LINE‚EQU„$D7�*  :START_OF_DATA�EQU�$DD�Definitions�for�certain�parts�of�the1FILLER_BYTE�EQU‚$FF�packet�retur ned�in�edit�mode.END_OF_DATA�EQU‚$DE�*ŠPAGEO*********************************************************************************‰MISCELLANEOUS�MACROS*O*******************************************************************************  *G*‚The�OUTPUT�and�OUTPUT_D0�macros�invoke�the�external�subroutine�OUTCHSF*‚to�output�a�character�to�the�EXORMACS/S�screen.‚OUTPUT_D0�just�callsC*‚the�routine�to�output�whatever�is�in�D0.B,�while�OUTCHS�has�as�anH*‚argument�the�value�of�a�character.‚This�character�must�be�in�the�rangeH*‚$00�-�$FF,�of�course,�and�must�be�an�immediate�value�specified�WITHOUT*‚THE�'#'.‚For�example,7*‰OUTPUT�'A'ƒcauses�an�'A'�to�be�written�to�the�screen.*OUTPUT_D0 MACRO ŠBSR.L‚OUTCHSŠENDM OUTPUT„MACRO ŠIFGEƒ\1-$80ŠMOVEQ‚#$FFFFFF00+\1,D0ŠENDC ŠIFLTƒ\1-$80 ŠMOVEQ‚#\1,D0ŠENDC ŠBSR.L‚OUTCHSŠENDMŠPAGEO*********************************************************************************‰DATA�VARIABLES*O******************************************************************************* ŠSECTION�0 **‚Flags.*�THENŠIf�there�is�one,1ŠCMP.B‚D0,D1Ž.‚If�this�character�is�one�of�those,&ŠBEQ.L‚ERASE_LINE‰.‚go�erase�the�line.ŠENDI–. ,ŠCLR„D1‘D1.W�<--�offset�from�table,�which�is4ŠMOVE.B�EDIT_TBL(PC,D0),D1�(routine�addr�-�JMPBASE).;ŠLEA„JMPBASE(PC),A0…Jump�to�the�specified�routine:‚that�is,4ŠJMP„0(A0,D1)‹to�JMPBASE�+�(routine�ad dr�-�JMPBASE).ŠPAGEO********************************************************************************:*‰TABLE�OF�ACTION�TO�TAKE�FOR�EACH�CHAR�WHILE�IN�EDIT�MODE*O******************************************************************************* EDIT_TBL: ***************7*‚$00�-�$1F‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------&ŠDC.BƒIGNORE-JMPBASE…$00�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$01�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$02�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$03�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$04�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$05�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$06�--�Ignore�it.ŠDC.BƒBELL-JMPBASE‡$07�--�Bell.,ŠDC.BƒPRINT-JMPBASE†$08�--�Print�as�is.�(BS)-ŠDC.BƒPRINT-JMPBASE†$09�--�Print�as�is.�(TAB)7ŠDC.BƒDO_LF-JMPBASE†$0A�--�Special�processing�for�(LF).@ŠDC.BƒPRINT_TERM-JMPBASE�$0B�--�Print�and�send�packet.�(UP�LINE)6ŠDC.BƒPRINT-JMPBASE†$0C�--�Print�as�is.�(CURSOR�RIGHT)7ŠDC.BƒDO_CR-JMPBASE†$0D�--�Special�processing�for�(CR).&ŠDC.BƒIGNORE-JMPBASE…$0E�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$0F�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$10�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$11�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$12�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$13�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$14�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$15�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$16�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$17�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$18�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$19�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$1A�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$1B�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$1C�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$1D�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$1E�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$1F�--�Ignore�it.ŠPAGE***************7*‚$20�-�$3F‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------0ŠDC.B‚PRINT_LOOK-JMPBASE�$20�--�Print�as�is.‚(�)0ŠDC.B‚PRINT_LOOK-JMPBASE�$21�--�Print�as�is.‚(!)0ŠDC.B‚PRINT_LOOK-JMPBASE�$22�--�Print�as�is.‚(")0ŠDC.B‚PRINT_LOOK-JMPBASE�$23�--�Print�as�is.‚(#)0ŠDC.B‚PRINT_LOOK-JMPBASE�$24�--�Print�as�is.‚($)0ŠDC.B‚PRINT_LOOK-JMPBASE�$25�--�Print�as�is.‚(%)0ŠDC.B‚PRINT_LOOK-JMPBASE�$26�--�Print�as�is.‚(&)0ŠDC.B‚PRINT_LOOK-JMPBASE�$27�--�Print�as�is.‚(')0ŠDC.B‚PRINT_LOOK-JMPBASE�$28�--�Print�as�is.‚(()0ŠDC.B‚PRINT_LOOK-JMPBASE�$29�--�Print�as�is.‚())0ŠDC.B‚PRINT_LOOK-JMPBASE�$2A�--�Print�as�is.‚(*)0ŠDC.B‚PRINT_LOOK-JMPBASE�$2B�--�Print�as�is.‚(+)0ŠDC.B‚PRINT_LOOK-JMPBASE�$2C�--�Print�as�is.‚(,)0ŠDC.B‚PRINT_LOOK-JMPBASE�$2D�--�Print�as�is.‚(-)0ŠDC.B‚PRINT_LOOK-JMPBASE�$2E�--�Print�as�is.‚(.)0ŠDC.B‚PRINT_LOOK-JMPBASE�$2F�--�Print�as�is.‚(/)0ŠDC.B‚PRINT_LOOK-JMPBASE�$30�--�Print�as�is.‚(0)0ŠDC.B‚PRINT_LOOK-JMPBASE�$31�--�Print�as�is.‚(1)0ŠDC.B‚PRINT_LOOK-JMPBASE�$32�--�Print�as�is.‚(2)0ŠDC.B‚PRINT_LOOK-JMPBASE�$33�--�Print�as�is.‚(3)0ŠDC.B‚PRINT_LOOK-JMPBASE�$34�--�Print�as�is.‚(4)0ŠDC.B‚PRINT_LOOK-JMPBASE�$35�--�Print�as�is.‚(5)0ŠDC.B‚PRINT_LOOK-JMPBASE�$36�--�Print�as�is.‚(6)0ŠDC.B‚PRINT_LOOK-JMPBASE�$37�--�Print�as�is.‚(7)0ŠDC.B‚PRINT_LOOK-JMPBASE�$38�--�Print�as�is.‚(8)0ŠDC.B‚PRINT_LOOK-JMPBASE�$39�--�Print�as�is.‚(9)0ŠDC.B‚PRINT_LOOK-JMPBASE�$3A�--�Print�as�is.‚(:)0ŠDC.B‚PRINT_LOOK-JMPBASE�$3B�--�Print�as�is.‚(;)0ŠDC.B‚PRINT_LOOK-JMPBASE�$3C�--�Print�as�is.‚(<)0ŠDC.B‚PRINT_LOOK-JMPBASE�$3D�--�Print�as�is.‚(=)0ŠDC.B‚PRINT_LOOK-JMPBASE�$3E�--�Print�as�is.‚(>)0ŠDC.B‚PRINT_LOOK-JMPBASE�$3F�--�Print�as�is.‚(?)ŠPAGE***************7*‚$40�-�$5F‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------0ŠDC.B‚PRINT_LOOK-JMPBASE�$40�--�Print�as�is.‚(@)0ŠDC.B‚PRINT_LOOK-JMPBASE�$41�--�Print�as�is.‚(A)0ŠDC.B‚PRINT_LOOK-JMPBASE�$42�--�Print�as�is.‚(B)0ŠDC.B‚PRINT_LOOK-JMPBASE�$43�--�Print�as�is.‚(C)0ŠDC.B‚PRINT_LOOK-JMPBASE�$44�--�Print�as�is.‚(D)0ŠDC.B‚PRINT_LOOK-JMPBASE�$45�--�Print�as�is.‚(E)0ŠDC.B‚PRINT_LOOK-JMPBASE�$46�--�Print�as�is.‚(F)0ŠDC. B‚PRINT_LOOK-JMPBASE�$47�--�Print�as�is.‚(G)0ŠDC.B‚PRINT_LOOK-JMPBASE�$48�--�Print�as�is.‚(H)0ŠDC.B‚PRINT_LOOK-JMPBASE�$49�--�Print�as�is.‚(I)0ŠDC.B‚PRINT_LOOK-JMPBASE�$4A�--�Print�as�is.‚(J)0ŠDC.B‚PRINT_LOOK-JMPBASE�$4B�--�Print�as�is.‚(K)0ŠDC.B‚PRINT_LOOK-JMPBASE�$4C�--�Print�as�is.‚(L)0ŠDC.B‚PRINT_LOOK-JMPBASE�$4D�--�Print�as�is.‚(M)0ŠDC.B‚PRINT_LOOK-JMPBASE�$4E�--�Print�as�is.‚(N)0ŠDC.B‚PRINT_LOOK-JMPBASE�$4F�--�Print�as�is.‚(O)0ŠDC.B‚PRINT_LOOK-JMPBASE�$50�--�Print�as�is.‚(P)0ŠDC.B‚PRINT_LOOK-JMPBASE�$51�--�Print�as�is.‚(Q)0ŠDC.B‚PRINT_LOOK-JMPBASE�$52�--�Print�as�is.‚(R)0ŠDC.B‚PRINT_LOOK-JMPBASE�$53�--�Print�as�is.‚(S)0ŠDC.B‚PRINT_LOOK-JMPBASE�$54�--�Print�as�is.‚(T)0ŠDC.B‚PRINT_LOOK-JMPBASE�$55�--�Print�as�is.‚(U)0ŠDC.B‚PRINT_LOOK-JMPBASE�$56�--�Print�as�is.‚(V)0ŠDC.B‚PRINT_LOOK-JMPBASE�$57�--�Print�as�is.‚(W)0ŠDC.B‚PRINT_LOOK-JMPBASE�$58�--�Print�as�is.‚(X)0ŠDC.B‚PRINT_LOOK-JMPBASE�$59�--�Print�as�is.‚(Y)0ŠDC.B‚PRINT_LOOK-JMPBASE�$5A�--�Print�as�is.‚(Z)0ŠDC.B‚PRINT_LOOK-JMPBASE�$5B�--�Print�as�is.‚([)0ŠDC.B‚PRINT_LOOK-JMPBASE�$5C�--�Print�as�is.‚(\)0ŠDC.B‚PRINT_LOOK-JMPBASE�$5D�--�Print�as�is.‚(])0ŠDC.B‚PRINT_LOOK-JMPBASE�$5E�--�Print�as�is.‚(^)0ŠDC.B‚PRINT_LOOK-JMPBASE�$5F�--�Print�as�is.‚(_)ŠPAGE***************7*‚$60�-�$7F‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------0ŠDC.B‚PRINT_LOOK-JMPBASE�$60�--�Print�as�is.‚(`)0ŠDC.B‚PRINT_LOOK-JMPBASE�$61�--�Print�as�is.‚(a)0ŠDC.B‚PRINT_LOOK-JMPBASE�$62�--�Print�as�is.‚(b)0ŠDC.B‚PRINT_LOOK-JMPBASE�$63�--�Print�as�is.‚(c)0ŠDC.B‚PRINT_LOOK-JMPBASE�$64�--�Print�as�is.‚(d)0ŠDC.B‚PRINT_LOOK-JMPBASE�$65�--�Print�as�is.‚(e)0ŠDC.B‚PRINT_LOOK-JMPBASE�$66�--�Print�as�is.‚(f)0ŠDC.B‚PRINT_LOOK-JMPBASE�$67�--�Print�as�is.‚(g)0ŠDC.B‚PRINT_LOOK-JMPBASE�$68�--�Print�as�is.‚(h)0ŠDC.B‚PRINT_LOOK-JMPBASE�$69�--�Print�as�is.‚(i)0ŠDC.B‚PRINT_LOOK-JMPBASE�$6A�--�Print�as�is.‚(j)0ŠDC.B‚PRINT_LOOK-JMPBASE�$6B�--�Print�as�is.‚(k)0ŠDC.B‚PRINT_LOOK-JMPBASE�$6C�--�Print�as�is.‚(l)0ŠDC.B‚PRINT_LOOK-JMPBASE�$6D�--�Print�as�is.‚(m)0ŠDC.B‚PRINT_LOOK-JMPBASE�$6E�--�Print�as�is.‚(n)0ŠDC.B‚PRINT_LOOK-JMPBASE�$6F�--�Print�as�is.‚(o)0ŠDC.B‚PRINT_LOOK-JMPBASE�$70�--�Print�as�is.‚(p)0ŠDC.B‚PRINT_LOOK-JMPBASE�$71�--�Print�as�is.‚(q)0ŠDC.B‚PRINT_LOOK-JMPBASE�$72�--�Print�as�is.‚(r)0ŠDC.B‚PRINT_LOOK-JMPBASE�$73�--�Print�as�is.‚(s)0ŠDC.B‚PRINT_LOOK-JMPBASE�$74�--�Print�as�is.‚(t)0ŠDC.B‚PRINT_LOOK-JMPBASE�$75�--�Print�as�is.‚(u)0ŠDC.B‚PRINT_LOOK-JMPBASE�$76�--�Print�as�is.‚(v)0ŠDC.B‚PRINT_LOOK-JMPBASE�$77�--�Print�as�is.‚(w)0ŠDC.B‚PRINT_LOOK-JMPBASE�$78�--�Print�as�is.‚(x)0ŠDC.B‚PRINT_LOOK-JMPBASE�$79�--�Print�as�is.‚(y)0ŠDC.B‚PRINT_LOOK-JMPBASE�$7A�--�Print�as�is.‚(z)0ŠDC.B‚PRINT_LOOK-JMPBASE�$7B�--�Print�as�is.‚({)0ŠDC.B‚PRINT_LOOK-JMPBASE�$7C�--�Print�as�is.‚(|)0ŠDC.B‚PRINT_LOOK-JMPBASE�$7D�--�Print�as�is.‚(})0ŠDC.B‚PRINT_LOOK-JMPBASE�$7E�--�Print�as�is.‚(~)7ŠDC.BƒDO_DEL-JMPBASE…$7F�--�Special�handling�for�(DEL).ŠPAGE***************7*‚$80�-�$9F‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------&ŠDC.BƒIGNORE-JMPBASE…$80�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$81�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$82�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$83�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$84�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$85�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$86�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$87�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$88�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$89�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$8A�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$8B�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$8C�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$8D�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$8E�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$8F�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$90�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$91�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$92�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$93�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$94�--�Ignore�it.&ŠDC.BƒIGNORE-J MPBASE…$95�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$96�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$97�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$98�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$99�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$9A�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$9B�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$9C�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$9D�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$9E�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$9F�--�Ignore�it.ŠPAGE***************7*‚$A0�-�$BF‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------9ŠDC.BƒTERMINATE-JMPBASE‚$A0�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A1�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A2�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A3�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A4�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A5�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A6�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A7�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A8�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$A9�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$AA�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$AB�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$AC�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$AD�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$AE�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$AF�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B0�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B1�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B2�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B3�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B4�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B5�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B6�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B7�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B8�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$B9�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$BA�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$BB�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$BC�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$BD�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$BE�--�Function�key:�send�packet.9ŠDC.BƒTERMINATE-JMPBASE‚$BF�--�Function�key:�send�packet.ŠPAGE***************7*‚$C0�-�$DF‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------=ŠDC.BƒPRINT_TERM-JMPBASE�$C0�--�Print�and�send�packet.‚(HOME)BŠDC.BƒPRINT_TERM-JMPBASE�$C1�--�Print�and�send�packet.‚(CURSOR�UP)DŠDC.BƒPRINT_TERM-JMPBASE�$C2�--�Print�and�send�packet.�(CURSOR�DOWN)5ŠDC.BƒPRINT-JMPBASE†$C3�--�Print�as�is.‚(CURSOR�LEFT)6ŠDC.BƒPRINT-JMPBASE†$C4�--�Print�as�is.‚(CURSOR�RIGHT)&ŠDC.BƒIGNORE-JMPBASE…$C5�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$C6�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$C7�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$C8�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$C9�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$CA�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$CB�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$CC�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$CD�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$CE�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$CF�--�Ignore�it.DŠDC.BƒPRINT_CHANGE-JMPBASE�$D0�--�Print�&�change.�(CHARACTER�INSERT)DŠDC.BƒPRINT_CHANGE-JMPBASE�$D1�--�Print�&�change.�(CHARACTER�DELETE)&ŠDC.BƒIGNORE-JMPBASE…$D2�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$D3�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$D4�--�Ignore�it.BŠDC.BƒERASE_LINE-JMPBASE�$D5�--�Special�handling�for�(ERASE�LINE).DŠDC.BƒPRINT_TERM-JMPBASE�$D6�--�Print�and�send�packet.�(LINE�INSERT)DŠDC.BƒPRINT_TERM-JMPBASE�$D7�--�Print�and�send�packet.�(LINE�DELETE)&ŠDC.BƒIGNORE-JMPBASE…$D8�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$D9�--�Ignore�it.5ŠDC.BƒPRINT-JMPBASE†$DA�--�Print�as�is.‚(FORWARD�TAB)6ŠDC.BƒPRINT-JMPBASE†$DB�--�Print�as�is.‚(BACKWAR D�TAB)&ŠDC.BƒIGNORE-JMPBASE…$DC�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$DD�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$DE�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$DF�--�Ignore�it.ŠPAGE***************7*‚$E0�-�$FF‚*ƒRoutine�offsetˆCharƒDescription�of�actionF***************ƒ----------------†----ƒ--------------------------------&ŠDC.BƒIGNORE-JMPBASE…$E0�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E1�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E2�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E3�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E4�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E5�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E6�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E7�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E8�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$E9�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$EA�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$EB�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$EC�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$ED�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$EE�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$EF�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F0�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F1�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F2�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F3�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F4�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F5�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F6�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F7�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F8�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$F9�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$FA�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$FB�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$FC�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$FD�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$FE�--�Ignore�it.&ŠDC.BƒIGNORE-JMPBASE…$FF�--�Ignore�it.ŠPAGEO*v*****************************************************************************O**********************************************************************************É***7***�GET_CURSOR_ADDRESS�--�RETURNS�ADDRESS�OF�CURSOR�******É***=***†FUNCTION:‚This�routine�returns�the�address�of�the�CRT�***?***‰controller�cursor,�relative�to�the�base�of�the�RAM�used‰***C***‰to�hold�the�characters�to�be�displayed�(called�screen�RAM).…******É******†NOTES:½******É******É***E***†REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturned‚***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒRƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆD�******‡A:ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ. ******É******†ENTRY�CONDITIONS:²******É***-***†EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:ž***@***‰D0.L�=�the�address�of�the�cursor�relative�to�screen�RAM.ˆ******É***O*^*****************************************************************************O******************************************************************************* GET_CURSOR_ADDRESS: !ŠMOVEQ‚#0,D0ŽD0�<--�$00�00�00�00. 9ŠMOVE.B�#$0E,CRTCADD‡D0�<--�$00�00�hh�00,�where�hh�is�the7ŠMOVE.B�CRTCREG,D0‰high�address�byte�taken�from�the�CRTŠLSL„#8,D0Žcontroller. 9ŠMOVE.B�#$0F,CRTCADD‡D0�<--�$00�00�hh�ll,�where�ll�is�the<ŠMOVE.B�CRTCREG,D0‰low�address�byte�from�the�CRT�controller. 4ŠADD.L‚D0,D0ŽConvert�from�char�address�to�byte�addr. ŠRTS—Return.ŠPAGEO*v********************************************************************************;***…CODE�TO�PERFORM�ACTIONS�FOR�CHAR'S�ENTERED�IN�EDIT�MODE*** ***…FUNCTION:F***‡Except�for�DUPLICATE,�these�are�all�routines�specified�in�EDIT_TBLC***‡for�the�handling�of�incoming�characters�in�edit�mode.‚DUPLICATEE***‡is�different�in�that�it�is�checked�for�separately�since�it�is�notE***‡known�at�assembly�time�which�character�will�be�the�DUPLICATE�char)***‡(and�the�EDIT_TBL�should�be�ROMable).****** ***…NOTES:*********…ENTRY�CONDITIONS:***‡D0.B�=�the�char�entered."***‡A5ƒ=�address�of�TERMDRV's�CCB.***O*^*****************************************************************************  **********6*‚Duplicate�on�this�line�the�char�from�the�line�above.* DUPLICATE:=ŠMOVE.L�S.LINE(PC),D0†If�we're�on�the�top�line�(start�of�this=ŠCMP.L‚S.SCRN(PC),D0†line�=�start�of�screen),�just�ignore�theŠBEQ.L‚IGNORE�DUPLICATE�char. =ŠBSR„GET_CURSOR_ADDRESS�We're�not�on�the�top�line,�so�get�the6ŠADD.L‚#SCREEN ,D0‰address�of�the�cursor�in�screen�RAM.?ŠSUB.L‚BPERLINE(PC),D0„A0�<--�addr�of�the�character�above�this.ŠMOVE.L�D0,A0Ž*4ŠMOVEQ‚#$7F,D0ŒD0.B�<--�the�char�there�(bits�0�-�6).ŠAND„(A0),D0Œ*-ŠBRA„PRINT_LOOKˆGo�act�like�he�typed�that�in.  *J*‚JMPBASE�is�used�in�constructing�the�table�EDIT_TBL.‚The�table�designatesM*‚the�routine�to�be�executed�for�a�given�char�by�storing�the�routine's�offsetH*‚from�JMPBASE.‚Since�the�offset�is�treated�as�an�unsigned�8-bit�number,?*‚the�routine�entry�points�must�all�be�fairly�close�to�JMPBASE.* JMPBASEƒEQU„*  **********&*‚Move�the�cursor�down�with�page�wrap.*DO_LF:>ŠMOVEQI�DOWNARROW,D0‡Translate�the�LF�to�a�DOWNARROW�so�we�get)*£page�wrap�and�fall�through�to�print�it.  ********** *‚Output�the�char�and�terminate.* PRINT_TERM:2ŠBSR.L‚MAKE_PACKETˆConstruct�a�termination�packet. ŠOUTPUT_D0‘Output�the�character.&ŠBRA.L‚SEND_PACKETˆGo�send�the�packet.  ***********‚Just�terminate.* TERMINATE:5ŠBSR.L‚MAKE_PACKETˆConstruct�a�termination�packet�andŠBRA.L‚SEND_PACKETˆgo�send�it.  **********"*‚Erase�the�line�the�cursor�is�on.* ERASE_LINE:0ŠOUTPUT�CR‘Go�back�to�the�beginning�of�the�line.'ŠOUTPUT�ERASE_EOLŠErase�to�end�of�line.3ŠBRA„CHANGE_EXITˆMark�change�to�this�line�and�exit.  **********,*‚Delete�the�char�to�the�left�of�the�cursor.*DO_DEL:BŠBSR„GET_CURSOR_ADDRESS�If�we're�not�on�the�1st�column�of�the�line9ŠADD.L‚#SCREEN,D0‰(cursor�addr�<>�start�of�current�line),ŠIF.L�D0��S.LINE(PC)�THEN#ŠOUTPUT�BS‘output�a�backspace�char.ŠENDI–* 6ŠOUTPUT�SPACEŽOutput�a�space�char�and�a�backspace�char/ŠOUTPUT�BS‘to�delete�the�char�under�the�cursor. >CHANGE_EXIT:�ST‚CHANGEDŒMark�that�we�changed�something�on�thisŠBRA„EXIT�line�and�exit.  **********@*‚Output�the�char�and�fake�a�CR�if�we�wrapped�around�the�screen.* PRINT_LOOK:(ŠST…CHANGEDŒMark�change�to�this�line�andŠOUTPUT_D0‘output�the�char.DŠBSR.L‚GET_CURSOR_ADDRESS�If�we're�not�on�the�1st�column�of�the�line<ŠADD.L‚#SCREEN,D0‰(cursor�address�<>�start�of�current�line),ŠCMP.L‚S.LINE(PC),D0†*ŠBNE„EXIT�just�exit. :ŠOUTPUT�UPARROWŒWe�wrapped,�so�move�us�back�to�the�line�we,ŠBRA„DO_CRŽwere�on�and�act�like�he�hit�a�CR.  **********D*‚Mark�that�the�line�was�changed�and�fall�through�to�PRINT�and�EXIT.* PRINT_CHANGE: ŠST…CHANGED  **********0*‚Just�output�the�char�and�fall�through�to�EXIT.*PRINT: ŠOUTPUT_D0  **********1*‚Just�ignore�this�char�and�return�from�EDITMODE.*IGNORE:5EXIT:…RESTORE�D0/D1/A0/A1‡Restore�registers�and�exit.ŠRTS—*  ***********‚Do�a�CR�LF�sequence.*DO_CR:.ŠBSR„MAKE_PACKETˆPrepare�a�termination�packet. >ŠMOVE.L�E.LINE(PC),D0†If�we're�on�the�last�line�of�the�virtualHˆIF.L�D0��E.SCRN(PC)�THEN�screen�(end�of�this�line�=�end�of�screen),9ŠMOVE.B�#$D9,PKT_TERM†put�a�$D9�terminator�in�the�packet,(ŠELSE–Else�(we're�not�on�the�last�line),9ŠMOVE.B�#$DF,PKT_TERM†put�a�$DF�terminator�in�the�packet,ŠENDI–* ŠOUTPUT�CR‘Output�a�CR,�LF. ŠOUTPUT�LF‘* &ŠBRA.L‚SEND_PACKETˆGo�send�the�packet.  ************ 07 = CTRL G = BELL*�ADDED‚01/30/85*8* RING_BELL flag is set so that the interrupt routine in9* KEYBRD.AG will output an ALARM command to the keyboard.*BELL: ŠSTˆRING_BELL ŠBRA‡EXITŠPAGEO*v*****************************************************************************O**********************************************************************************É***3***ŽMAKE_PACKET�--�PREPARE�A�TERMINATION�PACKET�******É***@***†FUNCTION:‚When�a�key�is�struck�which�necessitates�that�aŠ***@***‰packet�be�sent�to�the�driver,�this�routine�is�called.‚It‡***C***‰will�prepare�a�packet,�including�data�if�there�was�a�change…***D***‰on�the�line,�and�set�up�the�variables�for�the�FEEDER�routine„******‰to�send�it�later.¯******É******†NOTES:½******É******É******É***E***†REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturned‚***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR �lo�(CCR)…******‡D:ƒAP‚.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆD�******‡A:ƒPƒPƒ.ƒ.ƒ.ƒ.ƒ.ƒP ******É******†ENTRY�CONDITIONS:²***)***‰D0.B�=�the�terminating�character.Ÿ******É***-***†EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:ž******É******É***O*^*****************************************************************************O******************************************************************************* MAKE_PACKET: .ŠSAVEƒD0/A0/A1‹Save�registers�we'll�blow�away.ŠST…KB_LOCKŒLock�the�keyboard. **‚Construct�the�packet�header.*4ŠLEA„PKT_CFLAG,A1‡A1�<--�address�of�start�of�packet.0ŠST…(A1)+ŽSet�the�change�flag�to�$FF�(no�change)%*§for�now.‚We�may�overwrite�it�later.4ŠMOVE.B�D0,(A1)+‹Put�the�terminating�char�out�there. DŠBSR.L‚GET_CURSOR_ADDRESS�D0�<--�cursor�addr�relative�to�screen�RAM.BŠDIVUƒBPERLINE+2(PC),D0‚D0�<--�$00�xx�00�rr;�rr=line,�xx=2*column.9ŠADD.B‚#$20,D0ŒConvert�to�ASCII�and�put�it�in�the�buffer.ŠMOVE.B�D0,(A1)+‹*ŠSWAPƒD0‘D0.B�<--�column�#. ŠLSR„#1,D0Ž*9ŠADD.B‚#$20,D0ŒConvert�to�ASCII�and�put�it�in�the�buffer.ŠMOVE.B�D0,(A1)+‹* *B*‚If�we�changed�anything�on�this�line,�add�the�data�to�the�packet.*,ŠTST.B‚CHANGEDŒIf�the�line�has�been�changed,ŠIF…�THENŠ* 1ŠSF…CHANGEDŒReset�the�CHANGED�flag�for�next�time. >ŠMOVE.B�PKT_LINE,PKT_CFLAG�Move�the�line�#�to�the�change�flag. *1*‚Move�the�line�from�screen�RAM�to�packet�buffer.*@ŠMOVE.L�S.LINE(PC),A0†A0�<--�addr�of�current�line�in�screen�RAM.DŠMOVEƒC.LINE(PC),D0�D0�<--�#�of�char's�per�line�(adjusted�for�DBRA). AFILL_LOOP�MOVEQ‚#$7F,D1ŒGet�the�next�char�from�screen�RAM�and�and)ŠAND„(A0)+,D1‹off�all�but�the�low�7�bits.0ŠMOVE.B�D1,(A1)+‹Put�that�value�into�the�packet.;ŠDBRAƒD0,FILL_LOOP‡Keep�going�until�the�full�line�is�moved. *!*‚Get�rid�of�the�trailing�blanks.*DŠMOVEƒC.LINE(PC),D0�D0�<--�#�of�char's�per�line�(adjusted�for�DBRA)..ŠMOVEQ‚#SPACE,D1ŠD1�<--�space�char�for�search. >TRAIL_LOOP�CMP.B�-(A1),D1‹Search�backward�through�the�packet's2ŠDBNEƒD0,TRAIL_LOOP†data�area�for�a�nonblank�char.2ŠADD.L‚#1,A1ŽA1�<--�address�of�the�following�char. ŠENDI *5*‚Finish�up�the�packet,�prepare�the�feeder,�and�exit.*BŠMOVE.B�#END_OF_DATA,(A1)‚Add�the�end-of-data�indicator�to�packet. 5ŠLEA„PACKET,A0ŠSet�feeder�address�to�start�of�packet.ŠMOVE.L�A0,FEEDER_ADDRESS‚*5ŠSUB.L‚A0,A1ŽSet�feeder�count�to�#�of�bytes�in�packet)ŠADD„#1,A1Ž*†=‚end�addr�-�start�addr�+�1.ŠMOVEƒA1,FEEDER_COUNT„* -ŠRESTORE�D0/A0/A1ŠRestore�registers�and�exit.ŠRTSŠPAGEO*v********************************************************************************5***†SEND_PACKET�--�SEND�TERMINATION�PACKET�TO�TERMDRV***F***†FUNCTION:‚This�code�sends�the�termination�packet,�already�preparedC***‰in�the�buffer�PACKET,�to�the�driver�TERMDRV.‚Before�doing�so�itB***‰stores�the�current�cursor�line�#�in�the�packet.‚FEEDER_ADDRESS)***‰and�FEEDER_COUNT�must�already�be�set.*** ***†NOTES:*********†ENTRY�CONDITIONS:"***‰A5�=�address�of�TERMDRV's�CCB.***O*^***************************************************************************** SEND_PACKET: BŠBSR„GET_CURSOR_ADDRESS�D0�<--�cursor�addr�relative�to�screen�RAM.AŠDIVUƒBPERLINE+2(PC),D0‚D0�<--�$xx�xx�00�rr.‚rr=line�#,�xx=trash.9ŠADD.B‚#$20,D0ŒConvert�to�ASCII�and�put�it�in�the�packet.ŠMOVE.B�D0,PKT_LINEˆ* 8ŠBSR.L‚FEEDER�Call�the�feeder�to�give�this�to�the�driverŠBRA„EXIT�and�exit.   ŠENDN?FEEDER„IDNTƒ45,0„VME/10�subroutine�to�feed�a�buffer�to�TERMDRV.;ŠTTL„FEEDER:�VME/10�subroutine�to�feed�a�buffer�to�TERMDRV. NNNNNNNGP1XB`9h=p8O*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***4***†FILENAME:‚FEEDER�--�FEED�A�BUFFER�TO�TERMDRV–******É***8***†ENVIRONMENT:‚Linked�into�TERMDRV�for�the�VME/10.’******É***G***†FUNCTION:‚TERMDRV�basically�only�accepts�a�character�at�a�time.ƒ***D***‰If�you�have�a�buffer�full�of�characters�to�send,�you�can�use„***=***‰this�routine�to�give�them,�one�at�a�time,�to�TERMDRV.‹******É***E***†NOTES:‚When�control�is�returned�to�the�caller,�the�buffer�has…***@***‰not�necessarily�been�completely�sent.‚No�notification�is‡***;***‰provided�to�indicate�that�the�buffer�has�been�sent.�******É***,***†EXTERNAL�DATA�STRUCTURES�REFERENCED:Ÿ*** ***‰CCB�for�terminal�driver.¨******É***)***†EXTERNAL�ENTRY�POINTS�REFERENCED:¢******‰GOT_CHAR¸******É***"***†SERVICES�CALLED�VIA�TRAPS:©******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------D*…12/10/85‚F.W.BramwellƒInstall�NEW�Killer�modification�which�leaves,*žThe�Driver�ID�(Number)�and�Reason�(Number)2*žin�CRASHSAV�along�with�the�CCB�and�DCB�pointers.*'*†7/19/83‚Steve�FranckƒInitial�writing.*ŠPAGE* *‚XDEF's.*6ŠXDEFƒSTOP_ITŒEntry�pt.�for�background�routine�to�stop'*§us�from�trying�to�feed�more�char's�to *§the�driver.6ŠXDEFƒUNSTOP�Entry�pt.�for�us�to�resume�feeding�char's"*§to�the�driver�if�we�had�stopped.6ŠXDEFƒFEEDER�Entry�pt.�for�routine�that�feeds�a�buffer!*§a�byte�at�a�time�to�the�driver. ?ŠXDEFƒFEEDER_ADDRESS,FEEDER_COUNT,FEEDER_WAITING‚Variables�used%*§in�dealing�with�the�feeder�routine.>ŠXDEFƒREL_FLAG,REL_ADDR,REL_PAGES‚Variables�to�use�if�you�want&*§FEEDER�to�release�memory�to�the�exec*§when�it�is�done�feeding.   *0*‚XREF's�(indicate�where�the�XDEF�is,�if�known).*6ŠXREFƒGOT_CHAR‹Entry�pt.�in�TERMDRV�to�process�a�char.ŠPAGEO*********************************************************************************‰INCLUDE�FILES�AND�EQUATES*O******************************************************************************* *=*‚Define�the�environment�as�EXORMACS/S�in�a�switch�to�control*‚conditional�assemblies.*2ENVIRONMENT�EQU‚'EX/S'�This�is�for�the�EXORMACS/S.  **‚Include�files:5*‰UTILITY.MC‹General�purpose�macros�(e.g.�PUSH,�POP).,*‰IOE.SA�Equates�for�IOS-related�structures.7*‰EQUCCB.EQŒEquates�for�device-independent�part�of�CCB.9*‰TERMDRV.EQ‹Equates�for�the�generalized�terminal�driver.(*‰STR.EQ�Equates�for�trap�#0�calls,�etc.2*‰KILL.MCŽMacro�library�containing�the�KILL.�macro9*‰KILLDRV.EQ‹Equates�with�reasons�for�Killer�to�be�called*ŠNOLISTŠINCLUDE‚9995.&.UTILITY.MCŠINCLUDE‚9995.&.IOE.EQŠINCLUDE‚9995.&.CCB.EQŠINCLUDE‚9995.VMES10.TERMDRV.EQŠINCLUDE‚9995.&.STR.EQŠINCLUDE‚9995.&.KILL.MCŠINCLUDE‚9995.&.KILLDRV.EQŠLIST  .FALSE…EQU„$00�Value�FALSE�for�a�flag�variable.,TRUE†EQU„$FF�Value�TRUE‚for�a�flag�variable.ŠPAGEO*********************************************************************************‰DATA�VARIABLES*O******************************************************************************* ŠSECTION�0 *I*‚These�variables�are�used�as�arguments�to�the�FEEDER�routine�which�gives-*‚bytes�in�a�buffer�one�at�a�time�to�TERMDRV.*@FEEDER_ADDRESS�DC.L�0�Address�of�next�byte�for�feeder�subroutine*§to�feed�to�the�driver.;FEEDER_COUNT�DC.W�0‘#�of�bytes�remaining�to�feed�to�driver.CFEEDER_WAITING�DC.B�FALSE‹Flag�indicating�whether�or�not�the�feeder$*§is�waiting�for�room�in�the�receive"*§queue.‚Used�by�UNSTOP�routine�to'*§restart�the�feeder�if�it�had�to�stop. =REL_FLAG‚DC.BƒFALSEŽFlag�indicating�whether�or�not�the�feeder(*§should�release�memory�to�the�exec�when)*§it�is�done�feeding�a�buffer�to�TERMDRV.4REL_ADDR‚DC.Lƒ0’Start�addr�of�buffer�to�be�released.5REL_PAGES�DC.Lƒ0’#�of�pages�in�buffer�to�be�released.ŠPAGEO*v*****************************************************************************O**********************************************************************************É***4***�FEEDER�--�FEEDS�A�BUFFER�BYTEWISE�TO�TERMDRV�******É***G***†FUNCTION:‚This�routine,�whose�entry�point�is�XDEF'ed,�will�takeƒ***@***ˆthe�buffer�described�by�the�variables�FEEDER_ADDRESS�and‰***E***ˆFEEDER_COUNT�and�transfer�it�a�byte�at�a�time�to�the�terminal„***C***ˆdriver,�TERMDRV.‚It�senses�when�the�STOPPED�flag�in�the�CCB…***G***ˆgets�set,�which�means�that�the�driver's�receive�queue�is�almost‚***A***ˆfull,�and�stops�sending.‚Provisions�must�be�made�for�this‡***C***ˆroutine�to�be�invoked�again�later�when�there�is�room�in�the†******ˆreceive�queue.³******É******†NOTES:½******É******É***E***†REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturned‚***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒPƒPƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆD�******‡A:ƒPƒPƒ.ƒ.ƒPƒAƒ.ƒP ******É******†ENTRY�CONDITIONS:²***&***ˆA5ƒ=�address�of�TERMDRV's�CCB.¡******É***-***†EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:ž******É******É***O*^*****************************************************************************O******************************************************************************* ŠDS…0ŠOPT„BRS ŠSECTION�0 FEEDER: ;ŠSAVEƒD0/D1/A0/A1/A4…Save�registers�we,�or�the�driver,�use.AŠMOVE.L�FEEDER_ADDRESS,A4‚A4�<--�addr�of�1st�byte�to�feed�driver.  ŠREPEAT ;ŠSUB„#1,FEEDER_COUNT„Decrement�the�count�of�bytes�remaining$ŠBMI„DONE�and�get�out�if�we're�done. -ŠMOVE.B�(A4)+,D0‹D0�<--�next�byte�for�driver. 5ŠPEA„RETURN(PC)‰Call�the�driver�at�the�point�where�he6ŠPUSH.L�D1‘has�the�character�and�starts�to�process�it.ŠBRA.L‚GOT_CHAR‹* @RETURN„TST.B‚STOPPED(A5)ˆHaving�returned�from�the�driver,�see�if-ŠUNTIL‚�he's�full�and�repeat�if�he's�not.  *D*‚The�driver�can't�take�any�more�characters�now,�so�we�have�to�exit.*@ŠMOVE.L�A4,FEEDER_ADDRESS‚Save�address�of�next�byte�to�feed�him.6ŠST…FEEDER_WAITING…Remind�someone�that�we're�not�done. 4ŠBRA„EXIT�Just�exit�for�now;�we'll�get�called�later.  *H*‚The�buffer�has�been�fed�to�the�driver.‚Release�the�buffer�if�necessary *‚and�exit.*:DONE†TST.B‚REL_FLAG‹If�we're�supposed�to�release�a�buffer,ŠIF…�THENŠ* 7ŠSAVEƒD2-D7/A2-A3/A5…Save�rest�of�registers,�except�A6.;ŠMOVE.L�REL_ADDR,A0ˆA0�<--�start�addr�of�buffer�to�release.1ŠMOVE.L�REL_PAGES,D1‡D1�<--�#�of�pages�in�buffer.(ŠTR0$.PGFR�,�Ask�exec�to�free�the�pages.ŠBRA„RELEASED‹Good�return.>ŠRESTORE�D2-D7/A2-A3/A5„Restore�registers�for�CCB�Pointer�(A5)-ŠKILL.DRIVER�FEEDER_ID,T0PGFR,A5,DCB_ADDR(A5) �THENŠof�his�work�(this�should�be�the�case),)ŠBSR„FEEDER�call�him�to�let�him�continue.ŠENDI–* ŠRTS—Return.     ŠENDN IINCHAR„IDNTƒ45,0�Routine�to�get�incoming�char's�and�handle�special�modes.EŠTTL�INCHAR:�Routine�to�get�incoming�char's�and�handle�special�modes.NNNNNNNx�:‰@‘*O*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***I***…FILENAME:�INCHAR�--�GET�INCOMING�CHAR'S�AND�HANDLE�SPECIAL�MODES.ƒ******É***K***…ENVIRONMENT:�Part�of�VERSAdos�keyboard/screen�driver�for�the�VME/10.******É***G***…FUNCTION:�The�subroutine�in�this�module�is�called�by�TERMDRV�to…***#***‡handle�incoming�characters.§******É******…NOTES:¾******É***,***…EXTERNAL�DATA�STRUCTURES�REFERENCED: *******‡EDIT_FLAG„KB_LOCK„PAGEFLAG„PROMODE—******É***)***…EXTERNAL�ENTRY�POINTS�REFERENCED:£***"***‡GET_CHAR…EDITMODE…PAGEMODE ******É***"***…SERVICES�CALLED�VIA�TRAPS:ª******É******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------'*†5/23/83‚Steve�FranckƒInitial�writing.* * *‚XDEF's.*+ŠXDEFƒIN_CHARŒEntry�point�for�this�routine. *0*‚XREF's�(indicate�where�the�XDEF�is,�if�known).*2ŠXREFƒGET_CHAR‹Routine�to�get�a�scan�code�from�the&*§keyboard�and�generate�a�char,�update"*§modes,�etc.;�in�module�KEYBOARD. 7ŠXREFƒEDITMODE‹Routine�to�handle�incoming�characters�if*§we're�in�edit�mode. 8ŠXREFƒEDIT_FLAGŠFlag�indicating�whether�or�not�we�are�in *§edit�mode;�in�module�EDITMODE. 7ŠXREFƒPAGEMODE‹Routine�to�handle�incoming�characters�if%*§we're�in�page�mo de�or�protect�mode. 7ŠXREFƒPAGEFLAG‹Flag�indicating�whether�or�not�we�are�in*§page�mode;�in�module�CRTINIT. 6ŠXREFƒPROMODEŒFlag�indicating�whether�or�not�we�are�in!*§protect�mode;�in�module�OUTCHS. 9ŠXREFƒKB_LOCKŒFlag�indicating�whether�or�not�the�keyboard'*§is�'software�locked,'�meaning�that�no!*§characters�should�be�generated. **‚Equate�files�included:0*…UTILITY.MC„Utility�macros�(like�PUSH�and�POP).*ŠNOLISTŠINCLUDE�9995.&.UTILITY.MCŠLISTŠPAGEO*v*****************************************************************************O**********************************************************************************É***7***�IN_CHAR�--�HANDLE�CHAR�FROM�THE�VME/10�KEYBOARD�******É***H***…FUNCTION:�This�routine�is�called�by�TERMDRV,�the�keyboard�screen„***E***‡driver,�when�scan�codes�are�received�from�the�keyboard.‚After„***D***‡calling�GET_CHAR�to�figure�out�what�the�char�is,�EDITMODE�is†***D***‡called�if�necessary.‚'Software�lock'�of�the�keyboard�is�also…*** ***‡handled�by�this�routine.ª******É******…NOTES:¾******É***E***…REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturnedƒ***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒRƒPƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆR�******‡A:ƒ.ƒ.ƒ.ƒ.ƒ.ƒAƒ.ƒP ******É******…ENTRY�CONDITIONS:³***&***‡A5ƒ=�address�of�TERMDRV's�CCB.¢******É***-***…EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:Ÿ***I***‡CCR:��=�keystroke�didn't�generate�a�char�or�break�for�TERMDRV.***A***Œ:��=�generated�char�is�in�D0.W�(bits�8-15�are�0).„***%***’�=�a�break�was�generated.š***(***‡D0�is�not�preserved�in�any�case.¢******É***O*^*****************************************************************************O******************************************************************************* ŠDS…0 ŠSECTION�0ŠOPT„BRS IN_CHAR: (ŠSAVEƒD1‘Save�registers�we'll�blow�away. 0ŠBSR.L‚GET_CHAR‹Get�the�character�(or�whatever).'ŠIF…�THENŠIf�it�is�a�char�or�break, ŠIF…�THENŠ.�If�it's�a�break, "ŠSF…KB_LOCKŒ.ƒUnlock�the�keyboard; ŠELSE–.�Else�(it's�a�character), 4ŠTST.B‚KB_LOCKŒ.ƒIf�the�keyboard�is�software�locked,ŠIF…�THENŠ.ƒ* -ŠCLR„D0‘.…Set�CCR:��to�say�'false�alarm.' *ŠELSE–.ƒElse�(the�keyboard�is�not�locked), *ŠTST.B‚EDIT_FLAGŠ.…If�we�are�in�edit�mode,ŠIF…�THENŠ.…* 0ŠBSR.L‚EDITMODE‹.‡Call�the�edit�mode�handler�and-ŠCLR„D0‘.‡set�CCR:��to�say�'false�alarm.' 'ŠELSE–.…Else�(we�are�not�in�edit�mode), 8ŠMOVE.B�PAGEFLAG,D1ˆ.‡If�we�are�in�page�or�protect�mode,ŠOR.BƒPROMODE,D1‰.‡*ŠIF…�THENŠ.‡* 0ŠBSR.L‚PAGEMODE‹.‰Call�the�page�mode�handler;�he*±will�set�the�condition�codes. 'ŠELSE–.‡Else�(we�are�not�in�page�mode), /ŠMOVEQ‚#1,D1Ž.‰Set�CCR:�,�to�say�'there*±is�a�char�in�D0.' ŠENDI–. ŠENDI–. ŠENDI–. ŠENDI–. ŠENDI–.   7ŠRESTORE�D1�Restore�registers�and�return�with�conditionŠRTS—codes�set.   ŠENDNNN N7OUTCHSƒIDNT†45,0†Output�a�character�to�the�display�RAM.3‰TTL‡OUTCHS:ƒOutput�a�character�to�the�display�RAM.NNNNNNN™¢5ª9²?ºBÂ-Ê,Ò-Ú0â+êTòaúOQ SDA"B*S2::UBJJSRKZ>bFjK<*************************************************************º**�Routine�name:ŽOUTCHS˜*<*----------------------------------------------------------*-*�Current�revision.....................1.00�*1*�Date�written.........................12-18-82Œ*2*�Written�by...........................S.Pri-Tal‹*/*�Date�changed.........................3-1-83Ž*2*�Changed�by...........................R.�RUSTAD‹**º**�Description�of�change:£**º**º*0*�Date�changed.........................8-17-84�*1*�Changed�by...........................B.�NASONŒ**º**�Description�of�change:£**ƒChanged�all�XREF.S�to�XREF�**º*0*�Date�changed........................10-24-84�*1*�Changed�by...........................B.�NASONŒ**º**�Description�of�change:£*5*‚System�was�hanging�when�SHIFT/CLEAR�was�hit�while‡*7*‚there�was�an�output‚to�the�screen.‚The�registers�A2ƒ*:*‚and�D6�were�not�being�set�up�in�CLEAR_SCREEN,�which�is‚*;*‚called�by�BREAK_CLEAR�in�GET_CHAR�in�the�KEYBOARD�module*,*‚So�now�we�set�up�the�registers�properly.�**º*0*�Date�changed.........................1-30-85�*/*�Changed�by...........................M.�DUHŽ**º**�Description�of�change:£*7*ƒSet�RING_BELL�flag�when�$07�is�to�be�output�(BELL).„**º**º*<************************************************************9*�Function:�Output�the�character�in�D0.B�to�the�display„*/*‹RAM�if�character�is�printable,�else�perform„**‹the�required�function.™*<*----------------------------------------------------------*/*�Input�parame ters:‚D0.B�character�to�output.�*<*----------------------------------------------------------**�Registers�affected:�none¡*<*----------------------------------------------------------* *�External�routines�used:�none�*<************************************************************‰PAGE ‰XDEF†OUTCHS‰XDEF†EDIT_FLAG 4‰XDEF†RESET_SCREEN‚Alternate�entry�for�reset�command4‰XDEF†CLEAR_SCREEN‚Alternate�entry�for�clear�command‰XDEF†PROMODE‡Protect�mode�flag )‰XDEF†RABSOLUT†Read�absolute�entry�point. (‰XREF†CRTINITƒInit�the�screen�parameters‰XREF†SCRNINIT /‰XREF†FACS†Field�attribute,�word�sized�register3‰XREF†PAGEFLAG‚Word�sized�flag.�If=$FFFF,�page�mode 5‰XREF†CPERLINE‚Number�of�characters�per�absolute�line0‰XREF†BPERLINE‚Number�of�bytes�per�absolute�line2‰XREF†LPERSCRN‚Number�of�lines�per�absolute�screen 2‰XREF†C.LINE„Number�of�characters�per�virtual�line-‰XREF†B.LINE„Number�of�bytes�per�virtual�line *‰XREF†S.LINE„Start�address�of�current�line(‰XREF†E.LINE„End�address�of�current�line *‰XREF†PB.LINEƒUnused�part�of�absolute�line 2‰XREF†L.SCRN„Number�of�lines�in�the�virtual�screen <‰XREF†S.SCRN„Address�of�home�character�in�the�virtual�screen<‰XREF†E.SCRN„Address�of�last�character�in�the�virtual�screen (‰XREF†TOPLINEƒTop�line�of�virtual�screen+‰XREF†BOTLINEƒBottom�line�of�virtual�screen,‰XREF†LEFTCOLƒLeft�collumn�of�virtual�screen.‰XREF†RIGHTCOL‚Right�collumn�of�virtual�screen 9‰XREF†FEEDER„Address�of�subroutine�to�give�data�to�driver=‰XREF†FEEDER_ADDRESS†Address�of�data�buffer�to�give�to�FEEDER,‰XREF†FEEDER_COUNTˆ#�of�bytes�in�data�bufferA‰XREF†REL_FLAG‚Flag�which�tells�feeder�subroutine�to�release�mem.7‰XREF†REL_ADDR‚Memory�address�of�buffer�to�be�released.*‰XREF†REL_PAGES�Number�of�pages�in�buffer.‰XREF†DUP_CHAR (‰XREF†KB_LOCK�Key�board�lock/unlock�flag.‰XREF†POUTCHS�Output�character�in�protect�mode 0‰XREF†RING_BELL‹Flag�set�when�$07�is�detected�in%*§order�to�ring�the�bell�in�KEYBRD.AG‰PAGE .SCREENƒEQU‡$F17000�Base�address�of�display�RAM0CRTCADD‚EQU‡$F1A021�Address�register�of�the�CRTC-CRTCREG‚EQU‡$F1A023�Register�file�of�the�CRTC)EPCIBASE�EQU‡$F1A031�Base�address�of�EPCIKBDADDR‚EQU‡$0C$LFCHARƒEQU‡$0A‘ASCII�line�feed�char.0START_OF_DATA�EQU‚$DDŽ'Start�of�data'�indicator./END_OF_DATA�EQU„$DE‘End�of�write/read�indicator,END_OF_FIELD�EQUƒ$F9‘End�of�field�indicator.$FALSE„EQU‡0“Indicate�condition�false#TRUE…EQU‡-1’Indicate�true�condition"CLEARTAB�EQU‡$18‘Clear�tab�command#SPACE„EQU‡$20ŽASCII�space�character#ESC_CHAR‚EQU„$1B�ASCII�escape�char.;NUMBER_PAGES�EQU‚8‘Number�of�pages�to�give�to�feeder�during*£a�read�absolute.6INIT_TAB‚EQU„10‘Initial�tab�spacing.‚The�reset�command#*§($F1)�will�put�tabs�on�the�screen*§with�this�spacing. ** Register use:*’D0.L�=�general�use+*’D1.W�=�absolute�address�of�initial�cursor/*’D2.W�=�chracter�to�decode�and�word�to�display)*’D3.W�=�lines�per�virtual�screen�counter+*’D4.W�=�characers�per�virtual�line�counter *’D5.L�=�bytes�per�absolute�line*’D6.L�=�bytes�per�virtual�line*’D7.L�=�general�use-*’A0.L�=�address�of�cursor�in�the�display�RAM*’A1.L�=�Address�of�FACS*’A2.L�=�Address�of�S.LINE*’A3.L�-�General�use*  ‰PAGE ‰SECTIONƒ11  **ˆDEFINE�STORAGE*=ESC_FLAG‚DC.BƒFALSEŽThis�flag�is�true�if�someone�has�reserved(*§a�char�and�the�first�char�received�was&*§an�ESC.‚In�that�case�we�wait�for�the*§next�char�and�set�its�bit�7.:CHAR_RESERVED�DC.B�FALSE…Next�character�reserved�indicator(SAVE_CHAR…DS.B�1‰Save�area�for�character:SAVE_CR1†DS.B�1‰Save�area�for�character‚These�are�used�for;SAVE_CR2†DS.B�1‰Save�area�for�character‚read�absolute�only.)SAVE_CR3†DS.B�1‰Save�area�for�character‚*-SAVE_CURSORƒDS.L�1‰Current�cursor�ram�addressBCHAR_OWNER„DS.L�1‰Address�of�routine�that�owns�next�incoming�char.4XTCHBUF‚DS.W†10ˆScratch�buffer�for�feeder�subroutineEDIT_FLAG�DC.B…FALSE‰DS.W†0,PROMODE‚DC.W†FALSE …Set�protect�mode�to�false=COL_CNT‚DS.L†1‰Current�column�number,�used�in�set�tab�routine‰DS.W†0;SAVEFACS�DC.W†0‰Save�FACS�in�use�when�write�absolute�occurs>LASTFAC‚DC.B†FALSE…Last�character�processed�--�indicates�if�it*œwas�a�FAC�or�not.�THEN.S 8ŠTST.B‚ESC_FLAG‹If�the�last�char�we�received�was�an�ESC,ŠIF…�THEN.Sˆ* 2ŠSF…ESC_FLAG‹Clear�the�'last�char�was�an�ESC'�flag5ŠBSETƒ#7,D0Žand�set�bit�7�in�D0�and�D2�(both�of�which-ŠBSETƒ#7,D2Žhold�the�char�following�the�ESC). (ŠELSE.S”Else�(last�char�was�not�an�ESC), 6ŠIF.B�D0��#ESC_CHAR�THEN.S�If�this�char�is�an�ESC,0ŠST…ESC_FLAG‹set�the�'last�char�was�an�ESC'�flagŠBRA„RETURN�and�exit.ŠENDI–* ŠENDI /‰SF�CHAR_RESERVEDŽReset�character�reserved�flag:‰MOVE.L�CHAR_OWNER,A3ŠGet�the�address�of�the�routine�which*¨process�this�character'‰JMP�(A3)–Go�process�incoming�character ‰ENDI *(*ˆFind�entry�in�table�for�this�character*OUTCH1(‰MOVE†D2,D0…Reset�upper�part�of�register5‰ADD‡D0,D0…Multiply�by�two�because�table�is�word�wide+‰MOVE†JUMPTABL(PC,D0),D0�Get�offset�address2‰JMP‡JUMPTABL(PC,D0)„Go�process�incoming�character‰PAGEJUMPTABL,ŠDC.WƒRETURN-JUMPTABL„$00�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$01�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$02�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$03�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$04�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$05�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$06�--�Illegal�--�exit ŠDC.WƒBELL-JUMPTABL†$07�--�Bell.#ŠDC.WƒBS-JUMPTABLˆ$08�--�Backspace.(ŠDC.WƒHT-JUMPTABLˆ$09�--�Horizontal�tab.#ŠDC.WƒLF-JUMPTABLˆ$0A�--�Line�feed.&ŠDC.WƒUP-JUMPTABLˆ$0B�--�Vertical�tab.&ŠDC.WƒRIGHT-JUMPTABL…$0C�--�Form�feed.)ŠDC.WƒCR-JUMPTABLˆ$0D�--�Carriage�return.,ŠDC.WƒRETURN-JUMPTABL„$0E�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$0F�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$10�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$11�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$12�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$13�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$14�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$15�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$16�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$17�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$18�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$19�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1A�--�Illegal�--�exit!ŠDC.WƒESC-JUMPTABL‡$1B�--�Escape.,ŠDC.WƒRETURN-JUMPTABL„$1C�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1D�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1E�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1F�--�Illegal�--�exit,ŠDC.WƒDISPLAY-JUMPTABLƒ$20�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$21�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$22�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$23�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$24�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$25�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$26�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$27�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$28�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$29�--�Display�as�is.,ŠDC.WƒDISPLAY- JUMPTABLƒ$2A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$30�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$31�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$32�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$33�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$34�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$35�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$36�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$37�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$38�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$39�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$40�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$41�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$42�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$43�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$44�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$45�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$46�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$47�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$48�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$49�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$50�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$51�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$52�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$53�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$54�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$55�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$56�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$57�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$58�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$59�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$60�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$61�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$62�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$63�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$64�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$65�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$66�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$67�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$68�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$69�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$70�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$71�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$72�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$73�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$74�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$75�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$76�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$77�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$78�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$79�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7E�--�Display�as�is.+ŠDC.WƒRETURN-JUMPTABL„$7F�--�Display�as�is.'ŠDC.WƒRETURN-JUMPTABL„$80�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$81�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8 2�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$83�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$84�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$85�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$86�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$87�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$88�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$89�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8A�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8B�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8C�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8D�--�Ignore�it.4ŠDC.WƒSTART_EDITMODE-JUMPTABLƒ$8E�--�Start�edit�mode1ŠDC.WƒSTOP_EDITMODE-JUMPTABL„$8F�--�End�edit�mode'ŠDC.WƒRETURN-JUMPTABL„$90�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$91�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$92�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$93�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$94�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$95�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$96�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$97�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$98�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$99�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9A�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9B�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9C�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9D�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9E�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9F�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A0�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A1�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A2�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A3�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A4�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A5�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A6�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A7�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A8�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A9�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AA�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AB�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AC�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AD�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AE�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AF�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B0�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B1�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B2�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B3�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B4�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B5�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B6�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B7�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B8�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B9�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BA�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BB�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BC�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BD�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BE�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BF�--�Ignore�it.%ŠDC.WƒHOME-JUMPTABL†$C0�=�Cursor�home!ŠDC.WƒUP-JUMPTABLˆ$C1�=�Cursor�up%ŠDC.WƒDOWN-JUMPTABL†$C2�=�Cursor�down&ŠDC.WƒSEEKL-JUMPTABL…$C3�=�Cursor�left'ŠDC.WƒRIGHT-JUMPTABL…$C4�=�Cursor�right$ŠDC.WƒC5-JUMPTABLˆ$C5�=�Write�cursor#ŠDC.WƒC6-JUMPTABLˆ$C6�=�Read�cursor(ŠDC.WƒSPAGE-JUMPTABL…$C7�=�Set�page�mode*ŠDC.WƒRPAGE-JUMPTABL…$C8�=�Reset�page�mode0ŠDC.WƒSETTOP-JUMPTABL„$C9�=�Set�top�display�line5ŠDC.WƒSETBOTOM-JUMPTABL‚$CA�=�Set�bottom�display�line5ŠDC.WƒSETLEFT-JUMPTABLƒ$CB�=�Set�left�display�collumn7ŠDC.WƒSETRIGHT-JUMPTABL‚$CC�=�Set�right�display�collumn,ŠDC.WƒSETPRO-JUMPTABL„$CD�=�Set�protect�mode,ŠDC.WƒWABSOLUT-JUMPTABL‚$CE�=�Write�absolute+ŠDC.WƒRABSOLUT-JUMPTABL‚$CF�=�Read�absolute5ŠDC.WƒICHAR-JUMPTABL…$D0�=�Insert�character�at�cursor5ŠDC.WƒDCHAR-JUMPTABL…$D1�=�Delete�character�at�cursor,ŠDC.WƒKEYENAB-JUMPTABLƒ$D2�=�Enable�keyboard.ŠDC.WƒKEYDSABL-JUMPTABL‚$D3�=�Disable�keyboard?ŠDC.WƒEEPAGE-JUMPTABL„$D4�=�Erase�all�unprotected�to�end�of�pag?ŠDC.WƒEELINE-JUMPTABL„$D5�=�Erase�all�unprotected�to�end�of�lin5ŠDC.WƒINS_LINE-JUMPTABL‚$D6�=�Insert�a�line�at�cursor5ŠDC.WƒDEL_LINE-JUMPTABL‚$D7�=�Delete�a�line�at�cursor:ŠDC.WƒCLEAR-JUMPTABL…$D8�=�Erase�all�unprotected�in�screen5ŠDC.WƒRETURN-JUMPTABL„$D9�=�Send�page�to�line�printer'ŠDC.WƒSEEKFT-JUMPTABL„$DA�=�Forward�tab$ŠDC.WƒSEEKBT-JUMPTABL„$DB�=�Back�tab#ŠDC.WƒSETTAB-JUMPTABL„$DC�=�Set�tabŠDC.WƒRETURN-JUMPTABL„$DD�=ŠDC.WƒRETURN-JUMPT ABL„$DE�=0ŠDC.WƒRETURN-JUMPTABL„$DF�=�Send�line�to�printer%ŠDC.WƒSBLINK-JUMPTABL„$E0�=�Set�blink'ŠDC.WƒRBLINK-JUMPTABL„$E1�=�Reset�blink-ŠDC.WƒSINVERT-JUMPTABLƒ$E2�=�Set�video�invert/ŠDC.WƒRINVERT-JUMPTABLƒ$E3�=�Reset�video�invert-ŠDC.WƒUPBRIGHT-JUMPTABL‚$E4�=�Set�half�bright/ŠDC.WƒDNBRIGHT-JUMPTABL‚$E5�=�Reset�half�bright)ŠDC.WƒSULINE-JUMPTABL„$E6�=�Set�underline+ŠDC.WƒRULINE-JUMPTABL„$E7�=�Reset�underline,ŠDC.WƒNONDISP-JUMPTABLƒ$E8�=�Set�non-display(ŠDC.WƒSETDISP-JUMPTABLƒ$E9�=�Set�display-ŠDC.WƒPROTECT-JUMPTABLƒ$EA�=�Set�protect�mode-ŠDC.WƒALLOW-JUMPTABL…$EB�=�Reset�protect�modeŠDC.WƒRETURN-JUMPTABL„$EC�=ŠDC.WƒRETURN-JUMPTABL„$ED�=ŠDC.WƒRETURN-JUMPTABL„$EE�=ŠDC.WƒRETURN-JUMPTABL„$EF�=ŠDC.WƒRETURN-JUMPTABL„$F0�=2ŠDC.WƒRESET24-JUMPTABLƒ$F1�=�Reset�24�line�screen.ŠDC.WƒRETURN-JUMPTABL„$F2�=ŠDC.WƒRETURN-JUMPTABL„$F3�=ŠDC.WƒRETURN-JUMPTABL„$F4�=ŠDC.WƒRETURN-JUMPTABL„$F5�=ŠDC.WƒRETURN-JUMPTABL„$F6�=2ŠDC.WƒRESET25-JUMPTABLƒ$F7�=�Reset�25�line�screen.ŠDC.WƒRETURN-JUMPTABL„$F8�=ŠDC.WƒRETURN-JUMPTABL„$F9�=ŠDC.WƒRETURN-JUMPTABL„$FA�=ŠDC.WƒRETURN-JUMPTABL„$FB�=ŠDC.WƒRETURN-JUMPTABL„$FC�=ŠDC.WƒRETURN-JUMPTABL„$FD�=ŠDC.WƒRETURN-JUMPTABL„$FE�=ŠDC.WƒRETURN-JUMPTABL„$FF�=  ‰PAGE*'* $7F = DLE, delete character at cursor*DLE'‰AND.W…#$FF80,(A0)‰Null�character�space)‰OR.B†#$20,(A0)‹Space�character�at�cursor ‰BRA‡RETURN *** Send the command in D0 to this key board*'WKBD…OR.B†#KBDADDR,D0‰To�this�key�board‰MOVE.B„D0,EPCIBASE‰RTS ** 07 = CTRL G = BELL*�ADDED‚01/30/85*8* RING_BELL flag is set so that the interrupt routine in9* KEYBRD.AG will output an ALARM command to the keyboard.*BELL ‰STˆRING_BELL ‰BRA‡RETURN ** 08 = CTRL H = BS, back space*:* Cursor moves left to first unprotected column, with line* and page rollover.**BS SEEKL„EQU‡*‰IF.L†A0��S.LINE�OR.L‰A0��S.SCRN�THEN.S9‰MOVE.L„E.LINE,A0‹If�start�of�line�encountered�set�to�end‰ENDI)‰SUBQ.L„#2,A0�Back�cursor�up�one�position ‰BRA‡WRITCRSR‰PAGE*"* 09 = CTRL I = HT, horizontal tab*2* Seek a TAB at an un-protected spot to the right,* with line and page rollover.** If none found, move right*HT$SEEKFTƒEQU‡*“Seek�a�tab�to�the�right!‰MOVE.L„A0,A3�Set�loop�terminator*‰ADDQ.L„#2,A0�Get�off�of�current�character‰BRA.S…SEEKFT1‰REPEAT-‰MOVE.W„(A0)+,D0ŒScan�forward�on�current�line‰TST.B…D0’Is�the�tab�bit�set0‰BMI.S…SEEKFT2�Found�tab�position�if�bit�was�setSEEKFT1‰IF.L†A0��E.LINE�THEN.S+‰MOVE.L„S.LINE,A0‹Only�wrap�on�current�line‰ENDI (‰UNTIL.LƒA0��A3ŠLoop�for�entire�line%‰BRA‡RETURNŽJust�exit�if�no�tab�foundSEEKFT2)‰SUBQ.L„#2,A0�Adjust�because�of�increment,‰BRA‡WRITCRSRŒUpdate�current�cursor�position‰PAGE**�0A…LINE�FEED**LF8‰MOVE.L„A0,D0…Absolute�cursor�address�into�a�usable�reg.‰SUB.L…#SCREEN,D04‰DIVU†BPERLINE+2,D0‡D0.W�is�the�absolute�line�number7‰IFˆBOTLINE��D0�THEN.S‚IF�we�are�on�the�bottom�line‰BRA‡SCROLL1�Scroll�the�screen‰ENDI/‰BRA‡DOWN�If�not�at�bottom�move�the�cursor�down***�0D…Carriage�return*2* Position cursor at left most unprotected column.** FAC's are reset.*CR‰AND.W…#$4400,(A1)‰Reset�FACs‰MOVE.L„S.LINE,A0‹Start�of�line ‰BRA‡WRITCRSR * *�1B…Escape*(* Set high bit of next character output.* ESC†EQU‡*#‰BSR‡GET_CHARŒNeed�anoter�character ‰BSET†#7,D0‰BRA‡HAVE_CHAR‰PAGE**�$8E„START�EDIT�MODE*START_EDITMODE ‰BSR‡GET_CHAR‰IF.B�D0��#$FF�THEN.S‰MOVE†#$FFFF,DUP_CHAR‰ELSE.S‰MOVE†D2,DUP_CHAR‰ENDI ‰STˆEDIT_FLAG ‰BRA‡RETURN**�$8F‚STOP�EDIT�MODE* STOP_EDITMODE%‰SFˆEDIT_FLAG‹Turn�off�edit�mode�flag ‰BRA‡RETURN‰PAGE**�$C0„cursor�home*A* Cursor moves to top left corner of screen, seeks an unprotected* space to the right.** HOME…EQU‡* ‰MOVE.L„S.SCRN,A0‹Top�left�space6‰MOVE.L„A0,S.LINE‹Modify�start�and�end�of�current�line‰M OVE.L„A0,E.LINE‰ADD.L…D6,4(A2) ‰BRA‡WRITCRSR * * C1 = Up*C* Cursor moves up one line in same column, seeks unprotected column+* to the left, with line and page rollover.**(UP‡SUB.L…D5,A0�Same�column�in�line�above3‰SUB.L…D5,(A2)�Modify�start�and�end�of�current�line‰SUB.L…D5,4(A2)‰CMP.L…S.SCRN,A0‹Out�of�screen?‰BGE.S…UP.1�No,�do�it‰MOVE.L„E.SCRN,A0‹Yes,�rollover*‰MOVE.L„A0,S.LINE‹Update�start/end�of�line‰SUB.L…D6,(A2)‰MOVE.L„A0,E.LINE ‰ADD.W…#1,D4!‰LSL.W…#1,D4�Bytes�to�end�of�line(‰SUB.W…D4,A0�To�stay�in�the�same�collumn +UP.1…EQU‡*“Modify�start/end�of�current�line ‰BRA‡WRITCRSR‰PAGE* * C2 = Down*A* Cursor seeks an unprotected spot to the right, starting at same+* collumn on next line, with page rollover.* DOWN…EQU‡*%‰ADD.L…D5,A0�Same�column�on�next�line/‰ADD.L…D5,(A2)�Modify�start/end�of�current�line‰ADD.L…D5,4(A2)#‰CMP.L…E.SCRN,A0‹Out�of�the�screen?‰BLT.S…DOWN1�No,�do�it$‰MOVE.L„S.SCRN,A0‹Yes,�page�rollover‰MOVE.L„A0,S.LINE‰MOVE.L„A0,E.LINE&‰ADD.L…D6,4(A2)ŒD6=B.LINE,�A2==>S.LINE ‰ADD.W…#1,D4$‰LSL.W…#1,D4�D4=#�of�bytes�to�e.line ‰SUB.L…D4,D5 ‰ADD.W…D5,A0DOWN13‰BRA‡WRITCRSRŒSeek�an�unprotected�spot�to�the�right *** C3 = cursor left, same as back space 08.* * * C4 = Right*)* Seek an unprotected space to the right.*RIGHT'‰ADDQ.L„#2,A0�Get�off�of�current�column‰IF.L�A0��E.LINE�THEN.S‰MOVE.L„S.LINE,A0‹Do�line�wrap‰ENDI‰BRA‡WRITCRSRŒUpdate�the�cursor‰PAGE*+*�$C5„Move�the�cursor�to�the�requested�spot*C5: 'ŠBSR„GET_CHAR‹D0.B�<--�the�line�#�char.'ŠMOVE.B�D0,SAVE_CHAR‡Save�it�for�later. )ŠBSR„GET_CHAR‹D0.B�<--�the�column�#�char.&ŠMOVEQ‚#0,D1ŽD1�<--�the�column�#�char.ŠMOVE.B�D0,D1Ž*1ŠSUB.B‚#$20,D1ŒAdjust�it�so�0�is�first�line,�etc. 4ŠCMP„LEFTCOL,D1‰Ensure�that�the�column�#�is�in�range2ŠBLO„RETURN�(�LEFTCOL�<�column�#�<�RIGHTCOL).‚Just0ŠCMP„RIGHTCOL,D1ˆignore�the�command�if�it�isn't. ŠBHI„RETURN�* 4ŠMOVEQ‚#0,D0ŽD0�<--�line�#�char�(saved�from�before).ŠMOVE.B�SAVE_CHAR,D0‡*1ŠSUB.B‚#$20,D0ŒAdjust�it�so�0�is�first�line,�etc. 2ŠCMP„TOPLINE,D0‰Ensure�that�the�line�#�is�in�range0ŠBLO„RETURN�(�TOPLINE�<�line�#�<�BOTLINE�).‚Just/ŠCMP„BOTLINE,D0‰ignore�the�command�if�it�isn't. ŠBHI„RETURN�* /ŠMULUƒD5,D0ŽD0�<--�start�addr�of�absolute�line.ŠADD.L‚#SCREEN,D0‰*"ŠADD„D1,D1ŽA0�<--�addr�of�cursor�=ŠADD.L‚D0,D1Ž*„2�*�column�#�+'ŠMOVE.L�D1,A0Ž*„start�of�absolute�line. -ŠMOVEQ‚#0,D1ŽS.LINE�(start�of�virtual�line)�=7ŠMOVEƒLEFTCOL,D1‰*„2�*�left�column�of�virtual�display�+$ŠADD„D1,D1Ž*„start�of�absolute�line.ŠADD.L‚D0,D1Ž*ŠMOVE.L�D1,S.LINEŠ* +ŠADD.L‚D6,D1ŽE.LINE�(end�of�virtual�line)�=4ŠMOVE.L�D1,E.LINEŠ*„S.LINE�+�bytes�per�virtual�line. 5ŠBRA„WRITCRSR‹Seek�an�unprotected�space�to�the�right.‰PAGEC6‡EQU‡***�$C6„Read�the�cursor�position.**‚Input�parametersƒ:�none.*G*‚Registers�affected�:�D0.W�=�LLCC�(see�C5�for�an�explanation�of�LLCC).**+‰BSR‡READCRSRŒGet�cursor's�absolute�address‰DIVU†D5,D1�D1=00CC00LL‰SWAP†D1’D1=00LL00CC3‰LSL.W…#8-1,D1�D1=00LLCC00�(-1�to�convert�to�bytes)0‰ADD.L…#$DD2020DE,D1‡Add�the�offset�for�the�user*¦Set�start�data�and�end�data*‰LEA‡XTCHBUF(PC),A0†Set�up�for�FEEDER�call‰MOVE.L„D1,(A0)�Move�to�buffer,‰MOVE.W„#4,FEEDER_COUNT…Set�length�of�buffer:‰MOVE.L„A0,FEEDER_ADDRESSƒSet�address�of�buffer�for�FEEDER‰BSR‡FEEDERŽGive�data�to�driver‰BRA‡RETURNŽReturn�to�caller **�$C7„Set�page�mode.* SPAGE„EQU‡*6‰MOVE.W„#-1,PAGEFLAGˆSet�page�mode�flag�true�and�reset‰SFˆPROMODE�protect�mode.2‰MOVE.W„#$C0,D0�Entry�into�page�mode�causes�a�home *¦cursor.‰BRA‡POUTCHSƒ* **�$C8„Set�scroll�mode.* RPAGE„EQU‡*5‰CLR.W…PAGEFLAGŒReset�page�mode�flag�and�protect�mode‰SFˆPROMODE�flag. ‰BRA‡HOME**�$CD„Set�protect�mode*SETPRO‰STˆPROMODEƒSet�protect�mode‰CLR‡PAGEFLAG‚Reset�page�mode!‰MOVE†#$C0,D0ƒForce�a�cursor�home‰BRA‡POUTCHSƒ* ‰PAGE***�$C9„Set�top�line �of�virtual�display�area*G* The top line is set by: 1. Bringing the cursor to the requested line,*œand�then�entering�an�ESC�I."*™2.�Entering�outch�with�D0.W=LLC5 SETTOPƒEQU‡* ‰BSR‡GET_CHARŒGet�next�character‰SUB.B…#$20,D2$‰CMP.W…BOTLINE,D2Š0=botline ‰BHI‡RETURN$‰MOVE.W„D2,TOPLINEŠStore�in�constantINITIT‰BSR‡CRTINIT�Re-configure�CRT&‰BRA‡HOME†Put�cursor�in�home�position. *-*�$CA„Set�bottom�line�of�virtual�display�area*"*�Same�as�C9�for�bottom�line‚ESC�J*SETBOTOM�EQU‡*‰BSR‡GET_CHARŒGet�line�number!‰SUB.B…#$20,D2�Adjust�line�number+‰CMP.W…LPERSCRN,D2‰lperscrn>botline>topline ‰BHS‡RETURN‰CMP.W…TOPLINE,D2 ‰BLO‡RETURN‰MOVE.W„D2,BOTLINE ‰BRA‡INITIT *5*�$CB„Set�left�display�column�of�virtual�screen‚ESC�K* SETLEFT‚EQU‡*‰BSR‡GET_CHARŒGet�left�column‰SUB.B…#$20,D2‰CMP.W…RIGHTCOL,D2 ‰BHI‡RETURN‰MOVE.W„D2,LEFTCOL ‰BRA‡INITIT‰PAGE*4*�$CC„Set�right�display�column�of�dispaly�area‚ESC�L*SETRIGHT�EQU‡*‰BSR‡GET_CHARŒGet�right�column‰SUB.B…#$20,D2,‰CMP.W…CPERLINE,D2‰cperlineleftcol ‰BHS‡RETURN‰CMP.W…LEFTCOL,D2 ‰BLO‡RETURN‰MOVE.W„D2,RIGHTCOL ‰BRA‡INITIT SEEIFIN‚EQU‡*-‰LSR.W…#8,D0�Check�to�see�if�the�user�defined%‰TST.W…D0’the�spot�in�the�second�byte ‰BNE.S…RTSIT*:* The routine will calculate the current line and collumn.+* Left collumn is #00, and top line is #00.*2*�InputŒA0.L�=�Address�of�cursor�in�display�screen**�Output‹A0.L�=�unchanged*’D0.L�=�00CC00LL&*™whereˆLL�=�Line�number,�top�line�=�0'*¦CC�=�Collumn�number,�left�collumn�=�0 GETSPOT‚EQU‡*‰CLR.L…D0’HSKP ‰MOVE.L„A0,D04‰SUB.L…#SCREEN,D0‰=Absolute�cursor�address�on�screen ‰LSR.W…#1,D0*‰DIVU†CPERLINE,D0‰The�quotiant=line�number RTSIT„RTS‰PAGE**�$CD„erase�to�end�of�field*7* All contiguous unprotected characters are spaced out.** FACs are unaffected.* Cursor stays where is.* EEFIELD‚EQU‡*$‰MOVE.W„D6,D7�Words�per�virtual�line#‰LSR.W…#1,D7�Bytes�per�virtual�line-‰SUB.W…D4,D7�Number�of�bytes�to�start�of�line‰BRA.S…EEFIELD0 ‰CLR.W…D3 ‰CLR.W…D7&EEFIELD0�TST.W…(A0)�Is�spot�protected?‰BMI‡RETURNŽYes,�that's�it#‰AND.W…#$FF80,(A0)‰No,�space�it�out‰OR.W†#$20,(A0)+'‰DBRA†D4,EEFIELD0‰Repeat�to�end�of�line$‰ADD.W…PB.LINE,A0ŠStart�of�next�line‰MOVE.W„C.LINE,D4‰CMP.L…E.SCRN,A0(‰BLE.S…EEFIELD1ŒAre�we�ar�end�of�screen?#‰MOVE.L„S.SCRN,A0‹Yes,�roll�it�over.EEFIELD1�DBRA†D3,EEFIELD0‰Repeat�for�all�lines2‰MOVE.W„D7,D4�Add�the�characters�before�the�cursor‰DBRA†D7,EEFIELD0‰BRA‡RETURNŽAnd�then�return‰PAGE**�$CE„write�absolute* WABSOLUT: -ŠREPEAT”Wait�for�a�'start�of�data'�indicator.ŠBSR„GET_CHAR‹*ŠUNTIL.B�D0��#START_OF_DATA .ŠMOVEƒ(A1),SAVEFACS†Save�FACS�currently�in�use 'ŠBSR„GET_CHAR‹D0.B�<--�the�line�#�char.'ŠMOVE.B�D0,SAVE_CHAR‡Save�it�for�later. )ŠBSR„GET_CHAR‹D0.B�<--�the�column�#�char.&ŠMOVEQ‚#0,D1ŽD1�<--�the�column�#�char.ŠMOVE.B�D0,D1Ž*1ŠSUB.B‚#$20,D1ŒAdjust�it�so�0�is�first�line,�etc. 5ŠCMP„CPERLINE,D1ˆEnsure�that�the�column�#�is�in�range-ŠBHS„RETURN�(�LEFTCOL�<�column�#�<�RIGHTCOL). 4ŠMOVEQ‚#0,D0ŽD0�<--�line�#�char�(saved�from�before).ŠMOVE.B�SAVE_CHAR,D0‡*1ŠSUB.B‚#$20,D0ŒAdjust�it�so�0�is�first�line,�etc. /ŠCMP„LPERSCRN,D0ˆEnsure�the�line�#�is�in�range. ŠBHI„RETURN�*BŠMOVE.L�A0,SAVE_CURSOR…Save�the�cursor�address�in�the�vertual�scrn /ŠMULUƒD5,D0ŽD0�<--�start�addr�of�absolute�line.ŠADD.L‚#SCREEN,D0‰*"ŠADD„D1,D1ŽA0�<--�addr�of�cursor�=ŠADD.L‚D0,D1Ž*„2�*�column�#�+'ŠMOVE.L�D1,A0Ž*„start�of�absolute�line. -ŠMOVEQ‚#0,D1ŽS.LINE�(start�of�virtual�line)�=7ŠMOVEƒLEFTCOL,D1‰*„2�*�left�column�of�virtual�display�+$ŠADD„D1,D1Ž*„start�of�absolute�line.ŠADD.L‚D0,D1Ž*ŠMOVE.L�D1,S.LINEŠ* +ŠADD.L‚D6,D1ŽE.LINE�(end�of�virtual�line)�=4ŠMOVE.L�D1,E.LINEŠ*„S.LINE�+�bytes�per�virtual�line. 7ŠST…CHAR_RESERVED†Set�up�to�receive�incoming�charactersŠLEA„WABS1(PC),A3‡*ŠMOVE.L�A3,CHAR_OWNER†*%ŠBRA„WRITCRSR‹Update�cursor�position.WABS1!ŠIF.B�D0��#END _OF_DATA�THEN.S6‰MOVE.L„SAVE_CURSOR,D0†Restore�virtual�screen's�S.LINE *°and�E.LINE!‰MOVE.L„D0,D1�Copy�cursor�address‰SUB.L…#SCREEN,D0*‰DIVU†BPERLINE+2,D0‡Find�line�cursor�is�on*¦remainder�=�position�in�line‰CLR‡D0’Forget�line�we�are�on‰SWAP†D0,‰SUB.L…D0,D1�we�now�know�the�absolute�s.line-‰MOVE†LEFTCOL,D0Šso�adjust�it�by�the�value�in‰ADD‡D0,D0�leftcol.‰ADD.L…D0,D1�*1‰MOVE.L„D1,S.LINE‹bingo�we�now�have�start�of�line-‰ADD.L…B.LINE,D1‹add�the�number�of�bytes/line%‰MOVE.L„D1,E.LINE‹and�set�end�of�line8‰MOVE.L„SAVE_CURSOR,A0†Set�cursor�back�to�virtual�screen‰MOVE†SAVEFACS,FACS‰BRA‡WRITCRSRŒ*ŠENDIŠST…CHAR_RESERVED‰IF.B„D2��#$E0�AND.B‘D2��#$EB�THEN.S6‰TST.B…LASTFAC�See�if�the�last�character�processed�was*¦a�FAC.5‰IF„�THEN.S�If�it�was�not�a�FAC�then�destroy�what)*¦could�be�another�FAC�currently�on�scrn.9‰MOVE.B„#$FF,1(A0)ŠFac�processing�checks�the�current�char%*¦to�determine�if�a�new�FAC�should�be'*¦declared.�If�we�are�currently�sitting**¦on�a�FAC�definition�it�must�be�destroyed‰ENDI3‰STˆLASTFAC�Tell�the�loop�we�have�been�here�before. ‰BRA�OUTCH1‰ENDI3‰TST.B…LASTFAC�If�the�last�character�was�a�FAC�then"*¦the�cursor�must�be�moved�off�it.‰IFˆ�THEN.S)‰ADD.L…#2,A0�Move�the�cursor�off�the�FAC.4‰SFˆLASTFAC�Indicate�the�last�character�was't�a�FAC.‰ENDI8‰MOVE.W„LPERSCRN,D0‰FIND�THE�END�OF�THE�ABSOLUTE�DISPLAY ‰MULU†D5,D0�*‰ADD.L…#SCREEN,D0Š*5‰OR.W†FACS,D2�Write�the�current�character�to�the�scrn‰MOVE.W„D2,(A0)+Œ*‰IF.L†A0��D0�THEN.S&‰BRA‡RETURNŽExit�if�past�end�of�screen‰ENDI,‰BRA‡WRITCRSRŒUpdate�current�cursor�position **�$CF„read�absolute**RABSOLUT�EQU‡*8‰BSR‡GET_CHAR‚Get�row�address�for�beginning�adr.�of�read*‰MOVE.B„D0,SAVE_CHAR‚Save�the�row�address.8‰BSR‡GET_CHAR‚Get�col.�address�of�begining�read�address. ‰MOVE.B„D0,SAVE_CR1‰Save�it�also0‰BSR‡GET_CHAR‚Get�row�address�of�ending�address.‰MOVE.B„D0,SAVE_CR2‰Save�it.0‰BSR‡GET_CHAR‚Get�col.�address�of�ending�address‰MOVE.B„D0,SAVE_CR3‰Save�it.***ˆALLOCATE�MEMORY--SAVE�THE�BUFFER�ADDRESS*0‰MOVE.L„#4,D0…Service�request�code�for�PAGEALOC.7‰MOVE.L„#8,A0…Set�up�memory�descriptor�and�get�8�pages. ‰SUB.L…A1,A1‰TRAP†#0&‰BRA.S…RABSO1„Branch�if�we�got�memory.#‰BRA‡RETURN„Just�exit�if�we�didn't.**ˆSAVE�BUFFER�ADDRESS*RABSO13‰STˆREL_FLAGŒTell�feeder�to�release�mem.�when�done.*‰MOVE.L„A0,REL_ADDR‰Feeder�buffer�address.4‰MOVE.L„A0,FEEDER_ADDRESSƒBuffer�address�for�feeder..‰MOVE.L„A0,A2�Put�address�in�useable�register.@‰MOVE.L„#NUMBER_PAGES,REL_PAGES‚Tell�feeder�the�number�of�pages.‰MOVE.B„#START_OF_DATA,(A2)+;‰MOVE†#1,FEEDER_COUNT…Update�the�charater�count�for�feeder.*=*ˆFIND�THE�BEGINNING�AND�ENDING�ADDRESSES�BASED�ON�THE�CURSOR *ˆADDRESSES*/ˆMOVE‡SAVE_CR2,D0‰Convert�ending�address�first.)‰SUB‡#$2020,D0‹Adjust�the�cursor�address.‰BSR.S…CONVERT�*'‰MOVE.L„A0,A1�Put�it�in�the�proper�reg.,‰MOVE†SAVE_CHAR,D0ˆNow�do�beginning�address.)‰SUB‡#$2020,D0‹Adjust�the�cursor�address.‰BSR.S…CONVERT�*6‰MOVE.L„A0,D1�This�will�be�the�end�of�current�line�adr‰ADD.L…D5,D1�*?*†A0�=�STARTING�ADDRESS†A1�=�ENDING�ADDRESS„A2�=�BUFFER�ADDRESS ‰REPEAT8‰IF.L†A0��D1�THEN.SƒIf�we�are�at�the�end�of�the�line8‰MOVE.B„#END_OF_FIELD,(A2)+�move�in�the�line�terminator.*‰ADDQ†#1,FEEDER_COUNT…Update�feeder�count. ‰ADD.L…D5,D1‰ENDI ‰TST.B…1(A0)5‰IF‚�THEN.S�End�of�lines�are�flagged�by�an�end�of,‰MOVE.B‚#END_OF_FIELD,(A2)+ƒfield�character.*‰ADDQ†#1,FEEDER_COUNT…Adjust�feeder�count.‰ENDI‰IF.B…1(A0)��#01�THEN.S!‰ADDQ.L„#2,A0�Adjust�the�pointer. ‰BRA.S…RABSO2‰ENDI+‰MOVE.B„1(A0),D0ŒWe�could�be�on�a�tab�stop.)‰AND.B…#$7F,D0�Strip�of�the�tab�stop�bit.*‰MOVE.B„D0,(A2)+ŒMove�data�byte�to�buffer.%‰ADDQ.L„#2,A0�Bump�to�next�character.3‰ADDQ†#1,FEEDER_COUNT…Bump�feeders�character�count.RABSO2‰UNTIL.LƒA0��A1D‰MOVE.B„#END_OF_DATA,(A2)�We�are�all�done�moving�data�to�the�buffer.;‰ADDQ†#1,FEEDER_COUNT…Bump�number�of�characters�for�feeder. (‰BSR‡FEEDERŽSend�the�data�to�the�driver./‰BRA‡RETURNŽWe�are�all�done�--�thankyou�kindly.*2* Convert the llcc value to a display RAM address.**ˆInputƒD0.W�=�llcc*ˆOutput‚A0.L�=�screen�address* CONVERT‚EQU‡*%‰MOVE.L„D6,-(A7)ŒGet�some�ellbow�room ‰CLR.L…D6 ‰MOVE.W„D0,D6‰AND.W…#$00FF,D0‰CMP.W…CPERLINE,D0 ‰BGT.S…CONRET‰LSR.L…#8,D6�D6.L=000000ll‰CMP.W…LPERSCRN,D6 ‰BGT.S…CONRET ‰MULU.W„D5,D6 ‰LSL.W…#1,D0 ‰ADD.B…D0,D6‰ADD.L…#SCREEN,D6 ‰MOVE.L„D6,A0CONRETƒMOVE.L„(A7)+,D6‰RTS‰PAGE*8*‚$D0„Insert�a�character�at�the�current�cursor�position.B*‰Starting�at�the�current�cursor�position,�characters�are�moved�to@*‰the�right�until�the�end�of�line�or�a�protected�field�is�hit.‚A>*‰space�is�put�in�the�current�cursor�position.‚The�cursor�does *‰not�move.*7ICHAR:„MOVEQ‚#SPACE,D0ŠInitialize�LAST�CHAR�to�a�space. ICHAR12ŠMOVEQ‚#$7F,D1ŒD1�<--�the�char�from�this�position.ŠAND„(A0),D1Œ*9ŠAND„#$FF80,(A0)ˆPut�the�LAST�CHAR�out�there�in�its�place.ŠOR…D0,(A0)+‹and�advance�to�the�next�position.1ŠMOVEƒD1,D0ŽSet�LAST�CHAR�to�the�char�we�just�got;ŠDBRAƒD4,ICHAR1Š(for�next�pass)�and�loop�until�end�of�line. ICHAR3„BRA„RETURN�Exit. *8*‚$D1„Delete�a�character�at�the�current�cursor�position.F*‰Starting�just�past�the�current�cursor�position,�characters�are�movedB*‰to�the�left�until�the�end�of�line�or�a�protected�field�is�hit.‚A@*‰space�is�put�in�the�final�modifiable�position.‚The�cursor�does%*‰not�move.‚The�entry�point�is�DCHAR.*<DCHAR1„MOVEƒ2(A0),D0‹D0�<--�the�char�from�the�next�position. *ŠAND„#$7F,D0ŒPut�the�char�in�this�position%ŠOR…D0,(A0)+‹and�advance�to�the�next. :DCHAR:„AND„#$FF80,(A0)ˆRemove�the�char�from�this�position.2ŠDBRAƒD4,DCHAR1ŠLoop�if�there�are�more�characters. 6DCHAR2„OR…#$20,(A0)ŠPut�a�space�in�this�final�positionŠBRA„RETURN�and�return.‰PAGE**‚$D2ƒENABLE�KEYBOARD*KEYENAB ‰SFˆKB_LOCK ‰BRA‡RETURN   **‚$D3ƒDISABLE�KEYBOARD*KEYDSABL ‰STˆKB_LOCK ‰BRA‡RETURN   ***�$D4„erase�all�unprotected�to�end�of�page**ˆFACs�are�not�affected!*ˆCursor�position�is�not�affected* EEPAGEƒEQU‡*‰BSR‡GETSPOT�D0=00CC00LL‰SUB.W…TOPLINE,D0-‰SUB.W…D0,D3�Number�of�lines�to�end�of�screenEEPAGE1‚BSR‡ERASE�Erase�them ‰BRA‡RETURN  **�$D5„Erase�to�end�of�line* EELINEƒEQU‡*‰CLR.W…D3’Only�one�line ‰BRA‡EEPAGE1  *3*‚$D6„Insert�a�line�at�the�current�cursor�position.@*‰Starting�at�the�bottom�of�the�screen�and�working�up,�copy�each=*‰line�to�the�line�below.‚The�line�the�cursor�is�on�is�filled=*‰with�blanks�and�the�cursor�is�positioned�at�the�left�of�the3*‰line.‚(In�all�this,�'line'�means�'virtual�line.')*INS_LINE6ŠMOVE.L�E.SCRN,A0ŠA0�<--�addr�just�past�end�of�screen. AŠWHILE.L�A0��E.LINE�DO.S‚While�A0�is�not�on�the�current�line, 6ŠMOVE.L�A0,A1ŽA1�<--�addr�just�past�end�of�line�above./ŠSUB.L‚D5,A1Ž*‡(D5�is�bytes�per�absolute�line.)0ŠMOVE.L�A0,-(SP)‹Save�the�address�for�this�line. 6ŠMOVEƒC.LINE,D0ŠD0�<--�#�of�chars�in�virtual�line�-�1.@INS_LIN1‚MOVEƒ-(A1),-(A0)ˆMove�all�words�(attribute�and�char)�in.ŠDBRAƒD0,INS_LIN1ˆthis�line�to�the�line�below. 3ŠMOVE.L�(SP)+,A0‹Restore�the�address�for�this�line.-ŠSUB.L‚D5,A0ŽA0�<--�address�for�next�line�up. ŠENDW (*§At�this�point�A0�is�the�addr�just�past&*§the�end�of�the�current�virtual�line.6ŠMOVEƒC.LINE,D0ŠD0�<--�#�of�chars�in�virtual�line�-�1.?INS_LIN2‚AND.B‚#$80,-(A0)‰Fill�the�current�line�with�spaces�and%ŠOR.Bƒ#$20,(A0)Šinnocuous�attributes.ŠMOVE.B�#$44,-(A0)‰*ŠDBRAƒD0,INS_LIN2ˆ*%*§At�this�point�A0�is�the�addr�of�the(*§beginning�of�the�current�virtual�line.,ŠBRA„WRITCRSR‹Go�set�the�new�cursor�address.   **�$D7‚DELETE�LINE*DEL_LINE;‰MOVE.L„S.LINE,A0�Beginning�address�of�current�virtual�lineDELINE;‰MOVE.L„A0,A1…Calculate�the�address�of�the�beginning�of�the‰ADD.L…D5,A1…next�line.4‰MOVE†C.LINE,D0�Number�of�bytes�per�line�to�be�moved?‰CMP.L…E.SCRN,A1�See�if�move�from�address�is�passed�end�of�scrn-‰BHS.S…DEL INE2ƒBranch�if�passed�end�of�screen2‰MOVE.L„A0,-(A7)‚Save�destination�address�on�stackDELINE1*‰MOVE.W„(A1)+,(A0)+�Move�line�up�on�screen‰DBRA†D0,DELINE1‚*,‰MOVE.L„(A7)+,A0‚Restore�destination�address'‰ADD.L…D5,A0‡Point�to�next�virtual�line,‰BRA.S…DELINE„Go�move�next�line�up�on�screenDELINE22‰MOVE.B„#$44,(A0)+ƒBlank�the�bottom�line�of�screen.‰AND.B…#$80,(A0)„Save�tab�stop�if�there�is�one+‰OR.B†#$20,(A0)+ƒSet�space�in�this�location‰DBRA†D0,DELINE2ƒ*9‰MOVE.L„S.LINE,A0„Set�cursor�to�beginning�of�current�line‰BRA‡WRITCRSR…*   **�$D8„clear�screen,�cursor�home*B* All unprotected positions in display area are filled with nulls.* FAC's are not affected.* * Cursor moves to home position.** CLEAR_SCREENA‰MOVEM.LƒD0-D7/A0-A3,-(A7)ƒSet�up�the�alternate�entry�for�command6‰MOVE†L.SCRN,D3‹Set�up�the�reg�because�it�isn't�set�ip*%%%%%%%%%‚BWN‚10/24/84*6*ƒSet�up�the�other�registers�we�need�for�this�routine.*‰LEA‡S.LINE,A2‰MOVE.L„B.LINE,D6!*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLEAR„EQU‡*‰MOVE.L„S.SCRN,A0‹Start�at�home‰MOVE.W„C.LINE,D4‹A�full�line"‰BSR.S…ERASE�Erase�all�unprotected‰BRA‡HOME�Put�cursor�at�home *%* Erase D4.W characters in D3.w lines* ERASE„EQU‡*‰IF‚PAGEFLAG��#TRUE�THEN.S0‰TST‡(A0)+�Used�only�when�alternate�entry�called ‰BMI.S…ERASE1‰ENDI$‰AND.W…#$0080,(A0)‰Clear�current�FAC ‰OR.W†#$4400,(A0)+ˆWrite�a�space/ERASE1ƒDBRA†D4,ERASEŒRepeat�for�D4.w�characters)‰MOVE.W„C.LINE,D4‹Reset�character�counter$‰ADD.W…PB.LINE,A0ŠStart�of�next�line$‰DBRA†D3,ERASEŒRepeat�for�D3.w�lines‰RTS‰PAGE**�$DA„Forward�tab* * Same as HT* ** DB = BT, back tab*@* Position cursor at first tab in first unprotected to the left.**  SEEKBTƒEQU‡*‰MOVE.L„A0,A3�Loop�terminator‰REPEAT‰IF.L†A0��S.LINE�THEN.S+‰MOVE.L„E.LINE,A0‹Wrap�on�current�line�only‰ENDI1‰MOVE.W„-(A0),D0ŒCharacter�preceeding�current�one‰TST.B…D0’Is�this�a�tab�stop*‰BMI.S…SEEKBT2�Branch�if�we�hit�a�tab�stopSEEKBT1;‰UNTIL.LƒA0��A3ŠScan�line�until�we�get�where�we�startedSEEKBT2#‰BRA‡WRITCRSRŒUpdate�cursor�address‰PAGE** DC = set tab* SETTABƒEQU‡*/‰CLR.L…COL_CNTƒInitialize�current�column�number‰BRA.S…SETTAB2SETTAB1:‰ADD.L…#2,COL_CNTŠUpdate�the�column�count�for�the�next�guy‰MOVE.L„COL_CNT,D0@‰IF.L‚D0��BPERLINE�THEN.S�Make�sure�we�don't�go�out�of�range<‰WHILE�D2��#LFCHAR�DO.S„If�out�of�range�discard�incoming/‰BSR�GET_CHAR’until�terminated�with�a�line�feed‰ENDW‰BRA‡RETURNŽExit‰ENDISETTAB2.‰BSR‡GET_CHAR‚Get�next�character�of�tab�string6‰MOVE†LPERSCRN,D3‰Set�loop�control�for�absolute�screen‰SUBQ†#1,D3�DBRA�adjustment9‰CMP.B…#LFCHAR,D2ŠEnd�of�string�is�indicated�by�line�feed‰BNE.S…SETTAB2A‹**C*‡LINE�FEED�CHARACTER�DETECTED,‚IF�IT�FOLLOWED�SET�TABS--�RESET�ALL*‡CURRENT�TABS*SETTAB42‰TST.L…COL_CNT�If�column�count�zero�then�line�feed*°followed�set�command‰IF��THEN.S+‰LEA‡SCREEN,A0‹Point�to�beginning�of�screen+‰MOVE†LPERSCRN,D5‰Get�#�of�lines�per�screen8‰MULU†CPERLINE,D5‰*�characters�per�line�=�#�of�character*©positions�on�screenCLRTAB‰AND.W…#$FF7F,(A0)+ˆReset�tab(‰DBRA†D5,CLRTAB‹Loop�until�end�of�screen‰ENDI ‰BRA‡RETURNSETTAB2A4‰MOVE.L„COL_CNT,A0ŠPoint�to�current�position�in�line‰ADD.L…#SCREEN,A0Š*-‰CMP.B…#SPACE,D2‹Is�this�a�filler�character�?5‰BEQ.S…SETTAB1�Get�next�character�if�current�is�space'‰CMP.B…#CLEARTAB,D2ˆClear�tab�request�?+‰BEQ.S…RESETTABŒBranch�if�clear�tab�request**„SET�TAB�REQUEST*SETTAB37‰BSET.B„#7,1(A0)ŒSet�tab�bit�in�high�nibble�of�the�dis-4‰ADD.L…D5,A0�played�char.�for�every�column�on�screen‰DBRA†D3,SETTAB3Š*‰BRA.S…SETTAB1RESETTAB1‰BCLR.B„#7,1(A0)ŒTurn�tab�bit�off�in�every�column‰ADD.L…D5,A0�*‰DBRA†D3,RESETTAB‰* ‰BRA‡SETTAB1‰PAGE*F* The characters $E0-$EF will set or reset the field attribute bits in'* the XREFed, word sized register FACS.* FACS is defined as follows:**ˆD15�=�Se t�for�protect*ˆD14�=�Set�for�display*ˆD13�=�Set�for�blink*ˆD12�=�Set�for�underline*ˆD11�=�Set�for�inverse�video*ˆD10�=�color/intensity�bit�1*ˆD09�=�color/intensity�bit�2*ˆD08�=�color/intensity�bit�3 *„D07-D00�=�0* ** E0 = set blink* SBLINKƒEQU‡*B‰IF.B�1(A0)��#01�THEN.S…Allow�another�FAC�to�be�defined�only‚f&*¦if�we�are�currently�sitting�on�a�FAC *¦definition.!‰BSET.B„#5,(A1)�Set�the�blink�bit‰ELSE.S4‰MOVE.B„#$64,(A1)‹Not�on�a�current�FAC�definition�so*¦reset�the�FACS.‰ENDI#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen9‰MOVE.B„#01,1(A0)‹Simulate�character�position�used�by�FAC ‰BRA‡RETURN ** E1 = reset blink* RBLINKƒEQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FACC‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.#‰BCLR.B„#5,(A1)�Reset�the�blink�bit‰ELSE.S4‰MOVE.B„#44,(A1)ŒReset�any�other�FACS�for�this�line.‰ENDI ‰BRA‡RETURN ** E2 = set video invert* SINVERT‚EQU‡*C‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.#‰BSET.B„#3,(A1)�Set�the�inverse�bit‰ELSE.S7‰MOVE.B„#$4C,(A1)‹Set�invert�only�bit.�(plus�dislay�and *¦intensity.‰ENDI#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FAC ‰BRA‡RETURN ** E3 = reset video invert* RINVERT‚EQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FACC‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.%‰BCLR.B„#3,(A1)�Reset�the�inverse�bit‰ELSE.S#‰MOVE.B„#$44,(A1)‹Reset�everything.‰ENDI ‰BRA‡RETURN ** E4 = Set half bright*UPBRIGHT�EQU‡*,‰MOVE.B„(A1),D2�Get�the�MSB�part�of�the�FACs'‰AND.B…#$F8,D2�Only�the�brightness�bits ‰OR.B†#$05,D2�Set�to�half�bright‰MOVE.B„D2,(A1)�* ‰BRA‡RETURN ** E5 = Reset half bright*DNBRIGHT�EQU‡*,‰MOVE.B„(A1),D2�Get�the�MSB�part�of�the�FACs'‰AND.B…#$F8,D2�Turn�off�brightness�bits‰OR.B†#$02,D2�Reset�half�bright‰MOVE.B„D2,(A1)�* ‰BRA‡RETURN ** E6 = set underline* SULINEƒEQU‡*C‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.%‰BSET.B„#4,(A1)�Set�the�underline�bit‰ELSE.S)‰MOVE.B„#$54,(A1)‹Set�underline�FAC�only.‰ENDI#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FAC ‰BRA‡RET.1 ** E7 = reset underline* RULINEƒEQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FACC‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.'‰BCLR.B„#4,(A1)�Reset�the�underline�bit‰ELSE.S.‰MOVE.B„#44,(A1)ŒReset�all�FACS�for�this�line.‰ENDI ‰BRA‡RET.1 ** E8 = set non display* NONDISP‚EQU‡*C‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.'‰BCLR.B„#6,(A1)�Set�the�non-display�bit‰ELSE.S(‰MOVE.B„#4,(A1)�Turn�off�the�dispay�bit.‰ENDI#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FAC ‰BRA‡RETURN ** E9 = reset non-display* SETDISP‚EQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FACC‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.2‰BSET.B„#6,(A1)�Set�display�along�with�other�FACS.‰ELSE.S:‰MOVE.B„#$44,(A1)‹Set�display�bit�only,�turn�off�all�other*¦FACS.‰ENDI ‰BRA.S…RET.1 ** EA = set protect* PROTECT‚EQU‡*C‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.6‰BSET.B„#7,(A1)�Set�protect�bit�and�don' t�change�other*¦FACs�allready�there.‰ELSE.S'‰MOVE.B„#$C4,(A1)‹Set�protect�FAC�only.‰ENDI#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FAC ‰BRA.S…RET.1 ** EB = reset protect* ALLOW„EQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�FACC‰IF.B‚1(A0)��#01�THEN.SƒAllow�another�FAC�to�be�defined�only�if#*¦we�are�currently�sitting�on�a�FAC *¦definition.+‰BCLR.B„#7,(A1)�Reset�only�the�protect�FAC.‰ELSE.S!‰MOVE.B„#$44,(A1)‹Reset�all�FACs.‰ENDIRET.1„BRA‡RETURNŠPAGE* * F1 = reset*K* The display area is filled with spaces, all FAC's are reset, tabs are setL* every INIT_TAB spaces, the virtual screen is restored to its default size,* and the cursor is HOMEd.* RESET_SCREEN>‰MOVEM.L�D0-D7/A0-A3,-(A7)�Set�up�stack�so�we�can�exit�clean„T5‰LEA‡S.LINE,A2‡Fix�up�the�registers�because�we�didn't*¢come�through�the�normal�path‰MOVE.L„B.LINE,D6‡*$‰BRA.S…RESET25‰Clear�25�line�screen.RESET240‰MOVE†#24,NUMBER_LINES�Set�up�to�clear�24�lines.RESET253ŠBSR„SCRNINIT‹Reset�all�the�parameters�to�defaults. *‚Fill�the�screen�with�blanks.4ŠLEA„SCREEN,A0ŠA0�<--�start�addr�of�absolute�screen.6ŠMOVEƒ#$4400,D2ŠD2�<--�default�attributes�and�a�end�of#*¦line�char�for�filling�the�screen.:ŠMOVEƒNUMBER_LINES,D5„D5�<--�#�of�characters�on�screen�-�1<ŠMULUƒCPERLINE,D5ˆ*‚=�lines�per�screen�*�chars�per�line�-�1. ŠSUBQƒ#1,D5Ž* �DO.SŠWhile�there�are�more�tabs�to�place, 5ŠBSETW‚#7,(A0)ŒSet�a�tab�in�this�position�and�advance%ŠADD.L‚#2*INIT_TAB,A0…INIT_TAB�chars. 0ŠSUBQƒ#1,D5ŽKeep�going�until�all�tabs�are�placedŠENDW–on�this�line. /ŠMOVEƒBPERLINE,A0ˆA0.L�<--�address�of�next�line7ŠADD.L‚(SP)+,A0‹*„=�addr�of�last�line�+�bytes�per�line. 0ŠSUBQƒ#1,D2ŽKeep�going�until�all�lines�are�done. ŠUNTIL‚�*ŠSF…EDIT_FLAGŠClear�edit�modeŠSF…PAGEFLAG‹page�modeŠSF…PROMODEŒand�protect�mode.3ŠMOVE.LƒB.LINE,D6ˆHome�needs�bytes�per�virtual�line?ŠMOVE…#25,NUMBER_LINES�Set�up�the�screen�to�25�lines�in�case�we*£did�a�24�line�screen�clear.ŠBRA‡HOMEŒHome�the�cursor.‰PAGE* * DISPLAYL*---------------------------------------------------------------------------L* 1. Write the requested character in the display RAM at the current cursor.I* 2. Seek a non-protected spot to the right, with line and page rollover.6*„if�none�found,�sound�bell,�and�stay�at�current�spot.,* 3. Update the cursor register of the CRTC.** Input parameters:*------------------4* A0.L = current cursor posiotion in the display RAM8* D2.L = $000000XX, where XX is the requested character.0* D3.W = Maximum number of characters on screen.F* FACS = An XREFed, word sized register containing the FACs in effect.* DISPLAY‚EQU‡*‰MOVE.L�A0,A3’Init�reg.‰WHILE.L�A3��S.LINE�DO.S2‰MOVE.B�-1(A3),D0ŽMove�end�of�line�to�current�char‰AND.B�#$7F,D0‘could�be�a�tab7‰BNE.S�DISPLAY1�Branch�if�a�character�occupies�position0‰OR.B‚#$20,-1(A3)�Space�fill�to�move�end�of�line)‰SUBQ.L�#2,A3’Backup�to�beginning�of�line‰ENDWDISPLAY1‰IF.B‚1(A0)��#01�THEN.S5‰MOVE.B„#$44,FACS‹Reset�the�FAC�defined�for�this�line#*¦because�it�is�being�written�over.‰ENDI :‰MOVE.B„FACS,(A0)+ŠMove�current�FACS�to�current�Screen�loc%‰AND.B…#$80,(A0)‹Keep�tab�information,‰OR.B†D2,(A0)+ŒWrite�character�to�the�screen  SCROLLƒEQU‡*‰IF.L†A0��E.SCRN‚THEN.S!‰IF.B†EDIT_FLAG��#TRUE�THEN.S(‰BRA�HOMEŒEND�OF�SCREEN�AND�IN�EDIT�MODE‰ENDI*‰BRA.SƒSCROLL1‚End �of�screen�not�edit�mode‰ENDI SEEKR2‰IF.L†A0��E.LINE�THEN.S#‰ADD.L…D5,(A2)�Update�start�of�line‰ADD.L…D5,4(A2)Œand�end�ofline‰MOVE.L„S.LINE,A0‰ENDI‰BRA.S…WRITCRSR ** Scroll*)* Input parameters : A0.L > end of screen* SCROLL1‚EQU‡*2‰MOVE.L„E.SCRN,E.LINE‡Modify�start�and�end�of�line‰MOVE.L„E.SCRN,S.LINE‰SUB.L…D6,(A2) %‰MOVE.L„S.SCRN,A0‹Start�of�first�line‰MOVE.L„S.SCRN,A3!‰ADD.L…D5,A3�Start�of�second�line&‰BRA.S…SCROLLR�Do�not�scroll�last�line ,SCROLL2‚MOVE.W„C.LINE,D4‹Characters�per�line6SCROLLIT�MOVE.W„(A3)+,(A0)+‰Move�line�#n+1�to�line�#n.!‰DBRA†D4,SCROLLIT‰Scroll�one�line$‰ADD.W…PB.LINE,A0ŠStart�of�next�line‰ADD.W…PB.LINE,A3SCROLLR%‰DBRA†D3,SCROLL2ŠRepeat�for�all�lines $‰MOVE.L„S.LINE,A0‹Start�of�last�line7‰MOVE.W„C.LINE,D4‹Reset�last�line�to�no�facs�and�spaces‰MOVE.W„(A1),D2 ‰OR.B†#$20,D2 2SCROLL3‚AND.W…#$0080,(A0)‰Save�only�a�possible�tab,‰OR.W†D2,(A0)+ŒInit�FACs�and�space�character‰DBRA†D4,SCROLL3ŠThe�whole�line $‰MOVE.L„S.LINE,A0‹Start�of�last�line WRITCRSR�EQU‡**9* Convert display RAM address to absolute cursor address,* and write into CRTC.** A0.L = Diaplay cursor address*/‰MOVE.L„A0,D1�Calculate�cursor�absolute�address‰SUB.L…#SCREEN,D1+‰LSR.L…#1,D1�To�take�care�of�attribute�area WRITEABS�EQU‡**/* Write the absolute cursor address in the CRTC* * D1.W = absolute cursor address*!‰MOVE.B„#$0F,CRTCADDˆPoint�to�R152‰MOVE.B„D1,CRTCREGŠStore�LSB�of�new�cursor�address ‰LSR.W…#8,D1�Position�upper�byte!‰MOVE.B„#$0E,CRTCADDˆPoint�to�R143‰MOVE.B„D1,CRTCREGŠSrore�MSB�of�new�cursor�register 6RETURNƒMOVEM.Lƒ(A7)+,D0-D7/A0-A3ƒRestore�user's�values‰RTS‰PAGEREADCRSR�EQU‡***‚Read�the�cursor�position*6*‚This�routine�is�for�internal�use,�and�is�not�XDEFed.)*‚For�an�external�control�routine�see�C6.**‚Input�parametersƒ:�none*>*‚Registers�affected�:�D1.W�=�Absolute�address�of�cursor�spot.&*—A0.L�=�Screen�RAM�address�of�cursor.*‰CLR.L…D1’HSKP!‰MOVE.B„#$0E,CRTCADDˆPoint�to�R14.‰MOVE.B„CRTCREG,D1ŠGet�current�cursor�position‰ROL.W…#8,D1�Put�it�in�MSB!‰MOVE.B„#$0F,CRTCADDˆPoint�to�R154‰MOVE.B„CRTCREG,D1ŠGet�lower�byte�of�cursor�position-‰LSL.W…#1,D1�Adjust�for�screen�RAM�operations ‰MOVE.L„D1,A0‰ADD.L…#SCREEN,A0‰RTS***GET_CHAR3‰STˆCHAR_RESERVED‡Reserve�next�character�for�caller>‰MOVE.L„(A7)+,CHAR_OWNER„Save�callers�return�address�for�later'‰BRA‡RETURNŽWait�for�the�next�character‰END:PAGEMODE‚IDNTƒ45,0†VME/10�page�mode�emulation�for�TERMDRV.6ŠTTL„PAGEMODE:�VME/10�page�mode�emulation�for�TERMDRV.NNNNN NNr{?ƒ3O*v*****************************************************************************O*******************************************************************************O**********************************************************************************É***=***†FILENAME:‚PAGEMODE�--�PAGE�MODE�EMULATION�FOR�TERMDRV�******É***7***†ENVIRONMENT:‚Linked�into�TERMDRV�for�the�VME/10“******É***E***†FUNCTION:‚When�the�keyboard/screen�is�put�into�page�mode,�any…***?***‰characters�received�from�the�keyboard�are�sent�here�for‰******‰special�interpretation.©******É******†NOTES:½******É***,***†EXTERNAL�DATA�STRUCTURES�REFERENCED:Ÿ******É***)***†EXTERNAL�ENTRY�POINTS�REFERENCED:¢******‰OUTCHSº******É***"***†SERVICES�CALLED�VIA�TRAPS:©******É******É***O*******************************************************************************O*******************************************************************************O*^***************************************************************************** *,*‚Revision�history�(add�new�changes�to�top).*…Date†Author‰ChangesG*…--------‚-------------‚----------------------------------------------&*†5/23/83‚Russ�Rustad„Initial�writing.*ŠPAGE* *‚XDEF's.*:ŠXDEFƒPAGEMODE‹Entry�pt.�for�char's�received�in�page�mode.  *0*‚XREF's�(indicate�where�the�XDEF�is,�if�known).*8ŠXREFƒOUTCHS�Routine�in�OUTCHS�to�output�char�on�screen./*ž(All�of�the�following�are�XDEF'ed�in�CRTINIT)ŠPAGEO*********************************************************************************‰INCLUDE�FILES�AND�EQUATES*O******************************************************************************* **‚Include�files:*  *.*‚Equates�for�the�values�of�the�function�keys.*9FN_LOW„EQU„$A0�These�define�the�range�of�values�generated%FN_HIGHƒEQU„$BF�by�the�function�keys.ŠPAGEO*v*****************************************************************************O**********************************************************************************É***+***�PAGEMODE�--�PAGE�MODE�INPUT�HANDLER–******É***E***†FUNCTION:‚When�an�external�routine�receives�a�character�while…***:***‰the�screen�is�in�page�mode,�he�calls�this�routine.Ž******É******†NOTES:½******É***E***†REGISTER�USAGE:‚(A)rgument‚(D)estroyed‚(P)reserved‚(R)eturned‚***)***Œ0ƒ1ƒ2ƒ3ƒ4ƒ5ƒ6ƒ7‡SR�hi„SR�lo�(CCR)…******‡D:ƒAR‚.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.‡.ˆR�******‡A:ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒ.ƒP ******É******†ENTRY�CONDITIONS:²***8***‰D0.W�=�$00cc�where�cc�is�the�received�character.�******É***-***†EXIT�CONDITIONS�DIFFERENT�FROM�ENTRY:ž***6***‰CCR:��=�keystroke�did�not�generate�a�char.’***@***Ž,�=�generated�char�is�in�D0.W�(bits�8-15�are�0).ƒ***(***‰D0�is�not�preserved�in�any�case. ******É***O*^*****************************************************************************O******************************************************************************* ŠDS…0ŠOPT„BRS ŠSECTION�0  PAGEMODE: 1ŠMOVEM.L�D1,-(SP)ŠSave�registers�we'll�blow�away. DŠIF.B�D0��#FN_LOW�AND.B�D0��#FN_HIGH�THENƒIf�the�key�pressed*§was�a�function�key, 9ŠMOVEQ‚#1,D1ŒSet�CCR�to�,�to�say�'we�got�a�char.' %ŠELSE–Else�(it's�not �a�function�key), 8ŠBSR.L‚OUTCHS�Call�OUTCHS�to�output�the�char�and�set�CCR3ŠMOVEQ‚#0,D1Žto��to�say�'ignore�the�keystroke.' ŠENDI -ŠMOVEM.L�(SP)+,D1ŠRestore�registers�and�exit.ŠRTS—*   ŠENDNN8POUTCHSƒIDNT†45,0†Output�a�character�to�the�display�RAM.4ŠTTL‡POUTCHS:‚Output�a�character�to�the�display�RAM.NNNNNNN„‹”5œ<¤E¬4´,¼,Ä/Ì-ÔFÜHäNìSôNüST <JL$I,;4B<TDCLZTE\EdBl;tK<*************************************************************º**�Routine�name:�POUTCHS˜*<*----------------------------------------------------------*-*�Current�revision.....................1.10�*1*�Date�written.........................12-18-82Œ*2*�Written�by...........................S.Pri-Tal‹*/*�Date�changed.........................3-1-83Ž*2*�Changed�by...........................R.�RUSTAD‹**º**�Description�of�change:£**º*0*�Date�changed.........................8-17-84�*1*�Changed�by...........................B.�NASONŒ**º**�Description�of�change:£**ƒChanged�all�XREF.S�to�XREF�**º*0*�Date�changed.........................8-30-84�*3*ƒchanged�to�mask�'tab�stop'�bit.....D.�Vanderlinˆ**º*0*�Date�changed.........................1-30-85�*/*�Changed�by...........................M.�DUHŽ**º**�Description�of�change:£*7*ƒSet�RING_BELL�flag�when�$07�is�to�be�output�(BELL).„**º*<************************************************************9*�Function:�Output�the�cha racter�in�D0.B�to�the�display„*/*‹RAM�if�character�is�printable,�else�perform„**‹the�required�function.™*<*----------------------------------------------------------*/*�Input�parameters:‚D0.B�character�to�output.�*<*----------------------------------------------------------**�Registers�affected:�none¡*<*----------------------------------------------------------* *�External�routines�used:�none�*<************************************************************‰PAGE ‰XDEF†POUTCHS (‰XREF†CRTINITƒInit�the�screen�parameters‰XREF†SCRNINIT /‰XREF„FACS†Field�attribute,�word�sized�register3‰XREF„PAGEFLAG‚Word�sized�flag.�If=$FFFF,�page�mode5‰XREF„PROMODEƒWord�sized�flag.�If=$FFFF,�protect�mode 5‰XREF„CPERLINE‚Number�of�characters�per�absolute�line0‰XREF„BPERLINE‚Number�of�bytes�per�absolute�line2‰XREF„LPERSCRN‚Number�of�lines�per�absolute�screen 2‰XREF„C.LINE„Number�of�characters�per�virtual�line-‰XREF„B.LINE„Number�of�bytes�per�virtual�line *‰XREF„S.LINE„Start�address�of�current�line(‰XREF„E.LINE„End�address�of�current�line *‰XREF„PB.LINEƒUnused�part�of�absolute�line 2‰XREF„L.SCRN„Number�of�lines�in�the�virtual�screen <‰XREF„S.SCRN„Address�of�home�character�in�the�virtual�screen<‰XREF„E.SCRN„Address�of�last�character�in�the�virtual�screen (‰XREF„TOPLINEƒTop�line�of�virtual�screen+‰XREF„BOTLINEƒBottom�line�of�virtual�screen,‰XREF„LEFTCOLƒLeft�collumn�of�virtual�screen.‰XREF„RIGHTCOL‚Right�collumn�of�virtual�screen 9‰XREF†FEEDER„Address�of�subroutine�to�give�data�to�driver=‰XREF†FEEDER_ADDRESS†Address�of�data�buffer�to�give�to�FEEDER,‰XREF†FEEDER_COUNTˆ#�of�bytes�in�data�buffer ‰XREF†DUP_CHAR (‰XREF†KB_LOCK�Key�board�lock/unlock�flag 2‰XREF†RABSOLUTŒOutchs�read�absolute�entry�address. 0‰XREF†RING_BELL‹Flag�set�when�$07�is�detected�in%*§order�to�ring�the�bell�in�KEYBRD.AG‰PAGE .SCREENƒEQU‡$F17000�Base�address�of�display�RAM0CRTCADD‚EQU‡$F1A021�Address�register�of�the�CRTC-CRTCREG‚EQU‡$F1A023�Register�file�of�the�CRTC)EPCIBASE�EQU‡$F1A031�Base�address�of�EPCIKBDADDR‚EQU‡$0C$LFCHARƒEQU‡$0A‘ASCII�line�feed�char.0START_OF_DATA�EQU‚$DDŽ'Start�of�data'�indicator./END_OF_DATA�EQU„$DE‘End�of�write/read�indicator$FALSE„EQU‡0“Indicate�condition�false#TRUE…EQU‡-1’Indicate�true�condition"CLEARTAB�EQU‡$18‘Clear�tab�command#SPACE„EQU‡$20ŽASCII�space�character#ESC_CHAR‚EQU„$1B�ASCII�escape�char.+END_OF_FIELD�EQU�$F9�End�of�field�indicator6INIT_TAB‚EQU„10‘Initial�tab�spacing.‚The�reset�command#*§($F1)�will�put�tabs�on�the�screen*§with�this�spacing.* *ˆFAC�EQUATES*3PROTECT_FAC�EQU„$C5‡Protect�fac�with�intensity�code3DISPLAY_FAC�EQU„$44‡Display�fac�with�intensity�code/BLINK_FACƒEQU„$A5‡Blink�fac�with�intensity�code7UNDERLINE_FAC�EQU‚$55‡Underline�fac�with�intensity�code9INVERSE_FAC�EQU„$4D‡Inverse�video�fac�with�intensity�code!NODIS_FACƒEQU„$05‡Set�non-display** Register use:*’D0.L�=�general�use+*’D1.W�=�absolute�address�of�initial�cursor/*’D2.W�=�chracter�to�decode�and�word�to�display)*’D3.W�=�lines�per�virtual�screen�counter+*’D4.W�=�characers�per�virtual�line�counter *’D5.L�=�bytes�per�absolute�line*’D6.L�=�bytes�per�virtual�line*’D7.L�=�general�use-*’A0.L�=�address�of�cursor�in�the�display�RAM*’A1.L�=�Address�of�FACS*’A2.L�=�Address�of�S.LINE*’A3.L�-�General�use*  ‰PAGE ‰SECTIONƒ11  **ˆDEFINE�STORAGE*=ESC_FLAG‚DC.BƒFALSEŽThis�flag�is�true�if�someone�has�reserved(*§a�char�and�the�first�char�received�was&*§an�ESC.‚In�that�case�we�wait�for�the*§next�char�and�set�its�bit�7.:CHAR_RESERVED�DC.B�FALSE…Next�character�reserved�indicator(SAVE_CHAR…DS.B�1‰Save�area�for�character-SAVE_CURSORƒDS.L�1‰Current�cursor�ram�addressBCHAR_OWNER„DS.L�1‰Address�of�routine�that�owns�next�incoming�char.5XTCHBUF‚DS.W†162‡Scratch�buffer�for�feeder�subroutineEDIT_FLAG�DC.B…FALSE=COL_CNT‚DS.L†1‰Current�column�number,�used�in�set�tab�routine?PRO_FIELD�DC .B…FALSE…This�field�used�to�determine�where�to�stop(* when�a�protected�field�is�encountered.‰DS.W†00SAVEFACS‚DC.W…0‰FACS�saved�during�write�absolute=LASTFACƒDC.B…FALSE…Set�last�character�processed�to�not�a�FAC.8NUMBER_LINES�DC.Wƒ25‡Number�of�lines�to�clear�on�screen.‰PAGE POUTCHS‚DS.W†0 HAVE_CHAR‰MOVE.B„D0,D2�D2.B�=�Character ** Now find out what to do*:‰TST.B…CHAR_RESERVED‡Byte�is�set�if�a�routine�expects�more*ªthan�a�single�character‰IF��THEN.S 8ŠTST.B‚ESC_FLAG‹If�the�last�char�we�received�was�an�ESC,ŠIF…�THEN.Sˆ* 2ŠSF…ESC_FLAG‹Clear�the�'last�char�was�an�ESC'�flag5ŠBSETƒ#7,D0Žand�set�bit�7�in�D0�and�D2�(both�of�which-ŠBSETƒ#7,D2Žhold�the�char�following�the�ESC). (ŠELSE.S”Else�(last�char�was�not�an�ESC), 6ŠIF.B�D0��#ESC_CHAR�THEN.S�If�this�char�is�an�ESC,0ŠST…ESC_FLAG‹set�the�'last�char�was�an�ESC'�flagŠBRA„RETURN�and�exit.ŠENDI–* ŠENDI /‰SF�CHAR_RESERVEDŽReset�character�reserved�flag:‰MOVE.L�CHAR_OWNER,A3ŠGet�the�address�of�the�routine�which*¨process�this�character'‰JMP�(A3)–Go�process�incoming�character ‰ENDI *(*ˆFind�entry�in�table�for�this�character*OUTCH1(‰MOVE†D2,D0…Reset�upper�part�of�register5‰ADD‡D0,D0…Multiply�by�two�because�table�is�word�wide+‰MOVE†JUMPTABL(PC,D0),D0�Get�offset�address2‰JMP‡JUMPTABL(PC,D0)„Go�process�incoming�character‰PAGEJUMPTABL,ŠDC.WƒRETURN-JUMPTABL„$00�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$01�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$02�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$03�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$04�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$05�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$06�--�Illegal�--�exit ŠDC.WƒBELL-JUMPTABL†$07�--�Bell.#ŠDC.WƒBS-JUMPTABLˆ$08�--�Backspace.(ŠDC.WƒHT-JUMPTABLˆ$09�--�Horizontal�tab.%ŠDC.WƒDOWN-JUMPTABL†$0A�--�Line�feed.&ŠDC.WƒUP-JUMPTABLˆ$0B�--�Vertical�tab.&ŠDC.WƒRIGHT-JUMPTABL…$0C�--�Form�feed.)ŠDC.WƒCR-JUMPTABLˆ$0D�--�Carriage�return.,ŠDC.WƒRETURN-JUMPTABL„$0E�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$0F�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$10�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$11�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$12�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$13�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$14�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$15�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$16�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$17�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$18�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$19�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1A�--�Illegal�--�exit!ŠDC.WƒESC-JUMPTABL‡$1B�--�Escape.,ŠDC.WƒRETURN-JUMPTABL„$1C�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1D�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1E�--�Illegal�--�exit,ŠDC.WƒRETURN-JUMPTABL„$1F�--�Illegal�--�exit,ŠDC.WƒDISPLAY-JUMPTABLƒ$20�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$21�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$22�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$23�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$24�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$25�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$26�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$27�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$28�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$29�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$2F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$30�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$31�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$32�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$33�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$34�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$35�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$36�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$37�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$38�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$39�--�Display�as�is.,ŠDC.WƒDISP LAY-JUMPTABLƒ$3A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$3F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$40�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$41�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$42�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$43�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$44�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$45�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$46�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$47�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$48�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$49�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$4F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$50�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$51�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$52�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$53�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$54�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$55�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$56�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$57�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$58�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$59�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$5F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$60�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$61�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$62�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$63�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$64�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$65�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$66�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$67�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$68�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$69�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$6F�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$70�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$71�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$72�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$73�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$74�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$75�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$76�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$77�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$78�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$79�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7A�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7B�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7C�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7D�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7E�--�Display�as�is.,ŠDC.WƒDISPLAY-JUMPTABLƒ$7F�--�Display�as�is.'ŠDC.WƒRETURN-JUMPTABL„$80�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$81�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$82�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$83�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$84�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$85�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$86�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$87�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$88�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$89�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8A�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8B�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8C�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$8D�--�Ignore�it.4ŠDC.WƒSTART_EDITMODE-JUMPTABLƒ$8E�--�Start�edit�mode1ŠDC.WƒSTOP_EDITMODE-JUMPTABL„$8F�--�End�edit�mode'ŠDC.WƒRETURN-JUMPTABL„$90�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$91�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$92�--�Ignore�it.'ŠDC.WƒRETURN-JUMPT ABL„$93�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$94�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$95�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$96�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$97�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$98�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$99�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9A�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9B�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9C�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9D�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9E�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$9F�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A0�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A1�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A2�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A3�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A4�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A5�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A6�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A7�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A8�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$A9�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AA�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AB�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AC�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AD�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AE�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$AF�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B0�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B1�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B2�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B3�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B4�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B5�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B6�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B7�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B8�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$B9�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BA�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BB�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BC�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BD�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BE�--�Ignore�it.'ŠDC.WƒRETURN-JUMPTABL„$BF�--�Ignore�it.%ŠDC.WƒHOME-JUMPTABL†$C0�=�Cursor�home!ŠDC.WƒUP-JUMPTABLˆ$C1�=�Cursor�up%ŠDC.WƒDOWN-JUMPTABL†$C2�=�Cursor�down&ŠDC.WƒSEEKL-JUMPTABL…$C3�=�Cursor�left'ŠDC.WƒRIGHT-JUMPTABL…$C4�=�Cursor�right$ŠDC.WƒC5-JUMPTABLˆ$C5�=�Write�cursor#ŠDC.WƒC6-JUMPTABLˆ$C6�=�Read�cursor(ŠDC.WƒSPAGE-JUMPTABL…$C7�=�Set�page�mode*ŠDC.WƒRPAGE-JUMPTABL…$C8�=�Set�scroll�mode0ŠDC.WƒSETTOP-JUMPTABL„$C9�=�Set�top�display�line5ŠDC.WƒSETBOTOM-JUMPTABL‚$CA�=�Set�bottom�display�line5ŠDC.WƒSETLEFT-JUMPTABLƒ$CB�=�Set�left�display�collumn7ŠDC.WƒSETRIGHT-JUMPTABL‚$CC�=�Set�right�display�collumn-ŠDC.WƒSETPROT-JUMPTABLƒ$CD�=�Set�protect�mode,ŠDC.WƒWABSOLUT-JUMPTABL‚$CE�=�Write�absolute+ŠDC.WƒREADABSO-JUMPTABL‚$CF�=�Read�absolute5ŠDC.WƒICHAR-JUMPTABL…$D0�=�Insert�character�at�cursor5ŠDC.WƒDCHAR-JUMPTABL…$D1�=�Delete�character�at�cursor,ŠDC.WƒKEYENAB-JUMPTABLƒ$D2�=�Enable�keyboard.ŠDC.WƒKEYDSABL-JUMPTABL‚$D3�=�Disable�keyboard?ŠDC.WƒEEPAGE-JUMPTABL„$D4�=�Erase�all�unprotected�to�end�of�pag?ŠDC.WƒEELINE-JUMPTABL„$D5�=�Erase�all�unprotected�to�end�of�lin3ŠDC.WƒINS_LINE-JUMPTABL‚$D6�=�Page�mode�insert�line3ŠDC.WƒDEL_LINE-JUMPTABL‚$D7�=�Page�mode�delete�line:ŠDC.WƒCLEAR-JUMPTABL…$D8�=�Erase�all�unprotected�in�screen&ŠDC.WƒSNDPAGE-JUMPTABLƒ$D9�=�Send�page'ŠDC.WƒSEEKFT-JUMPTABL„$DA�=�Forward�tab$ŠDC.WƒSEEKBT-JUMPTABL„$DB�=�Back�tab#ŠDC.WƒSETTAB-JUMPTABL„$DC�=�Set�tabŠDC.WƒRETURN-JUMPTABL„$DD�=ŠDC.WƒRETURN-JUMPTABL„$DE�=(ŠDC.WƒSEND_LINE-JUMPTABL�$DF�=�Send�line%ŠDC.WƒSBLINK-JUMPTABL„$E0�=�Set�blink'ŠDC.WƒRBLINK-JUMPTABL„$E1�=�Reset�blink-ŠDC.WƒSINVERT-JUMPTABLƒ$E2�=�Set�video�invert/ŠDC.WƒRINVERT-JUMPTABLƒ$E3�=�Reset�video�invert-ŠDC.WƒUPBRIGHT-JUMPTABL‚$E4�=�Set�half�bright/ŠDC.WƒDNBRIGHT-JUMPTABL‚$E5�=�Reset�half�bright)ŠDC.WƒSULINE-JUMPTABL„$E6�=�Set�underline+ŠDC.WƒRULINE-JUMPTABL„$E7�=�Reset�underline,ŠDC.WƒNONDISP-JUMPTABLƒ$E8�=�Set�non-display(ŠDC.WƒSETDISP-JUMPTABLƒ$E9�=�Set�display-ŠDC.WƒPROTECT-JUMPTABLƒ$EA�=�Set�protect�mode-ŠDC.WƒALLOW-JUMPTABL…$EB�=�Reset�protect�modeŠDC.WƒRETURN-JUMPTABL„$EC�=ŠDC.WƒRETURN-JUMPTABL„$ED�=ŠDC.WƒRETURN-JUMPTABL„$EE�=ŠDC.WƒRETURN-JUMPTABL„$EF�=ŠDC.WƒRETURN-JUMPTABL„$F0�=2 ŠDC.WƒRESET24-JUMPTABLƒ$F1�=�Reset�24�line�screen.ŠDC.WƒRETURN-JUMPTABL„$F2�=ŠDC.WƒRETURN-JUMPTABL„$F3�=ŠDC.WƒRETURN-JUMPTABL„$F4�=ŠDC.WƒRETURN-JUMPTABL„$F5�=ŠDC.WƒRETURN-JUMPTABL„$F6�=2ŠDC.WƒRESET25-JUMPTABLƒ$F7�=�Reset�25�line�screen.ŠDC.WƒRETURN-JUMPTABL„$F8�=ŠDC.WƒRETURN-JUMPTABL„$F9�=ŠDC.WƒRETURN-JUMPTABL„$FA�=ŠDC.WƒRETURN-JUMPTABL„$FB�=ŠDC.WƒRETURN-JUMPTABL„$FC�=ŠDC.WƒRETURN-JUMPTABL„$FD�=ŠDC.WƒRETURN-JUMPTABL„$FE�=ŠDC.WƒRETURN-JUMPTABL„$FF�=  ‰PAGE*'* $7F = DLE, delete character at cursor*DLE'‰AND.W…#$FF80,(A0)‰Null�character�space)‰OR.B†#$20,(A0)‹Space�character�at�cursor ‰BRA‡RETURN *** Send the command in D0 to this key board*'WKBD…OR.B†#KBDADDR,D0‰To�this�key�board‰MOVE.B„D0,EPCIBASE‰RTS ** 07 = CTRL G = BELL*�ADDED‚01/30/85*8* RING_BELL flag is set so that the interrupt routine in9* KEYBRD.AG will output an ALARM command to the keyboard.*BELL ‰STˆRING_BELL ‰BRA‡RETURN‰PAGE** 08 = CTRL H = BS, back space*:* Cursor moves left to first unprotected column, with line* and page rollover.**BS SEEKL„EQU‡* ‰IF.B†PAGEFLAG��#TRUE�THEN.S‰IF.L†A0��S.SCRN�THEN.S9‰MOVE.L„E.SCRN,A0‹We�need�to�put�the�cursor�on�the�bottom7‰MOVE.L„A0,E.LINE‹line�and�update�the�beginning�and�end+‰MOVE.L„A0,S.LINE‹of�current�line�pointers.‰SUB.L…D6,S.LINE ‰BRA‡WRITCRSR‰ENDI‰IF.L†A0��S.LINE�THEN.S3‰SUB.L…D5,A0�Find�the�beginning�address�of�the�line:‰MOVE.L„A0,S.LINE‹above�the�cursor�and�update�the�pointer.0‰ADD.L…D6,A0�Find�the�ending�address�of�the�line:‰MOVE.L„A0,E.LINE‹above�the�cursor�and�update�the�pointer. ‰BRA‡WRITCRSRŒUpdate�the�cursor.‰ENDI0‰SUBQ.L„#2,A0�Move�the�cursor�left�one�position.‰BRA‡WRITCRSRŒ*‰ENDI!‰MOVE.L„A0,A3�Set�loop�terminator‰REPEAT‰IF.L†A0��S.SCRN�THEN.S6‰MOVE.L„E.SCRN,A0‹If�back�to�start�go�to�end�of�screen1‰MOVE.L„A0,E.LINE‹Set�end�of�current�virtual�line3‰MOVE.L„A0,S.LINE‹Set�start�of�current�virtual�line‰SUB.L…D6,(A2)�*‰ELSE.S‰IF.L†A0��S.LINE�THEN.S'‰SUB.L…D5,A0�Set�start�of�previous�line‰MOVE.L„A0,S.LINE‹*$‰ADD.L…D6,A0�Set�end�of�virtual�line.‰MOVE.L„A0,E.LINE‹and�A0�points�to�end�of�line‰ENDI‰ENDI&‰TST‡-(A0)�Is�current�spot�unprotected#‰BMI.S…SEEKL1ŽBranch�if�unprotected1‰TST.B…1(A0)�If�we�are�at�end�of�line�move�cursor*¦back�another�position.‰IFˆ�THEN.S‰*‰BRA.S…SEEKL1Ž*‰ELSE.S2‰BRA.S…SEEKL2ŽGo�update�cursor�because�we�found�an*¦unprotected�spot.‰ENDISEEKL1‰UNTIL.LƒA0��A35‰MOVE.L„S.SCRN,A0‹Put�cursor�in�home�position--no�un-$*¦protected�areas�in�current�screen.SEEKL2 ‰BRA‡WRITCRSR‰PAGE*"* 09 = CTRL I = HT, horizontal tab*2* Seek a TAB at an un-protected spot to the right,* with line and page rollover.**HT$SEEKFTƒEQU‡*“Seek�a�tab�to�the�right2‰SFˆPRO_FIELD‹Have�not�encountered�protected�field!‰MOVE.L„A0,A3�Set�loop�terminator*‰ADDQ.L„#2,A0�Get�off�of�current�character‰BRA.S…SEEKFT2‰REPEAT(‰TST‡(A0)+�Is�current�location�protected!‰BPL.S…SEEKFT1�Branch�if�it�isn't*3*ˆCursor�is�in�a�protected�field�--�check�to�see�if2*ˆencountered�earlier�and�we�are�still�in�it�or�if*ˆthis�is�the�first�time*0‰TST.B…PRO_FIELD‹First�time�in�protected�field�?‰IF��THEN.S0‰STˆPRO_FIELD‹Tell�world�we�have�encountered�the$*©protected�field�for�the�first�time.‰BRA.S…SEEKFT2�Now�move�out�of�protected�field‰ENDI7‰BRA.S…SEEKFT2�Still�in�protected�field�continue�search*©for�first�unprotected�field. SEEKFT16‰TST.B…PRO_FIELD‹If�this�is�an�unprotected�field�check$*¨to�see�if�we�passed�through�a�pro-"*¨tected�field�first.‚The�tab�must"*¨move�out�of�current�field�to�the*¨next�unprotected�field.‰IF��THEN.S/‰TST.B�-1(A0)’We�cannot�stop�on�an�end�of�line.‰IF��THEN.S�*/‰BRA.S‚SEEKFT2�Branch�if�we�are�at�end�of�line.‰ENDI'ŠSUBQ.L�#2,A0‘Adjust�the�cursor�address0ŠBRA�WRITCRSR‘Found�our�tab�stop�which�really�is"*ªjust�an�unprotected�field�to�the*ªright�of�the�curre nt�field.‰ENDISEEKFT2ŒIF.L‚A0��E.LINE�THEN.S“ADD.L‚D5,A0ˆDo�line�rollover8“MOVE.L�A0,E.LINE„Add�absolute�#�of�character�for�e.line2“SUB.L‚D6,A0ˆS.line�=�e.line�-�#�char�in�virt�line“MOVE.L�A0,S.LINE„*7ŒST�PRO_FIELD‰Because�we�went�off-line�fake�a�protected*¦field�hit�so�cursor�will�stop‰ENDI‰IF.L�A0��E.SCRN�THEN.S"ŒMOVE.L�S.SCRN,A0…Do�page�rollover'ŒMOVE.L�A0,S.LINE…Set�new�start�of�line%ŒMOVE.L�A0,E.LINE…Set�new�end�of�lineŒADD.L‚D6,E.LINE…*7ŒST�PRO_FIELD‰Because�we�went�off-line�fake�a�protected*¦field�hit�so�cursor�will�stop‰ENDISEEKFT3‰UNTIL.LƒA0��A3 ‰BRA�RETURN‰PAGE***�0D…Carriage�return*2* Position cursor at left most unprotected column.** FAC's are reset.*CR‰AND.W…#$4400,(A1)‰Reset�FACs‰MOVE.L„S.LINE,A0‹Start�of�line ‰BSR‡SEEKR ‰BRA‡WRITCRSR * *�1B…Escape*(* Set high bit of next character output.* ESC†EQU‡*#‰BSR‡GET_CHARŒNeed�anoter�character ‰BSET†#7,D0‰BRA‡HAVE_CHAR‰PAGE**�$8E„START�EDIT�MODE*START_EDITMODE ‰BSR‡GET_CHAR‰IF.B�D0��#$FF�THEN.S‰MOVE†#$FFFF,DUP_CHAR‰ELSE.S‰MOVE†D2,DUP_CHAR‰ENDI ‰STˆEDIT_FLAG ‰SFˆPAGEFLAG ‰SFˆPROMODE ‰BRA‡RETURN**�$8F‚STOP�EDIT�MODE* STOP_EDITMODE%‰SFˆEDIT_FLAG‹Turn�off�edit�mode�flag ‰BRA‡RETURN‰PAGE**�$C0„cursor�home*A* Cursor moves to top left corner of screen, seeks an unprotected* space to the right.* HOME…EQU‡* ‰MOVE.L„S.SCRN,A0‹Top�left�space6‰MOVE.L„A0,S.LINE‹Modify�start�and�end�of�current�line‰MOVE.L„A0,E.LINE‰ADD.L…D6,4(A2) ‰BSR‡SEEKR ‰BRA‡WRITCRSR * * C1 = Up*C* Cursor moves up one line in same column, seeks unprotected column+* to the left, with line and page rollover.**(UP‡SUB.L…D5,A0�Same�column�in�line�above3‰SUB.L…D5,(A2)�Modify�start�and�end�of�current�line‰SUB.L…D5,4(A2)‰CMP.L…S.SCRN,A0‹Out�of�screen?‰BGE.S…UP.1�No,�do�it4‰MOVE.L„A0,D0�Roll�screen�over--find�cursor�position(*¦relative�to�the�beginning�of�the�line.4‰SUB.L…S.LINE,D0‹D0�<--�cursor�offset�into�this�line,‰MOVE.L„E.SCRN,A0‹Point�to�bottom�of�screen.*‰MOVE.L„A0,S.LINE‹Update�start/end�of�line‰SUB.L…D6,(A2)‰MOVE.L„A0,E.LINE%‰MOVE.L„S.LINE,A0‹Position�the�cursor‰ADD.L…D0,A0�* +UP.1…EQU‡*“Modify�start/end�of�current�line ‰LEA‡2(A0),A0 ‰BRA‡SEEKL‰PAGE* * C2 = Down*A* Cursor seeks an unprotected spot to the right, starting at same+* collumn on next line, with page rollover.* DOWN…EQU‡*%‰ADD.L…D5,A0�Same�column�on�next�line/‰ADD.L…D5,(A2)�Modify�start/end�of�current�line‰ADD.L…D5,4(A2)#‰CMP.L…E.SCRN,A0‹Out�of�the�screen?‰BLT.S…DOWN1�No,�do�it4‰MOVE.L„A0,D0�Roll�screen�over--find�cursor�position(*¦relative�to�the�beginning�of�the�line.4‰SUB.L…S.LINE,D0‹D0�<--�cursor�offset�into�this�line/‰MOVE.L„S.SCRN,A0‹Point�to�beginning�of�screen.'‰MOVE.L„A0,S.LINE‹Update�line�pointers.‰MOVE.L„A0,E.LINE‹*‰ADD.L…D6,4(A2)Œ* ‰ADD.L…D0,A0�Position�the�cursorDOWN10‰BSR‡SEEKR�Seek�an�unprotected�spot�to�the�right ‰BRA‡WRITCRSR *** C3 = cursor left, same as back space 08.* * * C4 = Right*D* Seek an unprotected space to the right with line and page rollover*RIGHT!‰MOVE.L„A0,A3�Set�loop�terminator'‰ADDQ.L„#2,A0�Get�off�of�current�column ‰BRA.S…RIGHT1‰REPEAT-‰TST.W…(A0)+�Pointing�to�unprotected�column�?‰IF��THEN.S/‰TST.B…-1(A0)ŽWe�cannot�stop�on�an�end�of�line.$‰IFƒ�THEN.SŽEnd�of�line�is�a�00. ‰BRA.S‚RIGHT2‰ENDI'‰SUBQ.L„#2,A0�Adjust�for�auto�increment%‰BRA‡WRITCRSRŒUpdate�cursor�on�screen‰ENDIRIGHT1 ‰IF.B‚PAGEFLAG��#TRUE�THEN.S “BRA�WRITCRSR‰ENDI‰IF.L�A0��E.SCRN�THEN.S ‰MOVE.L�S.SCRN,A0„Do�screen�wrap;‰MOVE.L�A0,S.LINE„Update�beginning�and�ending�line�pointers‰MOVE.L�A0,E.LINE„*‰ADD.L‚D6,E.LINE„*‰ENDI‰IF.L�A0��E.LINE�THEN.S‰ADD.L…D5,A0�Do�line�wrap!‰MOVE.L„A0,E.LINE‹New�end�of�line‰SUB.L…D6,A0�New�start�of�line‰MOVE.L„A0,S.LINE‹*‰ENDIRIGHT2‰UNTIL.LƒA0��A3)‰BRA‡RETURNŽNo�unprotected�so�leave�as�is  ‰PAGE*+*�$C5„Move�the�cursor�to�the�requested�spot*C5: 'ŠBSR„GET_CHAR‹D0.B�<--�the�line�#�char.'ŠMOVE.B�D0,SAVE_CHAR‡Save�it�for�later. )ŠBSR„GET_CHAR‹D0.B�<--�the�column�#�char.&ŠMOVEQ‚#0,D1ŽD1�<--�the�column�#�char.ŠMOVE.B�D0,D1Ž*1ŠSUB.B‚#$20,D1ŒAdjust�it�so�0�is�first�line,�etc. 4ŠCMP„LEFTCOL,D1‰Ensure�that�the�column�#�is�in�range2ŠBLO„RETURN�(�LEFTCOL�<�column�#�<�RIGHTCOL).‚Just0ŠCMP„RIGHTCOL,D1ˆignore�the�command�if�it�isn't. ŠBHI„RETURN�* 4ŠMOVEQ‚#0,D0ŽD0�<--�line�#�char�(saved�from�before).ŠMOVE.B�SAVE_CHAR,D0‡*1ŠSUB.B‚#$20,D0ŒAdjust�it�so�0�is�first�line,�etc. 2ŠCMP„TOPLINE,D0‰Ensure�that�the�line�#�is�in�range0ŠBLO„RETURN�(�TOPLINE�<�line�#�<�BOTLINE�).‚Just/ŠCMP„BOTLINE,D0‰ignore�the�command�if�it�isn't. ŠBHI„RETURN�* /ŠMULUƒD5,D0ŽD0�<--�start�addr�of�absolute�line.ŠADD.L‚#SCREEN,D0‰*"ŠADD„D1,D1ŽA0�<--�addr�of�cursor�=ŠADD.L‚D0,D1Ž*„2�*�column�#�+'ŠMOVE.L�D1,A0Ž*„start�of�absolute�line. -ŠMOVEQ‚#0,D1ŽS.LINE�(start�of�virtual�line)�=7ŠMOVEƒLEFTCOL,D1‰*„2�*�left�column�of�virtual�display�+$ŠADD„D1,D1Ž*„start�of�absolute�line.ŠADD.L‚D0,D1Ž*ŠMOVE.L�D1,S.LINEŠ* +ŠADD.L‚D6,D1ŽE.LINE�(end�of�virtual�line)�=4ŠMOVE.L�D1,E.LINEŠ*„S.LINE�+�bytes�per�virtual�line.<‰IF.B‚PROMODE��#TRUE�THEN.SƒDo�a�seek�right�if�screen�is“BSR�SEEKR�in�protect�mode.‰ENDI ŠBRA„WRITCRSR‰PAGEC6‡EQU‡***�$C6„Read�the�cursor�position.**‚Input�parametersƒ:�none.*G*‚Registers�affected�:�D0.W�=�LLCC�(see�C5�for�an�explanation�of�LLCC).**+‰BSR‡READCRSRŒGet�cursor's�absolute�address‰DIVU†D5,D1�D1=00CC00LL‰SWAP†D1’D1=00LL00CC3‰LSL.W…#8-1,D1�D1=00LLCC00�(-1�to�convert�to�bytes)0‰ADD.L…#$DD2020DE,D1‡Add�the�offset�for�the�user*¦Set�start�data�and�end�data*‰LEA‡XTCHBUF(PC),A0†Set�up�for�FEEDER�call‰MOVE.L„D1,(A0)�Move�to�buffer,‰MOVE.W„#4,FEEDER_COUNT…Set�length�of�buffer:‰MOVE.L„A0,FEEDER_ADDRESSƒSet�address�of�buffer�for�FEEDER‰BSR‡FEEDERŽGive�data�to�driver‰BRA‡RETURNŽReturn�to�caller***�$C7„Set�page�mode.* SPAGE„EQU‡*‰MOVE.W„#-1,PAGEFLAG ‰SFˆPROMODE ‰BRA‡HOME **�$C8„Set�scroll�mode.* RPAGE„EQU‡*‰CLR.W…PAGEFLAG ‰SFˆPROMODE'‰MOVE.L„S.SCRN,A0�Do�a�scroll�mode�home‰MOVE.LƒA0,S.LINE‚*‰MOVE.LƒA0,E.LINE‚*‰ADD.L„D6,4(A2)ƒ*‰BRA‡WRITCRSR‚***�$CD„Set�protect�mode*SETPROT‰STˆPROMODEƒSet�protect�mode‰CLR‡PAGEFLAG‚Reset�page�mode-‰BRA‡HOME†Set�the�cursor�to�the�home�position‰PAGE***�$C9„Set�top�line�of�virtual�display�area*G* The top line is set by: 1. Bringing the cursor to the requested line,*œand�then�entering�an�ESC�I."*™2.�Entering�outch�with�D0.W=LLC5 SETTOPƒEQU‡* ‰BSR‡GET_CHARŒGet�next�character‰SUB.B…#$20,D2$‰CMP.W…BOTLINE,D2Š0=botline ‰BHI‡RETURN$‰MOVE.W„D2,TOPLINEŠStore�in�constantINITIT‰BSR‡CRTINIT�Re-configure�CRT&‰BRA‡HOME†Put�cursor�in�home�position. *-*�$CA„Set�bottom�line�of�virtual�display�area*"*�Same�as�C9�for�bottom�line‚ESC�J*SETBOTOM�EQU‡*‰BSR‡GET_CHARŒGet�line�number!‰SUB.B…#$20,D2�Adjust�line�number+‰CMP.W…LPERSCRN,D2‰lperscrn>botline>topline ‰BHS‡RETURN‰CMP.W…TOPLINE,D2 ‰BLO‡RETURN‰MOVE.W„D2,BOTLINE ‰BRA‡INITIT *5*�$CB„Set�left�display�column�of�virtual�screen‚ESC�K* SETLEFT‚EQU‡*‰BSR‡GET_CHARŒGet�left�column‰SUB.B…#$20,D2‰CMP.W…RIGHTCOL,D2 ‰BHI‡RETURN‰MOVE.W„D2,LEFTCOL ‰BRA‡INITIT‰PAGE*4*�$CC„Set�right�display�column�of�dispaly�area‚ESC�L*SETRIGHT�EQU‡*‰BSR‡GET_CHARŒGet�right�column‰SUB.B…#$20,D2,‰CMP.W…CPERLINE,D2‰cperlineleftcol ‰BHS‡RETURN‰CMP.W…LEFTCOL,D2 ‰BLO‡RETURN‰MOVE.W„D2,RIGHTCOL ‰BRA‡INITIT SEEIFIN‚EQU‡*-‰LSR.W…#8,D0�Check�to�see�if�the�user�defined%‰TST.W…D0’the�spot�in�the�second�byte ‰BNE.S…RTSIT*:* The routine will calculate the current line and collumn.+* Left collumn is #00, and top line is #00.*2*�InputŒA0.L�=�Address�of�cursor�in�display�screen**�Output‹A0.L�=�unchanged*’D0.L�=�00CC00LL&*™wher  eˆLL�=�Line�number,�top�line�=�0'*¦CC�=�Collumn�number,�left�collumn�=�0 GETSPOT‚EQU‡*‰CLR.L…D0’HSKP ‰MOVE.L„A0,D04‰SUB.L…#SCREEN,D0‰=Absolute�cursor�address�on�screen ‰LSR.W…#1,D0*‰DIVU†CPERLINE,D0‰The�quotiant=line�number RTSIT„RTS‰PAGE**�$CE„write�absolute* WABSOLUT: -ŠREPEAT”Wait�for�a�'start�of�data'�indicator.ŠBSR„GET_CHAR‹*ŠUNTIL.B�D0��#START_OF_DATA ,ŠMOVEƒ(A1),SAVEFACS†Save�current�FACS�in�use 'ŠBSR„GET_CHAR‹D0.B�<--�the�line�#�char.'ŠMOVE.B�D0,SAVE_CHAR‡Save�it�for�later. )ŠBSR„GET_CHAR‹D0.B�<--�the�column�#�char.&ŠMOVEQ‚#0,D1ŽD1�<--�the�column�#�char.ŠMOVE.B�D0,D1Ž*1ŠSUB.B‚#$20,D1ŒAdjust�it�so�0�is�first�line,�etc. 5ŠCMP„CPERLINE,D1ˆEnsure�that�the�column�#�is�in�range-ŠBHS„RETURN�(�LEFTCOL�<�column�#�<�RIGHTCOL). 4ŠMOVEQ‚#0,D0ŽD0�<--�line�#�char�(saved�from�before).ŠMOVE.B�SAVE_CHAR,D0‡*1ŠSUB.B‚#$20,D0ŒAdjust�it�so�0�is�first�line,�etc. /ŠCMP„LPERSCRN,D0ˆEnsure�the�line�#�is�in�range. ŠBHI„RETURN�*BŠMOVE.L�A0,SAVE_CURSOR…Save�the�cursor�address�in�the�vertual�scrn /ŠMULUƒD5,D0ŽD0�<--�start�addr�of�absolute�line.ŠADD.L‚#SCREEN,D0‰*"ŠADD„D1,D1ŽA0�<--�addr�of�cursor�=ŠADD.L‚D0,D1Ž*„2�*�column�#�+'ŠMOVE.L�D1,A0Ž*„start�of�absolute�line. -ŠMOVEQ‚#0,D1ŽS.LINE�(start�of�virtual�line)�=7ŠMOVEƒLEFTCOL,D1‰*„2�*�left�column�of�virtual�display�+$ŠADD„D1,D1Ž*„start�of�absolute�line.ŠADD.L‚D0,D1Ž*ŠMOVE.L�D1,S.LINEŠ* +ŠADD.L‚D6,D1ŽE.LINE�(end�of�virtual�line)�=4ŠMOVE.L�D1,E.LINEŠ*„S.LINE�+�bytes�per�virtual�line. 7ŠST…CHAR_RESERVED†Set�up�to�receive�incoming�charactersŠLEA„WABS1(PC),A3‡*ŠMOVE.L�A3,CHAR_OWNER†*%ŠBRA„WRITCRSR‹Update�cursor�position.WABS1!ŠIF.B�D0��#END_OF_DATA�THEN.S6‰MOVE.L„SAVE_CURSOR,D0†Restore�virtual�screen's�S.LINE *°and�E.LINE!‰MOVE.L„D0,D1�Copy�cursor�address‰SUB.L…#SCREEN,D0*‰DIVU†BPERLINE+2,D0‡Find�line�cursor�is�on*¦remainder�=�position�in�line‰CLR‡D0’Forget�line�we�are�on‰SWAP†D0,‰SUB.L…D0,D1�we�now�know�the�absolute�s.line-‰MOVE†LEFTCOL,D0Šso�adjust�it�by�the�value�in‰ADD‡D0,D0�leftcol.‰ADD.L…D0,D1�*1‰MOVE.L„D1,S.LINE‹bingo�we�now�have�start�of�line-‰ADD.L…B.LINE,D1‹add�the�number�of�bytes/line%‰MOVE.L„D1,E.LINE‹and�set�end�of�line8‰MOVE.L„SAVE_CURSOR,A0†Set�cursor�back�to�virtual�screen/‰MOVE†SAVEFACS,(A1)‡Reset�FACS�for�current�line‰BRA‡WRITCRSRŒ*ŠENDIŠST…CHAR_RESERVED‰IF.B�D2��#$E0�AND.BŽD2��#$EB�THEN.S6‰TST.B…LASTFAC�See�if�the�last�character�processed�was*¦a�FAC.5‰IF‚�THEN.S�If�it�was�not�a�FAC�then�destroy�what'*¦is�currently�on�the�screen�because�it*¦could�be�another�FAC.:‰MOVE.B„#$FF,1(A0)ŠDestroy�current�character.�(if�a�FAC�is&*¦written�here�the�code�will�be�a�01.)‰ENDI3‰STˆLASTFAC�Tell�the�loop�we�have�been�here�before.‰BRA‚OUTCH1“Process�the�FAC.‰ENDI3‰TST.B…LASTFAC�If�the�last�character�was�a�FAC�then3‰IFƒ�THEN.SŽthe�cursor�has�not�been�updated,�so-‰ADD.L…#2,A0�let's�add�2�and�get�off�our�FAC.)‰SFˆLASTFAC�Last�character�was�not�a�FAC.‰ENDI8‰MOVE.W„LPERSCRN,D0‰FIND�THE�END�OF�THE�ABSOLUTE�DISPLAY ‰MULU†D5,D0�*‰ADD.L…#SCREEN,D0Š*5‰OR.W†FACS,D2�Write�the�current�character�to�the�scrn‰MOVE.W„D2,(A0)+Œ*‰IF.L†A0��D0�THEN.S&‰BRA‡RETURNŽExit�if�past�end�of�screen‰ENDI,‰BRA‡WRITCRSRŒUpdate�current�cursor�position **�$CF„read�absolute*+*ˆUses�the�read�absolute�routine�in�outchs.*READABSO�EQU‡* ‰JMP‡RABSOLUT *2* Convert the llcc value to a display RAM address.**ˆInputƒD0.W�=�llcc*ˆOutput‚A0.L�=�screen�address* CONVERT‚EQU‡*%‰MOVE.L„D6,-(A7)ŒGet�some�ellbow�room ‰CLR.L…D6 ‰MOVE.W„D0,D6‰AND.W…#$00FF,D0‰CMP.W…CPERLINE,D0 ‰BGT.S…CONRET‰LSR.L…#8,D6�D6.L=000000ll‰CMP.W…LPERSCRN,D6 ‰BGT.S…CONRET ‰MULU.W„D5,D6 ‰LSL.W…#1,D0 ‰ADD.B…D0,D6‰ADD.L…#SCREEN,D6 ‰MOVE.L„D6,A0CONRETƒMOVE.L„(A7)+,D6‰RTS‰PAGE*8*‚$D0„Insert�a�character�at�the�current�cursor�position.B*‰Starting�at�the�current�cursor�position,�characters�are�moved�to@*‰the�right�until�the�end�of�line�! or�a�protected�field�is�hit.‚A>*‰space�is�put�in�the�current�cursor�position.‚The�cursor�does *‰not�move.*7ICHAR:„MOVEQ‚#SPACE,D0ŠInitialize�LAST�CHAR�to�a�space. .ICHAR1„TST„(A0)�If�this�position�is�protected,ŠBMI.S‚ICHAR3�get�out. 2ŠMOVEQ‚#$7F,D1ŒD1�<--�the�char�from�this�position.ŠAND„(A0),D1Œ*9ŠAND„#$FF80,(A0)ˆPut�the�LAST�CHAR�out�there�in�its�place.ŠOR…D0,(A0)+‹and�advance�to�the�next�position.1ŠMOVEƒD1,D0ŽSet�LAST�CHAR�to�the�char�we�just�got;ŠDBRAƒD4,ICHAR1Š(for�next�pass)�and�loop�until�end�of�line. ICHAR3„BRA„RETURN�Exit. *8*‚$D1„Delete�a�character�at�the�current�cursor�position.F*‰Starting�just�past�the�current�cursor�position,�characters�are�movedB*‰to�the�left�until�the�end�of�line�or�a�protected�field�is�hit.‚A@*‰space�is�put�in�the�final�modifiable�position.‚The�cursor�does%*‰not�move.‚The�entry�point�is�DCHAR.*�#TRUE�THEN.S ŠBRA�RETURNŠENDI6ŠMOVE.L�E.SCRN,A0ŠA0�<--�addr�just�past�end�of�screen. AŠWHILE.L�A0��E.LINE�DO.S‚While�A0�is�not�on�the�current�line, 6ŠMOVE.L�A0,A1ŽA1�<--�addr�just�past�end�of�line�above./ŠSUB.L‚D5,A1Ž*‡(D5�is�bytes�per�absolute�line.)0ŠMOVE.L�A0,-(SP)‹Save�the�address�for�this�line. 6ŠMOVEƒC.LINE,D0ŠD0�<--�#�of�chars�in�virtual�line�-�1.@INS_LIN1‚MOVEƒ-(A1),-(A0)ˆMove�all�words�(attribute�and�char)�in.ŠDBRAƒD0,INS_LIN1ˆthis�line�to�the�line�below. 3ŠMOVE.L�(SP)+,A0‹Restore�the�address�for�this�line.-ŠSUB.L‚D5,A0ŽA0�<--�address�for�next�line�up. ŠENDW (*§At�this�point�A0�is�the�addr�just�past&*§the�end�of�the�current�virtual�line.6ŠMOVEƒC.LINE,D0ŠD0�<--�#�of�chars�in�virtual�line�-�1.?INS_LIN2‚AND.B‚#$80,-(A0)‰Fill�the�current�line�with�spaces�and%ŠOR.Bƒ#$20,(A0)Šinnocuous�attributes.ŠMOVE.B�#$44,-(A0)‰*ŠDBRAƒD0,INS_LIN2ˆ*%*§At�this�point�A0�is�the�addr�of�the(*§beginning�of�the�current�virtual�line.,ŠBRA„WRITCRSR‹Go�set�the�new�cursor�address.   **�$D7‚DELETE�LINE*DEL_LINE‰IF.B�PROMODE��#TRUE�THEN.S ‰BRA�RETURN‰ENDI;‰MOVE.L„S.LINE,A0�Beginning�address�of�current�virtual�lineDELINE;‰MOVE.L„A0,A1…Calculate�the�address�of�the�beginning�of�the‰ADD.L…D5,A1…next�line.4‰MOVE†C.LINE,D0�Number�of�bytes�per�line�to�be�moved?‰CMP.L…E.SCRN,A1�See�if�move�from�address�is�passed�end�of�scrn-‰BHS.S…DELINE2ƒBranch�if�passed�end�of�screen2‰MOVE.L„A0,-(A7)‚Save�destination�address�on�stackDELINE1*‰MOVE.W„(A1)+,(A0)+�Move�line�up�on�screen‰DBRA†D0,DELINE1‚*,‰MOVE.L„(A7)+,A0‚Restore�destination�address'‰ADD.L…D5,A0‡Point�to�next�virtual�line,‰BRA.S…DELINE„Go�move�next�line�up�on�screenDELINE22‰MOVE.B„#$44,(A0)+ƒBlank�the�bottom�line�of�screen.‰AND.B…#$80,(A0)„Save�tab�stop�if�there�is�one+‰OR.B†#$20,(A0)+ƒSet�space�in�this�location‰DBRA†D0,DELINE2ƒ*9‰MOVE.L„S.LINE,A0„Set�cursor�to�beginning�of�current�line‰BRA‡W! RITCRSR…* PAGE*+*�$D5„Erase�to�end�of�line‚(Page�mode�only)* EELINEƒEQU‡*!‰MOVE†FACS,-(A7)ŠSave�current�FAC‰IF.B�1(A0)��#01�THEN.S ‰MOVE.Bƒ#$44,FACSŒReset�to�FACS.‰ELSE.S)‰MOVE.LƒA0,A3�Save�current�line�position.‰WHILE.L‚A3��S.LINE�DO.S=‰IF.B…-1(A3)��#01�THEN.SƒFind�the�FAC�code�for�this�field.‰MOVE.Bƒ-2(A3),FACSŒPropogate�the�current�FAC.‰BRA.S„EELINE1‰ELSE.S5‰SUBQ.Lƒ#2,A3�Find�a�FAC�definition�or�the�start�of�a *¦*‚line.‰ENDI‰ENDW‰ENDIEELINE1‰WHILE.L‚A0��E.LINE�DO.S/‰MOVE.BƒFACS,(A0)+‹Propogate�FAC�to�end�of�line%‰AND.B„#$80,(A0)ŒSave�tab�information3‰OR.B…#$20,(A0)+‹Move�end�of�line�marker�by�writing*°spaces�to�the�end.‰ENDW%‰MOVE†(A7)+,FACSŠRestore�current�FAC. ‰BRA‡RETURN**�$D8„clear�screen,�cursor�home*C* All unprotected positions in display area are filled with spaces.* FAC's are not affected.* * Cursor moves to home position.** CLEAR„EQU‡*‰MOVE.L„S.SCRN,A0‹Start�at�home‰MOVE.W„C.LINE,D4‹A�full�line"‰BSR.S…ERASE�Erase�all�unprotected‰BRA‡HOME�Put�cursor�at�home *%* Erase D4.W characters in D3.w lines* ERASE„EQU‡*‰IF.B�PROMODE��#TRUE�THEN.S‰TST.W…(A0)+�Is�it�protected?‰BMI.S…ERASE1ŽYes,�keep�looking'‰AND.W…#$FF80,-2(A0)‡Preserve�the�FAC's!‰OR.W†#$0000,-2(A0)‡Write�a�space‰ELSE.S,‰AND‡#$0080,(A0)‰Reset�FAC�but�save�tab�info,‰ORˆ#$4400,(A0)+ˆWrite�end�of�line�character‰ENDI/ERASE1ƒDBRA†D4,ERASEŒRepeat�for�D4.w�characters)‰MOVE.W„C.LINE,D4‹Reset�character�counter$‰ADD.W…PB.LINE,A0ŠStart�of�next�line$‰DBRA†D3,ERASEŒRepeat�for�D3.w�lines‰RTS‰PAGE**�$D9„SEND�PAGE**ˆSend�all�unprotected�fields*SNDPAGE9‰MOVE.L„S.SCRN,A0ŠStart�at�beginning�of�the�virtual�scrn.2‰MOVE.L„A0,-(A7)ŒSave�beginning�line�adr�on�stack.%‰LEA‡XTCHBUF,A1ŠFeeder�needs�a�buffer9‰MOVE.L„A1,FEEDER_ADDRESSƒTell�feeder�where�his�buffer�isA‰MOVE.B„#START_OF_DATA,(A1)+�Bracket�data�with�start�and�end�data:‰MOVE†#1,FEEDER_COUNT…Bump�number�of�characters�for�feeder*?*‡Find�all�unprotected�fields�on�the�screen�and�put�them�in�the**‡feeder�buffer�and�ship�them�to�the�host.*3‰MOVE…L.SCRN,D2ŽWe�only�want�to�do�1�screens�worth.0‰MOVE…C.LINE,D1ŒWe�do�1�screen�a�line�at�a�time.SNDPAGE1+‰TST.B…(A0)�Is�current�position�protected�?2‰BPL.S…SNDPAGE3ŒBranch�if�position�is�unprotected.#‰ADDQ.L„#2,A0�Go�to�next�character.%‰DBRA†D1,SNDPAGE1‰Do�the�entire�line.7‰ADD.L…D5,(A7)�Find�the�start�of�the�next�virtual�line.‰MOVE.L„(A7),A0�*4‰MOVE†C.LINE,D1‹Update�number�of�character�per�line.:‰DBRA†D2,SNDPAGE1‰Find�out�if�we�are�at�the�end�of�screen.6‰BRA.S…SNDPAGE4ŒEnd�of�screen�so�fix�feeder�buffer�and*¦ship�the�data�and�exit.SNDPAGE2,‰TST.B…(A0)�Is�current�character�protected�?3‰BPL.S…SNDPAGE3ŒBranch�if�character�is�unprotected.:‰MOVE.B„#END_OF_FIELD,(A1)+�Mark�end�of�unprotected�field.>‰ADDQ†#1,FEEDER_COUNT…Bump�the�number�of�chars.�for�the�driver4‰BRA.S…SNDPAGE6ŒGo�spin�through�the�protected�field.SNDPAGE33‰MOVEQ…#$7F,D0�The�char�is�in�bits�0-6�of�the�byte.‰AND.B…1(A0),D0$*¦Bit�7�is�the�'tab�stop'�bit�and�is*¦not�to�be�considered�"data"**‰BNE.S…SNDPAG35ŒBranch�if�not�end�of�line.7‰ADD.L…D5,(A7)�Find�the�next�virtual�line�beginning�adr‰MOVE.L„(A7),A0�*5‰MOVE†C.LINE,D1‹Update�number�of�characters�per�line.*B*…Check�to�see�if�we�were�in�a�protected�or�unprotected�field�when*…we�got�to�the�end�of�line.*!‰IF.B†PRO_FIELD��#TRUE�THEN.S6‰BRA.S…SNDPAGE7ŒContinue�processing�a�protected�field.‰ELSE.S*‰BRA.S…SNDPAG36ŒUnprotected�field�wrapped.‰ENDISNDPAG355‰MOVE.B„D0,(A1)+ŒMove�unprotected�character�to�feeder *ªbuffer.8‰ADDQ†#1,FEEDER_COUNT…Update�the�number�of�characters�to*ªgive�to�the�driver.&‰ADDQ.L„#2,A0�Point�to�next�character.)‰SFˆPRO_FIELD‹Last�field�was�unprotected.(‰DBRA†D1,SNDPAGE2‰Spin�through�the�line.5‰ADD.L…D5,(A7)�Find�the�beginning�of�the�next�virtual*©line.‰MOVE.L„(A7),A0�*0‰MOVE†C.LINE,D1‹Update�number�of�character/line.SNDPAG36:‰DBRA†" D2,SNDPAGE2‰Check�to�see�if�we�are�at�the�end�of�the *ªscreen.C‰MOVE.B„#END_OF_FIELD,(A1)+‚Move�end�of�field�mark�to�feeder�buffer.‰ADDQ†#1,FEEDER_COUNT…Update�the�feeder�count.SNDPAGE4A‰MOVE.B„#END_OF_DATA,(A1)„Move�end�of�data�mark�to�feeder�buffer..‰ADDQ†#1,FEEDER_COUNT…Update�the�feeder�count. ‰BSR‡FEEDERŽShip�data�to�driver.$‰MOVE.L„(A7)+,A0ŒClean�up�the�stack.‰BRA‡RETURNŽExit.SNDPAGE5$‰TST.B…(A0)�Is�character�protected�?#‰BPL.S…SNDPAGE3ŒBranch�if�it�isn't.SNDPAGE6(‰ADDQ†#2,A0�Point�to�the�next�character.'‰STˆPRO_FIELD‹Last�field�was�protected.'‰DBRA†D1,SNDPAGE5‰Go�throught�the�line.7‰ADD.L…D5,(A7)�Find�the�next�virtual�line�beginning�adr‰MOVE.L„(A7),A0�*+‰MOVE†C.LINE,D1‹Update�characters�per�line.SNDPAGE7/‰DBRA†D2,SNDPAGE5‰Go�through�the�entire�screen.0‰BRA‡SNDPAGE4ŒWe�are�at�the�end�of�the�screen�so&*¦fix�up�feeders�buffer�and�ship�it�to*¦the�driver�then�exit.‰PAGE**�$DA„Forward�tab* * Same as HT* ** DB = BT, back tab*=* Position cursor at first unprotected character to the left.** SEEKBTƒEQU‡*‰IF.L�A0��S.SCRN�THEN.S**ˆDO�SCREEN�WRAP*7‰MOVE.L„E.SCRN,A0�End�of�screen�becomes�new�end�of�line‰MOVE.L„A0,E.LINE�*2‰MOVE.L„A0,S.LINE�Update�the�start�of�line�pointer‰SUB.L…D6,S.LINE�*‰ENDI‰IF.L�A0��S.LINE�THEN.S**ˆDO�LINE�WRAP*‰SUB.L…D5,A0…New�start�of�line‰MOVE.L„A0,S.LINE�*‰ADD.L…D6,A0…New�end�of�line‰MOVE.L„A0,E.LINE�*‰ENDI**ˆFIND�AN�UNPROTECTED�FIELD*‰WHILE.L�A0��S.LINE�DO.S,‰TST‡-(A0)…Check�previous�character�position<‰BPL.S…SEEKBT1ƒBranch�if�unprotected�(hi�bit�of�word�is�off)‰ENDW**ˆSTART�OF�LINE�BUT�PROTECTED* ‰BRA‡SEEKBT*'*ˆFIND�PROTECTED�FIELD�OR�START�OF�LINE*SEEKBT1‰IF.L�A0��S.LINE�THEN.S‰TST‡(A0)†Is�location�protected‰BMI.S…SEEKBT2ƒBranch�if�it�is/‰BRA‡WRITCRSR‚Beginning�of�line�and�unprotectedSEEKBT2‰IF.L�A0��S.SCRN�THEN.S**ˆDO�SCREEN�WRAP*7‰MOVE.L„E.SCRN,A0�End�of�screen�becomes�new�end�of�line‰MOVE.L„A0,E.LINE�*2‰MOVE.L„A0,S.LINE�Update�the�start�of�line�pointer‰SUB.L…D6,S.LINE�*‰ENDI**ˆDO�LINE�WRAP*‰SUB.L…D5,A0…New�start�of�line‰MOVE.L„A0,S.LINE�*‰ADD.L…D6,A0…New�end�of�line‰MOVE.L„A0,E.LINE�*‰ENDI'‰TST‡-(A0)…Search�for�a�protected�field$‰BPL.S…SEEKBT1ƒBranch�if�unprotected&‰ADDQ.L„#2,A0…Adjust�for�the�decrement‰BRA‡WRITCRSR‚Update�cursor‰PAGE** DC = set tab* SETTABƒEQU‡*/‰CLR.L…COL_CNTƒInitialize�current�column�number‰BRA.S…SETTAB2SETTAB1:‰ADD.L…#2,COL_CNTŠUpdate�the�column�count�for�the�next�guy‰MOVE.L„COL_CNT,D0@‰IF.L‚D0��BPERLINE�THEN.S�Make�sure�we�don't�go�out�of�range<‰WHILE�D2��#LFCHAR�DO.S„If�out�of�range�discard�incoming/‰BSR�GET_CHAR’until�terminated�with�a�line�feed‰ENDW‰BRA‡RETURNŽExit‰ENDISETTAB2.‰BSR‡GET_CHAR‚Get�next�character�of�tab�string6‰MOVE†LPERSCRN,D3‰Set�loop�control�for�absolute�screen‰SUBQ†#1,D3�DBRA�adjustment9‰CMP.B…#LFCHAR,D2ŠEnd�of�string�is�indicated�by�line�feed‰BNE.S…SETTAB2A‹**C*‡LINE�FEED�CHARACTER�DETECTED,‚IF�IT�FOLLOWED�SET�TABS--�RESET�ALL*‡CURRENT�TABS*SETTAB42‰TST.L…COL_CNT�If�column�count�zero�then�line�feed*°followed�set�command‰IF��THEN.S+‰LEA‡SCREEN,A0‹Point�to�beginning�of�screen+‰MOVE†LPERSCRN,D5‰Get�#�of�lines�per�screen8‰MULU†CPERLINE,D5‰*�characters�per�line�=�#�of�character*©positions�on�screenCLRTAB‰AND.W…#$FF7F,(A0)+ˆReset�tab(‰DBRA†D5,CLRTAB‹Loop�until�end�of�screen‰ENDI ‰BRA‡RETURNSETTAB2A4‰MOVE.L„COL_CNT,A0ŠPoint�to�current�position�in�line‰ADD.L…#SCREEN,A0Š*-‰CMP.B…#SPACE,D2‹Is�this�a�filler�character�?5‰BEQ.S…SETTAB1�Get�next�character�if�current�is�space'‰CMP.B…#CLEARTAB,D2ˆClear�tab�request�?+‰BEQ.S…RESETTABŒBranch�if�clear�tab�request**„SET�TAB�REQUEST*SETTAB37‰BSET.B„#7,1(A0)ŒSet�tab�bit�in�high�nibble�of�the�dis-4‰ADD.L…D5,A0�played�char.�for�every�column�on�screen‰DBRA†D3,SETTAB3Š*‰BRA.S…SETTAB1RE" SETTAB1‰BCLR.B„#7,1(A0)ŒTurn�tab�bit�off�in�every�column‰ADD.L…D5,A0�*‰DBRA†D3,RESETTAB‰* ‰BRA‡SETTAB1‰PAGE**ˆ$DFƒSEND‚LINE* SEND_LINE"‰CLR‡D1ˆSet�protected�field�switch'‰LEA‡XTCHBUF,A1ŠPoint�to�feeder�buffer.:‰MOVE.L„A1,FEEDER_ADDRESSƒTell�feeder�where�his�buffer�is.:‰MOVE.B„#START_OF_DATA,(A1)+�Start�of�data�($DD)�required.5‰MOVE†#1,FEEDER_COUNT…Tell�feeder�he�has�1�character.5‰MOVE.L„S.LINE,A0ŠStart�at�the�beginning�of�the�line. ‰WHILE.LƒA0��E.LINE�DO ‰ADDQ.L„#1,A0…Bump�past�the�FAC.;‰MOVE.B„(A0)+,D0ƒFind�out�if�we�are�at�the�end�of�the�line.#‰AND.B…#$7F,D0„Could�be�a�tab�stop.‰IF��THEN.SSENDL1C‰MOVE.B„#END_OF_DATA,(A1)�End�of�line,�move�($DE)�to�feeder�buffer.1‰ADDQ†#1,FEEDER_COUNTƒUpdate�his�#�of�characters.&‰BSR‡FEEDER„Ship�buffer�to�the�driver.(‰BRA‡RETURN„Get�out�because�we�are�done.‰ENDI,‰CMP.B…#01,D0„Check�for�FAC�definition�code.‰IF��THEN.S‰MOVE.B�-1(A0),D0„Get�the�FAC"‰ROR.W…#2,D0…Get�to�the�right�bits**ˆCHECK�HALF�BRIGHT*&‰ROR.W…#1,D0…Half�bright�bit�on�or�off‰IF��THEN.S*‰MOVE.B�#$E5,(A1)+ƒSend�reset�half�bright.‰ELSE.S'‰MOVE.B�#$E4,(A1)+ƒSend�set�half�bright‰ENDI **ˆCHECK�VIDEO�INVERT*'‰ROR.W…#1,D0…Video�invert�bit�on�or�off‰IF��THEN.S)‰MOVE.B�#$E2,(A1)+ƒSend�set�video�invert.‰ELSE.S+‰MOVE.B�#$E3,(A1)+ƒSend�reset�video�invert.‰ENDI**ˆCHECK�UNDERLINE*$‰ROR.W…#1,D0…Underline�bit�on�or�off‰IF��THEN.S&‰MOVE.B�#$E6,(A1)+ƒSend�set�underline.‰ELSE.S(‰MOVE.B�#$E7,(A1)+ƒSend�reset�underline.‰ENDI* *ˆCHECK�BLINK* ‰ROR.W…#1,D0…Blink�bit�on�or�off‰IF��THEN.S"‰MOVE.B�#$E0,(A1)+ƒSend�set�blink.‰ELSE.S$‰MOVE.B�#$E1,(A1)+ƒSend�reset�blink.‰ENDI**ˆCHECK�DISPLAY*"‰ROR.W…#1,D0…Display�bit�on�or�off‰IF��THEN.S$‰MOVE.B�#$E9,(A1)+ƒSend�set�display.‰ELSE.S&‰MOVE.B�#$E8,(A1)+ƒSend�reset�display.‰ENDI**ˆCHECK�PROTECT*"‰ROR.W…#1,D0…Protest�bit�on�or�off‰IF��THEN.S$‰MOVE.B�#$EA,(A1)+ƒSend�set�protect.‰ELSE.S&‰MOVE.B�#$EB,(A1)+ƒSend�reset�protect.‰ENDI+‰ADDQ†#6,FEEDER_COUNT�Update�Feeders�count. ‰BRA.S…SENDL2‰ENDI1‰MOVE.B„D0,(A1)+‚Move�character�to�feeder�buffer.-‰ADDQ†#1,FEEDER_COUNT�Update�character�count.SENDL2‰ENDW4‰BRA‡SENDL1„End�of�line�encountered�--�time�to�quit.‰PAGE*F* The characters $E0-$EF will set or reset the field attribute bits in'* the XREFed, word sized register FACS.* FACS is defined as follows:**ˆD15�=�Set�for�protect*ˆD14�=�Set�for�display*ˆD13�=�Set�for�blink*ˆD12�=�Set�for�underline*ˆD11�=�Set�for�inverse�video*ˆD10�=�color/intensity�bit�1*ˆD09�=�color/intensity�bit�2*ˆD08�=�color/intensity�bit�3 *„D07-D00�=�0* ** E0 = set blink* SBLINKƒEQU‡*9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BSET.B„#5,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$64,(A1)‹reset�all�other�FACS‰ENDI'‰MOVE.B„FACS,(A0)‹Update�FAC�on�screen. :‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac4‰ORˆ#$8000,(A0)‰Tell�world�the�FAC�code�is�protected*¦so�it�cannot�be�written�over.2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** E1 = reset blink* RBLINKƒEQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen9‰MOVE.B„#$01,(A0)‹Simulate�character�position�used�by�fac9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BCLR.B„#5,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$44,(A1)‹reset�all�other�FACS‰ENDI‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN** E2 = set video invert* SINVERT‚EQU‡*9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BSET.B„#3,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$4C,(A1)‹reset�all�other�FACS‰ENDI'‰MOVE.B„FACS,(A0)‹Update�FAC�on�screen.:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡P# ROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** E3 = reset video invert* RINVERT‚EQU‡*9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BCLR.B„#3,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$44,(A1)‹reset�all�other�FACS‰ENDI#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** E4 = Set half bright*UPBRIGHT�EQU‡*,‰MOVE.B„(A1),D2�Get�the�MSB�part�of�the�FACs'‰AND.B…#$F8,D2�Only�the�brightness�bits ‰OR.B†#$04,D2�Set�to�half�bright‰MOVE.B„D2,(A1)�*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen9‰MOVE.B„#$01,(A0)‹Simulate�character�position�used�by�fac‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** E5 = Reset half bright*DNBRIGHT�EQU‡*,‰MOVE.B„(A1),D2�Get�the�MSB�part�of�the�FACs'‰AND.B…#$F8,D2�Turn�off�brightness�bits‰OR.B†#$04,D2�Reset�half�bright‰MOVE.B„D2,(A1)�*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** E6 = set underline* SULINEƒEQU‡*9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BSET.B„#4,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$54,(A1)‹reset�all�other�FACS‰ENDI'‰MOVE.B„FACS,(A0)‹Update�FAC�on�screen.:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN  ** E7 = reset underline* RULINEƒEQU‡*9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BCLR.B„#4,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$44,(A1)‹reset�all�other�FACS‰ENDI#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac(‰ORˆ#$8000,(A0)‰Set�protect�bit�for�FAC.2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** E8 = set non display* NONDISP‚EQU‡*9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BCLR.B„#6,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise%‰MOVE.B„#$4,(A1)Œreset�all�other�FACS‰ENDI'‰MOVE.B„FACS,(A0)‹Update�FAC�on�screen.:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN  ** E9 = reset non-display* SETDISP‚EQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BSET.B„#6,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$44,(A1)‹reset�all�other�FACS‰ENDI‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** EA = set protect* PROTECT‚EQU‡*9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BSET.B„#7,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$C4,(A1)‹reset�all�other�FACS‰ENDI'‰MOVE.B„FACS,(A0)‹Update�FAC�on�screen.:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac‰ORˆ#$8000,(A0)‰Set�protect�bit2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogated ‰BRA‡RETURN ** EB = reset protect* ALLOW„EQU‡*#‰MOVE.B„FACS,(A0)‹Put�FAC�on�screen:‰MOVE.B„#$01,1(A0)ŠSimulate�character�position�used�by�fac9‰IF.B�1(A0)��#01�THEN.S„If�we�are�on�a�FAC�definition8‰BCLR.B„#7,(A1)�just�OR�the�new�FAC�bit�into�current�FAC‰ELSE.S˜otherwise&‰MOVE.B„#$64,(A1)‹reset�all�other�FACS‰ENDI0‰ORˆ#$8000,(A0)‰Set�protect�bit�for�FAC�position2‰BSR‡PROFACŽCheck�to�see�if�FAC�must�be�propogatedRET.1„BRA‡RETURNŠPAGE* * F1 = reset*K* The display area is filled with spaces, all FAC's are reset, tabs are setL* every INIT# _TAB spaces, the virtual screen is restored to its default size,* and the cursor is HOMEd.*RESET24?‰MOVE†#24,NUMBER_LINES�Set�up�the�small�screen�reset.�(24�line) RESET253ŠBSR„SCRNINIT‹Reset�all�the�parameters�to�defaults. *‚Fill�the�screen�with�blanks.4ŠLEA„SCREEN,A0ŠA0�<--�start�addr�of�absolute�screen.5ŠMOVEƒ#$4400,D2ŠD2�<--�default�attributes�and�a�space*§char�for�filling�the�screen.:ŠMOVEƒNUMBER_LINES,D5„D5�<--�#�of�characters�on�screen�-�1<ŠMULUƒCPERLINE,D5ˆ*‚=�lines�per�screen�*�chars�per�line�-�1. ŠSUBQƒ#1,D5Ž* �DO.SŠWhile�there�are�more�tabs�to�place, 5ŠBSETW‚#7,(A0)ŒSet�a�tab�in�this�position�and�advance%ŠADD.L‚#2*INIT_TAB,A0…INIT_TAB�chars. 0ŠSUBQƒ#1,D5ŽKeep�going�until�all�tabs�are�placedŠENDW–on�this�line. /ŠMOVEƒBPERLINE,A0ˆA0.L�<--�address�of�next�line7ŠADD.L‚(SP)+,A0‹*„=�addr�of�last�line�+�bytes�per�line. 0ŠSUBQƒ#1,D2ŽKeep�going�until�all�lines�are�done. ŠUNTIL‚�*ŠSF…EDIT_FLAGŠClear�edit�modeŠSF…PAGEFLAG‹page�modeŠSF…PROMODEŒand�protect�mode.;ŠMOVE.LƒB.LINE,D6ˆHome�routine�needs�bytes�per�virtual�lineBŠMOVE…#25,NUMBER_LINES�Reset�lines/screen�because�we�may�have�done*£a�24�line�reset.ŠBRA‡HOMEŒHome�the�cursor.‰PAGE* * DISPLAYL*---------------------------------------------------------------------------L* 1. Write the requested character in the display RAM at the current cursor.I* 2. Seek a non-protected spot to the right, with line and page rollover.6*„if�none�found,�sound�bell,�and�stay�at�current�spot.,* 3. Update the cursor register of the CRTC.** Input parameters:*------------------4* A0.L = current cursor posiotion in the display RAM8* D2.L = $000000XX, where XX is the requested character.0* D3.W = Maximum number of characters on screen.F* FACS = An XREFed, word sized register containing the FACs in effect.* DISPLAY‚EQU‡* ‰IF.B†PAGEFLAG��#TRUE�THEN.S“BRA.S�DISPLAY1‰ENDI/‰TST‡(A0)�Check�for�cursor�in�a�protected�field‰BPL.S…DISPLAY1ŒBranch�if�not*<*„Cursor�is�in�a�protected�field�--�we�can�only�accept�a�FAC*%‰TST.B…D2’Check�if�character�is�a�FAC‰IF��THEN.S �BRA�OUTCH1‰ENDI*�BSR.S�SEEKR�Not�a�FAC�so�seek�unprotectedDISPLAY1‰BSR‡PROFACŽPropogate�FAC:‰MOVE.B„FACS,(A0)+ŠMove�current�FACS�to�current�Screen�loc%‰AND.B…#$80,(A0)‹Keep�tab�information,‰OR.B†D2,(A0)+ŒWrite�character�to�the�screen‰IF.LƒA0��E.LINE�THEN.S1‰ADD.L‚D5,S.LINEŽUpdate�beginning�and�ending�line5‰ADD.L‚D5,E.LINEŽaddresses�because�we�are�about�to�go‰ENDIšto�the�next�line.3‰BSR.S…SEEKR�If�protected�find�an�unprotected�char.#‰BRA‡WRITCRSRŒUpdate�current�cursor*?* Starting at the current display address, find an un-protected* spot to the right.* SEEKR„EQU‡* ‰IF.B�PAGEFLAG��#TRUE�THEN.S“RTS‰ENDI ‰MOVE.L„A0,A3�Set�up�termination‰IF.L†A0��S.LINE�THEN.S‰REPEAT D*„If�the�End�of�Line�character�is�in�the�first�character�position�ofB*„a�line,�while�we�are�in�protect�mode,‚the�cursor�is�moved�down�a*„line. ‰IF.B‚1(A0)��#00�THEN.S!‰ADD.L…D5,A0�Update�start�of�line‰MOVE.L„A0,S.LINE‹*+‰ADD.L…D5,E.LINE‹Update�end�of�virtual�line‰ELSE.S4‰BRA.S…SEEKR1ŽIf�End�of�Line�is�not�at�the�beginning'*¦of�the�line--go�ahead�and�seek�right.‰ENDI‰UNTIL.L�A0��A3‰RTS‰ENDI*7*„Find�an�unprotected�character�position�on�the�screen.*SEEKR1‰REPEAT‰IF.L†A0��E.SCRN�THEN.S9‰MOVE.L„S.SCRN,A0‹Wrap�the�search�for�an�unprotected�char2‰MOVE.L„A0,S.LINE‹Update�beginning�and�ending�adr.‰MOVE.L„A0,E.LINE‹*‰ADD.L…D6,$ E.LINE‹*,‰BRA.S…SEEKR2Ž*�Check�to�see�if�we�are�done.‰ENDI‰IF.L†A0��E.LINE�THEN.S#‰ADD.L…D5,(A2)�Update�start�of�line‰ADD.L…D5,4(A2)Œand�end�ofline‰MOVE.L„S.LINE,A0,‰BRA.S…SEEKR2Ž*�Check�to�see�if�we�are�done.‰ENDI2‰TST.W…(A0)+�Unprotected�fields�are�the�ones�where*¦bit�8�is�turned�off.‰IF��THEN.S5‰TST.B‚-1(A0)‘Make�sure�we�aren't�at�the�end�of�line.‰IF‚�THEN.S5‰ADD.LƒD5,S.LINE�In�protect�mode�the�cursor�cannot�be%*¦on�an�end�of�line--update�pointers.‰ADD.LƒD5,E.LINEƒ*‰MOVE.L‚S.LINE,A0�*3‰BRA.SƒSEEKR2�Go�make�sure�we�didn't�go�off-screen.‰ENDI3‰SUBQ.L„#2,A0�Character�not�protected�update�cursor*¦because�of�auto-increment.‰RTS‰ENDISEEKR2‰UNTIL.L�A0��A3*C*‚There�are�no�unprotected�fields�on�the�screen�so�home�the�cursor.**:‰MOVE.L„S.SCRN,A0‹Set�cursor�address�to�beginning�of�scrn.8‰MOVE.L„A0,S.LINE‹Update�beginning�and�ending�line�ptrs.‰ADD.L…D5,4(A2)Œ**‰RTS‡RETURNŽExit�no�unprotected�area�found‰PAGEWRITCRSR�EQU‡**9* Convert display RAM address to absolute cursor address,* and write into CRTC.** A0.L = Diaplay cursor address*/‰MOVE.L„A0,D1�Calculate�cursor�absolute�address‰SUB.L…#SCREEN,D1+‰LSR.L…#1,D1�To�take�care�of�attribute�area WRITEABS�EQU‡**/* Write the absolute cursor address in the CRTC* * D1.W = absolute cursor address*!‰MOVE.B„#$0F,CRTCADDˆPoint�to�R152‰MOVE.B„D1,CRTCREGŠStore�LSB�of�new�cursor�address ‰LSR.W…#8,D1�Position�upper�byte!‰MOVE.B„#$0E,CRTCADDˆPoint�to�R143‰MOVE.B„D1,CRTCREGŠSrore�MSB�of�new�cursor�register 6RETURNƒMOVEM.Lƒ(A7)+,D0-D7/A0-A3ƒRestore�user's�values‰RTS‰PAGEREADCRSR�EQU‡***‚Read�the�cursor�position*6*‚This�routine�is�for�internal�use,�and�is�not�XDEFed.)*‚For�an�external�control�routine�see�C6.**‚Input�parametersƒ:�none*>*‚Registers�affected�:�D1.W�=�Absolute�address�of�cursor�spot.&*—A0.L�=�Screen�RAM�address�of�cursor.*‰CLR.L…D1’HSKP!‰MOVE.B„#$0E,CRTCADDˆPoint�to�R14.‰MOVE.B„CRTCREG,D1ŠGet�current�cursor�position‰ROL.W…#8,D1�Put�it�in�MSB!‰MOVE.B„#$0F,CRTCADDˆPoint�to�R154‰MOVE.B„CRTCREG,D1ŠGet�lower�byte�of�cursor�position-‰LSL.W…#1,D1�Adjust�for�screen�RAM�operations ‰MOVE.L„D1,A0‰ADD.L…#SCREEN,A0‰RTS***GET_CHAR3‰STˆCHAR_RESERVED‡Reserve�next�character�for�caller>‰MOVE.L„(A7)+,CHAR_OWNER„Save�callers�return�address�for�later'‰BRA‡RETURNŽWait�for�the�next�character**ˆPROPOGATE�FAC�CODE*PROFAC‰IF.L‚A0��E.LINE�THEN.S ‰MOVE.L�A0,A10‰MOVE.B�(A1),D0�Get�the�FAC�which�will�be�moved.'‰ADDQ.L�#2,A1’Get�off�current�location.‰WHILE.L‚A1��E.LINE�DO.S2‰IF.Bƒ1(A1)��#00�THEN.S‚Check�for�end�of�line.7‰BRA.S‚PROFAC1�Branch�if�we�are�at�the�end�of�the�line.‰ENDI3‰CMP.B‚#1,1(A1)�Stop�if�we�are�on�a�FAC�definition.‰BEQ.S�PROFAC1A�*1‰MOVE.B�D0,(A1)�Move�the�FAC�code�to�end�of�line.‰ADDQ.L�#2,A1’*‰ENDW‰BRA.S�PROFAC1‰ENDIPROFAC1A)‰MOVE.L„A0,A1�Save�current�cursor�address‰IF.L†A1��S.LINE�THEN.S‰RTS›Exit�--�nothing�to�do“|L…‰ENDI1‰MOVE.B�-1(A1),D3ŽThere�could�be�a�tab�stop�here.%*¦Let's�turn�the�bit�off�before�we�go*¦on.‰AND.B�#$7F,D3‘*%‰IF‚‚THEN.SŽExit�--�nothing�to�do‰RTS‰ENDI‰WHILE.L�A1��S.LINE�DO.S@‰IF.B�-1(A1)��#01�THEN.SƒTry�to�find�where�a�FAC�was�defined‰MOVE.B�-2(A1),D0‰BRA.SƒPROFAC1‰ELSE.S ‰SUBQ.L‚#2,A1‰ENDI‰ENDW1‰MOVE.Bƒ#DISPLAY_FAC,D0‡Use�a�display�FAC�because*©a�01�was�not�found.8‰MOVE.BƒD0,FACSŽUpdate�the�FAC�for�the�rest�of�the�line.PROFAC1 ‰MOVE.L‚A0,A1‰WHILE.L�A1��S.LINE�DO.S'‰MOVE.B‚-(A1),D3�Get�previous�character,‰AND.Bƒ#$7F,D3�Check�if�line�end�or�tab�only‰BNE.S„PROFAC2,‰OR.B„#$20,(A1)�Remove�end�of�line�character!‰MOVE.B‚D0,-(A1)ŽUpdate�FAC�code.‰ENDWPROFAC2‰RTS‰END$ NNNNN:TERMDRVƒIDNTƒ45,0†VERSAdos�terminal�driver�with�type-ahead6ŠTTL„TERMDRV:‚VERSAdos�terminal�driver�with�type-ahead ŠLLENƒ120J**************************************************************************J**************************************************************************J**************************************************************************J***************************************************************************4*‰TERMDRV:‚VERSAdos�terminal�driver�with�type-ahead.*?*‰Purpose:‚VERSAdos�device�driver�to�handle�the�VME/10�keyboard *�&�screen.**‰Revision�history: 7*�12/09/85‚Install�NEW�Killer�modification�which�leaves,*šThe�Driver�ID�(Number)�and�Reason�(Number)2*šin�CRASHSAV�along�with�the�CCB�and�DCB�pointers.5*�01/15/85‚Added�code�to�return�error�code�to�user�in,*šhalt�I/O�parameter�block.�Return�of�$E6�in*šoriginal�I/O�parameter�block.9*�01/30/85‚Modified‚KEYBRD.AG,�OUTCHS.SA,�POUTCHS.SA,�and.*šEDITMODE.SA‚to�use�the�BELL�in�the�keyboard.?*�10/10/84‚There�was�a�problem�if�any�other�board�in�the�system0*šis�configured�to�use�the�same�interrupt�level,-*šbecause�GET_CHAR�assumes�that�the�interrupt*šis�always�for�him.,*šFixed�GET_CHAR�to�send�back�both�Z�bit�and)*šV�bit�set�if�the�interrupt�is�not�ours,+*šso�that�IN_CHAR�will�pass�it�along�to�the1*šmain�interrupt�handler,�and�we�will�then�return4*što�CMR�with�the�carry�bit�cleared�to�indicate�that *šthe�interrupt�is�not�ours.†bwn;*‘2/�9/84‚Fixed�problem�with�READ�TERMINATOR�initialization*šin�subroutine�SETUP.6*‘7/19/83‚Changed�RESET�command�sent�to�OUTCHS�to�$F7.**‘6/�3/83‚Initial�writing�by�Steve�Franck.**‰RMS68K�routines�used: *�TR0$.RQPA *�TR0$.QEVENT*�TR0$.QEVENTI *�TR0$.LOGPHY *�TR0$.GETTCB*�TR0$.DRIVKILL**‰Other�notes:6*�Currently�this�code�is�neither�ROMable�nor�position-*’independent.'*�Assemble�using�chain�file�TERMDRV.AF.*J**************************************************************************†�4–Iž2¦9®E¶J¾EÆBÎ<Ö4Þ:æBî8ö;þ<86<C&H.<6A>MFAN>VE^7fBn>v>J**************************************************************************J**************************************************************************J**************************************************************************‰PAGE*F*‚To�assemble�this�code�for�its�proper�target�environment,�change�thisA*‚equate,�which�will�serve�as�a�switch�in�conditional�assemblies.2*‚Valid�values�for�the�switch�are:‚'7201',�'EX/S'.(*‚FOR�NOW,�THIS�SWITCH�MUST�BE�'EX/S'!!!*ENVIRONMENT EQU 'EX/S' * % *‚XDEF's.*8ŠXDEFƒGOT_CHAR‹Entry�point�for�driver�to�receive�a�char.7ŠXDEFƒCHECK_WORK‰Background�exec's�entry�point�to�check*§for�more�work. * *‚XREF's.*=ŠXREFƒSTOP_IT,UNSTOP…Device-specific�routines�to�stop�further&*§traffic�from�the�device�and�to�allow *§it�again. ‰IFEQ†ENVIRONMENT-'EX/S'"*§Subroutines�for�initializing�and'*§controlling�VME/10�keyboard�&�screen."ŠXREFƒINIT_KEYBOARD,IN_CHAR,OUTCHS‰ENDC  **‚Equate�files�included:**‰EQUSTR*‰EQUTCB*‰EQUCCB*‰VMES10.IOE.SA*‰NIO*‰LV5&*‰NEC7201‚only�if�ENVIRONMENT�=�'7201'*‰VMES10.TERMDRV.EQ *‰KILL.MC *‰KILLDRV.EQ*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠNOLISTŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.CCB.EQŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.NIO.EQŠINCLUDE�9995.&.LV5.EQŠINCLUDE�9995.&.KILL.MCŠINCLUDE�9995.&.KILLDRV.EQ ŠLISTŠPAGEO*********************************************************************************‰NOTES�ON�CODING�STANDARDS*O******************************************************************************* G*‚Because�this�is�an�I/O�driver,�speed�is�of�the�utmost�importance,�andG*‚as�a�result�tradeoffs�were�made�decreasing�the�straightforwardness�ofL*‚the�code�in�favor�of�less�time�spent�processing�interrupts.‚In�particular,F*‚the�interrupt�service�portion�of�this�driver�is�not�at�all�modular--H*‚some�'routines'�have�multiple�entry�and�exit�points,�and�return�is�not*‚always�to�the�caller.*G*‚One�visual�aid�used�which�may�save�you�some�work�is�the�use�of�labelsD*‚in�executable�code.‚Consider�the�following�sample�program�segment:*.*‰LABEL1:˜label�alone�on�line,�followed�by�':'*‘MOVE.B�......7*‰LABEL2:�ADD.B‚......Šlabel�not�alone,�followed�by�':'-*‰LABEL3‚CMP.B‚......Šlabel�not�alone,�no�':'*F*‚Each�way�of�writing�the�label�has�its�own�significance.‚LABEL1�marksC*‚the�beginning�of�a�logical�module,�and�nothing�falls�into�LABEL1.G*‚LABEL2�is�a�label�branched�to�from�outside�the�logical�module.‚LABEL3F*‚is�a�'local'�label,�branched�to�only�from�within�the�logical�module.  >*‚For�each�subroutine,�register�usage�is�specified�as�follows:**‰Entry:�A5�=�address�of�CCB**‰Exit:‚A0�=�garbage"*�A1�=�address�of�our�side�of�7201*G*‚The�entry�conditions�specify�only�the�REQUIREMENTS�of�the�routine.‚InI*‚other�words,�a�register�may�be�known�to�contain�a�particular�value,�butI*‚if�it�is�not�used�by�a�routine,�it�is�not�listed�as�an�entry�condition.J*‚The�exit�conditions�list�only�those�registers�which�CHANGE.‚In�the�aboveH*‚example,�the�fact�that�A5�is�not�listed�as�an�exit�condition�indicates"*‚that�it�still�points�to�the�CCB.*J*‚If�a�module�does�not�represent�a�subroutine�(that�is,�will�not�return�toK*‚the�code�it�was�entered�from),�the�exit�conditions�for�the�registers�will*‚not�be�specified.ŠPAGEO******************************************************************************** *‰EQUATES*O******************************************************************************* *,* EQUATES FOR SOME SPECIAL ASCII CHARACTERS.*'NUL†EQU‡$00‡Null�char.‚Usually�ignored..BEL†EQU‡$07‡Bell�char.‚Rings�bell�on�terminal.BS‡EQU‡$08‡Backspace�char.6LF‡EQU‡$0A‡Line�feed�char.‚Causes�cursor�to�move�down.=CR‡EQU‡$0D†Carriage�return�char.‚Moves�cursor�to�left�margin.SPACE„EQU‡$20‡Space�char.$L_ARROW‚EQU‡$3C‡Left‚arrow�char�'<'.%R_ARROW‚EQU‡$3E‡Right�arrow�char�'>'.#BKSLASH‚EQU‡$5C‡Backslash�char�'\'.'CARET„EQU‡$5E‡Uparrow�(caret)�char�'^'.8DEL†EQU‡$7F‡Delete�char�(also�called�'rubout').‚Like�BS. $HI_CTLƒEQU‡$1F‡Highest�control�char. IBS_SP_BS�EQU�BS<<24+SPACE<<16+BS<<8‚Backspace,�space,�backspace�all�left-*§justified�in�32�bits. *?*‚Masks�delineating�all�recognized�(REC)�and�unrecognized�(UNR)(*‚attributes�(ATT)�and�parameters�(PAR).*‰IFEQ†ENVIRONMENT-'EX/S'BREC_ATTƒEQU„%1000001111000001‚1�bits�represent�defined�attributes.CUNR_ATTƒEQU„$FFFF-REC_ATT†The�1's�complement�of�% that�are�undefined. BREC_PARƒEQU„%0111011111111111‚1�bits�represent�defined�parameters.CUNR_PARƒEQU„$FFFF-REC_PAR†The�1's�complement�of�that�are�undefined.‰ENDC ŠPAGE**‚Miscellaneous�equates.* *IOEVCD„EQU„1’Event�code�we�will�use�(I/O). ;BRK_LENƒEQU„300�#�of�milliseconds�to�maintain�break�signal. *I*‚This�is�a�semi-arbitrary�value�that�can�be�written�out�to�a�register�onH*‚some�device�and�then�read�back,�in�order�to�test�(in�a�very�small�way)C*‚the�device's�health.‚On�the�7201,�for�example,�this�is�written�to*‚the�vector�register�(2B).*TEST_VAL‚EQU„$17ŠPAGEK*****************************************************************************‰EQUATES�FOR�TRANSPARENT�MODE*K*************************************************************************** *F*‚Equates�describing�the�part�of�the�CSB�used�when�setting�TRANSPARENTH*‚MODE.‚We�pass�the�driver�the�address�of�our�branch�table�and�he�passesI*‚us�back�the�address�of�his�branch�table,�the�value�we�should�have�in�A5G*‚when�we�call�him,�and�the�SR�that�we�should�use.‚Actually,�we�may�useG*‚a�different�SR�as�long�as�the�supervisor�bit�is�set�and�the�interrupt9*‚level�is�not�lower�than�the�one�in�the�SR�he�passes�us.*7ŠOFFSET�IOSTTM�This�stuff�will�be�in�the�CSB�at�IOSTTM.9IOSTMU„DS.Bƒ4’Here�the�user�will�store,�before�making�the&*§CHANGE�DEFAULTS�call,�the�address�of*§his�table�of�branches. 7ŠOFFSET�IOSTTM�This�stuff�will�be�in�the�CSB�at�IOSTTM.9IOSTMD„DS.Bƒ4’the�addr�of�the�driver's�table�of�branches;/IOSTMA„DS.Bƒ4’the�value�the�driver�wants�in�A5;5IOSTMS„DS.Bƒ2’the�SR�with�the�MINIMUM�interrupt�level*§set. 5ŠOFFSET�0ŽThis�defines�the�user's�TM�interface�table.*£We�JSR�to�this�entry�when:#TM_RCA„DS.Bƒ4’...we�receive�a�char.7TM_TBE„DS.Bƒ4’...we�become�capable�of�another�transmit.2TM_BRK_RECV�DS.B�4’...we�detect�an�incoming�break.�