{{ VGA-MULTISCREEN ┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Autor: Ingo Kripahle │ │ Copyright (c) 2010 Ingo Kripahle │ │ See end of file for terms of use. │ │ Die Nutzungsbedingungen befinden sich am Ende der Datei │ └──────────────────────────────────────────────────────────────────────────────────────────────────────┘ Informationen : hive-project.de Kontakt : drohne235@googlemail.com System : Hive Name : VGA-Text-Treiber 1024x768 Pixel, 64x24 Zeichen Chip : Bellatrix Typ : Treiber Version : 00 Subversion : 01 Funktion : Standard VGA-Text- und Tastatur-Treiber Dieser Bellatrix-Code kann als Stadardcode im EEPROM gespeichert werden und bietet drei getrennt ansteuerbare Textbildschirme und Tastaturfunktionen. Mit dem integrierten Loader kann Bellatrix mit einem beliebigen andern Code geladen werden. Komponenten : VGA 1024x768 Tile Driver v0.9 Chip Gracey MIT PS/2 Keyboard Driver v1.0.1 Chip Gracey, ogg MIT COG's : MANAGMENT 1 COG VGA 2 COG's KEYB 1 COG ------------------- 4 COG's Logbuch : 23-10-2008-dr235 - erste funktionsfähige version erstellt - cursor eingebaut 06-11-2008-dr235 - keyb auf deutsche zeichenbelegung angepasst (ohne umlaute) 24-11-2008-dr235 - tab, setcur, pos1, setx, sety, getx, gety, setcol, sline, screeninit curon, curoff - beltest 13-03-2009-dr235 - LF als Zeichencode ausgeblendet 22-03-2009-dr235 - abfrage für statustasten eingefügt 05-09-2009-dr235 - abfrage der laufenden cogs eingefügt - deutschen tastaturtreiber mit vollständiger belegung! von ogg eingebunden 22-03-2010-dr235 - anpassung trios 01-05-2010-dr235 - scrollup/scrolldown eingebunden & getestet 03-05-2010-dr235 - settab/getcols/getrows/getresx/getresy eingefügt & getestet - hive-logo eingefügt ------------------- 26-01-2011-dr235 - übernahme und anpassung des treibers aus trios 31-01-2011-dr235 - backspace als direktes steuerzeichen ($C8) eingefügt 01-02-2011-dr235 - multiscreenfähigkeit implementiert - 88 - mgr_wscr: steuert, in welchen screen zeichen geschrieben werden - 89 - mgr_dscr: steuert welcher screen angezeigt wird 05-02-2011-dr235 - umwandlung backspace $c8 --> $08 06-03-2011-dr235 - revision der steuercodes; nur noch funktionen mit parameter werden über eine 0-sequenz aufgerufen, alle anderen steuerzeichen werden auf 1-byte-zeichen abgebildet 20-04-2011-dr235 - integration einer kompatiblen loaderroutine, damit kann der treiber jetzt direkt aus dem rom gestartet und dennoch bella-code nachgeladen werden kann 02-10-2012-uheld - verzögertes Scrolling bei abgeschaltetem Cursor 21-10-2012-uheld - Window-Funktionen Notizen: - setheader ACHTUNG: row ist nicht die Zeilenposition, da zwei tiles untereinander ein zeichen bilden. vielmehr ist die reale zeilenposition row/2. }} {{ STEUERCODES Byte1 Byte2 Byte3 Byte4 Byte5 0 1 get.stat KEY_STAT Tastaturstatus abfragen 0 2 get.key KEY_CODE Tastaturcode abfragen 0 3 $01 put.curchar SETCUR Cursorzeichen setzen 0 3 $02 put.col SETX Cursor in Spalte n setzen 0 3 $03 put.row SETY Cursor in Zeile n setzen 0 3 $04 get.col GETX Cursorspalte abfragen 0 3 $05 get.row GETY Cursorzeile abfragen 0 3 $06 put.color SETCOL Farbe setzen 0 3 $07 put.sline SLINE Start Scrollbereich setzen 0 3 $08 put.eline ELINE Ende Scrollbereich setzen 0 3 $09 SINIT Screeninit 0 3 $0A put.tabnr put.tabpos TABSET Tabulatoren setzen 0 4 get.keyspec KEY_SPEC Sondertasten abfragen 0 5 put.x put.y SCR_LOGO Hive-Logo anzeigen 0 6 put.char SCR_CHAR Zeichen ohne Steuerzeichen ausgeben 0 58 put.wscrnr MGR_WSCR Schreibscreen setzen 0 59 put.wscrnr MGR_DSCR Anzeigescreen setzen 0 5A put.cnr getlong.color MGR_GETCOLOR Farbregister auslesen 0 5B put.cnr putlong.color MGR_SETCOLOR Farbregister setzen 0 5C getlong.resx MGR_GETRESX Abfrage der X-Auflösung 0 5D getlong.resy MGR_GETRESY Abfrage der Y-Auflösung 0 5E get.cols MGR_GETCOLS Abfrage der Textspalten 0 5F get.rows MGR_GETROWS Abfrage der Textzeilen 0 60 get.cogs MGR_GETCOGS Abfrage der anzahl belegter COG's 0 61 getlong.spec MGR_GETSPEC Abfrage der Funktionsspezifikationen 0 62 getlong.ver MGR_GETVER Abfrage der Version 0 63 MGR_LOAD Bellatrix-Code laden $01 CLS Bildschirm löschen $02 HOME Cursor in obere linke Ecke $03 POS1 Cursor an Zeilenanfang setzen $04 CURON Cursor anschalten $05 CUROFF Cursor abschalten $06 SCRLUP Zeile nach oben scrollen $07 SCRLDOWN Zeile nach unten scrollen $08 BS Rückschritt (Backspace) $09 TAB Tabulatorschritt $0A..FF CHAR Zeichenausgabe }} CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 'signaldefinitionen bellatrixix #0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus #8, BEL_VGABASE 'vga-signale (8pin) #16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale #18, BEL_MOUSEC,BEL_MOUSED 'maus-signale #20, BEL_VIDBASE 'video-signale(3pin) #23, BEL_SELECT 'belatrix-auswahlsignal #24, HBEAT 'front-led BUSCLK 'bustakt BUS_WR '/wr - schreibsignal BUS_HS ' '/hs - quittungssignal ' +---------- ' | +------- system ' | | +---- version (änderungen) ' | | | +- subversion (hinzufügungen) CHIP_VER = $00_01_02_01 ' ' +---------- ' | +-------- window ' | |+------- vektor ' | ||+------ grafik ' | |||+----- text ' | ||||+---- maus ' | |||||+--- tastatur ' | ||||||+-- vga ' | |||||||+- tv CHIP_SPEC = %00000000_00000000_00000000_10010110 COLS = 64 ROWS = 48 TILES = COLS * ROWS RESX = 1024 RESY = 768 COLORANZ = 8 USERCHARS = 16 '8x2 logo TAB1 = 16 TAB2 = 32 TAB3 = 48 TABANZ = 8 SPACETILE = $8000 + $20 << 6 SCROLLDIFF = 2 * COLS VGA_BASPORT = 8 'vga startport VGA_RESX = COLS * 16 'vga anzahl pixel x VGA_RESY = ROWS * 16 'vga anzahl pixel y KEYB_DPORT = BEL_KEYBD 'tastatur datenport KEYB_CPORT = BEL_KEYBC 'tastatur taktport CURSORCHAR = $0E 'cursorzeichen SCREENS = 3 'anzahl der screens WIN_P_SCR = 8 'Anzahl der Windows per Screen ' hbeat --------+ ' clk -------+| ' /wr ------+|| ' /hs -----+||| +------------------------- /cs ' |||| | -------- d0..d7 DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe M1 = %00000010_00000000_00000000_00000000 M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? M3 = %00000000_00000000_00000000_00000000 M4 = %00000010_00000000_00000000_00000000 'busclk=0? OBJ vga : "bel-vga" keyb : "bel-keyb" VAR long wind 'index des screens, in welchen aktuell geschrieben wird long dind 'index des screens, der aktuell dargestellt wird long keycode 'letzter tastencode long array[TILES/2*SCREENS] 'bildschirmpuffer byte tab[TABANZ] 'tabulatorpositionen word user_charbase 'adresse der userzeichen byte wscrnr 'nummer ausgabescreens byte this_win[SCREENS] 'Nr. des aktuellen Windows pro Screen byte col[SCREENS*WIN_P_SCR] 'spaltenposition byte row[SCREENS*WIN_P_SCR] 'zeilenposition long color[SCREENS*WIN_P_SCR] 'zeichenfarbe byte cursor[SCREENS*WIN_P_SCR] 'cursorzeichen byte curstat[SCREENS*WIN_P_SCR] 'cursorstatus 1 = ein byte sline[SCREENS] 'startzeile des scrollfensters (0 = 1. zeile) byte eline[SCREENS] 'endzeile des scrollfensters (0 = 1. zeile) byte needs_nl[SCREENS] 'Flag für verzögertes newline, falls curoff ' needs_nl ist ein Bit-Feld!! WIN_P_SCR darf deshalb nicht >8 sein!! byte nnl_idx 'Bitmaske für Operationen auf needs_nl byte windows[SCREENS*WIN_P_SCR*4] 'Window-Grenzen (x0,y0,xn,yn pro Window) byte ccol, crow 'current... werden durch win_set gefüllt long ccolor 'current... werden durch win_set gefüllt byte ccursor, ccurstat 'current... byte cwcols, cwrows 'current..., Breite und Höhe des aktuellen Window byte cx0, cy0, cxn, cyn 'Koordinaten des aktuellen Windows byte cneeds_nl long plen 'länge datenblock loader byte proghdr[16] 'puffer für objektkopf CON ''------------------------------------------------- BELLATRIX PUB main | zeichen,n 'chip: kommandointerpreter ''funktionsgruppe : chip ''funktion : kommandointerpreter ''eingabe : - ''ausgabe : - init_subsysteme 'bus/vga/keyboard/maus initialisieren repeat zeichen := bus_getchar '1. zeichen empfangen if zeichen ' > 0 print_char(zeichen) else zeichen := bus_getchar '2. zeichen kommando empfangen case zeichen 1: key_stat '1: Tastaturstatus senden 2: key_code '2: Tastaturzeichen senden 3: print_ctrl(bus_getchar) '3: Steuerzeichen ($100..$1FF) ausgeben 4: key_spec '4: Statustasten ($100..$1FF) abfragen 5: print_logo '5: hive-logo ausgeben 6: pchar(bus_getchar) '6: zeichen ohne steuerzeichen augeben ' ---------------------------------------------- WINDOW 80: win_define 82: win_set(wscrnr) 84: win_getcols 85: win_getrows 86: win_oframe ' ---------------------------------------------- CHIP-MANAGMENT 88: mgr_wscr 'setzt screen, in welchen geschrieben wird 89: mgr_dscr 'setzt screen, welcher angezeigt wird 90: mgr_getcolor 'farbregister auslesen 91: mgr_setcolor 'farbregister setzen 92: mgr_getresx 'x-auflösung abfragen 93: mgr_getresy 'y-auflösung abfragen 94: mgr_getcols 'spaltenanzahl abfragen 95: mgr_getrows 'zeilenanzahl abfragen 96: mgr_getcogs 'freie cogs abfragen 97: mgr_getspec 'spezifikation abfragen 98: mgr_getver 'codeversion abfragen 99: mgr_load 'bellatrix neu starten PUB init_subsysteme|i 'chip: initialisierung des bellatrix-chips ''funktionsgruppe : chip ''funktion : - initialisierung des businterface '' : - vga & keyboard-treiber starten ''eingabe : - ''ausgabe : - dira := db_in 'datenbus auf eingabe schalten outa[bus_hs] := 1 'handshake inaktiv keyb.start(keyb_dport, keyb_cport) 'tastaturport starten 'print_ctrl(0) 'bildschirm löschen '!!!! wordfill(@array, spacetile, tiles*SCREENS) ' verschoben nach screen_init wind := dind := wscrnr := 0 'auf ersten screen stellen repeat i from 0 to SCREENS-1 screen_init(i) set_current_win ' wscrnr = 0 --> Window 1 von Screen 0 aktivieren vga.start(vga_basport, @array, @vgacolors, 0, 0, 0) 'vga-treiber starten repeat i from 0 to TABANZ-1 'tabulatoren setzen tab[i] := i * 4 user_charbase := @uchar & $FFC0 'berechnet die nächste 64-byte-grenze hinter dem zeichensatz longmove(user_charbase,@uchar,16*USERCHARS) 'verschiebt den zeichensatz auf die nächste 64-byte-grenze repeat i from 0 to SCREENS-1 wind := TILES*i 'ausgabe-index berechnen _print_logo(0,0) 'hive-logo anzeigen ' row[i] := sline[wscrnr] 'home ' col[i] := 0 'pos1 schar(cursor[wscrnr]) 'cursor an wind := 0 PRI screen_init(i) | x, w ' alle Windows von Screen i auf Standardgröße setzen, Window 1 wählen wordfill(@array.word[i*TILES], spacetile, tiles) ' CLS cursor[i*WIN_P_SCR] := CURSORCHAR 'cursorzeichen setzen curstat[i*WIN_P_SCR] := 1 'cursor anschalten sline[i] := 2 'startzeile des scrollbereichs setzen eline[i] := rows 'endzeile des scrollbereichs setzen needs_nl[i] := 0 'darf nur am Bildschirmende 1 sein x := i * WIN_P_SCR * 4 windows[x++] := 0 ' x0 windows[x++] := 0 ' y0 windows[x++] := COLS - 1 ' xn windows[x++] := ROWS - 2 ' yn repeat w from 1 to WIN_P_SCR - 1 windows[x++] := 0 ' x0 windows[x++] := sline[i] ' y0 windows[x++] := COLS - 1 ' xn windows[x++] := ROWS - 2 ' yn cursor[i*WIN_P_SCR+w] := CURSORCHAR curstat[i*WIN_P_SCR+w] := 1 row[i*WIN_P_SCR+w] := sline[wscrnr] 'home col[i*WIN_P_SCR+w] := 0 'pos1 color[i*WIN_P_SCR+w] := 0 this_win[i] := 1 PUB bus_putchar(zeichen) 'chip: ein byte an regnatix senden ''funktionsgruppe : chip ''funktion : ein byte an regnatix senden ''eingabe : byte ''ausgabe : - waitpeq(M1,M2,0) 'busclk=1? & prop2=0? dira := db_out 'datenbus auf ausgabe stellen outa[7..0] := zeichen 'daten ausgeben outa[bus_hs] := 0 'daten gültig waitpeq(M3,M4,0) 'busclk=0? dira := db_in 'bus freigeben outa[bus_hs] := 1 'daten ungültig PUB bus_getchar : zeichen 'chip: ein byte von regnatix empfangen ''funktionsgruppe : chip ''funktion : ein byte von regnatix empfangen ''eingabe : - ''ausgabe : byte waitpeq(M1,M2,0) 'busclk=1? & prop2=0? zeichen := ina[7..0] 'daten einlesen outa[bus_hs] := 0 'daten quittieren waitpeq(M3,M4,0) 'busclk=0? outa[bus_hs] := 1 CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN PUB sub_putlong(wert) 'sub: long senden ''funktionsgruppe : sub ''funktion : subprotokoll um einen long-wert an regnatix zu senden ''eingabe : 32bit wert der gesendet werden soll ''ausgabe : - ''busprotokoll : [put.byte1][put.byte2][put.byte3][put.byte4] '' : [ hsb ][ ][ ][ lsb ] bus_putchar(wert >> 24) '32bit wert senden hsb/lsb bus_putchar(wert >> 16) bus_putchar(wert >> 8) bus_putchar(wert) PUB sub_getlong:wert 'sub: long empfangen ''funktionsgruppe : sub ''funktion : subprotokoll um einen long-wert von regnatix zu empfangen ''eingabe : - ''ausgabe : 32bit-wert der empfangen wurde ''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] '' : [ hsb ][ ][ ][ lsb ] wert := bus_getchar << 24 '32 bit empfangen hsb/lsb wert := wert + bus_getchar << 16 wert := wert + bus_getchar << 8 wert := wert + bus_getchar CON ''------------------------------------------------- CHIP-MANAGMENT-FUNKTIONEN PRI mgr_wscr|scrnr, oldscr 'cmgr: setzt screen, in welchen geschrieben wird ''funktionsgruppe : cmgr ''funktion : schaltet die ausgabe auf einen bestimmten screen ''eingabe : - ''ausgabe : - ''busprotokoll : [0][088][get.wscrnr] '' : wscrnr - nummer des screens 1..SCREENS scrnr := bus_getchar - 1 if scrnr => 0 and scrnr < SCREENS oldscr := wscrnr wscrnr := scrnr wind := TILES*wscrnr 'ausgabe-index berechnen win_set_int(oldscr, this_win[wscrnr]) PRI mgr_dscr|scrnr 'cmgr: setzt screen, welcher angezeigt wird ''funktionsgruppe : cmgr ''funktion : schaltet die anzeige auf einen bestimmten screen ''eingabe : - ''ausgabe : - ''busprotokoll : [0][089][get.scrnr] '' : scrnr - nummer des screens 1..SCREENS scrnr := bus_getchar - 1 if scrnr => 0 and scrnr < SCREENS dind := TILES*2*scrnr 'display-index berechnen vga.set_scrpointer(@array+dind) 'screenpointer für den displaytreiber neu setzen PUB mgr_getcolor|cnr 'cmgr: farbregister auslesen ''funktionsgruppe : cmgr ''funktion : farbregister auslesen ''eingabe : - ''ausgabe : - ''busprotokoll : [0][090][get.cnr][sub_putlong.color] '' : cnr - nummer des farbregisters 0..15 '' : color - erster wert cnr := bus_getchar sub_putlong(long[@vgacolors][cnr]) PUB mgr_setcolor|cnr 'cmgr: farbregister setzen ''funktionsgruppe : cmgr ''funktion : farbregister setzen ''eingabe : - ''ausgabe : - ''busprotokoll : [0][091][get.cnr][sub_getlong.color] '' : cnr - nummer des farbregisters 0..15 '' : color - farbwert cnr := bus_getchar long[@vgacolors][cnr] := sub_getlong PUB mgr_getresx 'cmgr: abfrage der x-auflösung ''funktionsgruppe : cmgr ''funktion : abfrage der x-auflösung ''eingabe : - ''ausgabe : - ''busprotokoll : [0][092][put.resx] '' : resx - x-auflösung sub_putlong(RESX) PUB mgr_getresy 'cmgr: abfrage der y-auflösung ''funktionsgruppe : cmgr ''funktion : abfrage der y-auflösung ''eingabe : - ''ausgabe : - ''busprotokoll : [0][093][put.resy] '' : resy - y-auflösung sub_putlong(RESY) PUB mgr_getcols 'cmgr: abfrage der Textspalten ''funktionsgruppe : cmgr ''funktion : abfrage der textspalten ''eingabe : - ''ausgabe : - ''busprotokoll : [0][094][put.cols] '' : cols - anzahl der textspalten bus_putchar(COLS) PUB mgr_getrows 'cmgr: abfrage der textzeilen ''funktionsgruppe : cmgr ''funktion : abfrage der textzeilen ''eingabe : - ''ausgabe : - ''busprotokoll : [0][095][put.rows] '' : rows - anzahl der textzeilen bus_putchar(ROWS/2) PUB mgr_getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind ''funktionsgruppe : cmgr ''funktion : abfrage wie viele cogs in benutzung sind ''eingabe : - ''ausgabe : cogs - anzahl der cogs ''busprotokoll : [0][096][put.cogs] '' : cogs - anzahl der belegten cogs cogs := i := 0 repeat 'loads as many cogs as possible and stores their cog numbers c := cog[i] := cognew(@entry, 0) if c=>0 i++ while c => 0 cogs := i repeat 'unloads the cogs and updates the string i-- if i=>0 cogstop(cog[i]) while i=>0 bus_putchar(cogs) PUB mgr_getspec 'cmgr: abfrage der spezifikation des chips ''funktionsgruppe : cmgr ''funktion : abfrage der version und spezifikation des chips ''eingabe : - ''ausgabe : cogs - anzahl der cogs ''busprotokoll : [097][sub_putlong.spec] '' : spec - spezifikation '' '' '' +---------- '' | +-------- window '' | |+------- vektor '' | ||+------ grafik '' | |||+----- text '' | ||||+---- maus '' | |||||+--- tastatur '' | ||||||+-- vga '' | |||||||+- tv ''CHIP_SPEC = %00000000_00000000_00000000_10010110 sub_putlong(CHIP_SPEC) PUB mgr_getver 'cmgr: abfrage der version ''funktionsgruppe : cmgr ''funktion : abfrage der version und spezifikation des chips ''eingabe : - ''ausgabe : cogs - anzahl der cogs ''busprotokoll : [098][sub_putlong.ver] '' : ver - version '' '' +---------- '' | +------- system '' | | +---- version (änderungen) '' | | | +- subversion (hinzufügungen) ''CHIP_VER = $00_01_02_01 sub_putlong(CHIP_VER) PUB mgr_load|i 'cmgr: bellatrix-loader ''funktionsgruppe : cmgr ''funktion : funktion um einen neuen code in bellatrix zu laden '' ''bekanntes problem: einige wenige bel-dateien werden geladen aber nicht korrekt gestartet ''lösung: diese datei als eeprom-image speichern ' kopf der bin-datei einlesen ------------------------------------------------------ repeat i from 0 to 15 '16 bytes --> proghdr byte[@proghdr][i] := bus_getchar plen := 0 plen := byte[@proghdr + $0B] << 8 plen := plen + byte[@proghdr + $0A] ' objektlänge an regnatix senden bus_putchar(plen >> 8) 'hsb senden bus_putchar(plen & $FF) 'lsb senden repeat i from 1 to 7 'alle anderen cogs anhalten ifnot i == cogid cogstop(i) dira := 0 'diese cog vom bus trennen cognew(@loader, plen) cogstop(cogid) 'cog 0 anhalten DAT org 0 loader mov outa, M_0 'bus inaktiv mov dira, DINP 'bus auf eingabe schalten mov reg_a, PAR 'parameter = plen mov reg_b, #0 'adresse ab 0 ' datenblock empfangen loop call #get 'wert einlesen wrbyte in, reg_b 'wert --> hubram add reg_b, #1 'adresse + 1 djnz reg_a, #loop ' neuen code starten rdword reg_a, #$A ' Setup the stack markers. sub reg_a, #4 ' wrlong SMARK, reg_a ' sub reg_a, #4 ' wrlong SMARK, reg_a ' rdbyte reg_a, #$4 ' Switch to new clock mode. clkset reg_a ' coginit SINT ' Restart running new code. cogid reg_a cogstop reg_a 'cog hält sich selbst an get waitpeq M_1, M_2 'busclk=1? & /cs=0? mov in, ina 'daten einlesen and in, DMASK 'wert maskieren mov outa, M_3 'hs=0 waitpeq M_3, M_4 'busclk=0? mov outa, M_0 'hs=1 get_ret ret ' hbeat --------+ ' clk -------+| ' /wr ------+|| ' /hs -----+|||+------------------------- /cs ' ||||| -------- d0..d7 DINP long %00001001000000000000000000000000 'constant dinp hex \ bus input DOUT long %00001001000000000000000011111111 'constant dout hex \ bus output M_0 long %00001000000000000000000000000000 'bus inaktiv M_1 long %00000010000000000000000000000000 M_2 long %00000010100000000000000000000000 'busclk=1? & /cs=0? M_3 long %00000000000000000000000000000000 M_4 long %00000010000000000000000000000000 'busclk=0? DMASK long %00000000000000000000000011111111 'datenmaske SINT long ($0001 << 18) | ($3C01 << 4) ' Spin interpreter boot information. SMARK long $FFF9FFFF ' Stack mark used for spin code. in res 1 reg_a res 1 reg_b res 1 CON ''------------------------------------------------- KEYBOARD-FUNKTIONEN PUB key_stat 'key: tastaturstatus abfragen bus_putchar(keyb.gotkey) PUB key_code 'key: tastencode abfragen keycode := keyb.key case keycode $c8: keycode := $08 'backspace wandeln bus_putchar(keycode) PUB key_spec 'key: statustaten vom letzten tastencode abfragen bus_putchar(keycode >> 8) CON ''------------------------------------------------- WINDOW-FUNKTIONEN PUB win_define | w, x0, y0, xn, yn, x w := bus_getchar x0 := bus_getchar #> 0 <# COLS y0 := (bus_getchar * 2) #> 0 <# ROWS xn := bus_getchar #> x0 <# COLS yn := (bus_getchar * 2) #> y0 <# ROWS if w < 1 or w => WIN_P_SCR ' Window 0 wird nicht überschrieben! return x := wscrnr*WIN_P_SCR*4 + w*4 windows[x++] := x0 windows[x++] := y0 windows[x++] := xn windows[x] := yn x := wscrnr*WIN_P_SCR + w col[x] := x0 row[x] := y0 PUB win_set(oldscr) | w w := bus_getchar if w < 0 or w => WIN_P_SCR return win_set_int(oldscr, w) PRI win_set_int(oldscr, w) | x ' current-Werte in altes Window sichern x := oldscr*WIN_P_SCR + this_win[oldscr] col[x] := ccol row[x] := crow color[x] := ccolor cursor[x] := ccursor curstat[x] := ccurstat needs_nl[oldscr] := cneeds_nl if ccurstat == 1 schar($20) ' current-Werte für neues Window setzen this_win[wscrnr] := w set_current_win if ccurstat == 1 schar(ccursor) PRI set_current_win | x x := wscrnr*WIN_P_SCR + this_win[wscrnr] ccol := col[x] crow := row[x] ccolor := color[x] ccursor := cursor[x] ccurstat := curstat[x] x := wscrnr*WIN_P_SCR*4 + this_win[wscrnr]*4 cx0 := windows[x++] cy0 := windows[x++] cxn := windows[x++] cyn := windows[x] cwcols := cxn - cx0 + 1 cwrows := cyn - cy0 + 2 nnl_idx := 1 << this_win[wscrnr] cneeds_nl := needs_nl[wscrnr] PUB win_getcols bus_putchar(cwcols) PUB win_getrows bus_putchar(cwrows / 2) PUB win_oframe | c, r c := ccol ' aktuelle Werte aufheben und am Ende zuruecksetzen r := crow if cy0 ' oberer Rand ist sichtbar crow := cy0 - 2 if cx0 ccol := cx0 - 1 schar(159) repeat ccol from cx0 to cxn schar(144) '- if cxn < COLS ccol := cxn + 1 schar(158) if cx0 ' linke Seite ist sichtbar ccol := cx0 - 1 repeat crow from cy0 to cyn step 2 schar(145) '| if cxn < COLS ' rechte Seite ist sichtbar ccol := cxn + 1 repeat crow from cy0 to cyn step 2 schar(145) '| if cyn < ROWS ' unterer Rand ist sichtbar crow := cyn + 2 if cx0 ccol := cx0 - 1 schar(157) repeat ccol from cx0 to cxn schar(144) '- if cxn < COLS ccol := cxn + 1 schar(156) ccol := c crow := r CON ''------------------------------------------------- SCREEN-FUNKTIONEN PUB print_char(c) | code,n 'screen: zeichen auf bildschirm ausgeben {{zeichen auf bildschirm ausgeben}} case c $01: 'clear screen? n := wind + cy0 * cols + cx0 ' links oben repeat cwrows wordfill(@array.word[n], spacetile, cwcols) n += COLS crow := cy0 ccol := cx0 needs_nl[wscrnr] &= !nnl_idx if ccurstat == 1 'cursor einschalten schar(ccursor) $02: 'home? cneeds_nl &= !nnl_idx if ccurstat == 1 schar($20) crow := cy0 ccol := cx0 if ccurstat == 1 schar(ccursor) $03: 'pos1 cneeds_nl &= !nnl_idx if ccurstat == 1 schar($20) ccol := cx0 if ccurstat == 1 schar(ccursor) $04: 'curon if cneeds_nl & nnl_idx newline cneeds_nl ^= nnl_idx ccurstat := 1 schar(ccursor) $05: 'curoff if ccurstat == 1 schar($20) ccurstat := 0 $06: 'scrollup scrollup $07: 'scrolldown scrolldown $08: 'backspace? cneeds_nl &= !nnl_idx if ccol > cx0 if ccurstat == 1 schar($20) ccol-- if ccurstat == 1 schar(ccursor) $09: 'tab ' !!!!!!!!!!!!!!!!! TAB absolut oder lieber relativ zum WINDOW?! repeat n from 0 to TABANZ-1 if ccol < tab[n] if ccurstat == 1 schar($20) ccol := tab[n] if ccurstat == 1 schar(ccursor) quit $0A: 'LF ausblenden return $0D: 'return? cneeds_nl &= !nnl_idx if ccurstat == 1 schar($20) newline if ccurstat == 1 schar(ccursor) $0E..$FF: 'character? pchar(c) if ccurstat == 1 schar(ccursor) PUB print_ctrl(c) | code,n,m 'screen: steuerzeichen ausgeben case c $01: 'setcur code := bus_getchar ccursor := code if ccurstat == 1 schar(code) $02: 'setx if ccurstat == 1 schar($20) cneeds_nl &= !nnl_idx ccol := bus_getchar #> 0 <# COLS if ccurstat == 1 schar(ccursor) $03: 'sety if ccurstat == 1 schar($20) cneeds_nl &= !nnl_idx crow := (bus_getchar * 2) #> 0 <# ROWS '2 tiles pro zeichen! if ccurstat == 1 schar(ccursor) $04: 'getx bus_putchar(ccol) $05: 'gety bus_putchar(crow / 2) $06: 'setcolor ccolor := bus_getchar $07: 'sline sline[wscrnr] := bus_getchar * 2 $08: 'eline eline[wscrnr] := bus_getchar * 2 $09: 'screeninit screen_init(wscrnr) set_current_win $0A: 'tabulator setzen n := bus_getchar m := bus_getchar if n =< (TABANZ-1) tab[n] := m $0B: 'winsetx if ccurstat == 1 schar($20) cneeds_nl &= !nnl_idx code := bus_getchar ~code ccol := code #> -cwcols <# cwcols ' negativ --> Abstand von rechts+1 if code < 0 ccol += cxn + 1 else ccol += cx0 if ccurstat == 1 schar(ccursor) $0C: 'winsety if ccurstat == 1 schar($20) cneeds_nl &= !nnl_idx code := bus_getchar ~code crow := (code * 2) #> -cwrows <# cwrows '2 tiles pro zeichen! if code < 0 crow += cyn + 2 else crow += cy0 if ccurstat == 1 schar(ccursor) $0D: 'wingetx bus_putchar(ccol - cx0) $0E: 'wingety bus_putchar((crow - cy0)/ 2) PRI schar(c)| i,addr 'screen: schreibt zeichen an aktuelle position ohne cursor i := $8000 + (c & $FE) << 6 + (ccolor << 1 + c & 1) array.word[addr := crow*cols+ccol+wind] := i 'oberes tile setzen array.word[addr + cols] := i | $40 'unteres tile setzen PRI pchar(c) 'screen: schreibt zeichen mit cursor an aktuelle position if cneeds_nl & nnl_idx newline cneeds_nl ^= nnl_idx schar(c) if ++ccol > cxn if ccurstat == 1 newline else cneeds_nl |= nnl_idx PUB newline | i 'screen: zeilenwechsel, inkl. scrolling am screenende ccol := cx0 if (crow += 2) > cyn crow -= 2 scrollup PUB scrollup | zadr 'screen: scrollt den screen nach oben ' Start: linke obere Ecke, Breite: Window-Breite, Schrittweite: absolute Screen-Breite zadr := wind + cy0 * cols + cx0 ' links oben repeat cwrows-2 wordmove(@array.word[zadr], @array.word[zadr+SCROLLDIFF], cwcols) zadr += COLS 'clear new line wordfill(@array.word[zadr], spacetile, cwcols) wordfill(@array.word[zadr+COLS], spacetile, cwcols) PUB scrolldown | zadr 'screen: scrollt den screen nach unten zadr := wind + (cyn+1) * cols + cx0 ' links unten repeat cwrows-2 wordmove(@array.word[zadr], @array.word[zadr-SCROLLDIFF], cwcols) zadr -= COLS 'clear new line wordfill(@array.word[zadr], spacetile, cwcols) wordfill(@array.word[zadr-COLS], spacetile, cwcols) PRI print_logo|x,y 'screen: hive-logo ausgeben x := bus_getchar y := bus_getchar _print_logo(x,y) PRI _print_logo(x,y)|padr padr := @hive+user_charbase-@uchar print_uchar(padr, x, y, 8, 2, 1) 'logo zeichnen PRI print_uchar(pBMP,xPos,yPos,xSize,ySize,clr)|c,i,j,t 'screen: zeichnet ein einzelnes tilefeld { - setzt in der tilemap des vga-treibers die adressen auf das entsprechende zeichen - setzt mehrer tiles je nach xSize und ySize - jedes tile besteht aus 16x16 pixel, weshalb die adresse jedes tiles mit c<<6 gebildet wird - alle 64 byte (c<<6) beginnt im bitmap ein tile } t:=xPos c:=0 repeat j from 0 to (ySize-1) repeat i from 0 to (xSize-1) array.word[yPos * cols + xPos + wind] := pBMP + (c<<6) + clr c++ xPos++ yPos++ xPos:=t DAT {{ '' array_ptr = Pointer to 3,072 long-aligned words, organized as 64 across by 48 down, '' which will serve as the tile array. Each word specifies a tile bitmap and '' a color palette for its tile area. The top 10 bits of each word form the '' base address of a 16-long tile bitmap, while the lower 6 bits select a '' color palette for the bitmap. For example, $B2E5 would specify the tile '' bitmap spanning $B2C0..$B2FF and color palette $25. '' color_ptr = Pointer to 64 longs which will define the 64 color palettes. The RGB data '' in each long is arranged as %%RGBx_RGBx_RGBx_RGBx with the sub-bytes 3..0 '' providing the color data for pixel values %11..%00, respectively: '' '' %%3330_0110_0020_3300: %11=white, %10=dark cyan, %01=blue, %00=gold '' %% ist quaternary-darstellung; jedes digit von 0 bis 3, also 4-wertigkeit bildaufbau: 24 zeilen zu je 64 zeichen; jedes zeichen wird durch zwei tiles gebildet die ?bereinander liegen. jedes tile belegt ein word: 10 bit bitmap und 6 bit color. zwei tiles ein long. '0 %%RGBx_RGBx_RGBx_RGBx long %%0330_0010_0330_0010 long %%0330_0330_0010_0010 long $3C043C04 'grau/blau erste - hive-version long $3C3C0404 Color-Calculator: http://www.rayslogic.com/propeller/Programming/Colors.htm For the 1024x768 VGA tile driver: 2 longs are required for each text foreground/background color combo, arranged as: $ff_bb_ff_bb $ff_ff_bb_bb where 'ff' is the foreground color and 'bb' is the background color 2 longs needed because characters are in an interleaved pair The first long is the color for the first character in a pair, the second long is for the second character in a pair. Demo routine "print()" only allows for 8 fore/back combinations (using longs 0 to 15) 1 long required for box colors, arranged as: $tl_br_fi_bb where 'tl' is top-left edge, 'br' is bottom-right edge, 'fi' is focus indicators, and 'bb' is background color The demo "box()" procedure hardwired to add 16 to input color number to pick box color and adds 5 to input color number to pick text color for box... So, "box(left,top,clr,str)" uses color number 16+clr for box colors and 5+clr for text color. You probably want the 'bb' background colors of these two to match! Note that this limits you to 4 box colors. 1 long used for graphics colors, arranged as $00_11_22_33 where 00,11,22,33 are the selectable graphics colors 0,1,2,3 Demo hardwired to use the 21st long (last one) for the graphics colors The Propeller's "tile driver" video uses 32-bit (long) values to define a four color palette The "color_ptr" parameter, given to the tile driver, specifies the location of the data block of up to 64 different long palette values Each long palette represents 4 different colors, one byte each. Each color byte uses 2 bits for each primary colors, RGB, arranged as RGBx. The "x" represents the two least significant bits, which are ignored. Parallax gives this example of a 32-bit long palette, represented as a 16-digit quaternary (2-bit) number: %%3330_0110_0020_3300 or $FC1408F0 The first byte, %%3330 (binary %11111100), is the color white The second byte, %%0110, is the color dark cyan }} org ' ' Entry: dummy-assemblercode fuer cogtest ' entry jmp entry 'just loops vgacolors long 'farbpalette '============================================================ ' v h v h ' v=Vordergrund, h=Hintergrund ' long $ 3C 04 3C 04 'Muster ' v v h h ' long $ 3C 3C 04 04 'Muster '0 %%RGBx_RGBx_RGBx_RGBx ' long %%0330_0010_0330_0010 ' long %%0330_0330_0010_0010 '============================================================ 'set 1 - grau auf weiß long $54FC54FC 'grau/weiß long $5454FCFC long $58FC58FC 'hellblau/weiß long $5858FCFC long $64FC64FC 'hellgrün/weiß long $6464FCFC long $94FC94FC 'hellrot/weiß long $9494FCFC long $00FC00FC 'schwarz/weiß long $0000FCFC long $0CFC0CFC 'blau/weiß long $0C0CFCFC long $30FC30FC 'grün/weiß long $3030FCFC long $C0FCC0FC 'rot/weiß long $C0C0FCFC long $C0408080 'redbox long $CC440088 'magentabox long $3C142828 'cyanbox long $FC54A8A8 'greybox long $3C14FF28 'cyanbox+underscore long $F030C050 'graphics colors long $881430FC long $8008FCA4 'set 2 - weiß auf schwarz { long $FC00FC00 'schwarz/weiß long $FCFC0000 long $A800A800 'schwarz/hellgrau long $A8A80000 long $54005400 'schwarz/dunkelgrau long $54540000 long $30043004 'grün/blau long $30300404 long $043C043C 'Color 0 reverse long $04043C3C long $FC04FC04 'weiss/blau long $FCFC0404 long $FF80FF80 'red/white long $FFFF8080 long $88048804 'magenta/blau long $88880404 long $C0408080 'redbox long $CC440088 'magentabox long $3C142828 'cyanbox long $FC54A8A8 'greybox long $3C14FF28 'cyanbox+underscore long $F030C050 'graphics colors long $881430FC long $8008FCA4 } 'set 3 - hellblau auf dunkelblau { long $3C043C04 'grau/blau erste - hive-version long $3C3C0404 long $F004F004 'yellow/blue long $F0F00404 long $C004C004 'rot/blau long $C0C00404 long $30043004 'grün/blau long $30300404 long $043C043C 'Color 0 reverse long $04043C3C long $FC04FC04 'weiss/blau long $FCFC0404 long $FF80FF80 'red/white long $FFFF8080 long $88048804 'magenta/blau long $88880404 long $C0408080 'redbox long $CC440088 'magentabox long $3C142828 'cyanbox long $FC54A8A8 'greybox long $3C14FF28 'cyanbox+underscore long $F030C050 'graphics colors long $881430FC long $8008FCA4 } 'set 4 - chess { '0..1: text color 0: long $F010F010 '0: Yellow on Green long $F0F01010 '2..3: text color 1: long $C0FCC0FC '1: red on white long $C0C0FCFC '4..5: text color 2: long $00FC00FC '2: black on white long $0000FCFC '6..7: text color 3: long $F010F010 '3: Yellow on Green long $F0F01010 long $043C043C 'Color 0 reverse long $04043C3C long $FC04FC04 'weiss/blau long $FCFC0404 long $FF80FF80 'red/white long $FFFF8080 long $88048804 'magenta/blau long $88880404 long $C0408080 'redbox long $CC440088 'magentabox long $3C142828 'cyanbox long $FC54A8A8 'greybox long $3C14FF28 'cyanbox+underscore long $F030C050 'graphics colors long $881430FC long $8008FCA4 } ' alte definitionen { long $F010F010 'yellow on dk green long $F0F01010 long $C000C000 'red long $C0C00000 long $30003000 'green long $30300000 long $0C000C00 'blue long $0C0C0000 long $FC04FC04 'white long $FCFC0404 long $FF88FF88 'magenta/white long $FFFF8888 long $C0408080 'redbox long $CC440088 'magentabox long $3C142828 'cyanbox long $FC54A8A8 'greybox long $3C14FF28 'cyanbox+underscore long $F030C050 'graphics colors long $881430FC long $8008FCA4 } DAT padding long 1[16] '64-byte raum für die ausrichtung des zeichensatzes uchar long hive long file "logo-hive-8x2.dat" '8x2=16 DAT {{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}