WRX1K V1.0 1996 - HIRES ON A 1K ZX81 - wilf rigter (updated 04/2005)

 

This article contains all information needed to demonstrate WRX true

bit mapped high resolution graphics on a barebones ZX81 or TS1000.

 

The WRX1K program is a demo that will work with just 1K of RAM.

It is a scaled down version of WRX16, which generates a 256x192 pixel

array but that would require  6Kbytes for the hires video screen alone.

 

Unlike pseudo hires, in true hires any pixel on the screen can be directly

set or reset.

 

The WRX1K video driver and the demo Basic and M/C application program

and the display are all crammed into 1K of RAM space.

 

WRX1K video driver generates a smooth, non-flicker 64x48 pixel hires mini

display in the center of the screen which is actually the same resolution as

a screen plot generated by the ZX PLOT commands.

 

The WRX video driver replaces the main part of the ZX video routine. The

driver runs in the background and uses the equivalent of just six normal

lines of ZX video characters to generate the mini display.

 

This frees up a lot more CPU time for the demo Basic and M/C programs,

which run in the SLOW mode 4X faster than with the normal ZX video screen.

 

The whole demo program is small enough to type in by hand but a companion

zip file is available here WRX1K1.ZIP including a ready to run .p file.

 

A 16K demo version with the Hires file between 8-16K can be found here:

 

HRDEMO3.P

 

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 (unmodified) 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 had to make the inevitable speed/size tradeoffs and used a large trashcan 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 the

Normal Sinclair display. This is required for users to be able to list and edit

the BASIC program lines on a 1K machine. Rather then explaining the details

here, I suggest reading the annotated source code and send me an email if you

like more information

 

 

For TS1000 users, the 2K RAM in a TS1000 permits the demo program

to be expanded in several ways :

 

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.

If you have any problems, questions, or if you have any

neat demo source code post them on www.ts1000.us or

contact me via email at: wrigter@dccnet.com

 

enjoy

 

wilf

 

--------------------------------------------------------------------------------------

 

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 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)

 

----------------------------------------------------

 

                       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 L<VAL "16" THEN GOTO VAL "100"

 300 LET A=A-VAL "16"

 310 LET L=L-PI/PI

 320 IF L>NOT 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 -------