Jump to content
IGNORED

PRANTIC


ClausB

Recommended Posts

When I could finally afford an Epson RX-80, around 1983, I wrote an Atari screen dump utility that could print most any graphics mode, even mixed, by emulating ANTIC and GTIA. It used OS shadow registers to trace the display list, read pixel data, interpret them according to the ANTIC mode, color them (luminance only) using the shadowed color registers, and fill the printer's graphics buffer with dots in various dither patterns. It worked pretty well, even in GTIA modes, though it did not do PM graphics (since those registers are not shadowed) nor DLIs.

 

I wrote the proof of concept in BASIC A+, leaving out some features like GTIA modes and character extender mode. Once the overall logic worked, I recoded it in assembly, putting those features in. Later I modified it for Atari LOGO and included PM graphics support for the turtle, because LOGO provided those shadows.

 

In 1985 I interviewed for a job as a C programmer, so I added comments to the assembly code, and wrote another simplified version in Action!, the closest thing I had to C. I printed out all three code versions, as well as some sample screen dumps. They helped me get the job, and my first task there was to write a CGA screen dumper in Intel assembly for a color Epson dot-matrix printer!

 

I still have those printouts, but have not found the disk files. Maybe I'll scan and post some. I did find earlier disk versions, uncommented and maybe buggy. They are here:

PRANTIC.zip

 

Here's an early BASIC A+ version (also in above .ZIP):

200 OPEN #3,8,0,"P:"
210 BYTEMAP=2000:PIXEL=3000
220 CLOCKS=0:DIM COL(4)
230 DIM MASK(4):FOR I=1 TO 4:READ MASK(I):NEXT I
240 DATA 192,240,252,255
250 DIM DOT(7,5):FOR COL=0 TO 7:FOR LL=0 TO 5
260     READ J:DOT(COL,LL)=85*J
270     NEXT LL:NEXT COL
280 DATA 3,3,3,3,3,3,3,1,3,3,2,3,1,3,2,1,3,2,1,2,1,2,1,2
290 DATA 0,1,2,0,1,2,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0
1000 WIDTH=PEEK(559)&3
1001 POKE 559,0
1010 IF WIDTH=1 THEN WIDTH=128
1020 IF WIDTH=2 THEN WIDTH=160
1030 IF WIDTH=3 THEN WIDTH=192
1040 DIM PFCOL(4):FOR I=0 TO 4:PFCOL(I)=PEEK(708+I)&14/2:NEXT I
1050 DIM CLOKS(7):FOR I=0 TO 7:READ CLOKS(I):NEXT I
1060 DATA 4,2,2,1,1,1,1,.5
1070 DIM DBYTS(7):FOR I=0 TO 7:READ J:DBYTS(I)=J/8:NEXT I
1080 DATA 2,1,2,1,1,2,2,1
1082 DIM SLINS(7):FOR I=0 TO 7:READ SLINS(I):NEXT I
1084 DATA 8,4,4,2,1,2,1,1
1090 DLLC=DPEEK(560):CHRSET=PEEK(756)*256:DONE=0
1100 WHILE  NOT DONE
1110   INST=PEEK(DLLC)&127:DLLC=DLLC+1
1120   MODE=INST&15:INST=INT(INST/16)
1130   IF MODE=1:REM JUMP INSTRUCTION
1140     DLLC=DPEEK(DLLC)
1150     SLINS=1:CLOKS=WIDTH:COL=PFCOL(4):GOSUB PIXEL
1160     IF INST&4 THEN DONE=1
1170     ELSE 
1190     IF MODE=0:REM BLANK LINES
1200       SLINS=INST+1:CLOKS=WIDTH:COL=PFCOL(4):GOSUB PIXEL
1210       ELSE 
1215       IF INST&4 THEN DDLC=DPEEK(DLLC):DLLC=DLLC+2
1220       IF MODE&8:REM BIT-MAPPED MODES
1230         BMODE=MODE&7
1235         CLOKS=CLOKS(BMODE):SLINS=SLINS(BMODE)
1240         FOR I=0 TO 4:COL(I)=PFCOL(I):NEXT I
1250         FOR I=0 TO WIDTH/CLOKS(BMODE)*DBYTS(BMODE)-1
1260           BYTE=PEEK(DDLC+I):GOSUB BYTEMAP
1270           NEXT I:DDLC=DDLC+I
1280         ELSE :REM CHARACTER MODES
1290         BMODE=10-MODE:IF BMODE=8 THEN BMODE=7
1295         CLOKS=CLOKS(BMODE):SLINS=SLINS(BMODE)
1300         FOR J=0 TO 7
1310           FOR I=0 TO WIDTH/CLOKS(BMODE)*DBYTS(BMODE)-1
1320             FOR K=0 TO 4:COL(K)=PFCOL(K):NEXT K
1330             NAME=PEEK(DDLC+I)
1340             IF MODE<6:REM 128 CHAR. SETS
1350               IF MODE<4:REM REVERSE VIDEO
1360                 IF NAME&128 THEN COL(1)=PFCOL(2):COL(2)=PFCOL(1)
1370                 ELSE 
1380                 IF NAME&128 THEN COL(2)=PFCOL(3)
1390                 ENDIF 
1400               ADDR=(NAME&127)*8+J+CHRSET&64512
1410               ELSE 
1420               COL(0)=PFCOL(INT(NAME/64))
1430               ADDR=(NAME&63)*8+J+CHRSET&65024
1440               ENDIF 
1450             BYTE=PEEK(ADDR):GOSUB BYTEMAP
1460             NEXT I
1470           NEXT J
1480         DDLC=DDLC+I
1490         ENDIF 
1500       ENDIF 
1510     ENDIF 
1520   ENDWHILE 
1530 CLOSE #3
1535 POKE 559,34
1540 END 
2000 MASK=256*(16*DBYTS(BMODE)-1)
2010 FOR K=1 TO 1/DBYTS(BMODE)
2020   BYTE=BYTE*16*DBYTS(BMODE)=BYTE&MASK/256
2030   IF BMODE=7 THEN P=( NOT P)+2
2040   IF P=0 THEN P=5
2050   COL=COL(P-1):GOSUB PIXEL
2060   NEXT K
2070 RETURN 
3000 IF SLINS>4 THEN RETURN 
3005 IF WIDTH<>160 THEN RETURN 
3010 IF CLOCKS=0:REM START NEW LINE
3020   ? #3;"..A";CHR$(2*SLINS);".L@.";
3030   ENDIF 
3040 CLOCKS=CLOCKS+CLOKS:IF CLOCKS=WIDTH THEN CLOCKS=0
3050 FOR L=0 TO 6*CLOKS-1:LL=L-6*INT(L/6)
3060   PUT #3,DOT(COL,LL)&MASK(SLINS)
3070   NEXT L
3080 RETURN 

  • Like 16
Link to comment
Share on other sites

  • 3 months later...
  • 2 years later...
  • 1 year later...
  • 5 months later...

I'm comparing the printed, commented listing with the RPRANTIC.SRC.txt file above. The printed version used 480 printer dots per line, not ideal for Atari's 320 pixels. The SRC file uses 640 dots, and is likely the version which made the image printouts above. I'm in the process of typing the comments into the SRC file and verifying the code. I'll post it when finished.

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...