Modified ZX Spectrum ROM, with lots of bug fixes and extensions by Henk de Groot [groot@idca.tds.philips.nl]. List of changes follows: o Bug fixes as mentioned in "The complete Spectrum Rom Disassembly" by Dr Ian Logan and Dr Frank O'Hara. o Support for EPSON printer via an Z80-PIO chip and Centronics connection. o Monitor support: start up with black screen and white characters. o Lightpen support: Lightpen routine for DK'Tronics lightpen is built in. 48K ROM modified by Henk de Groot (Documentation) illegal modification without Amstrad's permission http://www.srcf.ucam.org/~pak21/spectrum/roms/ comp.sys.sinclair > The GROOT.ROM list of changes. Henk de Groot Jan 31 1994, 6:39 pm It seems that some people get confused about the different roms for the spectrum. Here is what I have done to the original ZX-Spectrum rom. Featues: o Bug fixes as mentioned in "The complete Spectrum Rom Disassembly" by Dr Ian Logan and Dr Frank O'Hara. o Support for EPSON printer via an Z80-PIO chip and centronics connection. o Monitor support: start up with black screen with white characters. o Lightpen support: Lightpen routine for DK'Tronics lightpen build in. Here is the assembly code of the changes. The whole thing can be found on archive sites under the name "newrom.???" where ??? is .exe, .zip, .arj or whatever. ------------------------- BEGIN OF CHANGE LIST --------------------------------- This file relects the changes to the original ZX Spectrum ROM. The labels and page numbers refer to the book "The Complete Spectrum Rom Disassembly" by Dr Ian Logan & Dr Frank O'Hara, published by Melbourne House Publishers, ISBN 0 86161 116 0. Jump to initialize the Z80-PIO chip --------------------------------------------------------------------------- ----- THE 'START' The maskable interrupt is disabled and the DE register pair set to hold the 'top of possible RAM' 0000 F3 START DI Disable the 'keyboard interrupt' 0001 AF XOR A +00 for 'start' (but +FF for 'NEW'). 0002 11FFFF LD DE,FFFF Top of possible RAM. 0005 C3AA04 JP 04AA,PIO-INIT Init Z80-PIO --------------------------------------------------------------------------- ----- New NMI routine: Quick start basic without memory erase! --------------------------------------------------------------------------- ----- 0066 F3 RESET DI Disable the 'keyboard interrupt' 0067 AF XOR A Make the border black in 0068 D3FE OUT (FE),A color. 006A 3E3F LD A,3F Set I register to hold 006C ED47 LD I,A the value of +3F. 006E 2AB25C LD HL,(RAMTOP) Preserve current RAMTOP 0071 C31912 JP 1219,RAM-SET Act as if RAM is tested --------------------------------------------------------------------------- ----- Initialize Z80-PIO. This is a new routine. This routine is stored at a spot where useless ZX81 code was left, called "THE 'PROGRAM NAME' SUBROUTINE (ZX81)" --------------------------------------------------------------------------- ----- Init Z80-PIO Port DB = Control port "A" Port FB = Control port "B" Port 9B = Data port "A" Port BB = Data port "B" 04AA 3E3F PIO-INIT LD A,3F Program Z80-PIO port A to 04AC D3DB OUT (DB),A be all "outputs". 04AE 3EFF LD A,FF Port A will be connected to the 04B0 D3FB OUT (FB),A Centronix data lines. 04B2 3E80 LD A,80 Program port B to "inputs" 04B4 D3FB OUT (FB),A Except bit 8 on port B 04B6 3E02 LD A,02 Bit 2 of port B will be the 04B8 D3BB OUT (BB),A "Stobe", initialize to "1" 04BA AF XOR A +00 for 'start' (but +FF for 'NEW'). 04BB C3CB11 JP 11CB,START/NEW Jump forward. --------------------------------------------------------------------------- ----- Printer support for EPSON type printer added. --------------------------------------------------------------------------- ----- 09F4 C32C39 PRINT-OUT JP 392C,PRINTER Call printer routine --------------------------------------------------------------------------- ----- Fix bug on page 33, LD A,+18 sould read LD A,+19 --------------------------------------------------------------------------- ----- 0A30 0E02 LD C,02 Set column value 0A32 3E19 LD A,19 Test against top line 0A34 B8 CP B Note: Bug fixed, was 18 --------------------------------------------------------------------------- ----- Fix bug on page 34, exit via PO-STORE --------------------------------------------------------------------------- ----- 0A4A F1 POP AF Fetch old value of P-FLAG 0A4B C32039 JP 3920,REP-PO-ST Jump to repair routine --------------------------------------------------------------------------- ----- Change for printer implementation --------------------------------------------------------------------------- ----- THE 'COPY-LINE' SUBROUTINE The subroutine is entered with HL register pair holding the base address of the thirtytwo bytes that form the pixel-line and the B register holding the pixel-line number. 0EF4 C36E38 COPY-LINE JP 386E,COPY-LN Copy printerbuffer to printer --------------------------------------------------------------------------- ----- Turn initial white screen into initial black. This is a lot better when using a monitor on the spectrum. --------------------------------------------------------------------------- ----- 11CB 47 START/NEW LD B,A Save the flag for later. 11CC 3E00 LD A,00 Makes the border black in 11CE D3FE OUT (FE),A colour (was white). --------------------------------------------------------------------------- ----- Turn initial white screen into initial black. This is a lot better when using a monitor on the spectrum. --------------------------------------------------------------------------- ----- 1265 3E07 LD A,07 Initialise the colour system 1267 328D5C LD (ATTR-P),A variables to : FLASH 0, 126A 328F5C LD (ATTR-T),A BRIGHT 0, PAPER 0,& INK 7 126D 32485C LD (BORDCR),A --------------------------------------------------------------------------- ----- New Copyright message: --------------------------------------------------------------------------- ----- Was: 1539 '(C) 1982 Sinclair Research Ltd' New: 1539 '(C) New Zx Spectrum ROM READY ' --------------------------------------------------------------------------- ----- Fix bug on page 177, -65536 bug --------------------------------------------------------------------------- ----- 3032 C3393A JP 3A39,FIX-177 Jump to fix for -65536 3035 23 NOFIX-177 INC HL Point to the next location 3036 72 LD (HL),D Store the high byte of the result. 3037 2B DEC HL Move the pointer back to 3038 2B DEC HL address the first byte of the 3039 2B DEC HL result. 303A D1 FIXED-177 POP DE Restore STKEND to DE. 303B C9 RET Finished. --------------------------------------------------------------------------- ----- Fix bug on page 185, Jump was to the wrong place --------------------------------------------------------------------------- ----- 31FF 28DA JR Z,31DB,DIV-34TH Was: jump to DIV-START --------------------------------------------------------------------------- ----- Fix bug on page 186, Code sould be skipped --------------------------------------------------------------------------- ----- 3221 FE91 CP 91 Compare e to 91 hex, 145 decimal. 3223 181A JR 323F,T-SMALL Jump always, omitting the code from 3225 to 323E always! --------------------------------------------------------------------------- ----- New COPY-LINE routine, copy to EPSON printer via Z80-PIO --------------------------------------------------------------------------- ----- 386E DDE5 COPY-LN PUSH IX Use IX as an index 3870 3A815C LD A,(PR-CC) Get printer column 3873 0605 COPY-MUL LD B,05 Multiply 2^5 (=32) times 3875 87 ADD A to calculate offset in the 3876 10FD DJNZ COPY-MUL printer buffer. 3878 1600 LD D,00 Transfer the offset to the 387A 5F LD E,A DE register pair 387B DD21005B LD IX,5B00 Load IX with printer buffer 387F 5F LD E,A Why again?? 3880 DD19 ADD IX,DE Add the offset to IX register 3882 0620 LD B,20 Fetch 32 bytes 3884 7E LD A,(HL) And store into the printer 3885 DD7700 LD (IX+00),A Buffer. 3888 23 INC HL Next byte to be printed 3889 DD23 INC IX Next byte in the printer buffer. 388B 10F7 DJNZ 3884 Until all 32 bytes are done. 388D 3A815C LD A,(PR-CC) Increment column number. 3890 3C INC A 3891 FE08 CP 08 Do we have 8 lines in the buffer 3893 2806 JR Z,COPY-PRT Yes, jump forward 3895 32815C LD (PR-CC),A Store the new column number 3898 DDE1 POP IX Restore IY register 389A C9 RET End of copy-ln routine. COPY-PRT Copy the contents of the printerbuffer at 5B00 hex to an EPSON like printer. 389B F5 COPY-PRT PUSH AF Don't distroy register A 389C 21005B LD HL,5B00 HL points to the printer buffer 389F 3E1B LD A,1B Send "1B 41 08" 38A1 CD0A39 CALL 390A,PRT-BYTE (set linefeet pitch to 38A4 3E41 LD A,41 8/72 inch) 38A6 CD0A39 CALL 390A 38A9 3E08 LD A,08 38AB CD0A39 CALL 390A,PRT-BYTE 38AE 3E1B LD A,1B Send "1B 4D" 38B0 CD0A39 CALL 390A,PRT-BYTE (Select Elite (12 cpi)) 38B3 3E4D LD A,4D 38B5 CD0A39 CALL 390A,PRT-BYTE 38B8 3E1B LD A,1B Send "1B 4B 00 01" 38BA CD0A39 CALL 390A,PRT-BYTE (Print standard density 38BD 3E4B LD A,4B graphics, 256 dots will 38BF CD0A39 CALL 390A,PRT-BYTE follow) 38C2 3E00 LD A,00 38C4 CD0A39 CALL 390A,PRT-BYTE 38C7 3E01 LD A,01 38C9 CD0A39 CALL 390A,PRT-BYTE Note: the pixels in the buffer are horizontally aligned, the printer head has the pixels verticaly aligned. We have to fetch one bit from the the 8 byte that are above eachother. 38CC 0620 LD B,20 Handle 32 bytes. 38CE 112000 LD DE,0020 Offset between succesive 38D1 C5 NXT-BYTE PUSH BC lines. 38D2 0608 LD B,08 There are 8 pixels in one byte 38D4 C5 NXT-PIXEL PUSH BC 38D5 E5 PUSH HL 38D6 0608 LD B,08 We print 8 pixels at the time 38D8 CB16 NXT-FETCH RL (HL) Get one bit from this byte 38DA 17 RLA Shift into register A 38DB 19 ADD HL,DE Handle next byte 38DC 10FA DJNZ 38D8,NXT-FETCH 38DE E1 POP HL 38DF C1 POP BC 38E0 CD0A39 CALL 390A,PRT-BYTE Print out the pixel image in A 38E3 10EF DJNZ 38D4,NXT-PIXEL Next pixel of this set of bytes 38E5 C1 POP BC 38E6 23 INC HL 38E7 10E8 DJNZ 38D1,NXT-BYTE Next group of 8 bytes 38E9 3E0D LD A,0D Send cariage return 38EB CD0A39 CALL 390A,PRT-BYTE 38EE 3E0A LD A,0A Send linefeet 38F0 CD0A39 CALL 390A,PRT-BYTE 38F3 3E1B LD A,1B Send "1B 32" 38F5 CD0A39 CALL 390A,PRT-BYTE (linefeed pitch 1/6 inch) 38F8 3E32 LD A,32 38FA CD0A39 CALL 390A,PRT-BYTE 38FD 3E12 LD A,12 Send DC2 to cancel Elite 38FF CD0A39 CALL 390A,PRT-BYTE 3902 AF XOR A Clear PR-CC. 3903 32815C LD (PR-CC),A 3906 F1 POP AF Restore register A 3907 DDE1 POP IX This one was left on the stack (this part was "called" by a jump instruction) 3909 C9 RET End of copy-ln routine. PRT-BYTE Send the contents of register A to the printer. The register contents will not be changed after the routine has been completed. 390A C5 PRT-BYTE PUSH BC Save all the register we need 390B F5 PUSH AF 390C AF XOR A Look if the printer is BUSY 390D DBBB PRT-BUSY IN A,(BB) Look at dataline 8 of Z80-PIO 390F 07 RLCA port B. 3910 38FA JR C,390C,PRT-BUSY Repeat if printer is busy 3912 F1 POP AF 3913 F5 PUSH AF Restore register A 3914 D39B OUT (9B),A Put A on Z80-PIO port A 3916 AF XOR A Make A clean 3917 D3BB OUT (BB),A Lower the STROBE signal, data 3919 3E02 LD A,02 line 2 of port B. Immediately 391B D3BB OUT (BB),A rais it again. The data is 391D F1 POP AF clocked in into the printer 391E C1 POP BC with the STROBE signal. 391F C9 RET Restore registers and return --------------------------------------------------------------------------- ----- Fix bug on page 34, exit via PO store. --------------------------------------------------------------------------- ----- 3920 32915C REP-PO-ST LD (P-FLAG),A This instruction was overwritten 3923 C3DC0A JP 0ADC,PO-STORE Jump to PO-STORE (the Fix) --------------------------------------------------------------------------- ----- Junk, I'm sorry! --------------------------------------------------------------------------- ----- 3926 2A805C LD HL,(5C80) 3929 265B LD H,5B 392B C9 RET --------------------------------------------------------------------------- ----- Support for serial printer, called from the print routine at 09F4 in the ROM --------------------------------------------------------------------------- ----- 392C CD030B PRINTER CALL 0B03,PO-FETCH The current print position 392F FDCB014E BIT 1,(FLAGS) Test if printer, if not continue 3933 CAF709 JP Z,09F7 the original routine PRINT-OUT 3936 CA283A JP Z,3A28,PR-REINIT Looks like a NOP to me... 3939 FE06 CP 06 Test for PRINT comma (,) 393B CAC839 JP Z,39C8,PR-COMMA Handle a comma "TAB" 393E FE0D CP 0D Test for cariage return 3940 2833 JR Z,3975,PR-CR Handle cariage return 3942 FE16 CP 16 Test for AT control character 3944 2854 JR Z,399A,PR-AT Handle AT control 3946 FE17 CP 17 Test for TAB control character 3948 284A JR Z,3994,PR-TAB Handle TAB control 394A FE1C CP 1C Non sinclair extension 394C 2818 JR Z,3966,PR-TRANS Transparent writes! 394E FE20 CP 20 Test for other controlls 3950 DA0A39 JP C,390A,PRT-BYTE Other controls direct to printer 3953 FE80 CP 80 Test for normal ASCII set 3955 382F JR C,3986,PR-NORM Handle normal characters 3957 FE90 CP 90 Test for block graphics 3959 DA0E3A JP C,3A0E,PR-GRAPH Handle block grapics 395C D6A5 SUB A5 Re-base on tokens 395E D2100C JP NC,0C10,PO-TOKENS Expand token 3961 C615 ADD 15 Re-base on UDG's 3963 C3F939 JP 39F9,PR-UDG Handle UDG's PR-TRANS Transparent writes. The character following the transparent write control will be send to the printer unmodified, This allows printout of non sinclair characters, it creates an access path to all the printers capabilities without limitation! 3966 116C39 PR-TRANS LD DE,396C Point to PR-TRANS2 3969 C3800A JP 0A80,PO-CHANGE Change output routine entry 396C CD0A39 PR-TRANS2 CALL 390A,PRT-BYTE Send byte unmodified 396F 11F409 LD DE,09F4 Point to PRINT-OUT 3972 C3800A JP 0A80,PO-CHANGE Change output routine entry PR-CR Send a linefeet and cariage return to the printer. 3975 FD364500 PR-CR LD (PR-CC),00 Reset the column counter 3979 CD283A CALL 3A28,PR-REINIT Re-initialize the Z80-PIO 397C 3E0A LD A,0A Send a linefeet 397E CD0A39 CALL 390A,PRT-BYTE 3981 3E0D LD A,0D Send a cariage return 3983 C30A39 JP 390A,PRT-BYTE Send and exit via PRT-BYTE PR-NORM Printout a normal character. 3986 FE60 PR-NORM CP 60 Check if it's a pound character 3988 2865 JR Z,39EF,PR-POUND It is, special action 398A FE7F CP 7F Check if it's a copyright symbol 398C 2866 JR Z,39F4,PR-CRIGHT It is, special action 398E FD3445 INC (PR-CC) Advancd column pointer 3991 C30A39 JP 390A,PRT-BYTE Send byte and exit. PR-TAB and PR-AT The TAB and AT control characters are followed by one or two column and row characters (for AT only). We bend the input stream temporary to another routine to pick the characters up. Not that he row information of the AT control is send to the bitbucket (i.e. is skipped). 3994 11A639 PR-TAB LD DE,39A6 Point to PR-TAB2 3997 C3800A JP 0A80,PO-CHANGE Change output routine entry 399A 11A039 PR-AT LD DE,39A0 Point to PR-AT2 399D C3800A JP 0A80,PO-CHANGE Change output routine entry 39A0 11B439 PR-AT2 LD DE,39B4 Point to PR-AT3 39A3 C3800A JP 0A80,PO-CHANGE Change output routine entry 39A6 11AE39 PR-TAB2 LD DE,39AE Point to PR-TAB3 39A9 CD800A CALL 0A80,PO-CHANGE Change output routine entry 39AC 180C JR 39BA,PR-AT-TAB Now execute TAB instruction 39AE 11F409 PR-TAB3 LD DE,09F4 Point to PRINT-OUT 39B1 C3800A JP 0A80,PO-CHANGE Change output routine entry 39B4 11F409 PR-AT3 LD DE,09F4 Point to PRINT-OUT 39B7 CD800A CALL 0A80,PO-CHANGE Change output routine entry 39BA FD9645 PR-AT-TAB SUB (PR-CC) Test against current position 39BD D8 RET C We already passed the position 39BE C8 RET Z We already are at the position 39BF 47 LD B,A Nr of spaces to print in B 39C0 3E20 PR-SPACE LD A,20 load A with space character 39C2 CD8639 CALL 3986,PR-NORM Printout the space 39C5 10F9 DJNZ 39C0 Repeat until B holds 0 39C7 C9 RET Finished. PR-COMMA This control (use in basic to make colums) advances the output to the nearest column which is a multiple of 16. 39C8 FD7E45 PR-COMMA LD A,(PR-CC) Fetch current position 39CB 47 LD B,A Save in register B 39CC E6F0 AND F0 Calculate A MOD 16 39CE C610 ADD 10 Add 16 (tabs are each 16th pos) 39D0 90 SUB B Calculate nr of spaces to 39D1 47 LD B,A be printed 39D2 18EC JR 39C0,PR-SPACE Print spaces. 39D4 C9 RET Junk PR-8BYTES Print character or graphic image of 8x8 pixel format. The image is stored in MEMBOT. The printer must have been set up to receive the 8 image bytes. 39D5 0608 PR-8BYTES LD B,08 We have 8 pixels 39D7 C5 PR-8NXTPI PUSH BC Save pixel counter 39D8 0608 LD B,08 We have 8 bytes to handle 39DA 21925C LD HL,MEMBOT Place where the bytes are 39DD AF XOR A Start with clean acumulator 39DE CB16 PR-8NXTBY RL (HL) Fetch a bit from current byte 39E0 CB17 RL A Shift bit into A 39E2 23 INC HL Next byte 39E3 10F9 DJNZ 39DE,PR-8NXTBY Until 8 Bytes are handled 39E5 CD0A39 CALL 390A,PRT-BYTE Print out the image 39E8 C1 POP BC Restore pixel counter 39E9 10EC DJNZ 39D7,PR-8NXTPI Loop until 8 pixels are read 39EB FD3445 INC (PR-CC) Increment coulumn pointer 39EE C9 RET Ready. PR-POUND Print out a pound character. A pound character is not available in an american ASCII set, it is however in a Spectrum. We have to compose the pound sign ourselfs. 39EF 21003F PR-POUND LD HL,3F00 HL points to pound sign. 39F2 1810 JR 3A04,PR-IMAGE Print character image addressed by HL. PR-CRIGHT Print out a copyright character. A copyright character is not available in an american ASCII set, it is however in a Spectrum. We have to compose the copyright sign ourselfs. 39F4 21F83F LD HL,3FF8 HL points to copyright. 39F7 1810 JR 3A04,PR-IMAGE Print character image addressed by HL. PR-UDG Print User defined characters. A holds the number of the UDG to be printer i.e. A=0 means print UDG "A" = character 144 (90 Hex). 39F9 ED5B7B5C PR-UDG LD DE,(UDG) Load DE with UDG base 39FD 6F LD L,A UDG number to HL 39FE 2600 LD H,00 3A00 29 ADD HL,HL Multiply by 8 3A01 29 ADD HL,HL 3A02 29 ADD HL,HL 3A03 19 ADD HL,DE Add UDG base to HL PR-IMAGE Print 8 byte image pointed to by HL to the printer by means of graphics. 3A04 11925C PR-IMAGE LD DE,MEMBOT Temporary storage space 3A07 010800 LD BC,0008 Copy all 8 bytes 3A0A EDB0 LDIR 3A0C 1804 JR 3A12,PR-MEMBOT Print this image and return. 3A0E 47 PR-GRAPH LD B,A Move the graphic code 3A0F CD380B CALL 0B38,PO-GR-1 Construct the graphic form. PR-MEMBOT Print 8 byte image stored in MEMBOT. 3A12 3E1B PR-MEMBOT LD A,1B Send "1B 4B 08 00" 3A14 CD0A39 CALL 390A,PRT-BYTE (Print standard density 3A17 3E4B LD A,4B graphics, 8 bytes will 3A19 CD0A39 CALL 390A,PRT-BYTE follow) 3A1C 3E08 LD A,08 3A1E CD0A39 CALL 390A,PRT-BYTE 3A21 3E00 LD A,00 3A23 CD0A39 CALL 390A,PRT-BYTE 3A26 18AD JR 39D5,PR-8BYTES Send the 8 graphic bytes PR-REINIT Initialize Z80-PIO. If a program distroyed the programming of the Z80-PIO this routine will fix it. This routine is called whenever a cariage return is send to the printer. 3A28 3E3F PR-REINIT LD A,3F 3A2A D3DB OUT (DB),A 3A2C 3EFF LD A,FF 3A2E D3FB OUT (FB),A 3A30 3E80 LD A,80 3A32 D3FB OUT (FB),A 3A34 3E02 LD A,02 3A36 D3BB OUT (BB),A 3A38 C9 RET --------------------------------------------------------------------------- ----- Fix bug on page 177, -65536 bug, Implementation partly based on page 230 The implementation of page 230 could be implemented because I want to continue the original ROM routine at the spot just after the patched in 'JP'instruction. --------------------------------------------------------------------------- ----- 3A39 F5 FIX-177 PUSH AF Save the sign byte in A. 3A3A 3C INC A Make any FF in A into 00. 3A3B B3 OR E Test all 3 bytes now for zero. 3A3C B2 OR D 3A3D 2014 JR NZ,3A53,ADD-STORE Jump if not -65536. 3A3F F1 POP AF Clear the stack. 3A40 E5 PUSH HL Don't change HL pointer! 3A41 3680 LD (HL),80 Enter 80 hex into second byte. 3A43 23 INC HL 3A44 3600 LD (HL),00 Enter 00 hex into third byte. 3A46 23 INC HL 3A47 3600 LD (HL),00 Enter 00 hex into fourth byte. 3A49 23 INC HL 3A4A 3600 LD (HL),00 Enter 00 hex into fifth byte. 3A4C E1 POP HL 3A4D 2B DEC HL 3A4E 3691 LD (HL),91 Enter 91 hex into first byte. 3A50 C33A30 JP 303A,FIXED-177 Jump to the POP DE instruction Just before the RET of the original routine. 3A53 F1 ADD-STORE POP AF The next instructions are left over because the 'JP' was patched over it 3A54 77 LD (HL),A Store it on the stack 3A55 23 INC HL 3A56 73 LD (HL),E 3A57 C33530 JP 3035,NOFIX-177 --------------------------------------------------------------------------- ----- Lightpen routine This routine is not called from other routines in the rom but its meant to be called from basic. The adress is 15555, so its easy to remember. The routine is meant for a DK'Tronics lightpen. I have such a pen, but no schematic diagram. --------------------------------------------------------------------------- ----- 3CC3 0E3F LIGHT-IN LD C,3F 3CC5 210000 LD HL,0000 Set line counter to 0 3CC8 11FB01 LD DE,01FB Timing loop counter init 3CCB 76 HALT Wait for interrupt 3CCC 1B LI-TIME1 DEC DE Decrement counter 3CCD 7A LD A,D Compare to 0 3CCE B3 OR E 3CCF 20FB JR NZ,3CCC,LI-TIME1 While not 0 loop back 3CD1 110001 LD DE,0100 Timeout timer 3CD4 3EFF LD A,FF For "CP D" below 3CD6 ED40 LI-AGAIN IN B,(C) Read lightpen input port. 3CD8 CB40 BIT 0,B Wait for signal from pen. 3CDA 2809 JR Z,3CE5,LI-FOUND If signal is found jump out 3CDC 060D LD B,0D Timing loop counter init 3CDE 10FE LI-TIME2 DJNZ 3CDE,LI-TIME2 Wait a little 3CE0 23 INC HL Increment Line counter 3CE1 1B DEC DE Decrement timeout counter 3CE2 BA CP D If D becomes FF time-out 3CE3 20F1 JR NZ,3CD6,LI-AGAIN 3CE5 3E00 LI-FOUND LD A,00 Compare against 00 3CE7 BC CP H Are we above the first line? 3CE8 20D9 JR NZ,3CC3,LIGHT-IN Light pen at wrong pos, redo 3CEA CB3D SRL L HL counts faster than there 3CEC CB3D SRL L are rows. Devide by 8 to 3CEE CB3D SRL L get a real line number. 3CF0 E5 PUSH HL Transfer line number to BC 3CF1 C1 POP BC The contents of BC will be the 3CF2 C9 RET Return value of the "USR" function --------------------------------------------------------------------------- ----- Change arrow-up character (on key 'H') to '^' which is more standard in ASCII sets. It's also used a lot in Pascal (Hisoft Pascal HP4TM16) which uses this character as a pointer. --------------------------------------------------------------------------- ----- 3EF2 DEFB 28 3EF3 DEFB 44 3EF4 DEFB 00 3EF5 DEFB 00 3EF6 DEFB 00 --------------------------------------------------------------------------- ----- -------------------------- END OF CHANGE LIST ---------------------------------- -- / / de Groot Dep: WGA | E-Mail: g...@idca.tds.philips.nl /---/ __ __ / Tel: +31 55 432104 | Corp: Digital Equipment Corporation / / (-_ / / /( Loc: V2-B03 | Site: Apeldoorn, The Netherlands