************************************************************************* ************************************************************************* ** ** ** SOUND SYSTEM ** ** ** ************************************************************************* ************************************************************************* ------------------------------------------------------------------------- | | | OSWORD 07 - Make a sound | | | ------------------------------------------------------------------------- ; On entry, control block pointed to by &F0/1 ; Y=0 on entry ; XY +0 Channel - &hsfc for Hold, Sync, Flush, Channel ; 2 Amplitude/Envelope ; 4 Pitch ; 6 Duration E82D INY E82E LDA (&F0),Y ; Get channel high byte E830 CMP #&FF E832 BEQ &E88D ; Channel &FFxx, speech command E834 CMP #&20 ; Is channel>=&20 ? E836 LDX #&08 ; Prepare X=8 for unrecognised OSWORD call E838 BCS &E7CA ; Pass to sideways ROMs for channel &2000+ E83A DEY ; Point back to channel low byte E83B JSR &E8C9 ; Get Channel 0-3, and Cy if >=&10 for Flush E83E ORA #&04 ; Convert to buffer number 4-7 E840 TAX E841 BCC &E848 ; If not Flush, skip past E843 JSR &E1AE ; Flush buffer E846 LDY #&01 ; Point back to channel high byte E848 JSR &E8C9 ; Get Sync 0-3, and Cy if >=&10 for Hold E84B STA &FA ; Save Sync in &FA E84D PHP ; Stack flags E84E LDY #&06 E850 LDA (&F0),Y ; Get Duration byte E852 PHA ; and stack it E853 LDY #&04 E855 LDA (&F0),Y ; Get pitch byte E857 PHA ; and stack it E858 LDY #&02 ; E85A LDA (&F0),Y ; Get amplitude/envelope byte E85C ROL ; Move Hold into bit 0 E85D SEC ;set carry E85E SBC #&02 ;subract 2 E860 ASL ;multiply by 4 E861 ASL ; E862 ORA &FA ;add S byte (0-3) ; At this point, ; b7, 0=envelope, 1=volume ; b6-3, envelope-1 or volume+15 ; b2, Hold ; b1-0, Sync E864 JSR &E1F8 ; Wait for space and insert into buffer E867 BCC &E887 ; Byte inserted, jump to insert the rest E869 PLA ; Insert aborted (Escape pressed), drop stacked pitch E86A PLA ; Drop stacked duration E86B PLP ; Restore flags ; And exit ------------------------------------------------------------------------- | | | OSBYTE 117 - Read VDU status | | | ------------------------------------------------------------------------- E86C LDX &D0 ;get VDU status byte in X E86E RTS ;and return ************* set up sound data for Bell ******************************** E86F PHP ;push P E870 SEI ;bar interrupts E871 LDA &0263 ;get bell channel number in A E874 AND #&07 ; (bits 0-3 only set) E876 ORA #&04 ;set bit 2 E878 TAX ;X=A = bell channel number +4=buffer number E879 LDA &0264 ;get bell amplitude/envelope number E87C JSR &E4B0 ;store it in buffer pointed to by X E87F LDA &0266 ;get bell duration E882 PHA ;save it E883 LDA &0265 ;get bell frequency E886 PHA ;save it ; Insert sound pitch and duration into sound buffer ; E887 SEC ; Set carry E888 ROR &0800,X ; Set bit 7 of channel flags to indicate it's active E88B BMI &E8A4 ; Jump forward to insert pitch and duration ------------------------------------------------------------------------- | | | SOUND &FFxx - Speech System | | | ------------------------------------------------------------------------- ; On entry, control block pointed to by &F0/1 ; Y=1 on entry ; XY +0 Channel - &FFxx - xx=Speech command ; 2 Word number/Address ; 4 Ignored ; 6 Ignored E88D PHP ; Save flags E88E INY ; Y=2 E88F LDA (&F0),Y ; Get word number low byte E891 PHA ; and stack it E892 INY ; Y=3 E893 LDA (&F0),Y ; Get word number high byte E895 PHA ; and stack it E896 LDY #&00 ; Y=0 E898 LDA (&F0),Y ; Get speech command E89A LDX #&08 ; X=8 for Speech buffer E89C JSR &E1F8 ; Insert speech command into speech buffer E89F BCS &E869 ; Buffer insert aborted (Escape pressed), drop stack and abandon E8A1 ROR &02D7 ; Clear bit 7 of speech buffer busy flag ; Insert two bytes into buffer ; E8A4 PLA ; Get word number high byte or pitch back E8A5 JSR &E4B0 ; Insert into speech buffer or sound buffer E8A8 PLA ; Get word number low byte or duration back E8A9 JSR &E4B0 ; Insert into speech buffer or sound buffer E8AC PLP ; Restore flags E8AD RTS ; and return ************************************************************************* * * * OSWORD 08 - Define Envelope * * * ************************************************************************* ; On entry, control block pointed to by &F0/1 ; Y=0 on entry ; A=envelope number from (&F0),0 ;XY +0 Envelope number, also in A ; 1 bits 0-6 length of each step in centi-secsonds bit 7=0 auto repeat ; 2 change of Pitch per step (-128-+127) in section 1 ; 3 change of Pitch per step (-128-+127) in section 2 ; 4 change of Pitch per step (-128-+127) in section 3 ; 5 number of steps in section 1 (0-255) ; 6 number of steps in section 2 (0-255) ; 7 number of steps in section 3 (0-255) ; 8 change of amplitude per step during attack phase (-127 to +127) ; 9 change of amplitude per step during decay phase (-127 to +127) ; 10 change of amplitude per step during sustain phase (-127 to +127) ; 11 change of amplitude per step during release phase (-127 to +127) ; 12 target level at end of attack phase (0-126) ; 13 target level at end of decay phase (0-126) E8AE SBC #&01 ;set up appropriate displacement to storage area E8B0 ASL ;A=(A-1)*16 or 15 E8B1 ASL ; E8B2 ASL ; E8B3 ASL ; E8B4 ORA #&0F ; E8B6 TAX ;X=A E8B7 LDA #&00 ;A=0 E8B9 LDY #&10 ;Y=&10 E8BB CPY #&0E ;is Y>=14?? E8BD BCS &E8C1 ;yes then E8C1 E8BF LDA (&F0),Y ;else get byte from parameter block E8C1 STA &08C0,X ;and store it in appropriate area E8C4 DEX ;decrement X E8C5 DEY ;Decrement Y E8C6 BNE &E8BB ;if not 0 then do it again E8C8 RTS ;else exit ;note that envelope number is NOT transferred ; E8C9 LDA (&F0),Y ;get byte E8CB CMP #&10 ;is it greater than 15, if so set carry E8CD AND #&03 ;AND 3 to keep channel in bits 0-1 E8CF INY ;increment Y, step to next parameter byte E8D0 RTS ;and exit ************************************************************************* * * * OSWORD 03 ENTRY POINT * * * * read interval timer * * * ************************************************************************* ;F0/1 points to block to store data E8D1 LDX #&0F ;X=&F displacement from clock to timer E8D3 BNE &E8D8 ;jump to E8D8 ************************************************************************* * * * OSWORD 01 ENTRY POINT * * * * read system clock * * * ************************************************************************* ;F0/1 points to block to store data E8D5 LDX &0283 ;X=current system clock store pointer E8D8 LDY #&04 ;Y=4 E8DA LDA &028D,X ;read byte E8DD STA (&F0),Y ;store it in parameter block E8DF INX ;X=x+1 E8E0 DEY ;Y=Y-1 E8E1 BPL &E8DA ;if Y>0 then do it again E8E3 RTS ;else exit ************************************************************************* * * * OSWORD 04 ENTRY POINT * * * * write interval timer * * * ************************************************************************* F0/1 points to block to store data E8E4 LDA #&0F ;offset between clock and timer E8E6 BNE &E8EE ;jump to E8EE ALWAYS!! ************************************************************************* * * * OSWORD 02 ENTRY POINT * * * * write system clock * * * ************************************************************************* F0/1 points to block to store data E8E8 LDA &0283 ;get current clock store pointer E8EB EOR #&0F ;and invert to get inactive timer E8ED CLC ;clear carry E8EE PHA ;store A E8EF TAX ;X=A E8F0 LDY #&04 ;Y=4 E8F2 LDA (&F0),Y ;and transfer all 5 bytes E8F4 STA &028D,X ;to the clock or timer E8F7 INX ; E8F8 DEY ; E8F9 BPL &E8F2 ;if Y>0 then E8F2 E8FB PLA ;get back stack E8FC BCS &E8E3 ;if set (write to timer) E8E3 exit E8FE STA &0283 ;write back current clock store E901 RTS ;and exit ************************************************************************* * * * OSWORD 00 ENTRY POINT * * * * read line from current input to memory * * * ************************************************************************* ;F0/1 points to parameter block ; +0/1 Buffer address for input ; +2 Maximum line length ; +3 minimum acceptable ASCII value ; +4 maximum acceptable ASCII value E902 LDY #&04 ;Y=4 E904 LDA (&F0),Y ;transfer bytes 4,3,2 to 2B3-2B5 E906 STA &02B1,Y ; E909 DEY ;decrement Y E90A CPY #&02 ;until Y=1 E90C BCS &E904 ; E90E LDA (&F0),Y ;get address of input buffer E910 STA &E9 ;store it in &E9 as temporary buffer E912 DEY ;decrement Y E913 STY &0269 ;Y=0 store in print line counter for paged mode E916 LDA (&F0),Y ;get lo byte of address E918 STA &E8 ;and store in &E8 E91A CLI ;allow interrupts E91B BCC &E924 ;Jump to E924 E91D LDA #&07 ;A=7 E91F DEY ;decrement Y E920 INY ;increment Y E921 JSR OSWRCH ;and call OSWRCH E924 JSR OSRDCH ;else read character from input stream E927 BCS &E972 ;if carry set then illegal character or other error ;exit via E972 E929 TAX ;X=A E92A LDA &027C ;A=&27C get character destination status E92D ROR ;put VDU driver bit in carry E92E ROR ;if this is 1 VDU driver is disabled E92F TXA ;X=A E930 BCS &E937 ;if Carry set E937 E932 LDX &026A ;get number of items in VDU queque E935 BNE &E921 ;if not 0 output character and loop round again E937 CMP #&7F ;if character is not delete E939 BNE &E942 ;goto E942 E93B CPY #&00 ;else is Y=0 E93D BEQ &E924 ;and goto E924 E93F DEY ;decrement Y E940 BCS &E921 ;and if carry set E921 to output it E942 CMP #&15 ;is it delete line &21 E944 BNE &E953 ;if not E953 E946 TYA ;else Y=A, if its 0 we are still reading first ;character E947 BEQ &E924 ;so E924 E949 LDA #&7F ;else output DELETES E94B JSR OSWRCH ;until Y=0 E94E DEY ; E94F BNE &E94B ; E951 BEQ &E924 ;then read character again E953 STA (&E8),Y ;store character in designated buffer E955 CMP #&0D ;is it CR? E957 BEQ &E96C ;if so E96C E959 CPY &02B3 ;else check the line length E95C BCS &E91D ;if = or greater loop to ring bell E95E CMP &02B4 ;check minimum character E961 BCC &E91F ;if less than minimum backspace E963 CMP &02B5 ;check maximum character E966 BEQ &E920 ;if equal E920 E968 BCC &E920 ;or less E920 E96A BCS &E91F ;then JUMP E91F E96C JSR OSNEWL ;output CR/LF E96F JSR &E57E ;call Econet vector with A=13 E972 LDA &FF ;A=ESCAPE FLAG E974 ROL ;put bit 7 into carry E975 RTS ;and exit routine ************************************************************************* * * * OSBYTE 05 ENTRY POINT * * * * SELECT PRINTER TYPE * * * ************************************************************************* E976 CLI ;allow interrupts briefly E977 SEI ;bar interrupts E978 BIT &FF ;check if ESCAPE is pending E97A BMI &E9AC ;if it is E9AC E97C BIT &02D2 ;else check bit 7 buffer 3 (printer) E97F BPL &E976 ;if not empty bit 7=0 E976 E981 JSR &E1A4 ;check for user defined routine E984 LDY #&00 ;Y=0 E986 STY &F1 ;F1=0 ************************************************************************* * * * OSBYTE 01 ENTRY POINT * * * * READ/WRITE USER FLAG (&281) * * * * AND * * * * OSBYTE 06 ENTRY POINT * * * * SET PRINTER IGNORE CHARACTER * * * ************************************************************************* ; A contains osbyte number E988 ORA #&F0 ;A=osbyte +&F0 E98A BNE &E99A ;JUMP to E99A ************************************************************************* * * * OSBYTE 0C ENTRY POINT * * * * SET KEYBOARD AUTOREPEAT RATE * * * ************************************************************************* E98C BNE &E995 ;if &F0<>0 goto E995 E98E LDX #&32 ;if X=0 in original call then X=32 E990 STX &0254 ;to set keyboard autorepeat delay ram copy E993 LDX #&08 ;X=8 ************************************************************************* * * * OSBYTE 0B ENTRY POINT * * * * SET KEYBOARD AUTOREPEAT DELAY * * * ************************************************************************* E995 ADC #&CF ;A=A+&D0 (carry set) ************************************************************************* * * * OSBYTE 03 ENTRY POINT * * * * SELECT OUTPUT STREAM * * * * AND * * * * * * OSBYTE 04 ENTRY POINT * * * * ENABLE/DISABLE CURSOR EDITING * * * ************************************************************************* E997 CLC ;clear carry E998 ADC #&E9 ;A=A+&E9 E99A STX &F0 ;store X ************************************************************************* * * * OSBYTE A6-FF ENTRY POINT * * * * READ/ WRITE SYSTEM VARIABLE OSBYTE NO. +&190 * * * ************************************************************************* E99C TAY ;Y=A E99D LDA &0190,Y ;i.e. A=&190 +osbyte call number E9A0 TAX ;preserve this E9A1 AND &F1 ;new value = OLD value AND Y EOR X! E9A3 EOR &F0 ; E9A5 STA &0190,Y ;store it E9A8 LDA &0191,Y ;get value of next byte into A E9AB TAY ;Y=A E9AC RTS ;and exit ******* SERIAL BAUD RATE LOOK UP TABLE ************************************ \ b0-b2=tx baud setting, b3-b5=rx baud setting, b6='serial, not CFS' \ Also 'is a SOUND buffer' table, b7=buffer is a SOUND buffer E9AD DB &64 ; % 01100100 0 = 9600 buffer 0 = not SOUND E9AE DB &7F ; % 01111111 1 = 75 buffer 1 = not SOUND E9AF DB &5B ; % 01011011 2 = 150 buffer 2 = not SOUND E9B0 DB &6D ; % 01101101 3 = 300 buffer 3 = not SOUND E9B1 DB &C9 ; % 11001001 4 = 1200 buffer 4 = SOUND E9B2 DB &F6 ; % 11110110 5 = 2400 buffer 5 = SOUND E9B3 DB &D2 ; % 11010010 6 = 4800 buffer 6 = SOUND E9B4 DB &E4 ; % 11100100 7 = 9600 buffer 7 = SOUND E9B5 DB &40 ; % 01000000 8 = 19200 buffer 8 = not SOUND ************************************************************************* * * * OSBYTE &13 ENTRY POINT * * * * Wait for VSync * * * ************************************************************************* E9B6 LDA &0240 ;read vertical sync counter E9B9 CLI ;allow interrupts briefly E9BA SEI ;bar interrupts E9BB CMP &0240 ;has it changed? E9BE BEQ &E9B9 ;no then E9B9 ; falls through and reads VDU variable X ************************************************************************* * * * OSBYTE 160 ENTRY POINT * * * * READ VDU VARIABLE * * * ************************************************************************* ;X contains the variable number ; 0 =lefthand column in pixels current graphics window ; 2 =Bottom row in pixels current graphics window ; 4 =Right hand column in pixels current graphics window ; 6 =Top row in pixels current graphics window ; 8 =lefthand column in absolute characters current text window ; 9 =Bottom row in absolute characters current text window ;10 =Right hand column in absolute characters current text window ;11 =Top row in absolute characters current text window ;12-15 =current graphics origin in external coordinates ;16-19 =current graphics cursor in external coordina4es ;20-23 =old graphics cursor in internal coordinates ;24 =current text cursor in X and Y E9C0 LDY &0301,X ;get VDU variable hi E9C3 LDA &0300,X ;low E9C6 TAX ;X=low byte E9C7 RTS ;and exit ************************************************************************* * * * OSBYTE 18 ENTRY POINT * * * * RESET SOFT KEYS * * * ************************************************************************* E9C8 LDA #&10 ;set consistency flag E9CA STA &0284 ; E9CD LDX #&00 ;X=0 E9CF STA &0B00,X ;and wipe clean E9D2 INX ;soft key buffer E9D3 BNE &E9CF ;until X=0 again E9D5 STX &0284 ;zero consistency flag E9D8 RTS ;and exit ************************************************************************* * * * OSBYTE &76 (118) SET LEDs to Keyboard Status * * * ************************************************************************* ;osbyte entry with carry set ;called from &CB0E, &CAE3, &DB8B E9D9 PHP ;save flags E9DA SEI ;disable interupts E9DB LDA #&40 ;switch on CAPS and SHIFT lock lights E9DD JSR &E9EA ;via subroutine E9E0 BMI &E9E7 ;if ESCAPE exists (M set) E9E7 E9E2 CLC ;else clear V and C E9E3 CLV ;before calling main keyboard routine to E9E4 JSR &F068 ;switch on lights and read Ctrl and Shift to A=%csxxxxxx E9E7 PLP ;restore IRQs E9E8 ROL ;rotate bit 7 (Ctrl) into Carry, and bit 6 (Shift) into Minus E9E9 RTS ;return to calling routine, A=%sxxxxxxx, C=Ctrl, M=Shift ; ***************** Turn on keyboard lights and Test Escape flag ************ ;called from &E1FE, &E9DD ; E9EA BCC &E9F5 ;if carry clear E9EC LDY #&07 ;switch on shift lock light E9EE STY &FE40 ; E9F1 DEY ;Y=6 E9F2 STY &FE40 ;switch on Caps lock light E9F5 BIT &FF ;set minus flag if bit 7 of &00FF is set indicating E9F7 RTS ;that ESCAPE condition exists, then return ; ****************** Write A to SYSTEM VIA register B ************************* ;called from &CB6D, &CB73 E9F8 PHP ;push flags E9F9 SEI ;disable interupts E9FA STA &FE40 ;write register B from Accumulator E9FD PLP ;get back flags E9FE RTS ;and exit ************************************************************************* * * * OSBYTE 154 (&9A) SET VIDEO ULA * * * ************************************************************************* E9FF TXA ;osbyte entry, X transferred to A thence to *******Set Video ULA control register **entry from VDU routines ************** ;called from &CBA6, &DD37 EA00 PHP ;save flags EA01 SEI ;disable interupts EA02 STA &0248 ;save RAM copy of new parameter EA05 STA &FE20 ;write to control register EA08 LDA &0253 ;read space count EA0B STA &0251 ;set flash counter to this value EA0E PLP ;get back status EA0F RTS ;and return ************************************************************************* * * * OSBYTE &9B (155) write to palette register * * * ************************************************************************* ;entry X contains value to write EA10 TXA ;A=X EA11 EOR #&07 ;convert to palette format EA13 PHP ; EA14 SEI ;prevent interrupts EA15 STA &0249 ;store as current palette setting EA18 STA &FE21 ;store actual colour in register EA1B PLP ;get back flags EA1C RTS ;and exit ************************************************************************* * GSINIT string initialisation * * F2/3 points to string offset by Y * * * * ON EXIT * * Z flag set indicates null string, * * Y points to first non-blank character * * A contains first non-blank character * ************************************************************************* EA1D CLC ;clear carry EA1E ROR &E4 ;Rotate moves carry to &E4 EA20 JSR &E03A ;skip spaces and get character EA23 INY ;increment Y to point to next character EA24 CMP #&22 ;check to see if it's '"' EA26 BEQ &EA2A ;if so EA2A (carry set) EA28 DEY ;decrement Y EA29 CLC ;clear carry EA2A ROR &E4 ;move bit 7 to bit 6 and put carry in bit 7 EA2C CMP #&0D ;check to see if it's CR to set Z EA2E RTS ;and return ************************************************************************* * GSREAD string read routine * * F2/3 points to string offset by Y * * * ************************************************************************* ; EA2F LDA #&00 ;A=0 EA31 STA &E5 ;store A EA33 LDA (&F2),Y ;read first character EA35 CMP #&0D ;is it CR EA37 BNE &EA3F ;if not goto EA3F EA39 BIT &E4 ;if bit 7=1 no 2nd '"' found EA3B BMI &EA8F ;goto EA8F - error 'Bad string' EA3D BPL &EA5A ;if not EA5A EA3F CMP #&20 ;is it a control character? EA41 BCC &EA8F ;if so, go to EA8F - error 'Bad string' EA43 BNE &EA4B ;if it's not a space EA4B EA45 BIT &E4 ;is bit 7 of &E4 =1 EA47 BMI &EA89 ;if so goto EA89 EA49 BVC &EA5A ;if bit 6 = 0 EA5A EA4B CMP #&22 ;is it '"' EA4D BNE &EA5F ;if not EA5F EA4F BIT &E4 ;if so and Bit 7 of &E4 =0 (no previous ") EA51 BPL &EA89 ;then EA89 EA53 INY ;else point at next character EA54 LDA (&F2),Y ;get it EA56 CMP #&22 ;is it '"' EA58 BEQ &EA89 ;if so then EA89 EA5A JSR &E03A ;skip spaces and read a byte from text EA5D SEC ;and return with carry set EA5E RTS ;and (&F2),Y=>any following text ; EA5F CMP #&7C ;is it '|' EA61 BNE &EA89 ;if not EA89 EA63 INY ;if so increase Y to point to next character EA64 LDA (&F2),Y ;get it EA66 CMP #&7C ;and compare it with '|' again EA68 BEQ &EA89 ;if its '|' then EA89 EA6A CMP #&22 ;else is it '"' EA6C BEQ &EA89 ;if so then EA89 EA6E CMP #&21 ;is it ! EA70 BNE &EA77 ;if not then EA77 EA72 INY ;increment Y again EA73 LDA #&80 ;set bit 7 EA75 BNE &EA31 ;loop back to EA31 to set bit 7 in next CHR EA77 CMP #&20 ;is it a space EA79 BCC &EA8F ;if less than EA8F Bad String Error EA7B CMP #&3F ;is it '?' EA7D BEQ &EA87 ;if so EA87 EA7F JSR &EABF ;else modify code as if CTRL had been pressed EA82 BIT &D9B7 ;if bit 6 set EA85 BVS &EA8A ;then EA8A EA87 LDA #&7F ;else set bits 0 to 6 in A EA89 CLV ;clear V EA8A INY ;increment Y EA8B ORA &E5 ;add in any bit 7 from |! prefix EA8D CLC ;clear carry EA8E RTS ;Return ; EA8F BRK ; EA90 DB &FD ;error number EA93 DB 'Bad String' ; message EA9B BRK ; ************ Modify code as if SHIFT pressed ***************************** EA9C CMP #&30 ;if A='0' skip routine EA9E BEQ &EABE ; EAA0 CMP #&40 ;if A='@' skip routine EAA2 BEQ &EABE ; EAA4 BCC &EAB8 ;if A<'@' then EAB8 EAA6 CMP #&7F ;else is it DELETE EAA8 BEQ &EABE ;if so skip routine EAAA BCS &EABC ;if greater than &7F then toggle bit 4 EAAC EOR #&30 ;reverse bits 4 and 5 EAAE CMP #&6F ;is it &6F (previously ' _' (&5F)) EAB0 BEQ &EAB6 ;goto EAB6 EAB2 CMP #&50 ;is it &50 (previously '`' (&60)) EAB4 BNE &EAB8 ;if not EAB8 EAB6 EOR #&1F ;else continue to convert ` _ EAB8 CMP #&21 ;compare &21 '!' EABA BCC &EABE ;if less than return EABC EOR #&10 ;else finish conversion by toggling bit 4 EABE RTS ;exit ; ;ASCII codes &00 &20 no change ;21-3F have bit 4 reverses (31-3F) ;41-5E A-Z have bit 5 reversed a-z ;5F & 60 are reversed ;61-7E bit 5 reversed a-z becomes A-Z ;DELETE unchanged ;&80+ has bit 4 changed ************** Implement CTRL codes ************************************* EABF CMP #&7F ;is it DEL EAC1 BEQ &EAD1 ;if so ignore routine EAC3 BCS &EAAC ;if greater than &7F go to EAAC EAC5 CMP #&60 ;if A<>'`' EAC7 BNE &EACB ;goto EACB EAC9 LDA #&5F ;if A=&60, A=&5F EACB CMP #&40 ;if A<&40 EACD BCC &EAD1 ;goto EAD1 and return unchanged EACF AND #&1F ;else zero bits 5 to 7 EAD1 RTS ;return ; EAD2 DB '/!BOOT',&0D