* HighSTE - Grožbildemulator fr ATARI STE * Version 1.0 * (c) Jens Mller 1993 OUTPUT .PRG INCLUDE "TOSDEF.S" INCLUDE "AESDEF.S" esc equ 27 LINE_A equ $A000 v_lin_wr equ $02 * Line-A Variable BYTES_LIN equ -$02 * neg. Line-A Variablen V_REZ_VT equ -$04 V_REZ_HZ equ -$0C V_REZ_WR equ -$28 V_CEL_MY equ -$2A V_CEL_MX equ -$2C V_CEL_HT equ -$2E MOUSE_Y equ -$0258 MOUSE_X equ -$025A DEV_TAB equ -$02B4 VBLVEKTOR equ $70 GEMVEKTOR equ $88 LINEWID equ $FF820E * STE-Videoregister VBASEHI equ $FF8201 VBASEMID equ $FF8203 VBASELO equ $FF820D SCROLLX equ 16 SCROLLY equ 16 *** Start ************************************************* text move.l 4(sp),a5 lea mystack(pc),sp move.l $C(a5),d0 add.l $14(a5),d0 add.l $1C(a5),d0 add.l #$100,d0 move.l d0,keep move.l d0,-(sp) move.l a5,-(sp) clr.w -(sp) call_gemdos Mshrink lea 12(sp),sp appl_init * aus AUTO-Ordner heraus gestartet? tst.w global beq.s auto_ok clr.l int_in+4 * nein -> Abbruch wind_set #0,#WF_NEWDESK graf_mouse #ARROW,#1 form_alert #1,#no_auto appl_exit call_gemdos Pterm0 auto_ok clr.w wait_flag lea title(pc),a0 bsr printline lea test_inst(pc),a0 bsr super_exec tst.w installed beq.s no_inst_ok lea yet_inst(pc),a0 bsr printline move.w #-1,wait_flag bra pexit no_inst_ok lea test_ste(pc),a0 * auf STE-Hardware testen bsr super_exec tst.w ste bne.s ste_ok lea no_ste(pc),a0 * kein STE -> Abbruch bsr printline move.w #-1,wait_flag bra pexit ste_ok call_xbios Getrez * Mindestaufl”sung ermitteln addq.l #2,sp move.w d0,resolution cmp.w #3,d0 bcs.s check_planes lea wrong_res(pc),a0 bsr printline move.w #-1,wait_flag bra pexit check_planes bsr config dc.w LINE_A move.l a0,linea_var move.w #4,planes * Anzahl der Planes setzen clr.w new_res * und gewnschte Aufl”sung move.w #320,x_wind move.w #200,y_wind cmp.w #16,res_f beq.s planes_ok move.w #2,planes move.w #1,new_res move.w #640,x_wind cmp.w #4,res_f beq.s planes_ok move.w #1,planes move.w #2,new_res move.w #400,y_wind planes_ok move.w res_x,d7 * Bildspeichergr”že ermitteln add.w #15,d7 lsr.w #4,d7 * Breite in W”rtern add.w d7,d7 * Breite in Bytes mulu planes,d7 * mal Anzahl der Planes mulu res_y,d7 * mal H”he cmp.l #32000,d7 bls pexit add.w #254,d7 move.l d7,d6 sub.l #32000,d6 * Test, ob direkt unterm Videospeicher Platz ist call_xbios Logbase addq.l #2,sp move.l d0,videobase moveq.l #-1,d0 * gr”žten freien Speicherblock erfragen bsr Emalloc move.l d0,d5 bsr Emalloc * und reservieren tst.l d0 beq.s new_v_mem move.l d0,d4 * Startadresse in d4 bsr Emfree * wieder freigeben add.l d5,d4 cmp.l videobase(pc),d4 * Block direkt am Video-Ram bne.s new_v_mem * nein sub.l d6,d5 * freier Speicher minus ben”tigter bcs.s new_v_mem * nicht genug Speicher move.l d5,d0 * 1. Block reservieren bsr Emalloc move.l d0,a5 move.l d6,d0 * Block unter Video-Ram reservieren bsr Emalloc move.l d0,-(sp) move.l a5,d0 * Zwischenblock wieder freigeben bsr Emfree move.l (sp)+,d0 * Anfangsadr. fr Video-Ram add.l d0,d6 cmp.l videobase,d6 beq.s video_ok * Adr. Video-Ram in d0 bsr Emfree * lag nicht unterm System-Video-Ram new_v_mem move.l d7,d0 * v”llig neuen Video-Ram reservieren bsr Emalloc tst.l d0 bne.s video_ok lea memfull(pc),a0 * kein freier Speicher bsr printline move.w #-1,wait_flag bra pexit video_ok add.l #255,d0 * Video-Ram auf 256-Byte-Grenze clr.b d0 move.l d0,videobase clr.w x_offs clr.w y_offs moveq.w #-1,d1 move.w new_res,d2 cmp.w resolution,d2 * andere Aufl”sung? beq.s set_res move.w d2,d1 move.w d2,resolution set_res move.w d1,-(sp) * Aufl”sung move.l d0,-(sp) * physischer und move.l d0,-(sp) * logischer Bildspeicher call_xbios Setscreen lea $C(sp),sp move.w #-1,first_call lea install(pc),a0 * installieren bsr super_exec lea inst_done(pc),a0 * Erfolgsmeldung bsr printline clr.w -(sp) * resident beenden move.l keep(pc),-(sp) call_gemdos Ptermres * HighSTE installieren - in Vektoren einklinken install move.l GEMVEKTOR,oldgemvec move.l #newgem,GEMVEKTOR move.l VBLVEKTOR,oldvblvec move.l #newvbl,VBLVEKTOR move.l dump_vec,olddumpvec move.l #newdump,dump_vec rts * Programm beenden bei nichterfolgter Installation pexit tst.w wait_flag beq.s pexit1 lea key(pc),a0 bsr printline bsr inchar pexit1 lea crlf(pc),a0 bsr printline call_gemdos Pterm0 data no_auto dc.b '[3][HighSTE muž beim Booten|' dc.b 'aus dem AUTO-Ordner heraus |' dc.b 'gestartet werden (hinter|' dc.b 'einem evtl. GDOS-Treiber)!]' dc.b '[ Abbruch ]',0 title dc.b esc,'q',esc,'E' dc.b 'Grožbild-Emulator HighSTE 1.0',13,10 dc.b '(c) Jens Mller 1993',13,10,0 yet_inst dc.b 13,10,'HighSTE bereits installiert!',0 no_ste dc.b 13,10,'Dieser Rechner ist kein ATARI STE!',0 wrong_res dc.b 13,10,'Unbekannte Aufl”sung!',0 key dc.b 13,10,13,10,'Taste drcken...',0 crlf dc.b 13,10,0 memfull dc.b 13,10,'Nicht genug Speicher!',0 inst_done dc.b esc,'E','HighSTE 1.0 installiert',0 bss wait_flag ds.w 1 new_res ds.w 1 planes ds.w 1 keep ds.l 1 videobase ds.l 1 linea_var ds.l 1 ds.l 50 mystack ds.l 1 INCLUDE "AESLIB.S" *** Test auf STE ****************************************** text test_ste clr.w ste move.l _p_cookies,d0 * "movea" setzt keine Flags beq.s cookie_end * kein Cookie-Jar vorhanden move.l d0,a0 cookie_test tst.l (a0) beq.s cookie_end cmp.l #'_VDO',(a0)+ beq.s cookie_val addq.l #4,a0 * n„chster Cookie bra.s cookie_test cookie_val cmp.l #$010000,(a0) bne.s cookie_end move.w #-1,ste cookie_end rts bss ste ds.w 1 *** Test auf bereits installiertes HighSTE **************** * Rckgabe: d0 != 0 -> installiert text test_inst clr.w installed move.l VBLVEKTOR,a1 test_loop cmpi.l #'XBRA',-12(a1) * XBRA gefunden? beq.s test_own rts * nicht installiert test_own cmpi.l #'HSTE',-8(a1) * eigene Programmkennung beq.s test_end movea.l -4(a1),a1 * Kette weiterverfolgen bra.s test_loop test_end move.w #-1,installed * bereits installiert rts bss installed ds.w 1 *** Konfigurierung **************************************** text config lea cfg_file(pc),a0 * Konfigurationsfile ”ffnen bsr open move.w d0,handle bmi.s new_cfg pea res_x * CFG-File einlesen move.l #6,-(sp) * direkt auf 3 Variablen move.w d0,-(sp) call_gemdos Fread lea $C(sp),sp cmp.l #6,d0 bne.s new_cfg bsr close bra.s check_cfg new_cfg lea ask(pc),a0 bsr printline lea width(pc),a0 * Breite eingeben bsr printline bsr get_num move.w d0,res_x lea height(pc),a0 * H”he eingeben bsr printline bsr get_num move.w d0,res_y cmp.w #2,resolution * bei Monochrom keine Farbabfrage beq.s check_cfg lea color(pc),a0 * Farbanzahl eingeben bsr printline bsr get_num move.w d0,res_f * Mindestausmaže sind bei Monochrom 640*400, * bei 4 Farben 640*200 und bei 16 Farben 320*200 * Breite ist immer ein Vielfaches von 16 (volle W”rter) check_cfg cmp.w #2,resolution bne.s c_cfg3 cmp.w #640,res_x * bei hoher Aufl”sung bcc.s c_cfg1 move.w #640,res_x c_cfg1 cmp.w #400,res_y bcc.s c_cfg2 move.w #400,res_y c_cfg2 move.w #2,res_f bra.s c_cfg6 c_cfg3 cmp.w #16,res_f * Farbaufl”sung bcs.s c_cfg4 move.w #16,res_f * 16 Farben cmp.w #320,res_x bcc.s c_cfg5 move.w #320,res_x bra.s c_cfg5 c_cfg4 move.w #4,res_f * nur 4 Farben cmp.w #640,res_x bcc.s c_cfg5 move.w #640,res_x c_cfg5 cmp.w #200,res_y * beide Farbaufl”sungen bcc.s c_cfg6 move.w #200,res_y c_cfg6 add.w #15,res_x * Breite auf volle Wortbreite and.w #$FFF0,res_x * Kontrollausgabe lea title(pc),a0 bsr printline lea width(pc),a0 bsr printline move.w res_x,d0 bsr out_num lea height(pc),a0 bsr printline move.w res_y,d0 bsr out_num lea color(pc),a0 bsr printline move.w res_f,d0 bsr out_num lea confirm(pc),a0 bsr printline c_loop bsr inchar and.b #$DF,d0 bsr outchar lea crlf(pc),a0 bsr printline cmp.b #13,d0 beq.s c_end cmp.b #'S',d0 beq.s c_save cmp.b #'N',d0 beq new_cfg bra.s c_loop c_save clr.w -(sp) * CFG-File anlegen pea cfg_file call_gemdos Fcreate addq.l #8,sp move.w d0,handle tst.w d0 bmi.s c_end * Fehler pea res_x * CFG-File sichern move.l #6,-(sp) * direkt auf 3 Variablen move.w d0,-(sp) call_gemdos Fwrite lea $C(sp),sp bsr close c_end rts data cfg_file dc.b 'HIGHSTE.CFG',0 ask dc.b 13,10,'gewnschte Aufl”sung?' dc.b 13,10,'(max. 8000 * 8000)',0 width dc.b 13,10,'Breite: ',0 height dc.b 13,10,'H”he : ',0 color dc.b 13,10,'Farben: ',0 confirm dc.b 13,10,13,10 dc.b 'Weiter(Return) Sichern(S) Neu(N) ',0 bss resolution ds.w 1 handle ds.w 1 res_x ds.w 1 res_y ds.w 1 res_f ds.w 1 *** Grundroutinen ***************************************** text Emalloc move.l d0,-(sp) call_gemdos Malloc addq.l #6,sp rts Emfree move.l d0,-(sp) call_gemdos Mfree addq.l #6,sp rts super_exec move.l a0,-(sp) call_xbios Supexec addq.l #6,sp rts printline movem.l a0-a2/d0-d2,-(sp) move.l a0,-(sp) call_gemdos Cconws addq.l #6,sp movem.l (sp)+,a0-a2/d0-d2 rts inchar movem.l a0-a2/d1-d2,-(sp) call_gemdos Crawcin addq.l #2,sp and.l #$FF,d0 movem.l (sp)+,a0-a2/d1-d2 rts outchar movem.l a0-a2/d0-d2,-(sp) and.w #$FF,d0 move.w d0,-(sp) call_gemdos Cconout addq.l #4,sp movem.l (sp)+,a0-a2/d0-d2 rts * Zahl eingeben get_num lea num_buf(pc),a1 clr.l d1 gn_loop bsr.s inchar cmp.b #3,d0 beq pexit cmp.b #8,d0 bne.s gn_1 tst.l d1 beq.s gn_loop subq.l #1,a1 * BS subq.l #1,d1 lea backspace(pc),a0 bsr.s printline bra.s gn_loop gn_1 cmp.b #13,d0 beq.s gn_calc * CR cmp.l #5,d1 * max. 5 Stellen bhi.s gn_loop cmp.b #'0',d0 bcs.s gn_loop cmp.b #'9',d0 bhi.s gn_loop move.b d0,(a1)+ * Ziffer addq.l #1,d1 bsr.s outchar bra.s gn_loop gn_calc clr.b (a1) lea num_buf(pc),a0 clr.l d1 gn_c_lp clr.l d0 move.b (a0)+,d0 sub.b #'0',d0 bcs.s gn_test cmp.b #9,d0 bhi.s gn_test move.l d1,d2 add.l d1,d1 add.l d1,d1 add.l d2,d1 add.l d1,d1 add.l d0,d1 bra.s gn_c_lp gn_test move.l d1,d0 cmp.l #8000,d0 bls.s gn_end move.l #8000,d0 gn_end rts data backspace dc.b 8,32,8,0 bss num_buf ds.b 6 text out_num and.l #$7FFF,d0 moveq.w #-1,d1 o_num1 divu #10,d0 swap d0 move.w d0,-(sp) addq.l #1,d1 clr.w d0 swap d0 tst.l d0 bne.s o_num1 o_num2 move.w (sp)+,d0 add.w #'0',d0 bsr outchar dbf d1,o_num2 rts open clr.w -(sp) move.l a0,-(sp) call_gemdos Fopen addq.l #8,sp rts close move.w handle,-(sp) call_gemdos Fclose addq.l #4,sp rts *** neuer Hardcopy-Vektor ********************************* text dc.b 'XBRA' dc.b 'HSTE' olddumpvec ds.l 1 newdump rts * blož schnell wieder raus... *** neuer Gemvektor *************************************** text dc.b 'XBRA' dc.b 'HSTE' oldgemvec ds.l 1 newgem cmp.l #115,d0 * VDI-Aufruf? bne.s oldgem * nein movea.l d1,a0 move.l 4(a0),a1 * intin-Adresse move.l 12(a0),intoutadr * intout-Adresse movea.l (a0),a0 * contrl-Adresse cmpi.w #1,(a0) * v_opnwk-Aufruf? bne.s oldgem * nein cmp.w #10,(a1) * Bildschirmtreiber? bhi.s oldgem * nein move.w #1,(a1) * ja -> immer aktuelle Aufl”sung move.l 2(sp),oldgemret * Return-Adresse merken move.l #set_vdi,2(sp) * nach VDI eigene Routine aufrufen oldgem move.l oldgemvec(pc),-(sp) rts set_vdi move.l intoutadr(pc),a0 * intout (work_out)-Array move.w res_x(pc),(a0) * des VDI ver„ndern subq.w #1,(a0) move.w res_y(pc),2(a0) subq.w #1,2(a0) move.l linea_var(pc),a0 * LINE-A Variablen „ndern move.w res_x(pc),V_REZ_HZ(a0) move.w res_x(pc),DEV_TAB(a0) subq.w #1,DEV_TAB(a0) move.w res_y(pc),V_REZ_VT(a0) move.w res_y(pc),DEV_TAB+2(a0) subq.w #1,DEV_TAB+2(a0) move.w V_REZ_HZ(a0),d0 * horizontale Aufl”sung lsr.w #3,d0 * durch 8 = Cursorpositionen move.w d0,V_CEL_MX(a0) subq.w #1,V_CEL_MX(a0) * max. Cursorspalte mulu planes(pc),d0 * mal Anzahl Planes move.w d0,v_lin_wr(a0) * = Bytes pro Zeile move.w d0,BYTES_LIN(a0) mulu V_CEL_HT(a0),d0 * mal Zeichensatzh”he move.w d0,V_REZ_WR(a0) * = Bytes pro Charakterzeile clr.l d0 move.w V_REZ_VT(a0),d0 * vertikale Aufl”sung divu V_CEL_HT(a0),d0 * durch Zeichensatzh”he subq.w #1,d0 move.w d0,V_CEL_MY(a0) * = max. Cursorzeile move.w MOUSE_X(a0),mousex move.w MOUSE_Y(a0),mousey tst.w first_call beq.s set_vdi1 lea set_video(pc),a0 * Video-Register im bsr super_exec * Supervisor-Mode set_vdi1 movea.l oldgemret(pc),a0 * zurck zum aufrufenden rts * Programm set_video move.w res_x,d0 * horizontale Aufl”sung sub.w x_wind,d0 lsr.w #4,d0 * durch 4 mulu planes(pc),d0 * mal Planes = Worte pro Zeile move.w d0,LINEWID * Videoregister setzen clr.w first_call rts bss oldgemret ds.l 1 intoutadr ds.l 1 first_call ds.w 1 *** neuer VBL-Vektor ************************************** text dc.b 'XBRA' dc.b 'HSTE' oldvblvec ds.l 1 newvbl movem.l d0-d1/a0,-(sp) movea.l linea_var(pc),a0 * Line-A Variablen move.w MOUSE_X(a0),d0 move.w MOUSE_Y(a0),d1 cmp.w mousex(pc),d0 * Mausposition ge„ndert? bne.s new_mouse cmp.w mousey(pc),d1 beq vblend * nein new_mouse move.w d0,mousex move.w d1,mousey * Test auf Scrollen nach links sub.w #SCROLLX,d0 * von aktueller Mausposition Scroll- move.w d0,d1 * bereich und Offset subtrahieren sub.w x_offs,d0 bpl.s c_right and.w #$FFF0,d1 * auf 16 Bit ausrichten tst.w d1 bpl.s c_left1 * nicht ber linken Rand hinaus clr.w d1 * scrollen c_left1 move.w d1,x_offs * neuer X-Offset bra.s c_up * Test auf Scrollen nach rechts c_right move.w x_offs,d0 * (x_offs + x_wind - SCROLLX) add.w x_wind,d0 sub.w #SCROLLX,d0 * ist Maus hinter dieser Linie, sub.w mousex,d0 * so muž gescrollt werden bpl.s c_up move.w mousex,d0 * Mausposition add.w #SCROLLX,d0 * plus Scrollbereich add.w #15,d0 * auf n„chste gerade Adresse and.w #$FFF0,d0 * = Ende Sichtfenster cmp.w res_x,d0 * hinterm rechten Rand? bcs.s c_right1 * nein move.w res_x,d0 * ja -> rechter Rand = Ende c_right1 sub.w x_wind,d0 move.w d0,x_offs * Test auf Scrollen nach oben c_up move.w mousey,d0 sub.w #SCROLLY,d0 * von aktueller Mausposition Scroll- move.w d0,d1 * bereich und Offset subtrahieren sub.w y_offs,d0 bpl.s c_down tst.w d1 bpl.s c_up1 * nicht ber linken Rand hinaus clr.w d1 * scrollen c_up1 move.w d1,y_offs * neuer Y-Offset bra.s set_reg * Test auf Scrollen nach unten c_down move.w y_offs,d0 * (y_offs + y_wind - SCROLLY) add.w y_wind,d0 sub.w #SCROLLY,d0 * ist Maus hinter dieser Linie, sub.w mousey,d0 * so muž gescrollt werden bpl.s set_reg move.w mousey,d0 * Mausposition + Scrollbereich add.w #SCROLLY,d0 * = Ende Sichtfenster cmp.w res_y,d0 * hinterm unterem Rand? bcs.s c_down1 * nein move.w res_y,d0 * ja -> unterer Rand = Ende c_down1 sub.w y_wind,d0 move.w d0,y_offs * videoadr = videobase + (x_offs + y_offs*res_x) * planes / 8 set_reg move.w y_offs,d0 * y_offs*res_x mulu res_x,d0 clr.l d1 * add x_offs move.w x_offs,d1 add.l d1,d0 move.w resolution,d1 * mal planes / 16 addq.w #2,d1 * mal 2 (gerade Adresse) lsr.l d1,d0 add.l d0,d0 add.l videobase,d0 * = videoadr move.l d0,videoadr move.b videoadr+1(pc),VBASEHI * in dieser Reihenfolge move.b videoadr+2(pc),VBASEMID * setzen, sonst keine move.b videoadr+3(pc),VBASELO * Wirkung! vblend movem.l (sp)+,d0-d1/a0 move.l oldvblvec,-(sp) rts bss x_offs ds.w 1 y_offs ds.w 1 mousex ds.w 1 mousey ds.w 1 x_wind ds.w 1 y_wind ds.w 1 videoadr ds.l 1 *** Ende ************************************************** END ***********************************************************