WRX1K V1.0 1996 - HIRES ON A 1K ZX81 wilf rigter (rigter@cafe.net) This article contains all information needed to demonstrate WRX true bit mapped high resolution graphics on a 1K/2K Sinclair ZX81. The full size program WRX16 generates a 256x192 pixel array while the WRX1K demo generates a 64x48 pixel array in the center of the screen. The small scale demo runs on an unmodified 1K/2K ZX81/TS1000 and is small enough to type in by hand. The small hires screen has another interesting side effect: it runs SLOW mode programs almost 4X faster than the Sinclair SLOW video mode while providing a continuous display. I would like to acknowledge the wonderful work of Dr. Carlos Delhez for creating XTender and Jack Raats for the PC tools to transfer XTender files to ASCII. INTRODUCTION WRX1K and it's big brother WRX16 use the same algorithm of addressing the hires screen memory with the I and R registers. Both require SRAM for the hires screen and this means that 16K-64K DRAM packs are not suitable. While a few people may have installed 8K or 32K SRAM chips in their ZX81, everyone has 1K or 2K installed. With the 1K memory as the lowest common denominator, I modified the WRX16 program to run on this minimal platform. I must confess to being a minimalist at heart and the challenge of packing performance into a small package is a little like writing code for a controller chip. I made the inevitable speed/size tradeoffs, experienced the occasional flash of insight and used a large trash can to write this program. The resulting code is short (210 bytes) and relatively easy to type in, even from a ZX81 keyboard. This is important here since there is (still) no standard way to transfer programs from a PC to a ZX81. The WRX1K program has some special features to operate with only 1K memory. When starting the hires mode, it dynamically creates a 384 byte space above RAMTOP for the hires screen but reclaims this space when returning to normal Sinclair display. This is required for users to be able to list and edit the BASIC program lines on a 1K machine. While I could spend time explaining how it all works, I suggest reading the annotated source code and send me an email if you like more information. WRX1K.ZIP which includes the binary C and XTENDER compatable P files, will be available at the NVG site. This article includes the following listings: LOADER.BAS LOADER.HEX WRX1K1.HEX WRX1K1.BAS LOADER.SRC WRX1K1.SRC INSTALLING WRX1K1.SRC WITH ZXAS ZXAS is the ARTIC assembler used to write this program and may be used on a ZX81 or on a PC using XTender, the shareware ZX81 emulator by Dr. Carlos Delhez. Using the ZX81, you can type in the source listing WRX1K1.SRC (;comments are optional) and assemble the required object code in line 1 REM. In order to use ZXAS you must have a 16K+ rampack installed. After assembling the ML code and entering the WRX1K1.BAS listing, you must lower RAMTOP with POKE 16389,68 and SAVE to tape. Finally remove the rampack, LOAD the saved program into the 1K/2K ZX81 and RUN. INSTALLING WRX1K1.HEX WITH HEX LOADER In order to load the WRX1K1.HEX FILE, type in the BASIC program LOADER.BAS Since the ML code is stored in a large REM line this is created first by entering a short 16 hex byte program called LOADER.HEX which will expand the 1 REM 0123456789ABCDEF line by 256 bytes. USING THE HEX LOADER The HEX LOADER accepts the following commands "Q"=QUIT, "N"=NEXT LINE, "P"=PREVIOUS. Hex code is entered 16 bytes at a time in one line of 32 hex values WITHOUT spaces. The HEX listing includes spaces between each two digit hex value for clarity and line numbers for reference only . Compare the typed in hex data in the command line with the listing before pressing the N/L key. The HEX data is checked for 32 character length. After entering the LOADER.HEX line, press "Q" to quit the loader. SAVING to tape is optional at this point since this format may be used as the starting point for entering your own ML programs in hex format. Next enter RAND USR 16516. This executes the LOADER.HEX code just entered and expands the existing 1 REM line by adding 256 new spaces. Don't worry if the 1REM line appears to be empty, this is caused by the first two characters chr$118 which make the contents of 1 REM invisible. To be able to see the rest of the BASIC listing POKE 16419,10 and LIST 10. Next restart the loader with RUN and enter the 14 lines of 16 hex values each line ending with a N/L (enter). Please double check the hex data before pressing the enter key. After the last hex data line is entered erase the LOADER.BAS lines (but not the 1 REM line). SAVE again and then type in the WRX1K.BAS program. Finally SAVE this program to tape and start the WRX1K demo with RUN. STARTING WRX1K RUN starts the WRX1K hires mode with RAND USR 16516, which lowers RAMTOP (and changes Stack Pointer without NEW), and starts the hires video mode. RAND USR 16709 clears the hires display file and RAND USR 16696 selects a white or black background. The BASIC program uses Marvin Minsky's circle plotting algorithm to calculate the coordinates for a series of concentric circles. This algorithm is faster than the COS/SIN function. The X and Y coordinates are poked into variables 16507/16508 and the plot bit is set in variable 16417. The program loops endlessly plotting white on black and then black on white. The BREAK key returns to Sinclair video, interrupts the program and automatically reclaims the hires screen memory. You can list the basic with POKE 16419,5 and LIST 5. On a 1K ZX81 the basic listing may be short because of the limited memory. Use LIST with higher line numbers to view the remainder of the program. WRX1K VARIABLES WRX1K uses several System Variable (SYSVAR) bytes to transfer data to the machine language program: POKE 16507,X - the X coordinate for plotting pixels (0-63) POKE 16508,Y - the Y coordinate for plotting pixels (0-47) POKE 16417,Z - the plot/unplot flag (0=unplot 1=plot) WRX1K UTILITIES The entry points for the ML program are : RAND USR 16516 - START the hires mode RAND USR 16648 - HPLOT or unplot pixel at x,y (uses SYSVAR 16417,16507/8) RAND USR 16693 - INVERT hires screen (plot black on white or white on black) RAND USR 16709 - CLEAR hires screen RAND USR 16723 - USER routine (60 bytes free) TS1000 (2K) USERS The 2K memory in a TS1000 permits the demo program to be expanded in several ways ie. 1. Multiple screens of 64x48 2. Larger hires screen of 128x96 2. No need to reclaim screen memory 3. Lower case and special character pattern tables 4. bigger BASIC and ML programs. 5. Line and circle plotting utilities. I will post WRX2K if there is interest (or you may prefer to "roll" your own version). FEEDBACK The information in this package is enough to get started. A companion file WRX1K11.ZIP will be posted on the NVG ftp site. If you have any problems, questions, or if you have any neat demo source code post them on comp.sys.sinclair (no binaries please) or contact me via email at: rigter@cafe.net enjoy wilf ---------------------------------------------------- START OF LISTINGS ----------------- LOADER.BAS ---------- 1 REM 0123456789ABCDEF 70 PRINT " HEX LOADER BY WILF RIGTER" 80 LET L=NOT PI 90 LET A=VAL "16514" 100 PRINT AT PI,NOT PI;"Q=STOP,N=NEXT,P=PREVIOUS LINE ";CHR$ (L+28) 110 INPUT A$ 120 IF A$="N" THEN GOTO VAL "200" 130 IF A$="P" THEN GOTO VAL "300" 140 IF A$="Q" THEN STOP 150 IF LEN A$<>VAL "32" THEN GOTO VAL "100" 160 FOR N=0 TO 31 STEP 2 170 POKE A+N/2,16*CODE A$(N+1)+CODE A$(N+2)-476 180 NEXT N 200 LET A=A+VAL "16" 210 LET L=L+PI/PI 220 IF LNOT PI THEN GOTO VAL "100" 330 GOTO VAL "80" LOADER.HEX - STARTS AT 16514 (4082$) ---------------------------------------- LINE 0 7676CD230F01000121804034C39E0900 WRX1K1.HEX - STARTS AT 16514 (4082$) ---------------------------------------- LINE 0 7676DD21BF40018001CDC50E2A0440C5 LINE 1 D13FED52D3FD2204402B363E2BF92B2B LINE 2 220240D3FEC37606E3E3E3E3ED4F0000 LINE 3 0000000000004040404040DDE9060410 LINE 4 FE2A04400630DD21CE40180811080019 LINE 5 05CADD407CED477DC3AAC0DD21E6403E LINE 6 98C3A102CD2002CD460F3009DD21BF40 LINE 7 3E98C3A1023E1EED472A044011800119 LINE 8 DD218102188E2A7B407DE6074704AF37 LINE 9 1F10FD4F7D1717E6E06F3E2F94D867AF LINE A 2929296C8F67ED5B0440197EB1FDCB21 LINE B 462001A977C9060821B0407EEE807723 LINE C 10F9C92A0440AF77545D13017F01EDB0 LINE D C9000000000000000000000000000000 LINE E 00000000000000000000000000000000 LINE F 00000000000000000000000000000000 WRX1K1.BAS - DEMO PROGRAM PLOTS CIRCLES 1 REM line created by LOADER or ZXAS 5 REM WRX1K1.BAS 10 RAND USR VAL "16516" 20 RAND USR VAL "16709" 30 RAND USR VAL "16696" 40 POKE VAL "16417",PI/PI 50 LET P=VAL "16648" 60 LET X1=VAL "16507 70 LET Y1=X1+PI/PI 80 LET T=VAL "24" 90 LET S=VAL "32" 100 FOR R=PI/PI TO VAL "24" STEP VAL "4" 110 LET X=R 120 LET Y=PI-PI 130 FOR N=1 TO 3.2*R 140 LET X=X-Y/R 150 LET Y=Y+X/R 160 POKE X1,S+X 170 POKE Y1,T+Y 180 RAND USR P 190 POKE X1,S-X 200 POKE Y1,T-Y 210 RAND USR P 220 NEXT N 230 NEXT R 240 GOTO 20 LOADER.SRC CALL 0F23 ;SET FAST MODE LD BC,0100 ;256 SPACES LD HL,4080 ;MSB OF LINE LENGTH INC (HL) ;ADD 256 BYTES JP 099E ;MAKE ROOM AND EXIT WRX1K1.SRC ;************************ ;WRX1K1-1996 WILF RIGTER* ;CREATES A 64X48 HIRES * ;SCREEN ON A 1K SINCLAIR* ;INCLUDES INITIALIZATION* ;CLEAR,INVERT SCREEN AND* ;PLOT/UNPLOT ROUTINES * ;CODE LENGTH = 210 BYTES* ;HFILE LENGTH= 384 BYTES* ;************************ ;A SMALL SCALE DEMO OF ;WRX16 - TRUE BIT MAPPED ;256X192 HIRES GRAPHICS ;---------------------- ;THE MAIN HIRES ROUTINES START ;LOCATED AT 16516 ($4084) ;MAKE ROOM ABOVE RAMTOP ;AND START HIRES VIDEO ;---------------------- LD IX,HR ;HR VECTOR LD BC,180 ;64X48 BITS CALL EC5 ;TEST ROOM LD HL,(4004);LOWER RAMTOP PUSH BC POP DE CCF SBC HL,DE STACK OUT FD,A ;TURN OFF NMI LD (4004),HL;NEW RAMTOP DEC HL LD (HL),3E DEC HL LD SP,HL ;NEW SP DEC HL DEC HL LD (4002),HL;NEW ERROR SP OUT FE,A ;TURN ON NMI JP 676 ;NEXT LINE LBUF ;DUMMY DFILE LINE = ;1 LINE OF 64 PIXELS ;EXECUTED ABOVE 32K ;------------------- E3 E3 E3 E3;DELAY 76T LD R,A ;NOW LOAD R LBYTE 00 00 00 00;8 LBYTES WITH 00 00 00 00;8 PIXELS EACH 40 40 40 40;DELAY 20T 40 ;DELAY 4T JP (IX) ;RETURN TO HR HR ;THE 64X48 VIDEO ROUTINE ;NEVER CALL DIRECTLY:MUST ;INITIALIZE WITH "START" ;CHECKS BREAK KEY:IF DOWN ;JUMPS VIA STOP TO NORMAL ;SINCLAIR VIDEO ;OR ELSE LOOPS TO VSYNC ;----------------------- LD B,04 ;LOAD DELAY HR0 DJNZ HR0 ;DELAY 56T LD HL,(4004);TOP OF HFILE LD B,30 ;48 LINES LD IX,HR1 ;RETURN VECTOR JR HR2 ;SKIP HR1 HR1 LD DE,08 ;8*8 BITS ADD HL,DE ;NEXT LINE DEC B JP Z HR3 ;LAST LINE? HR2 LD A,H ;REFRESH LD I,A ;ADDRESS IN LD A,L ;REG I AND R JP C0AA ;JUMP TO LBUF HR3 LD IX,HR4 ;VSYNC VECTOR LD A,98 ;104 BLANK JP 2A1 ;POP MAIN REG HR4 CALL 220 ;DUMMY PUSH CALL F46 ;BREAK KEY JR NC STOP;TO EXIT HR LD IX,HR ;HR VECTOR LD A,98 ;BLANK LINES JP 2A1 ;POP MAIN REG STOP ;BREAK EXIT TO LD A,1E ;SINCLAIR VIDEO LD I,A ;ROM PATTERNS LD HL,(4004) ;RAMTOP + 1 LD DE,180 ;HFILE LENGTH ADD HL,DE ;RESTORE RAMTOP LD IX,0281;SINCLAIR VIDEO JR STACK ; ;------------------------ ;START OF THE HIRES ;SCREEN UTILITIES ;------------------ PLOT ;LOCATED AT 16648 (4108$) ;PLOT ROUTINE CALCULATES ;BYTE LOCATION AND BIT ;POSITION FROM THE X/Y ;COORDINATES. PLOT/UNPLOT ;FLAG IS BIT 0 OF (4021) ;IF BIT 0 = 1 THEN PLOT ;IF BIT 0 = 0 THEN UNPLOT ;----------------------- LD HL,(407B);L=X H=Y BIT LD A,L ;3 LSB OF X AND 7 ;BIT LOCATION LD B,A INC B XOR A SCF ;SET C FLAG BIT1 RRA ;SHIFT BIT DJNZ BIT1 LD C,A ;SAVE BIT BYTE LD A,L ;CALCULATE RLA ;OFFSET = RLA ;Y*8+X/8 AND E0 LD L,A ;START PLOT LD A,2F ;ORIGIN AT SUB H ;BOTTOM/LEFT RET C ;EXIT IF OUT LD H,A ;OF BOUNDS XOR A ;A=0 ADD HL,HL ;SHIFT INTO ADD HL,HL ADD HL,HL LD L,H ;LSB = 0 TO ADC A,A ;GET 9TH BIT LD H,A ;MSB = 0 TO LD DE,(4004);DE=HFILE ADD HL,DE ;BYTE ADDRESS LD A,(HL) ;FETCH BYTE OR C ;AND SET BIT BIT 0,(IY+33);TEST FOR UN JR NZ LDPLT ;SKIP UNPLOT XOR C ;RESET BIT LDPLT LD (HL),A ;LD HFILE RET INVERT ;LOCATED AT 16696 (4138$) ;INVERTS SCREEN WITH ;8TH BIT IN LBUF ;---------------------- LD B,8 ;8 LBYTES LD HL,LBYTE;FIRST INV1 LD A,(HL) ;INVERT 8TH XOR 80 ;BIT LD (HL),A INC HL ;NEXT LBYTE DJNZ INV1 ;REPEAT 8X RET CLEAR ;LOCATED AT 16709 (4145$) ;LOADS HFILE WITH ZEROES ;----------------------- LD HL,(4004); HFILE XOR A ;ZERO LD (HL),A ;FIRST LD D,H LD E,L INC DE ;NEXT LD BC,017F ;384 BYTES LDIR ;COPY OVER RET USER ;LOCATED AT 16723 (4153$) ;START OF USER CODE BLOCK ;LAST BYTE 16788 (4194$) ;----------------------- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 RET ------- END OF LISTINGS -------