frandsen@rimfaxe.diku.dk (Tommy Frandsen) (09/28/90)
To Portfolio Users... There has been som interest in programming graphics applications for the Portfolio. As you may know the Portfolio supports 240*64 pixel graphics, but the built-in software dosen't use this capability. Below I have included a program, that demonstrates how to program graphics on the Portfolio. The graphics mode on the Portfolio works very well. You can activate the built-in applications also when in graphics mode (it automaticly switch bewtween graphics and text and back again) and you can turn it on/off and retain graphics mode. But it isn't possible to output text while in graphics mode and PrtScr dosen't work (two intereseting programming projects). The program draws nice random figures on the screen. The program is rather compact, so it dosen't take up much memory (about 2.7K) either on the disk or in memory (you can call the built-in applications while the program is active). To activate the program just type 'pix' at the DOS prompt. If you want to see another sequence of figures, just follow 'pix' with a seed for the random number generator, fx. 'pix 123'. The program continues to run until a key is pressed. It also disactivates the automatic power off (not by intention), so it may drain your batteries if you forget to stop it (or you could power off manually, in witch case the program will continue to run, when you turn on the Portfolio again). I have also included the Turbo C source for the program. You are welcomed to include any part of the program in your own programs. If you write a good program, it would be nice to hear about it in this newsgroup. The only way to use the graphics mode is with BIOS function calls. Since the Portfolio is BIOS-compatible, you can find the relevant BIOS functions in any book about BIOS programming (I can recommend DOS Programmers Reference from QUE, this book also discusses how to call BIOS functions from high level languages such as C or Pascal). But you don't need to know anything about BIOS-programming to use the C-functions I have provided. Please write to me, if you have problems with the program. I would also be glad to hear from others, who has experiences with programming the Portfolio at the BIOS level (is there a way to setup the Portfolio thru BIOS calls, fx. to switch sound on/off). frandsen@diku.dk /* This program demonstrates how to use BIOS calls for programming the */ /* Atari Portfolio in graphics mode. The program should be compiled */ /* with Turbo C 1.5 or 2.0. */ /* */ /* Written by: Tommy Frandsen (frandsen@diku.dk) - 9/23/90. */ #include <conio.h> #include <stdlib.h> #include <dos.h> #define GRAPHIC 0x04 #define TEXT 0x07 #define PIX_OFF 0 #define PIX_ON 1 #define XDIM 240 #define YDIM 64 #define XMIN 0 #define XMAX (XDIM-1) #define YMIN 0 #define YMAX (YDIM-1) #define LINE_OLD 30 #define LINE_DIF 2 #define LINE_MAX 75 #define RAND_INT 10 #define RAND_THR 8 void set_mode(int mode); void pixel(int x, int y, int color); void line(int x1, int y1, int x2, int y2, int color); int test(int x, int y); main(int argc, char *argv[]) { struct { int x1; int y1; int x2; int y2; } old[LINE_OLD]; int x1, y1, x2, y2; int x1_dir=1, y1_dir=1; int x2_dir=1, y2_dir=1; int i; set_mode(GRAPHIC); for(i=0; i<LINE_OLD; i++) old[i].x1 = old[i].y1 = old[i].x2 = old[i].y2 = 0; i = 0; if(argc>1) srand(atoi(argv[1])); x1 = x2 = rand()%XDIM; y1 = y2 = rand()%YDIM; for(;;) { if (rand()%RAND_INT>RAND_THR) x1_dir = -x1_dir; if (rand()%RAND_INT>RAND_THR) y1_dir = -y1_dir; if (rand()%RAND_INT>RAND_THR) x2_dir = -x2_dir; if (rand()%RAND_INT>RAND_THR) y2_dir = -y2_dir; x1 += LINE_DIF*x1_dir; y1 += LINE_DIF*y1_dir; x2 += LINE_DIF*x2_dir; y2 += LINE_DIF*y2_dir; if (x1>XMAX) x1 = XMAX; if (y1>YMAX) y1 = YMAX; if (x2>XMAX) x2 = XMAX; if (y2>YMAX) y2 = YMAX; if (x1<XMIN) x1 = XMIN; if (y1<YMIN) y1 = YMIN; if (x2<XMIN) x2 = XMIN; if (y2<YMIN) y2 = YMIN; if ((long)(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)>LINE_MAX*LINE_MAX) { x1 = x2 = rand()%XDIM; y1 = y2 = rand()%YDIM; } line(old[i].x1, old[i].y1, old[i].x2, old[i].y2, PIX_OFF); old[i].x1=x1; old[i].y1=y1; old[i].x2=x2; old[i].y2=y2; line(old[i].x1, old[i].y1, old[i].x2, old[i].y2, PIX_ON); i = (i+1)%LINE_OLD; if (kbhit()) break; } set_mode(TEXT); } /* set_mode: Use this function to move between text and graphics mode. */ /* Use set_mode(4) to set graphics mode and set_mode(7) to */ /* set text mode. */ void set_mode(int mode) { union REGS regs; regs.h.ah = 0; regs.h.al = mode; int86(0x10, ®s, ®s); } /* pixel: Sets or clears the pixel in (x,y). color=1 will set a pixel */ /* and color=0 will clear a pixel. 0<=x<=239 and 0<=y<=63. */ void pixel(int x, int y, int color) { union REGS regs; regs.h.ah = 0x0c; regs.h.al = color; regs.h.bh = 0; regs.x.cx = x; regs.x.dx = y; int86(0x10, ®s, ®s); } /* line: Draws a line between (x1,y1) and (x2,y2). color=1 will draw a */ /* line and color=0 will clear a line. 0<=x1<=239, 0<=y1<=63, */ /* 0<=x2<=239 and 0<=y2<=63. */ void line(int x1, int y1, int x2, int y2, int color) { int x, y, d, a, b; int dx_diag, dy_diag; int dx_nondiag, dy_nondiag; int diag_inc, nondiag_inc; int i, swap; x = x1; y = y1; a = x2-x1; b = y2-y1; if (a<0) { a = -a; dx_diag = -1; } else dx_diag = 1; if (b<0) { b = -b; dy_diag = -1; } else dy_diag = 1; if (a<b) { swap = a; a = b; b = swap; dx_nondiag = 0; dy_nondiag = dy_diag; } else { dx_nondiag = dx_diag; dy_nondiag = 0; } d = b+b-a; v nondiag_inc = b+b; diag_inc = b+b-a-a; for(i=0; i<=a; i++) { pixel(x, y, color); if (d<0) { x = x+dx_nondiag; y = y+dy_nondiag; d = d+nondiag_inc; } else { x = x+dx_diag; y = y+dy_diag; d = d+diag_inc; } } } /* test: Is the pixel in (x,y) set?. Returns 1 if set, otherwise 0. */ /* 0<=x<=239 and 0<=y<=63 */ int test(int x, int y) { union REGS regs; regs.h.ah = 0x0d; regs.h.bh = 0; regs.x.cx = x; regs.x.dx = y; int86(0x10, ®s, ®s); return(regs.h.al); } Below is an uuencoded version of the executable. To decode it place it in a file and use the command 'uudecode file-name'. --- cut here --- begin 666 pix.exe M35I[ 8 " 'D ___\ ( . ) ' $Q:.3&%_P#_^/S_^XS*+HD6 M@0+__[0PS2&++@( BQXL ([:HZU_^ N,!JL+B1ZG_"[#"\?__P:Q"___Z 4! MQ#ZE"XO'B]C__[G_?R:!/3@W=1DFBU4"@/H_?CUU$(#FW__9@/Y9=03Z__?R MKN-G0R8X!776@,T/_X#WV8D.QKD! -/C@\,/_PB!X_C_I:D+#O\6.@W_/XS: M*^J+/C@-@?\ 7,'OZ3_^XGSQX -<B@#/M#_CPQR(K$$T^]'.^]R&8,'..< M= ?YZ@!U#H1_UA#K=P>+_>L#Z:0XQ$G? ]JMNT[#'[\+H4<KV([ M$I7_O\M M7]/GCM*+Y^@B".@*"3.'A\ NC@85OT -N:&'#RO/\ZJ /@W_-J/C?R0VH?R? M"^AS %#HP04(Q]H>VN@S &#_\#P-B^RT3(I& K6Y#@#_ 9"Z;POK/QZX #7Q M.OR6F]SQG0OS)8S*CMIQ/+HJW1_#Y"7%%I#_YO3*\@ R\.T0+OAN ( [\.Y M'K]]"X_AHOSI_[@#DY,* %;A'U=5FX'L_@#'1O@!4PK[^OO\^_[C'_NX!-J? M EDS]NM#GAY B][1X_Z-E@C_P38/ O#_!O#X#@3P^ X"__#P1H/^'GRXM(-^ M"'\X 7X/BUX*_W=UY0-9_/^=L 99Z+T&N_ F??[BQ_2^HE^].BO\D#RB>&0 M5O;]\NB@\0H.X?&#^@C#BU;WV+#IB?OHBNKX#?KJ^NBFFW3J^ W\ZOSH7NKX M#?[B(^K^MM'@ _C%'"GY 4;RT_CTTC_A^/:!_^\ ?@._P(?[3O(_?@7'W@,B M/P"!8^OT0H;YZ?;I^C]. O_?0(S_]@ ?3$#V #D]/7Z,3S9]?H B\<KW!_N MF5)0^/Q;60[H 4!AO+/\?:+&##^*Q+WXND#V!/*"__?R7PE?P:!^_D5=AWH MH 7C\ O@8)+RX_ *,\"_EO:&KZIF\=C_-_#X"6;Q\/@,9O'P^ SX.V;Q\.@7 M 8/$"NKX#8D_JNAI+? 0X_$*\ ]&Y^@.N)V> 0!M^$&$ &W&0+L>_WT'\NC0 M PO = */X?#]N ?A[VCI_%F+Y5U?7L,_Z8/_#^P0QD;Q (I&!(A&\(UI(?U0 M_+@00NNY!AHBV-KX"0S:"-H,&_;S $0$B1'R!EHA^O;*^ QIRO[AX\@6A!#< M"-SJ^@J^W_KLBWX,*[SI=@XK=@H(\7^X#8O']]B+^,?$___K88P9\? ""_;J MQC7\ZO#TZ>K\\NH[_GT5B<.*?OZ+_G;^Y^N?\4/TA^L+^/!YW^S& T-2QBO' M\N[W,NGP_,+P[I_\X.M0_R$\=A#][/WJZ"S__C!;@W[N 'T=ONH#<$B^7NSW M]@!Q6[WW^K?K&T;1XY[C_(WC_!A\^./_K OI.\=^J=LAM? .#>'P'$K1Z0:* M\K3X.]VF]3[&"R!U!0?QZQ,._\J+'O'1XXF'0 W_L/ &]C/ N/7]=@C\_P\K MP)FY"@"W +_)"XH<'SZH 0%U^+TH@/LK= 8\POLM=01%ZO<Y__]W+H#K,'(I M]^$#PQ+6=.OK(_P2B_K)\9>'T??B8>.2E^H3T=?]!==S__?A37P']]KWV(/: M %TW_?]VS_0$Z(?_66!LU('J__\ 3O"<P6CM0OK"<<&KPL(]V$ N/__X/]6 M!@,&YH/2.. LR('!UO<+?Y32=0H[S',&A^C.^ _JI:*EHO@)+.'HMO_R\N\P MV*$+_P[\4.D,]?3_(?^70 WKZ?\6R@S\S ;<_,[\P!/ZP/P?3H/L"(U&^+_? M 5D04OCE"/T&WP?[__SA"'GH"@X>C4[VB4[RC%;TA^W&1O95_/?-9^F(Y.KY M_V%=RSPE<A4\)G<1Z?DVAX(WT8\&UOPYT><?AE7I_S3_= ;X"HL8AQ!< HM, M^E3R?/[_\G0('P?_7O*<G%8>!HY>^!CPUX\$CT37# +\^@C]\D0,@60,0P@! M (G4B<Z)X=#(B<*)!!^U4(#B%OY8R^Q6_?)/"_9\%(/^#_]8=@.^5] VT@R* MA-0,'SZ8ENL-]][J(G?JQP;\_>W__XO&HZ\+O/)>P@( AGNT5LF8P9:2A2?A M]^.1_.'Y!/?F \B6] /1A?]>RPO]5'X("_]U!3/ _?#I@K_1!04 )?ZX^*$R M#N$-*-&+7OUW+P0[X^''<BTDUX/"]<)W _P+BT3LYHE' NL*X0,I/.@#QHOP MB?@$"-&CRWX%#^&&ZSD[-O5UX0B)8#AVOZK9O:<STB6\[VB!X@ -?'K_5E9 MX,F#,(!^EG4$A[I("DWAO\77YPKQ_V/-B18V#:,T#5W#B_>A^/_WN5H!NS5. M#N@I_P4!&J O>G@_:'ZHW]_.-;VC 2,3 *,5/I<!EWX_[7UM"Z/!@4*+HP> M!PK\'OZ. [F^@ "))JQ C,6'__[6DXLVI0N#Q@(^N8 ^K0L#(7QR$=ZG'?ZQ M?S+ _[X7N7: \7^#[ *$X0/# \'__^3R_"OX<F"+YXS CMB,T([ AW]12?.D MUJJ.W8?RA]F+^#]6T$/H&0!W!W) Z!+\?_GY/"!T"#P-= 0\"77HV/_:Z^1+ MZ0="J@K =0%#X?^&X._YXQ6L22PB= \$_^$B/%QU!X \(G4"[POVO_##Z:SW M60/*L+E.B1Z?'_X+0P/;B_0B*^MRYHOE_Q^)+J$+XPZ)=@"#Q0(VK!Z&M.#Z M=/ QB48:H7__)AJ+<K%1Z"#^68OX' "3)!Z^NP[A,#/V_%D?[0;__]\VJ0OH M OZ#Q *+V >CH[KA#_]U ^D_]\"Y__^)/X/#X/T"#":R](D'Q?-4=7)B__]O M+4,@+2!#;W!Y<FEG:'0@__\H8RD@,3DX-R!";W)L86YD__\@26YT;"X 1&EV M:61E(&5R\.%RZ0T*06)N^6UAPP]L('#Q9W)A;2!T_^#G;6EN871I;V[B3:@7 M@&23#?[J^ \@__XA_V[-\O___P% __@- O__[_T4-9?_!/_X$N#\&/\(__@2 M.G'B(#:@@-0'_O43./XK! 4&9A05!1/_[V(6!1$"___X"P4%\?@,_P\ !/W= M^_^ $]'V @4/SPJ&]?_X#/#;X@W^=%@!G!!; OYB @#P 0 M ) 5@!; 08.'XL.# "+\4Z)]XS; QX* ([#_?.D4[@K %#++HLN" ", MVHGH/0 0=@.X ! IQ2G"*<..VH[#L0/3X(G!T>!(2(OPB_CSI0GM==C\CL*. MVS'V,?^Z$ "MB<71[4IU!:V)Q;(0<P.DZ_$QR='M2G4%K8G%LA!R(M'M2G4% MK8G%LA#1T='M2G4%K8G%LA#1T4%!K+?_BMCI$P"MB]BQ ]+O@,_@@.0'= R( MX4%!)HH!JN+ZZZ:L",!T-#P!= 6(P4'KZHG[@^</@<< (+$$T^N,P '8+0 " MCL")\X/F#]/KC-@!V([8Z7+_*D9!0BH.'[Y8 5N#PQ")VC'_K C =!:T '' MB\>#YP^Q!-/H <*.PB8!'>OEK0G =0B!PO\/CL+KV#T! '7:B\.+/@0 BS8& < '& 08" "T0 ([8CL QV_J.UHOG^R[_+P ! ,+K end