Initial checkin of TriOS R56

This commit is contained in:
Jörg Deckert 2013-12-10 15:32:47 +01:00
commit 8f2077df1b
114 changed files with 48208 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
{{ TV-Spezifika für belflash
}}
CON
COLS = 40
ROWS = 13
TLINES_PER_ROW = 1
DEFAULT_Y0 = 0 ' bei 13 Zeilen ist kein Platz für eine dauerhafte Überschrift
SPACETILE = $220
TV_BASPORT = 23
OBJ
tv : "bel-tv"
CON
TV_COUNT = 14 ' Anzahl der long-Variablen ab tv_status
VAR
long colors[8 * 2]
long tv_status '0/1/2 = off/invisible/visible read-only (14 longs)
long tv_enable '0/non-0 = off/on write-only
long tv_pins '%pppmmmm = pin group, pin group mode write-only
long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only
long tv_screen 'pointer to screen (words) write-only
long tv_colors 'pointer to colors (longs) write-only
long tv_ht 'horizontal tiles write-only
long tv_vt 'vertical tiles write-only
long tv_hx 'horizontal tile expansion write-only
long tv_vx 'vertical tile expansion write-only
long tv_ho 'horizontal offset write-only
long tv_vo 'vertical offset write-only
long tv_broadcast 'broadcast frequency (Hz) write-only
long tv_auralcog 'aural fm cog write-only
long vid_arr ' Kopie des Pointers auf den "Bildwiederholspeicher"
long ccolor ' aktuelle Anzeigefarbe
PUB start(array)
vid_arr := array
start_tv(TV_BASPORT, array)
PUB start_tv(basepin, array) : okay
'' Start terminal - starts a cog
'' returns false if no cog available
setcolors(@palette)
'out(0)
longmove(@tv_status, @tv_params, TV_COUNT)
tv_pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101
tv_screen := array
tv_colors := @colors
okay := tv.start(@tv_status)
PUB setcolors(colorptr) | i, fore, back
'' Override default color palette
'' colorptr must point to a list of up to 8 colors
'' arranged as follows:
''
'' fore back
'' ------------
'' palette byte color, color 'color 0
'' byte color, color 'color 1
'' byte color, color 'color 2
'' ...
repeat i from 0 to 7
fore := byte[colorptr][i << 1]
back := byte[colorptr][i << 1 + 1]
colors[i << 1] := fore << 24 + back << 16 + fore << 8 + back
colors[i << 1 + 1] := fore << 24 + fore << 16 + back << 8 + back
PUB set_dscr(scr_ptr)
tv_screen := scr_ptr
PUB get_color(cnr)
return long[colors][cnr & $F]
PUB set_color(cnr, colr)
long[colors][cnr & $F] := colr
PUB set_ccolor(colr)
ccolor := colr
PUB get_ccolor
return ccolor
PUB schar(offset, c)
word[vid_arr][offset] := (ccolor << 1 + c & 1) << 10 + $200 + c & $FE
DAT
tv_params long 0 'status
long 1 'enable
long 0 'pins
long %10010 'mode
long 0 'screen
long 0 'colors
long cols 'hc
long rows 'vc
long 4 'hx
long 1 'vx
long 0 'ho
long 0 'vo
long 0 'broadcast
long 0 'auralcog
' fore back
' color color
palette byte $07, $0A '0 white / dark blue
byte $07, $BB '1 white / red
byte $9E, $9B '2 yellow / brown
byte $04, $07 '3 grey / white
byte $3D, $3B '4 cyan / dark cyan
byte $6B, $6E '5 green / gray-green
byte $BB, $CE '6 red / pink
byte $3C, $0A '7 cyan / blue

View File

@ -0,0 +1,310 @@
{{ VGA-Spezifika für belflash
}}
CON
COLS = 64
ROWS = 48
TLINES_PER_ROW = 2
DEFAULT_Y0 = TLINES_PER_ROW ' 1 Zeile Platz lassen für HIVE-Logo
COLORANZ = 8
SPACETILE = $8000 + $20 << 6
VGA_BASPORT = 8 'vga startport
OBJ
vga : "bel-vga"
VAR
long vid_arr ' Kopie des Pointers auf den "Bildwiederholspeicher"
long ccolor ' aktuelle Anzeigefarbe
PUB start(array)
vid_arr := array
vga.start(VGA_BASPORT, array, @vgacolors, 0, 0, 0) 'vga-treiber starten
PUB set_dscr(scr_ptr)
vga.set_scrpointer(scr_ptr) 'screenpointer für den displaytreiber neu setzen
PUB get_color(cnr)
return long[@vgacolors][cnr]
PUB set_color(cnr, colr)
long[@vgacolors][cnr] := colr
PUB set_ccolor(colr)
ccolor := colr
PUB get_ccolor
return ccolor
PUB schar(offset, c) | i
i := $8000 + (c & $FE) << 6 + (ccolor << 1 + c & 1)
word[vid_arr][offset] := i 'oberes tile setzen
word[vid_arr][offset + cols] := i | $40 'unteres tile setzen
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
}}
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
}
'set 5 - grün auf schwarz
' v h v h ' v=Vordergrund, h=Hintergrund
' long $ 3C 04 3C 04 'Muster
' v v h h
' long $ 3C 3C 04 04 'Muster
long $30003000 'color 0: grün auf schwarz
long $30300000
long $C000C000 'color 1: rot auf schwarz
long $C0C00000
long $0C000C00 'color 2: blau auf schwarz
long $0C0C0000
long $E000E000 'color 3: gelb auf schwarz
long $E0E00000
long $D000D000 'color 4: orange auf schwarz
long $D0D00000
long $3C003C00 'color 5: cyan auf schwarz
long $3C3C0000
long $FC00FC00 'color 6: weiß auf schwarz
long $FCFC0000
long $C800C800 'color 7: magenta auf schwarz
long $C8C80000
long $00300030 'color 8: schwarz auf grün
long $00003030
long $00C000C0 'color 9: schwarz auf rot
long $0000C0C0
long $000C000C 'color 10: schwarz auf blau
long $00000C0C
long $00E000E0 'color 11: schwarz auf gelb
long $0000E0E0
long $00D000D0 'color 12: schwarz auf orange
long $0000D0D0
long $003C003C 'color 13: schwarz aufcyan
long $00003C3C
long $00FC00FC 'color 14: schwarz auf weiß
long $0000FCFC
long $00C800C8 'color 15: schwarz auf magenta
long $0000C8C8

View File

@ -0,0 +1,977 @@
{{ 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
oder : MANAGMENT 1 COG
TV 1 COG
KEYB 1 COG
-------------------
3 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
31.12.2011-dr235 - anpassung für verschiedene zeilenumbrüche in print_char eingefügt
28.06.2012-dr235 - fehler im loader behoben (cog0 wurde nicht in allen fällen beendet)
dank dafür geht an pic :)
02-10-2012-uheld - verzögertes Scrolling bei abgeschaltetem Cursor
21-10-2012-uheld - Window-Funktionen
28-11-2012-uheld - wahlweise Einbindung von VGA- oder TV-Treiber über #define
15-04-2013-dr235 - konstanten für bellatrix-funktionen komplett ausgelagert
Notizen:
- setheader
ACHTUNG: Mit VGA-Treiber ist row nicht die Zeilenposition, da zwei Tiles untereinander ein
Zeichen bilden. Vielmehr ist die reale Zeilenposition row/2.
...oder allgemeingültig für VGA und TV: row/vdrv#TLINES_PER_ROW
}}
{{ 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 $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
}}
'#define __TV
'#define __VGA
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
' +----------
' | +------- system
' | | +---- version (änderungen)
' | | | +- subversion (hinzufügungen)
CHIP_VER = $00_01_02_02
#ifdef __TV
CHIP_SPEC = gc#b_tv|gc#b_key|gc#b_txt|gc#b_win
#endif
#ifdef __VGA
CHIP_SPEC = gc#b_vga|gc#b_key|gc#b_txt|gc#b_win
#endif
RESX = vdrv#COLS * 16
RESY = vdrv#ROWS * 16
TILES = vdrv#COLS * vdrv#ROWS
USERCHARS = 16 '8x2 logo
TABANZ = 8
SCROLLDIFF = vdrv#TLINES_PER_ROW * vdrv#COLS
CURSORCHAR = $0E 'cursorzeichen
SCREENS = 3 'anzahl der screens
WIN_P_SCR = 8 'Anzahl der Windows per Screen
OBJ
#ifdef __TV
vdrv : "belf-tv"
#endif
#ifdef __VGA
vdrv : "belf-vga"
#endif
keyb : "bel-keyb"
bus : "bel-bus"
gc : "glob-con" 'globale konstanten
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/vdrv#TLINES_PER_ROW*SCREENS] 'bildschirmpuffer
byte tab[TABANZ] 'tabulatorpositionen
word user_charbase 'adresse der userzeichen
byte wscrnr 'nummer ausgabescreens
word lchar 'letztes zeichen
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 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 ' muss in vdrv definiert werden!! '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
gc#b_keystat: key_stat 'tastaturstatus senden
gc#b_keycode: key_code 'tastaturzeichen senden
gc#b_printctrl: print_ctrl(bus.getchar) 'steuerzeichen ($100..$1FF) ausgeben
gc#b_keyspec: key_spec 'statustasten ($100..$1FF) abfragen
gc#b_printlogo: print_logo 'hive-logo ausgeben
gc#b_printqchar: pchar(bus.getchar) 'zeichen ohne steuerzeichen augeben
' ---------------------------------------------- WINDOW
gc#b_wdef: win_define
gc#b_wset: win_set(wscrnr)
gc#b_wgetcols: win_getcols
gc#b_wgetrows: win_getrows
gc#b_woframe: win_oframe
' ---------------------------------------------- CHIP-MANAGMENT
gc#b_mgrload: mgr_load 'neuen bellatrix-code laden
gc#b_mgrwscr: mgr_wscr 'setzt screen, in welchen geschrieben wird
gc#b_mgrdscr: mgr_dscr 'setzt screen, welcher angezeigt wird
gc#b_mgrgetcol: mgr_getcolor 'farbregister auslesen
gc#b_mgrsetcol: mgr_setcolor 'farbregister setzen
gc#b_mgrgetresx: mgr_getresx 'x-auflösung abfragen
gc#b_mgrgetresy: mgr_getresy 'y-auflösung abfragen
gc#b_mgrgetcols: mgr_getcols 'spaltenanzahl abfragen
gc#b_mgrgetrows: mgr_getrows 'zeilenanzahl abfragen
gc#b_mgrgetcogs: mgr_getcogs 'freie cogs abfragen
gc#b_mgrgetspec: mgr_getspec 'spezifikation abfragen
gc#b_mgrgetver: mgr_getver 'codeversion abfragen
gc#b_mgrreboot: reboot 'bellatrix neu starten
PUB init_subsysteme|i 'chip: initialisierung des bellatrix-chips
''funktionsgruppe : chip
''funktion : - initialisierung des businterface
'' : - vga & keyboard-treiber starten
''eingabe : -
''ausgabe : -
bus.init_bus
keyb.start(gc#b_keybd, gc#b_keybc) 'tastaturport starten
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
vdrv.start(@array)
repeat i from 0 to TABANZ-1 'tabulatoren setzen
tab[i] := i * 4
' Ein schönes Logo gibt's z.Z. nur bei VGA
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
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], vdrv#SPACETILE, tiles) ' CLS
cursor[i*WIN_P_SCR] := CURSORCHAR 'cursorzeichen setzen
curstat[i*WIN_P_SCR] := 1 'cursor anschalten
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++] := vdrv#COLS - 1 ' xn
windows[x++] := vdrv#ROWS - vdrv#TLINES_PER_ROW ' yn
repeat w from 1 to WIN_P_SCR - 1
windows[x++] := 0 ' x0
windows[x++] := vdrv#DEFAULT_Y0 ' y0
windows[x++] := vdrv#COLS - 1 ' xn
windows[x++] := vdrv#ROWS - vdrv#TLINES_PER_ROW ' yn
cursor[i*WIN_P_SCR+w] := CURSORCHAR
curstat[i*WIN_P_SCR+w] := 1
row[i*WIN_P_SCR+w] := vdrv#DEFAULT_Y0 'home
col[i*WIN_P_SCR+w] := 0 'pos1
color[i*WIN_P_SCR+w] := 0
this_win[i] := 1
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 * vdrv#TLINES_PER_ROW * scrnr 'display-index berechnen
dind := TILES * 2 * scrnr 'display-index berechnen
vdrv.set_dscr(@array+dind)
PUB mgr_getcolor|cnr 'cmgr: farbregister auslesen
''funktionsgruppe : cmgr
''funktion : farbregister auslesen
''eingabe : -
''ausgabe : -
''busprotokoll : [0][090][get.cnr][bus.putlong.color]
'' : cnr - nummer des farbregisters 0..15
'' : color - erster wert
cnr := bus.getchar
bus.putlong(vdrv.get_color(cnr))
PUB mgr_setcolor|cnr, colr 'cmgr: farbregister setzen
''funktionsgruppe : cmgr
''funktion : farbregister setzen
''eingabe : -
''ausgabe : -
''busprotokoll : [0][091][get.cnr][bus.getlong.color]
'' : cnr - nummer des farbregisters 0..15
'' : color - farbwert
cnr := bus.getchar
colr := bus.getlong
vdrv.set_color(cnr, colr)
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
bus.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
bus.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(vdrv#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(vdrv#ROWS/vdrv#TLINES_PER_ROW)
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][bus.putlong.spec]
'' : spec - spezifikation
''
''
'' +----------
'' | +-------- window
'' | |+------- vektor
'' | ||+------ grafik
'' | |||+----- text
'' | ||||+---- maus
'' | |||||+--- tastatur
'' | ||||||+-- vga
'' | |||||||+- tv
''CHIP_SPEC = %00000000_00000000_00000000_10010110
bus.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][bus.putlong.ver]
'' : ver - version
''
'' +----------
'' | +------- system
'' | | +---- version (änderungen)
'' | | | +- subversion (hinzufügungen)
''CHIP_VER = $00_01_02_01
bus.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]
plen := plen - 8
' objektlänge an regnatix senden
bus.putchar(plen >> 8) 'hsb senden
bus.putchar(plen & $FF) 'lsb senden
repeat i from 0 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 <# vdrv#COLS-1
y0 := (bus.getchar * vdrv#TLINES_PER_ROW) #> 0 <# vdrv#ROWS-1
xn := bus.getchar #> x0 <# vdrv#COLS-1
yn := (bus.getchar * vdrv#TLINES_PER_ROW) #> y0 <# vdrv#ROWS-1
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] := vdrv.get_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]
vdrv.set_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 + vdrv#TLINES_PER_ROW
nnl_idx := 1 << this_win[wscrnr]
cneeds_nl := needs_nl[wscrnr]
PUB win_getcols
bus.putchar(cwcols)
PUB win_getrows
bus.putchar(cwrows / vdrv#TLINES_PER_ROW)
PUB win_oframe | c, r
c := ccol ' aktuelle Werte aufheben und am Ende zuruecksetzen
r := crow
if cy0 ' oberer Rand ist sichtbar
crow := cy0 - vdrv#TLINES_PER_ROW
if cx0
ccol := cx0 - 1
schar(159)
repeat ccol from cx0 to cxn
schar(144) '-
if cxn < vdrv#COLS-1
ccol := cxn + 1
schar(158)
if cx0 ' linke Seite ist sichtbar
ccol := cx0 - 1
repeat crow from cy0 to cyn step vdrv#TLINES_PER_ROW
schar(145) '|
if cxn < vdrv#COLS-1 ' rechte Seite ist sichtbar
ccol := cxn + 1
repeat crow from cy0 to cyn step vdrv#TLINES_PER_ROW
schar(145) '|
if cyn < vdrv#ROWS - vdrv#TLINES_PER_ROW ' unterer Rand ist sichtbar
crow := cyn + vdrv#TLINES_PER_ROW
if cx0
ccol := cx0 - 1
schar(157)
repeat ccol from cx0 to cxn
schar(144) '-
if cxn < vdrv#COLS-1
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}}
'anpassung für die verschiedenen zeilenumbrüche
'damit sollten alle drei versionen funktionieren:
'dos/win: $0d $0a
'unix/linux: $0a
'mac: $0d
if c == $0a and lchar == $0d
c := 0
lchar := c
case c
$0E..$FF: 'character?
pchar(c)
if ccurstat == 1
schar(ccursor)
return
gc#b_cls: 'clear screen?
n := wind + cy0 * vdrv#COLS + cx0 ' links oben
repeat cwrows
wordfill(@array.word[n], vdrv#SPACETILE, cwcols)
n += vdrv#COLS
crow := cy0
ccol := cx0
needs_nl[wscrnr] &= !nnl_idx
if ccurstat == 1 'cursor einschalten
schar(ccursor)
gc#b_home: 'home?
cneeds_nl &= !nnl_idx
if ccurstat == 1
schar($20)
crow := cy0
ccol := cx0
if ccurstat == 1
schar(ccursor)
gc#b_pos1: 'pos1
cneeds_nl &= !nnl_idx
if ccurstat == 1
schar($20)
ccol := cx0
if ccurstat == 1
schar(ccursor)
gc#b_curon: 'curon
if cneeds_nl & nnl_idx
newline
cneeds_nl ^= nnl_idx
ccurstat := 1
schar(ccursor)
gc#b_curoff: 'curoff
if ccurstat == 1
schar($20)
ccurstat := 0
gc#b_scrollup: 'scrollup
if ccurstat == 1
schar($20)
scrollup
if ccurstat == 1
schar(ccursor)
gc#b_scrolldown: 'scrolldown
if ccurstat == 1
schar($20)
scrolldown
if ccurstat == 1
schar(ccursor)
gc#b_backspace: 'backspace?
cneeds_nl &= !nnl_idx
if ccol > cx0
if ccurstat == 1
schar($20)
ccol--
if ccurstat == 1
schar(ccursor)
gc#b_tab: 'tab
repeat n from 0 to TABANZ-1
if ccol < tab[n] + cx0
if ccurstat == 1
schar($20)
ccol := tab[n] + cx0
if ccurstat == 1
schar(ccursor)
quit
gc#b_lf: 'LF ausblenden
cneeds_nl &= !nnl_idx
if ccurstat == 1
schar($20)
newline
if ccurstat == 1
schar(ccursor)
gc#b_crlf: 'return?
if ccurstat == 1
schar($20)
newline
if ccurstat == 1
schar(ccursor)
PUB print_ctrl(c) | code,n,m 'screen: steuerzeichen ausgeben
case c
gc#b_setcur: 'setcur
code := bus.getchar
ccursor := code
if ccurstat == 1
schar(code)
gc#b_setx: 'setx
if ccurstat == 1
schar($20)
cneeds_nl &= !nnl_idx
ccol := bus.getchar #> 0 <# vdrv#COLS-1
if ccurstat == 1
schar(ccursor)
gc#b_sety: 'sety
if ccurstat == 1
schar($20)
cneeds_nl &= !nnl_idx
crow := (bus.getchar * vdrv#TLINES_PER_ROW) #> 0 <# vdrv#ROWS-vdrv#TLINES_PER_ROW
if ccurstat == 1
schar(ccursor)
gc#b_getx: 'getx
bus.putchar(ccol)
gc#b_gety: 'gety
bus.putchar(crow / vdrv#TLINES_PER_ROW)
gc#b_setcol: 'setcolor
vdrv.set_ccolor(bus.getchar)
gc#b_sinit: 'screeninit
screen_init(wscrnr)
set_current_win
gc#b_tabset: 'tabulator setzen
n := bus.getchar
m := bus.getchar
if n =< (TABANZ-1)
tab[n] := m
gc#b_wsetx: 'winsetx
if ccurstat == 1
schar($20)
cneeds_nl &= !nnl_idx
code := bus.getchar
ccol := ~code #> -cwcols <# cwcols-1 ' negativ --> Abstand von rechts+1
if code < 0
ccol += cxn + 1
else
ccol += cx0
if ccurstat == 1
schar(ccursor)
gc#b_wsety: 'winsety
if ccurstat == 1
schar($20)
cneeds_nl &= !nnl_idx
code := bus.getchar
~code
crow := (code * vdrv#TLINES_PER_ROW) #> -cwrows <# cwrows-vdrv#TLINES_PER_ROW '2 tiles pro zeichen!
if code < 0
crow += cyn + vdrv#TLINES_PER_ROW
else
crow += cy0
if ccurstat == 1
schar(ccursor)
gc#b_wgetx: 'wingetx
bus.putchar(ccol - cx0)
gc#b_wgety: 'wingety
bus.putchar((crow - cy0) / vdrv#TLINES_PER_ROW)
PRI schar(c)
vdrv.schar(crow * vdrv#COLS + ccol + wind, c)
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 += vdrv#TLINES_PER_ROW) > cyn
crow -= vdrv#TLINES_PER_ROW
scrollup
PUB scrollup | zadr 'screen: scrollt den screen nach oben
' Start: linke obere Ecke, Breite: Window-Breite, Schrittweite: absolute Screen-Breite
zadr := wind + cy0 * vdrv#COLS + cx0 ' links oben
repeat cwrows-vdrv#TLINES_PER_ROW
wordmove(@array.word[zadr], @array.word[zadr+SCROLLDIFF], cwcols)
zadr += vdrv#COLS
'clear new line
wordfill(@array.word[zadr], vdrv#SPACETILE, cwcols)
if vdrv#TLINES_PER_ROW > 1
wordfill(@array.word[zadr+vdrv#COLS], vdrv#SPACETILE, cwcols)
PUB scrolldown | zadr 'screen: scrollt den screen nach unten
zadr := wind + (cyn+vdrv#TLINES_PER_ROW-1) * vdrv#COLS + cx0 ' links unten
repeat cwrows-vdrv#TLINES_PER_ROW
wordmove(@array.word[zadr], @array.word[zadr-SCROLLDIFF], cwcols)
zadr -= vdrv#COLS
'clear new line
wordfill(@array.word[zadr], vdrv#SPACETILE, cwcols)
if vdrv#TLINES_PER_ROW > 1
wordfill(@array.word[zadr-vdrv#COLS], vdrv#SPACETILE, cwcols)
PRI print_logo|x,y 'screen: hive-logo ausgeben
x := bus.getchar
y := bus.getchar
_print_logo(x,y)
#ifdef __TV
PRI _print_logo(x,y)|c, r
c := ccol
r := crow
ccol := x #> 0 <# vdrv#COLS-1
crow := (y * vdrv#TLINES_PER_ROW) #> 0 <# vdrv#ROWS-vdrv#TLINES_PER_ROW '2 tiles pro zeichen!
pchar(" ")
pchar("H")
pchar("i")
pchar("v")
pchar("e")
ccol := c
crow := r
#endif
#ifdef __VGA
PRI _print_logo(x,y)|padr
padr := @hive+user_charbase-@uchar
print_uchar(padr, x, y, 8, 2, 1) 'logo zeichnen
#endif
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 * vdrv#COLS + xPos + wind] := pBMP + (c<<6) + clr
c++
xPos++
yPos++
xPos:=t
DAT
org
'
' Entry: dummy-assemblercode fuer cogtest
'
entry jmp entry 'just loops
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

Binary file not shown.

View File

@ -0,0 +1,275 @@
{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fcharset0 Arial;}}
{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\lang1031\f0\fs20 char y=0, x=0 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=0, x=1 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0003_3333_3300_0000\par
LONG %%0033_3000_3330_0000\par
LONG %%0330_0000_0033_0000\par
LONG %%3300_0000_0003_3000\par
LONG %%3300_0000_0000_3000\par
LONG %%3000_0000_0000_3300\par
LONG %%3000_0000_0000_3300\par
LONG %%3300_0000_0000_3000\par
LONG %%3300_0000_0003_3000\par
LONG %%0330_0000_0033_0000\par
LONG %%0033_3000_0333_0000\par
LONG %%0033_3333_3330_0000\par
LONG %%0333_0000_0333_0000\par
char y=0, x=2 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=0, x=3 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3003_3330_0333_3300\par
LONG %%3033_3333_0333_3300\par
LONG %%3033_3333_0333_3300\par
char y=0, x=4 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%3000_3333_0000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%3000_3333_0000_3333\par
LONG %%3000_0000_0000_3333\par
LONG %%3000_0000_0000_3333\par
char y=0, x=5 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
char y=0, x=6 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%3333_3000_0000_0033\par
LONG %%3333_3333_0000_0033\par
LONG %%3333_3333_3000_0033\par
LONG %%3333_3333_3300_0033\par
LONG %%3333_3333_3330_0033\par
LONG %%0000_3333_3330_0033\par
LONG %%0000_0033_3333_0033\par
LONG %%3333_0003_3333_0033\par
char y=0, x=7 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=0 \par
LONG %%0000_0000_0000_0000\par
LONG %%3330_0000_0000_0000\par
LONG %%0033_3000_0000_0000\par
LONG %%0000_3300_0000_0000\par
LONG %%0000_3300_0000_0000\par
LONG %%0000_0330_0000_0000\par
LONG %%0000_0330_0000_0000\par
LONG %%0000_0330_0000_0000\par
LONG %%0000_0330_0000_0000\par
LONG %%0000_3300_0000_0000\par
LONG %%0003_3000_0000_0000\par
LONG %%0333_0000_0000_0000\par
LONG %%3330_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=1 \par
LONG %%3330_0000_0033_3000\par
LONG %%3300_0000_0003_3333\par
LONG %%3300_0000_0003_3300\par
LONG %%0330_0000_0033_0000\par
LONG %%0033_0000_0030_0000\par
LONG %%0033_0000_0330_0000\par
LONG %%0003_3333_3330_0000\par
LONG %%0003_3333_3330_0000\par
LONG %%0033_0000_0330_0000\par
LONG %%0033_0000_0030_0000\par
LONG %%0330_0000_0033_0000\par
LONG %%3300_0000_0003_3330\par
LONG %%0000_0000_0000_0333\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=2 \par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0033_3333\par
LONG %%0000_0000_3330_0000\par
LONG %%0000_0000_3300_0000\par
LONG %%0000_0003_3000_0000\par
LONG %%0000_0003_0000_0000\par
LONG %%0000_0033_0000_0000\par
LONG %%0000_0003_0000_0000\par
LONG %%0000_0003_0000_0000\par
LONG %%0000_0003_3000_0000\par
LONG %%0000_0000_3300_0000\par
LONG %%0000_0000_0333_3033\par
LONG %%0000_0000_0003_3333\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=3 \par
LONG %%3033_3333_0333_3300\par
LONG %%3033_3333_0333_3300\par
LONG %%3003_3330_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%3000_0000_0333_3300\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=4 \par
LONG %%3003_3333_3000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%3003_3333_3000_3333\par
LONG %%0003_3333_3000_3333\par
LONG %%0003_3333_3000_3333\par
LONG %%0003_3333_3000_3333\par
LONG %%0003_3333_3000_3333\par
LONG %%0003_3333_3000_3333\par
LONG %%0003_3333_3000_3333\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=5 \par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0000_3333\par
LONG %%3330_0000_0003_3333\par
LONG %%3330_0000_0003_3333\par
LONG %%3330_0000_0033_3333\par
LONG %%3333_3333_3333_3333\par
LONG %%3333_3333_3333_3330\par
LONG %%3333_3333_3333_3300\par
LONG %%3333_3333_3333_3000\par
LONG %%3333_3333_3330_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=6 \par
LONG %%3333_3003_3333_0033\par
LONG %%3333_3003_3333_0033\par
LONG %%3333_3003_3333_0033\par
LONG %%3333_3003_3333_0033\par
LONG %%3333_0033_3333_0033\par
LONG %%0000_3333_3330_0033\par
LONG %%3333_3333_3330_0033\par
LONG %%3333_3333_3300_0033\par
LONG %%3333_3333_3000_0033\par
LONG %%3333_3333_0000_0033\par
LONG %%3333_3000_0000_0033\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
char y=1, x=7 \par
LONG %%0000_0000_0000_0003\par
LONG %%0000_0000_0000_0003\par
LONG %%0000_0000_0000_0003\par
LONG %%0000_0000_0000_0003\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_3333\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
LONG %%0000_0000_0000_0000\par
}

Binary file not shown.

5956
flash/regnatix/regflash.spin Normal file

File diff suppressed because it is too large Load Diff

90
forth/adm.lib Normal file
View File

@ -0,0 +1,90 @@
hex
ifnot: lib:adm
: lib:adm ;
\ kommandoformen
ifnot: adm:fkt! \ ( fkt -- )
: adm:fkt! b[ [a!] ]b ;
ifnot: adm:fkt!b! \ ( b fkt -- )
: adm:fkt!b! b[ [a!] [a!] ]b ;
ifnot: adm:fkt!b@ \ ( fkt -- b )
: adm:fkt!b@ b[ 0 [a!] [a!] [a@] ]b ;
ifnot: adm:fkt!b!b@ \ ( b fkt -- b )
: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ;
ifnot: adm:fkt!l@ \ ( fkt -- l )
: adm:fkt!l@ b[ [a!] [a.l@] ]b ;
ifnot: adm:fkt!s! \ ( s fkt -- )
: adm:fkt!s! b[ [a!] [a.s!] ]b ;
\ administra-chipmanagment-funktionen
\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten
\ sfkt:
\ 0: hss-engine abschalten
\ 1: hss-engine anschalten
\ 2: dac-engine abschalten
\ 3: dac-engine anschalten
\ sstat - status/cognr startvorgang
ifnot: adm:setsound
: adm:setsound
5C adm:fkt!b!b@ ;
\ adm:getspec ( -- spec ) - chipspezifikation abfragen
\
\ +---------- com
\ | +-------- i2c
\ | |+------- rtc
\ | ||+------ lan
\ | |||+----- sid
\ | ||||+---- wav
\ | |||||+--- hss
\ | ||||||+-- bootfähig
\ | |||||||+- dateisystem
\ %00000000_00000000_00000000_01001111
ifnot: adm:getspec
: adm:getspec
5D adm:fkt!l@ ;
\ adm:setsyssound ( syssnd -- ) - systemklänge
\ syssnd = 0 - systemklänge aus
\ syssnd = 1 - systemklänge an
ifnot: adm:setsyssound
: adm:setsyssound
5E adm:fkt!b! ;
\ adm:getsoundsys ( -- sndsys ) - abfrage aktives soundsystem
\ 0 - sound aus
\ 1 - hss
\ 2 - wav
ifnot: adm:getsoundsys
: adm:getsoundsys
5F adm:fkt!b@ ;
\ adm:load ( cstr -- ) - neuen administra-code laden
ifnot: adm:aload
: adm:aload
60 adm:fkt!s! ;
\ adm:getcogs ( -- cogs ) - anzahl der belegten cogs
ifnot: adm:getcogs
: adm:getcogs
61 adm:fkt!b@ ;
\ adm:getver ( -- ver ) - abfrage der codeversion
ifnot: adm:getver
: adm:getver
62 adm:fkt!l@ ;
\ adm:reset ( -- ) - reset administra
ifnot: adm:reset
: adm:reset
63 adm:fkt! ;

55
forth/ari.lib Normal file
View File

@ -0,0 +1,55 @@
hex
ifnot: lib:ari
: lib:ari ;
\ abs ( n1 -- abs_n1 ) absolute value of n1
ifnot: abs
: abs _execasm1>1 151 _cnip ;
\ u*/mod ( u1 u2 u3 -- u4 u5 ) u5 = (u1*u2)/u3, u4 is the
\ remainder. Uses a 64bit intermediate result.
ifnot: u*/mod
: u*/mod rot2 um* rot um/mod ;
\ u*/ ( u1 u2 u3 -- u4 ) u4 = (u1*u2)/u3 Uses a 64bit
\ intermediate result.
ifnot: u*/
: u*/ rot2 um* rot um/mod nip ;
\ sign ( n1 n2 -- n3 ) n3 is the xor of the sign bits of
\ n1 and n2
ifnot: sign
: sign xor 80000000 and ;
\ */mod ( n1 n2 n3 -- n4 n5 ) n5 = (n1*n2)/n3, n4 is the
\ remainder. Uses a 64bit intermediate result.
ifnot: */mod
: */mod 2dup sign >r abs rot dup r> sign >r abs rot abs
um* rot um/mod r> if negate swap negate swap then ;
\ */ ( n1 n2 n3 -- n4 ) n4 = (n1*n2)/n3. Uses a 64bit
\ intermediate result.
ifnot: */
: */ */mod nip ;
\ /mod ( n1 n2 -- n3 n4 ) \ signed divide & mod n4 = n1/n2,
\ n3 is the remainder
ifnot: /mod
: /mod 2dup sign >r abs swap abs swap u/mod r> if negate swap
negate swap then ;
\ * ( n1 n2 -- n1*n2) n1 multiplied by n2
ifnot: *
: * um* drop ;
\ / ( n1 n2 -- n1/n2) n1 divided by n2
ifnot: /
: / /mod nip ;
\ rnd ( -- n1 ) n1 is a random number from 00 - FF
ifnot: rnd
: rnd cnt COG@ 8 rshift cnt COG@ xor FF and ;

485
forth/basics.mod Normal file
View File

@ -0,0 +1,485 @@
fl
hex
: mod:basics ;
\ Copyright (c) 2010 Sal Sanci
\ Anpassung für Hive-System 2011 dr235
\ ------------------------------------------------------ BASICS
\ this words needs to align with the assembler code
: _stptr 5 _cv ;
: _sttop 2e _cv ;
\ _words ( cstr -- )
: _words lastnfa
begin
2dup swap dup if npfx else 2drop -1 then
if dup .strname space then
nfa>next dup 0=
until 2drop cr ;
\ words name ( -- ) prints the words in the forth dictionary
: words parsenw _words ;
\ .long ( n -- ) emit 8 hex digits
: .long dup 10 rshift .word .word ;
\ st? ( -- ) prints out the stack
: st? ." ST: " _stptr COG@ 2+ dup _sttop <
if _sttop swap - 0
do _sttop 2- i - COG@ .long space loop
else drop
then cr ;
\ variable ( -- ) skip blanks parse the next word and create
\ a variable, allocate a long, 4 bytes
: variable
lockdict create $C_a_dovarl w, 0 l, forthentry freedict ;
\ constant ( x -- ) skip blanks parse the next word and create
\ a constant, allocate a long, 4 bytes
: constant
lockdict create $C_a_doconl w, l, forthentry freedict ;
\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to
\ ina anded with n2
: waitpeq _execasm2>0 1E0 _cnip ;
\ locknew ( -- n2 ) allocate a lock, result is in n2, -1
\ if unsuccessful
: locknew -1 4 hubop -1 = if drop -1 then ;
\ (forget) ( cstr -- ) wind the dictionary back to the word
\ which follows - caution
: (forget) dup
if
find if
pfa>nfa nfa>lfa dup here W! W@ wlastnfa W!
else .cstr 3f emit cr then
else drop then ;
\ forget ( -- ) wind the dictionary back to the word which
\ follows - caution
: forget parsenw (forget) ;
\ free ( -- ) display free main bytes and current cog longs
: free dictend W@ here W@ - . ." bytes free - " par
coghere W@ - . ." cog longs free" cr ;
\ ifnot: name ( -- ) - bedingte compilierung; wenn name schon
\ im wörterbuch vorhanden, wird bis zum nächsten semikolon
\ der eingabestrom ignoriert
: ifnot: parsenw nip find if begin key 3B = until
key drop then ;
\ bei konstrukte, die keine doppelpunkdefinition sind, muss der
\ block mit diesem Wort abgeschlossen werden
: :; ;
\ --------------------------------------------------------- BUS
\ bin ( -- ) - umschaltung auf duales zahlensystem
\ : bin 2 base W! ;
\ +---------------------------- /hs
\ |+--------------------------- /wr
\ ||+-------------------------- busclk
\ |||+------------------------- hbeat
\ ||||+------------------------ al
\ |||||+----------------------- /bel
\ ||||||+---------------------- /adm
\ |||||||+--------------------- /ram2
\ ||||||||+-------------------- /ram1
\ ||||||||| +--------- a0..10
\ ||||||||| |
\ ||||||||| | +- d0..7
\ |||||||||+---------++------+
\ 00000000000000000000000000000000
\ bin 00000111111111111111111100000000 constant dinp hex
\ bin 00000111111111111111111111111111 constant dout hex
\ bin 00000010000000000000000000000000 constant boff hex
\ bin 00000100011110000000000000000000 constant _s1 hex
\ bin 00000000001110000000000000000000 constant _b1 hex
\ bin 00000010001110000000000000000000 constant _b2 hex
\ bin 00000110001110000000000000000000 constant _b3 hex
\ bin 00000000010110000000000000000000 constant _a1 hex
\ bin 00000010010110000000000000000000 constant _a2 hex
\ bin 00000110010110000000000000000000 constant _a3 hex
\ bin 00001000000000000000000000000000 constant ?hs hex
8000000 constant ?hs
: [inp] \ ( -- ) bus eingabe
7FFFF00 dira COG! ; \ dinp
: [out] \ ( -- ) bus ausgabe
7FFFFFF dira COG! ; \ dout
: [off] \ ( -- ) bus aus
2000000 dira COG! 0 outa COG! ; \ boff
: [end] \ ( -- ) buskommunikation beendet
4780000 outa COG! [inp] ; \ _s1
: [hs=1] \ ( -- ) wartet auf hs = 1
?hs dup waitpeq ;
: [hs=0] \ ( -- ) warten auf hs = 0
0 ?hs waitpeq ;
: [s!] \ ( c ctrl -- ) sende 8 bit an einen slave
[out] [hs=1] swap ff and or outa COG! [hs=0] [end] ;
: [s@] \ ( ctrl -- c ) empfängt 8 bit von einem slave
[inp] [hs=1] outa COG! [hs=0] ina COG@ ff and [end] ;
: [b!] \ ( c -- ) sende 8 bit an bellatrix
2380000 [s!] ; \ _b2
: [a!] \ ( c -- ) sende 8 bit an administra
2580000 [s!] ; \ _a2
: [b@] \ ( -- c ) empfängt 8 bit von bellatrix
6380000 [s@] ; \ _b3
: [a@] \ ( -- c ) empfängt 8 bit von administra
6580000 [s@] ; \ _a3
: <8 \ ( -- )
8 lshift ;
\ [b.l!] ( 32b -- ) - long an bellatrix senden
: [b.l!]
dup 18 rshift [b!]
dup 10 rshift [b!]
dup 8 rshift [b!]
[b!] ;
\ [b.l@] ( -- 32b ) - long von bellatrix einlesen
: [b.l@]
[b@] <8
[b@] or <8
[b@] or <8
[b@] or ;
\ [a.s@] ( -- ) - einen cstring von administra empfangen
\ und im pad speichern
: [a.s@]
[a@] pad 2dup C! 1+ swap
0 do dup [a@] swap C! 1+ loop drop ;
\ [a.s!] ( cstr -- ) - einen cstring an administra senden
: [a.s!]
dup C@ dup [a!] \ ( -- cstr len ) len senden
0 do \ ( cstr len -- cstr )
1+ dup C@ [a!] \ ( cstr -- cstr+1 ) zeichen senden
loop drop ; \ ( cstr -- )
\ [a.w@] ( -- 16b ) - 16bit-wert von administra einlesen
: [a.w@]
[a@] <8 [a@] or ;
\ [a.l!] ( 32b -- ) - long an administra senden
: [a.l!]
dup 18 rshift [a!]
dup 10 rshift [a!]
dup 8 rshift [a!]
[a!] ;
\ [a.l@] ( -- 32b ) - long von administra einlesen
: [a.l@]
[a@] <8
[a@] or <8
[a@] or <8
[a@] or ;
wvariable b[lock] \ nummer der semaphore für den
\ zugriff auf die bus-hardware
\ b[ ( -- ) bus belegen; wartet bis semaphore freigegeben ist
: b[ begin b[lock] W@ lockset -1 <> until [inp] ;
\ ]b ( -- ) bus freigeben
\ ! busclk bleibt auf ausgabe, da dieses signal sonst
\ kein definierten pegel besitzt !
: ]b [off] b[lock] W@ lockclr drop ;
\ administra-kommandoformate
: b[a! b[ [a!] ;
: b[a!a! b[ [a!] [a!] ;
: adm:fkt! b[a! ]b ; \ ( fkt -- )
: adm:fkt!b@ b[a! [a@] ]b ; \ ( fkt -- b )
: adm:fkt!b! b[a!a! ]b ; \ ( b fkt -- )
: adm:fkt!b!b@ b[a!a! [a@] ]b ; \ ( b fkt -- b )
: adm:fkt!s@ b[a! [a.s@] ]b ; \ ( fkt -- )
: adm:fkt!s!b@ b[a! [a.s!] [a@] ]b ; \ ( s fkt -- b )
: adm:fkt!b!l@ b[a!a! [a.l@] ]b ; \ ( b fkt -- l )
\ ----------------------------------------------------- SD0.LIB
\ marker-funktionen
\ adm:dmact ( dmnr -- ) - marker aktivieren
: adm:dmact 19 adm:fkt!b!b@ drop ;
\ adm:dmset ( dmnr -- ) - marker setzen
: adm:dmset 1A adm:fkt!b! ;
\ dateisystem-funktionen
\ adm:volname ( -- ) - name des volumes im pad ablegen
: adm:volname 0C adm:fkt!s@ ;
\ adm:mount ( -- err ) - medium mounten
: adm:mount 01 adm:fkt!b@ ;
\ adm:unmount ( -- err ) - medium unmounten
: adm:unmount 18 adm:fkt!b@ ;
\ adm:checkmounted ( -- t/f )
: adm:checkmounted 0D adm:fkt!b@ ;
\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren
: adm:diropen 02 adm:fkt! ;
\ adm:nextfile ( -- st )
\ st = 0 - keine gültige datei
\ st = 1 - dateiname im pad gültig
\ bei gültigem eintrag befindet sich der dateiname im pad
: adm:nextfile b[ 3 [a!] [a@] dup if [a.s@] then ]b ;
\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen
: adm:fattrib 0B adm:fkt!b!l@ ;
\ adm:chdir ( cstr -- err ) - verzeichnis öffnen
: adm:chdir 16 adm:fkt!s!b@ ;
\ adm:getc ( -- c ) - ein zeichen aus der geöffneten datei lesen
: adm:getc 06 adm:fkt!b@ ;
\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist
: adm:eof 1E adm:fkt!b@ ;
\ adm:open ( cstr modus -- err ) - datei öffnen
\ modus "R" $52 - Read
\ modus "W" $57 - Write
\ modus "A" $41 - Append
: adm:open b[ 4 [a!] [a!] [a.s!] [a@] ]b ;
\ adm:close ( -- ) - datei schließen
: adm:close 05 adm:fkt!b@ ;
\ ----------------------------------------------------- SCR.LIB
\ [dscr] ( scrnr -- ) display-screen setzen
: [dscr] 0 [b!] 59 [b!] [b!] ;
\ [wscr] ( scrnr -- ) schreib-screen setzen
: [wscr] 0 [b!] 58 [b!] [b!] ;
\ [key?] ( -- c ) - ungekapselte tastaturstatusabfrage
: [key?] 0 [b!] 1 [b!] [b@] ;
\ [key] ( -- c ) - ungekapselte tastaturabfrage
: [key] 0 [b!] 2 [b!] [b@] ;
\ [emit] ( c -- ) - ungekapselte zeichenausgabe
: [emit] emit? if emit then ;
\ ----------------------------------------------------- TOOLS
\ cls ( -- ) - screen löschen
: cls 01 emit ;
\ .tab ( -- ) - tabulator
: .tab 09 emit ;
\ .err ( err -- ) - fehlermeldung ausgeben
\ 0 no error
\ 1 fsys unmounted
\ 2 fsys corrupted
\ 3 fsys unsupported
\ 4 not found
\ 5 file not found
\ 6 dir not found
\ 7 file read only
\ 8 end of file
\ 9 end of directory
\ 10 end of root
\ 11 dir is full
\ 12 dir is not empty
\ 13 checksum error
\ 14 reboot error
\ 15 bpb corrupt
\ 16 fsi corrupt
\ 17 dir already exist
\ 18 file already exist
\ 19 out of disk free space
\ 20 disk io error
\ 21 command not found
\ 22 timeout
\ 23 parameter error
: .err dup if ERR then drop ;
\ .pad ( -- ) - ausgabe eines strings im pad
: .pad pad .cstr ;
\ .vname ( -- ) - ausgabe des namens der eingelegten sd-card
: .vname adm:volname .pad ;
\ mount ( -- ) - sd-card mounten
: mount adm:mount .err ." Medium : " .vname cr ;
\ unmount ( -- ) - sd-card unmounten
: unmount adm:unmount .err ;
\ mount? ( -- ) - test ob medium mounted ist
\ wird als exception gewertet
: mount? adm:checkmounted 0= if 1 .err then ;
\ padbl ( -- ) fills this cogs pad with blanks
: padbl pad padsize bl fill ;
\ .entry ( -- st ) - einen verzeichniseintrag ausgeben
: .entry
adm:nextfile 13 adm:fattrib if 0F emit else space then
dup if .pad .tab then ;
\ .len ( st -- st ) - dateilänge ausgeben
: .len dup if 0 adm:fattrib . then ;
\ lscnt ( cnt1 st -- cnt2 st ) - spaltenformatierung für ls
\ cnt - spaltenzähler, st - flag verzeichnisende
: lscnt
swap 1+ dup 4 = if cr drop 0 else .tab then swap ;
\ lsl ( -- ) - verzeichnis anzeigen, long-format
: lsl mount?
adm:diropen begin .entry .len cr 0= until padbl ;
\ ls ( -- ) - verzeichnis in spalten anzeigen
: ls mount?
adm:diropen 0 begin .entry lscnt 0= until drop padbl cr ;
\ cd name ( -- ) - verzeichnis wechseln
: cd mount? parsenw adm:chdir .err ;
\ open name ( -- ) - datei lesend öffnen und auf fehler prüfen
: open
mount? parsenw dup
if 52 adm:open else drop 23 then .err ;
\ close ( -- ) - geöffnete datei schließen
: close adm:close .err ;
\ dload name - datei compilieren; log im gleichen screen
\ load name - datei compilieren; log screen 3
\ sys name - datei aus sys compilieren; log screen 3
\ die datei wird in der nächsten freien cog compiliert
\ fl ist für load nicht nötig und bringt in dem kontext
\ die cog-zuordnung durcheinander
: (load)
begin adm:getc emit adm:eof until ;
: (dload)
open cogid nfcog iolink
(load)
cogid iounlink close ;
: (sload)
open cogid 3 dup b[ [wscr] ]b iolink
(load)
cogid dup b[ [wscr] ]b iounlink close ;
: load
." Loading... " (sload) ;
: dload
(dload) ;
: sys
2 adm:dmset 1 adm:dmact ." Loading... " (sload) 2 adm:dmact ;
\ ------------------------------------------------- SPIN-LOADER
\ (spin) ( cstr -- ) - c" reg.sys" (spin)
: (spin)
dup C@ 1+
0 do
dup i + C@
ldvar 1+ i + C!
loop drop
1 ldvar C!
;
\ spin name ( -- ) - spinobjekt "name" starten
: spin
parsenw (spin) ;
\ regime ( -- ) - startet dir trios-cli "regime"
: regime
0 adm:dmact
c" reg.sys" (spin) ;
\ ----------------------------------------------------- DRV:INT
wvariable icog \ nummer der drv:int-cog
wvariable lcog \ nummer interaktiven cog
\ xint ( n -- ) io von cog n auf drv:int umschalten
: xint icog W@ ioconn ;
\ [cogscr] ( nr -- ) - umschaltung screen + cog
: [cogscr]
dup 2dup lcog W! xint [dscr] [wscr] ;
\ =n ( n1 n2 -- n1 n1=n2 )
: =n 2dup = swap drop ;
\ [esc] ( -- ) - manager für esc-funktionen im drv:int
: [esc]
begin [key?] until [key]
71 =n if 1b [emit] then \ esc - q : esc-char/quit
31 =n if 1 [cogscr] then \ esc - 1 : cog-screen 0
32 =n if 2 [cogscr] then \ esc - 2 : cog-screen 1
33 =n if 3 [cogscr] then \ esc - 3 : cog-screen 2
62 =n if lcog W@ cogreset then \ esc - b : break (cog)
72 =n if reboot then \ esc - r : reset (chip)
drop ; \ esc - esc : pause
\ drv:int ( -- ) treiber für bellatrix-terminal
\ diese cog fragt in einer endlosschleife ab, ob zeichen
\ versendet oder empfangen werden sollen. um die zeichenausgabe
\ zu beschleunigen, findet ausgabe und eingabe in einem
\ verhältnis von 512:1 statt. per esc-code können spezielle
\ funktionen im driver ausgelöst werden.
: drv:int
\ name und typ der cog einstellen
cogid dup cogstate 10 swap C! c" drv:int" over
cognumpad ccopy
20 delms 0D emit \ verzögertes cr für prompt
begin
\ input --> vga/video
200 0 do key? \ eingabezeichen vorhanden?
if key b[ [b!] ]b then loop \ cog ---> bel.vga
\ output <-- keyboard
b[ [key?] \ tastenstatus bellatrix?
if [key] dup 1b = if drop [esc] else [emit] thens ]b
0 until ;
\ ----------------------------------------------------- SYSINIT
: start \ ( -- ) initialisierung hive
locknew b[lock] W! \ b-semaphore
0 dup cogstate 10 swap C! c" drv:ldr" over
cognumpad ccopy
5 dup icog W! c" drv:int" swap cogx 1 b[ [cogscr] ]b ;
: _ob onboot ;
: onboot _ob start ;

81
forth/bel.lib Normal file
View File

@ -0,0 +1,81 @@
hex
ifnot: lib:bel
: lib:bel ;
ifnot: [b.w!]
: [b.w!] \ ( 16b -- ) - word an bellatrix senden
dup 8 rshift [b!] [b!] ;
\ kommandoformate
ifnot: bel:fkt! \ ( fkt -- )
: bel:fkt! b[ 0 [b!] [b!] ]b ;
ifnot: bel:fkt!b! \ ( b fkt -- )
: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ;
ifnot: bel:fkt!b!l@ \ ( b fkt -- l )
: bel:fkt!b!l@ b[ 0 [b!] [b!] [b!] [b.l@] ]b ;
ifnot: bel:fkt!b!l! \ ( l b fkt -- )
: bel:fkt!b!l! b[ 0 [b!] [b!] [b!] [b.l!] ]b ;
ifnot: bel:fkt!l@ \ ( fkt -- l )
: bel:fkt!l@ b[ 0 [b!] [b!] [b.l@] ]b ;
ifnot: bel:fkt!b@ \ ( fkt -- b )
: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ;
\ chipmanagment-funktionen
ifnot: bel:wscr \ ( scrnr -- ) - schreibscreen setzen
: bel:wscr 58 bel:fkt!b! ;
ifnot: bel:dscr \ ( scrnr -- ) - displayscreen setzen
: bel:dscr 59 bel:fkt!b! ;
ifnot: bel:getcol \ ( colnr -- col ) - farbe abfragen
: bel:getcol 5A bel:fkt!b!l@ ;
ifnot: bel:setcol \ ( col colnr -- ) - farbe setzen
: bel:setcol 5B bel:fkt!b!l! ;
ifnot: bel:getresx \ ( -- resx ) - abfrage x-auflösung
: bel:getresx 5C bel:fkt!l@ ;
ifnot: bel:getresy \ ( -- resy ) - abfrage y-auflösung
: bel:getresy 5D bel:fkt!l@ ;
ifnot: bel:getcols \ ( -- cols ) - abfrage textspalten
: bel:getcols 5E bel:fkt!b@ ;
ifnot: bel:getrows \ ( -- rows ) - abfrage textzeilen
: bel:getrows 5F bel:fkt!b@ ;
ifnot: bel:getcogs \ ( -- cogs ) - abfrage belegte cogs
: bel:getcogs 60 bel:fkt!b@ ;
ifnot: bel:getspec \ ( -- spec ) - abfrage codespezifikation
: bel:getspec 61 bel:fkt!l@ ;
ifnot: bel:getver \ ( -- ver ) - abfrage codeversion
: bel:getver 62 bel:fkt!l@ ;
ifnot: bel:load \ ( cstr -- ) - bellatrix-code laden
: bel:load
52 adm:open .err \ datei öffnen
b[
0 [b!] 57 [b!] \ bella-loader starten
10 0 do 06 [a!] [a@] [b!] loop \ header einlesen
0A [a!] 0 [a.l!] \ 0 adm:seek
[b@] <8 [b@] or \ dateilänge empfangen
0 do 06 [a!] [a@] [b!] loop \ datei senden
]b
adm:close .err \ datei schließen
;

74
forth/cog.lib Normal file
View File

@ -0,0 +1,74 @@
hex
ifnot: lib:cog
: lib:cog ;
\ cog special register
ifnot: ctra 1F8 wconstant ctra :;
ifnot: ctrb 1F9 wconstant ctrb :;
ifnot: frqa 1FA wconstant frqa :;
ifnot: frqb 1FB wconstant frqb :;
ifnot: phsa 1FC wconstant phsa :;
ifnot: phsb 1FD wconstant phsb :;
ifnot: vcfg 1FE wconstant vcfg :;
ifnot: vscl 1FF wconstant vscl :;
\ this words needs to align with the assembler code
ifnot: _faddrmask : _faddrmask 1 _cv ;
ifnot: _flongmask : _flongmask 2 _cv ;
ifnot: _stptr : _stptr 5 _cv ;
ifnot: _sttos : _sttos 7 _cv ;
ifnot: _treg1 : _treg1 8 _cv ;
ifnot: _treg2 : _treg2 9 _cv ;
ifnot: _treg3 : _treg3 a _cv ;
ifnot: _treg4 : _treg4 b _cv ;
ifnot: _treg5 : _treg5 c _cv ;
ifnot: _treg6 : _treg6 d _cv ;
ifnot: _stbot : _stbot e _cv ;
ifnot: _sttop : _sttop 2e _cv ;
ifnot: _rsbot : _rsbot _sttop ;
\ waitcnt ( n1 n2 -- n1 ) \ wait until n1, add n2 to n1
ifnot: waitcnt
: waitcnt _execasm2>1 1F1 _cnip ;
\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to
\ ina anded with n2
ifnot: waitpeq
: waitpeq _execasm2>0 1E0 _cnip ;
\ waitpne ( n1 n2 -- ) \ wait until state n1 is not equal
\ to ina anded with n2
ifnot: waitpne
: waitpne _execasm2>0 1E8 _cnip ;
\ lockret ( n1 -- ) deallocate a lock, previously allocated
\ via locknew
ifnot: lockret
: lockret 5 hubop 2drop ;
\ locknew ( -- n2 ) allocate a lock, result is in n2, -1
\ if unsuccessful
ifnot: locknew
: locknew -1 4 hubop -1 = if drop -1 then ;
\ cog+ ( -- ) add a forth cog
ifnot: cog+
: cog+ (cog+) ;
\ (cog-) ( -- ) stop first forth cog, cannot be executed form
\ the first forth cog
ifnot: (cog-)
: (cog-) nfcog cogstop ;
\ cog- ( -- ) stop first forth cog, cannot be executed form
\ the first forth cog
ifnot: cog-
: cog- (cog-) ;

65
forth/debug.mod Normal file
View File

@ -0,0 +1,65 @@
hex
ifnot: mod:debug
: mod:debug ;
\ keycode ( -- ) - anzeige der tastaturcodes
ifnot: keycode
: keycode
begin
0 key? if
drop key dup dup ." code : " emit ." : " . cr 1B =
then until ;
\
\ Noisy reset messages
\
\ print out a reset message to the console
\ (rsm) ( n -- ) n is the last status
\ 0011FFFF - stack overflow
\ 0012FFFF - return stack overflow
\ 0021FFFF - stack underflow
\ 0022FFFF - return stack underflow
\ 8100FFFF - no free cogs
\ 8200FFFF - no free main memory
\ 8400FFFF - fl no free main memory
\ 8500FFFF - no free cog memory
\ 8800FFFF - eeprom write error
\ 9000FFFF - eeprom read error
: (rsm) state W@ 2 and 0= swap
\ process the last status
dup 0= if c" ok" else
dup FF11 = if c" DST OVER" else
dup FF12 = if c" RST OVER" else
dup FF21 = if c" DST LOW" else
dup FF22 = if c" RST LOW" else
dup 8001 = if c" COGs OUT" else
dup 8002 = if c" hMEM OUT" else
dup 8003 = if c" ROM WR" else
dup 8004 = if c" FL" else
dup 8005 = if c" cMEM OUT" else
dup 8006 = if c" ROM RD" else
c" ?"
thens
rot if
lockdict cr c" ERR : " .cstr swap . .cstr cr freedict
else 2drop then ;
: onreset (rsm) 4 state orC! ;
\ .byte ( n1 -- )
: .byte <# # # #> .cstr ;
\ [if (dumpb)
: (dumpb) cr over .addr space dup .addr _ecs bounds ; ]
\ [if (dumpm)
: (dumpm) cr .word _ecs ; ]
\ [if (dumpe)
: (dumpe) tbuf 8 bounds do i C@ .byte space loop 2 spaces tbuf 8 bounds do i C@ dup bl < if drop 2e then emit loop ; ]
\ dump ( adr cnt -- ) uses tbuf
[if dump
: dump (dumpb) do i (dumpm) i tbuf 8 cmove (dumpe) 8 +loop cr ; ]

22
forth/fib.mod Normal file
View File

@ -0,0 +1,22 @@
: mod:fib ;
\ ( n -- f ) berechnet die nte fibonacci-zahl
: fib
0 1 rot 0 do over + swap loop drop ;
\ benchmark über n fibonacci-zahlen
: fibo-bench
1+ 1 do
i ." fibo(" . ." ) = "
i cnt COG@ swap fib cnt COG@ swap .
swap - ." , ticks : " .
cr
loop ;
decimal 40 fibo-bench hex

59
forth/g0.lib Normal file
View File

@ -0,0 +1,59 @@
\ require ari.lib
ifnot: lib:g0
: lib:g0 ;
hex
10 constant g0:xtiles
0C constant g0:ytiles
5000 constant g0:disp_base
decimal
ifnot: g0:load
: g0:load
c" g0key.bel" bel:load ;
ifnot: g0:reboot
: g0:reboot 99 b[ [b!] ]b ;
hex
ifnot: g0:setcolortab
: g0:setcolortab \ ( addr -- )
5D b[ [b!]
40 0 do dup L@ [b.l!] 4 + loop
]b drop ;
ifnot: g0:settilescreen
: g0:settilescreen \ ( addr -- )
5E b[ [b!]
g0:ytiles 0 do
g0:xtiles 0 do dup W@ [b.w!] 2 + loop
loop ]b drop ;
decimal
\ ifnot: g0:setscreen
: g0:setscreen \ ( addr addr -- )
g0:setcolortab g0:settilescreen ;
ifnot: g0:static
: g0:static 98 b[ [b!] ]b ;
ifnot: g0:dynamic
: g0:dynamic 97 b[ [b!] ]b ;
ifnot: g0:clear \ ( -- ) - bildschirm loeschen
: g0:clear 10 b[ [b!] ]b ;
ifnot: g0:color \ ( color -- ) - zeichenfarbe setzen
: g0:color 12 b[ [b!] [b!] ]b ;
ifnot: g0:width \ ( x -- ) - punktgroesse setzen
: g0:width 13 b[ [b!] [b!] ]b ;
ifnot: g0:plot \ ( y x -- ) - punkt setzen
: g0:plot 15 b[ [b!] [b!] [b!] ]b ] ;

155
forth/hplay.mod Normal file
View File

@ -0,0 +1,155 @@
hex
ifnot: mod:hplay
: mod:hplay ;
\ kommandoformate
ifnot: adm:fkt! \ ( fkt -- )
: adm:fkt! b[ [a!] ]b ;
ifnot: adm:fkt!b! \ ( b fkt -- )
: adm:fkt!b! b[ [a!] [a!] ]b ;
ifnot: adm:fkt!b!w@ \ ( b fkt -- w )
: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ;
ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b )
: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ;
ifnot: bel:fkt!b@ \ ( fkt -- b )
: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ;
ifnot: bel:char \ ( b -- )
: bel:char b[ [b!] ]b ;
\ hss-funktionen
ifnot: hss:load \ ( cstr -- err ) - hss-datei laden
: hss:load dup if 64 adm:fkt!s!b@ then ;
ifnot: hss:play \ ( -- ) - datei im puffer abspielen
: hss:play 65 adm:fkt! ;
ifnot: hss:stop \ ( -- ) - player stop
: hss:stop 66 adm:fkt! ;
ifnot: hss:reg \ hreg ( regnr -- 16b )
: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ;
ifnot: hss:vol \ hvol ( vol -- ) - lautstärke 0..15
: hss:vol 6A adm:fkt!b! ;
\ keyboard-funktionen
ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen
: key:stat 1 bel:fkt!b@ ;
\ steuerzeichen
ifnot: scr:cls \ ( -- ) - screen löschen
: scr:cls 01 bel:char ;
ifnot: scr:home \ ( -- ) - cursor oben links
: scr:home 02 bel:char ;
ifnot: scr:curon \ ( -- ) - cursor anschalten
: scr:curon 04 bel:char ;
ifnot: scr:curoff \ ( -- ) - cursor abschalten
: scr:curoff 05 bel:char ;
\ sd0-funktionen
\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren
ifnot: adm:diropen
: adm:diropen
02 adm:fkt! ;
\ adm:nextfile ( -- st )
\ st = 0 - keine gültige datei
\ st = 1 - dateiname im pad gültig
\ bei gültigem eintrag befindet sich der dateiname im pad
ifnot: adm:nextfile
: adm:nextfile
b[ 03 [a!] [a@] dup if [a.s@] then ]b ;
\ metafunktionen
\ hload name ( -- ) - hss-datei in player laden
ifnot: hload
: hload mount? parsenw hss:load .err ;
ifnot: .hset
: .hset \ ( shift -- ) - eine registersatz ausgeben
5 0 do dup i + hss:reg .word space loop drop ;
ifnot: .hreg
: .hreg \ ( -- ) - register ausgeben
14 0 do i .hset cr 5 +loop ;
ifnot: fadeout
: fadeout \ ( -- ) - sound langsam ausblenden
f 0 do e i - hss:vol 50 delms loop ;
ifnot: end?
: end? \ ( cnt -- flag ) - abfrage nach cnt wiederholungen
4 hss:reg = ;
ifnot: hwait
: hwait \ ( -- flag ) - wartet auf songende oder taste
begin 50 delms key? 2 end? or until key drop ;
ifnot: hreg..
: hreg.. \ ( -- ) - fortlaufende anzeige register
scr:curoff scr:cls begin scr:home .hreg 2 end? until
scr:curon fadeout hss:stop ;
ifnot: (hplay)
: (hplay) \ ( cstr -- )
." Datei : " dup .cstr hss:load .err f hss:vol hss:play
hwait fadeout hss:stop 100 delms cr ;
\ hplay name ( -- ) - datei abspielen
ifnot: hplay
: hplay
hload hss:play ;
\ files? ( -- cnt ) - anzahl dateien im dir
ifnot: files?
: files?
adm:diropen
0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ;
\ filenr? ( nr -- )
ifnot: filenr?
: filenr?
adm:diropen
0 do adm:nextfile drop loop ;
\ hdirplay ( -- ) - gesamtes verzeichnis abspielen
\ im verzeichnis dürfen nur hss-dateien sein!
ifnot: hdirplay
: hdirplay
decimal files? dup ." Dateien : " . cr
0 do i dup 1 + . 3 + filenr? pad (hplay) loop padbl hex ;
: (hp) ." play : " dup .cstr hss:load .err ;
ifnot: playliste
: playliste
c" kw.hss" (hplay)
c" genes.hss" (hplay)
c" greenpuz.hss" (hplay)
c" hssintro.hss" (hplay)
c" kali766.hss" (hplay)
c" machine.hss" (hplay)
c" metroid.hss" (hplay)
c" mrboss.hss" (hplay)
c" mrevil.hss" (hplay)
c" raind.hss" (hplay)
c" sytrus.hss" (hplay)
c" tbellsp1.hss" (hplay) ;

60
forth/hss.lib Normal file
View File

@ -0,0 +1,60 @@
hex
ifnot: lib:hss
: lib:hss ;
\ kommandoformate
ifnot: adm:fkt! \ ( fkt -- )
: adm:fkt! b[ [a!] ]b ;
ifnot: adm:fkt!b! \ ( b fkt -- )
: adm:fkt!b! b[ [a!] [a!] ]b ;
ifnot: adm:fkt!b!b! \ ( b b fkt -- )
: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ;
ifnot: adm:fkt!b!w@ \ ( b fkt -- w )
: adm:fkt!b!w@ b[ [a!] [a!] [a.w@] ]b ;
ifnot: adm:fkt!s!b@ \ ( cstr fkt -- b )
: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ;
\ hss-funktionen
\ ( cstr -- err ) - hss-datei laden
ifnot: hss:load
: hss:load dup if 64 adm:fkt!s!b@ then ;
\ ( -- ) - datei im puffer abspielen
ifnot: hss:play
: hss:play 65 adm:fkt! ;
\ ( -- ) - player stop
ifnot: hss:stop
: hss:stop 66 adm:fkt! ;
\ ( -- ) - player pause
ifnot: hss:pause
: hss:pause 67 adm:fkt! ;
\ hreg ( regnr -- 16b )
\ 0 iEndFlag iRowFlag iEngineC iBeatC iRepeat Player
\ 5 iNote iOktave iVolume iEffekt iInstrument Kanal 1
\ 10 iNote iOktave iVolume iEffekt iInstrument Kanal 2
\ 15 iNote iOktave iVolume iEffekt iInstrument Kanal 3
\ 20 iNote iOktave iVolume iEffekt iInstrument Kanal 4
\
\ iEndFlag Repeat oder Ende wurde erreicht
\ iRowFlag Trackerzeile (Row) ist fertig
\ iEngineC Patternzähler
\ iBeatC Beatzähler (Anzahl der Rows)
\ iRepeat Zähler für Loops
ifnot: hss:reg
: hss:reg 69 b[ [a!] [a!] [a.w@] ]b ;
\ hvol ( vol -- ) - lautstärke 0..15
ifnot: hss:vol
: hss:vol 6A adm:fkt!b! ;

17
forth/key.lib Normal file
View File

@ -0,0 +1,17 @@
hex
ifnot: lib:key
: lib:key ;
\ kommandoformate
ifnot: bel:fkt!b@ \ ( fkt -- b )
: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ;
\ keyboard-funktionen
ifnot: key:stat \ ( -- stat ) - tastenstatus abfragen
: key:stat 1 bel:fkt!b@ ;
ifnot: key:code \ ( -- code ) - tastencode abfragen
: key:code 2 bel:fkt!b@ ;
ifnot: key:spec \ ( -- spec ) - spezialtasten abfragen
: key:spec 4 bel:fkt!b@ ;

206
forth/rom.mod Normal file
View File

@ -0,0 +1,206 @@
\ ACHTUNG: Diese Modifikation nicht bei einer Installation im
\ HI-EEPROM verwenden!
hex
[if mod:rom
: mod:rom ; ]
\ constant ( x -- ) skip blanks parse the next word and create a constant, allocate a long, 4 bytes
[if constant
: constant lockdict create $C_a_doconl w, l, forthentry freedict ; ]
\
\ CONFIG PARAMETERS BEGIN
\
40 wconstant fsps \ a page size which works with 32kx8 & 64kx8 eeproms
\ and should work with larger as well.
8000 constant fsbot \ file-system bottom: the start adress in eeprom for the file system
\ file system top: the end address of the file system
\ uncomment the line for your comfiguration
\ 8000 constant fstop \ the end address for the file system with one 24LC256 32k eeprom
10000 constant fstop \ the end address for the file system with one 24LC512 64k eeprom
\ 20000 constant fstop \ the end address for the file system with two 24LC512 64k eeprom
\ 30000 constant fstop \ the end address for the file system with 3 24LC512 64k eeprom
\ 40000 constant fstop \ the end address for the file system with 4 24LC512 64k eeprom
\ 50000 constant fstop \ the end address for the file system with 5 24LC512 64k eeprom
\ 60000 constant fstop \ the end address for the file system with 6 24LC512 64k eeprom
\ 70000 constant fstop \ the end address for the file system with 7 24LC512 64k eeprom
\ NOTE IF you have DEMOBOARD or any system with 32K EEPROM, you will step on your spin image
\ when you write to the EEPROM. You can still use it (if you are tricky), but KNOW WHAT YOUR DOING!!!
\
\ CONFIG PARAMETERS END
\
\ lasti? ( -- t/f ) true if this is the last value of i in this loop
[if lasti?
: lasti? _rsptr COG@ 2+ COG@ 1- _rsptr COG@ 3 + COG@ = ; ]
\ padbl ( -- ) fills this cogs pad with blanks
[if padbl
: padbl pad padsize bl fill ; ]
\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out
[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop
swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ]
\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to
\ 8 sequential eeproms
\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1
[if eereadpage : eereadpage begin 1 lockset 0= until
1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r
_eestart A0 or _eewrite swap _eewrite or swap _eewrite or
_eestart r> A1 or _eewrite or
rot2 bounds
do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ]
\ _eeread ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out
[if _eeread : _eeread _sdai 0 8 0 do 1 lshift _sclh _sda? _scll if 1 or then loop
swap if _sdah else _sdal then _sdao _sclh _scll _sdal ; ]
\ the eereadpage and eewritePage words assume the eeprom are 64kx8 and will address up to
\ 8 sequential eeproms
\ eereadpage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1
[if eereadpage : eereadpage begin 1 lockset 0= until
1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r
_eestart A0 or _eewrite swap _eewrite or swap _eewrite or
_eestart r> A1 or _eewrite or
rot2 bounds
do lasti? _eeread i C! loop _eestop 1 lockclr drop ; ]
\ EW@ ( eeAddr -- n1 )
[if EW@
: EW@ t0 2 eereadpage if 8006 ERR then t0 W@ ; ]
\ EC@ ( eeAddr -- c1 )
[if EC@
: EC@ EW@ FF and ; ]
\ (fspa) ( addr1 -- addr2) addr2 is the next page aligned address after addr1
: (fspa) fsps 1- + fsps 1- andn ;
\ (fsnext) ( addr1 -- addr2 t/f) addr - the current file address, addr2 - the next addr, t/f - true if we have
\ gone past the end of the eeprom. t0 -length of the current file
\ t1 - length of the file name (char)
: (fsnext) t0 W@ t1 C@ + 2+ 1+ + (fspa) dup fstop >= ;
\ (fswr) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to write, addr2 - the address to write from
\ n1 - the number of bytes to write
: (fswr) dup >r rot dup r> + fstop 1- > if A0 ERR then rot2 eewritepage if 88 ERR then ;
\ (fsrd) ( addr1 addr2 n1 -- ) addr1 - the eepropm address to read, addr2 - the address of the read buffer
\ n1 - the number of bytes to read
: (fsrd) dup >r rot dup r> + fstop 1- > if C0 ERR then rot2 eereadpage if 90 ERR then ;
\ (fsfree) ( -- n1 ) n1 is the first location in the file system, -1 if there are none
: (fsfree) -1 fsbot begin
\ read 3 bytes into t0, t1 and process
dup t0 3 (fsrd) t0 W@ FFFF = if nip dup -1 else (fsnext) then
until drop ;
\ (fsfind) ( cstr -- addr ) find the last file named cstr, addr is the eeprom address, 0 if not found
: (fsfind) fsbot 0 >r begin
\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf
dup t0 22 (fsrd) t0 W@ FFFF = if -1 else
over t1 cstr= if r> drop dup >r then
(fsnext)
then
until 2drop r> ;
\ (fslast) ( -- addr ) find the last file, 0 if not found
: (fslast) 0 fsbot begin
\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf
dup t0 22 (fsrd) t0 W@ FFFF = if -1 else
nip dup
(fsnext)
then
until drop ;
\ fsclear ( -- )
: fsclr padbl fsbot 400 + fsbot do i pad fsps (fswr) 2e emit fsps +loop -1 fsbot EW! ;
: fsclear -1 fsbot EW! ;
\ fsfree ( -- )
: fsfree (fsfree) dup -1 = if 0 else fstop swap - then . ." bytes free in fs" cr ;
\ fsls ( -- ) list the files
: fsls cr fsbot begin
\ read namesizemax 1F + 3 bytes into t0, t1, and tbuf
dup t0 22 (fsrd) t0 W@ FFFF = if -1 else
dup .addr space t0 W@ .addr space t1 .cstr cr
(fsnext)
then
until fstop swap - cr . ." bytes free in files system" cr cr ;
\ (fsread) ( cstr -- )
: (fsread) (fsfind) dup if
\ read 3 bytes into t0, t1 and process
dup t0 3 (fsrd)
t1 C@ + 2+ 1+ t0 W@ bounds do
ibound i - fsps >= if
i pad fsps (fsrd) pad fsps bounds
do i C@ emit loop i fsps 1- + seti
else
i EC@ emit
then
loop
else drop then padbl ;
\ fsread ( -- ) filename
: fsread parsenw dup if (fsread) else drop then ;
\ (fsload) ( ctsr -- )
: (fsload) cogid nfcog iolink (fsread) d emit d emit cogid iounlink ;
\ fsload filename ( -- ) send the file to the next free forth cog
: fsload parsenw dup if (fsload) else drop then ;
\ (fsk) ( n1 -- n2)
: (fsk) 8 lshift key or ;
\ fswrite filename ( -- ) writes a file until ... followed immediately by a cr is encountered
: fswrite (fsfree) dup -1 <> parsenw dup rot and if
\ set the file length to 0, copy in the file name
0 pad W! dup C@ 2+ 1+ pad + swap pad 2+ ccopy
\ find the first free page
0 swap key (fsk) (fsk) (fsk)
\ ( eaddr1 n1 addr2 n2 ) eaddr - start of file in the eeprom, n1 - bytes written so far, addr2 - next addr in the pad,
\ n2 - a 4 byte key buffer
begin
\ check to see if we have a ... at the end of a line
2E2E2E0D over = if
-1
else
\ get a key from the key buffer, write it the the pad
swap over 18 rshift dup dup d = if drop cr else emit then over C! 1+ tuck pad - fsps = if
\ we have a page worth of data, write it out
nip rot2 2dup + pad fsps (fswr) fsps + rot pad swap
then
\ get another key
(fsk) 0
then
until
\ any keys left?
drop pad - dup 0> if
\ write the leftover, not a full page
>r 2dup + pad r> dup >r (fswr) r> +
else
drop
then
\ write the length of FFFF for the next file
2dup + FFFF swap (fspa) dup fstop 1- < if EW! else 2drop then
\ subtract the length of the filename +1, and the 2 bytes which are the length of the file, and update the length of the file
over 2+ EC@ 2+ 1+ - swap EW!
else 2drop clearkeys then padbl
;
\ fsdrop ( -- ) deletes last file
: fsdrop (fslast) dup -1 = if drop else FFFF swap EW! then ;

69
forth/scr.lib Normal file
View File

@ -0,0 +1,69 @@
hex
ifnot: lib:scr
: lib:scr ;
\ kommandoformate
ifnot: bel:char \ ( b -- )
: bel:char b[ [b!] ]b ;
ifnot: bel:fkt!b! \ ( b fkt -- )
: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ;
ifnot: bel:fkt!b!b! \ ( b b fkt -- )
: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ;
ifnot: bel:ctrl! \ ( ctrl -- )
: bel:ctrl! b[ 0 [b!] 3 [b!] [b!] ]b ;
ifnot: bel:ctrl!b! \ ( b ctrl -- )
: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ;
ifnot: bel:ctrl!b@ \ ( ctrl -- b@ )
: bel:ctrl!b@ b[ 0 [b!] 3 [b!] [b!] [b@] ]b ;
ifnot: bel:ctrl!b!b! \ ( b b ctrl -- )
: bel:ctrl!b!b! b[ 0 [b!] 3 [b!] [b!] [b!] [b!] [b!] ]b ;
\ einfache steuerzeichen
ifnot: scr:cls \ ( -- ) - screen löschen
: scr:cls 01 bel:char ;
ifnot: scr:home \ ( -- ) - cursor oben links
: scr:home 02 bel:char ;
ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang
: scr:pos1 03 bel:char ;
ifnot: scr:curon \ ( -- ) - cursor anschalten
: scr:curon 04 bel:char ;
ifnot: scr:curoff \ ( -- ) - cursor abschalten
: scr:curoff 05 bel:char ;
ifnot: scr:scrlu \ ( -- ) - screen nach oben scrollen
: scr:scrlu 06 bel:char ;
ifnot: scr:scrld \ ( -- ) - screen nach unten scrollen
: scr:scrld 07 bel:char ;
ifnot: scr:bs \ ( -- ) - backspace
: scr:bs 08 bel:char ;
ifnot: scr:tab \ ( -- ) - tabulator
: scr:tab 09 bel:char ;
\ screen-funktionen
ifnot: scr:logo \ ( y x -- ) - hive logo
: scr:logo 5 bel:fkt!b!b! ;
ifnot: scr:char \ ( char -- ) - zeichensatz direkt ausgeben
: scr:char 6 bel:fkt!b! ;
\ parametrisierte steuerzeichen
ifnot: scr:setcur \ ( cur -- ) - cursorzeichen setzen
: scr:setcur 01 bel:ctrl!b! ;
ifnot: scr:setx \ ( x -- ) - cursor position x setzen
: scr:setx 02 bel:ctrl!b! ;
ifnot: scr:sety \ ( y -- ) - cursor position y setzen
: scr:sety 03 bel:ctrl!b! ;
ifnot: scr:getx \ ( -- x ) - cursor position x abfragen
: scr:getx 04 bel:ctrl!b@ ;
ifnot: scr:gety \ ( -- y ) - cursor position y abfragen
: scr:gety 05 bel:ctrl!b@ ;
ifnot: scr:setcol \ ( colnr -- ) - farbe wählen 0..15
: scr:setcol 06 bel:ctrl!b! ;
ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich
: scr:sline 07 bel:ctrl!b! ;
ifnot: scr:eline \ ( row -- ) - endzeile scrollbereich
: scr:eline 08 bel:ctrl!b! ;
ifnot: scr:sinit \ ( -- ) -
: scr:sinit 09 bel:ctrl! ;
ifnot: scr:tabset \ ( pos nr -- ) - tabulatorposition setzen 0..7
: scr:tabset 0A bel:ctrl!b!b! ;

176
forth/sd0.lib Normal file
View File

@ -0,0 +1,176 @@
hex
ifnot: lib:sd0
: lib:sd0 ;
\ ------------------------------------ lib:sd0
\ kommandoformate
ifnot: adm:fkt!b! \ ( b fkt -- )
: adm:fkt!b! b[ [a!] [a!] ]b ;
ifnot: adm:fkt!b!b@ \ ( b fkt -- b )
: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ;
ifnot: adm:fkt!b!l@ \ ( b fkt -- l )
: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ;
ifnot: adm:fkt!l! \ ( l fkt -- )
: adm:fkt!l! b[ [a!] [a.l!] ]b ;
ifnot: adm:fkt!l@ \ ( fkt -- l )
: adm:fkt!l@ b[ [a!] [a.l@] ]b ;
ifnot: adm:fkt!b!l! \ ( l b fkt -- )
: adm:fkt!b!l! b[ [a!] [a!] [a.l!] ]b ;
ifnot: adm:fkt!s!b@ \ ( s fkt -- b )
: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ;
ifnot: adm:fkt!b!s!b@ \ ( s b fkt -- b )
: adm:fkt!b!s!b@ b[ [a!] [a!] [a.s!] [a@] ]b ;
ifnot: adm:fkt!s!s!b@ \ ( s s fkt -- b )
: adm:fkt!s!s!b@ b[ [a!] [a.s!] [a.s!] [a@] ]b ;
\ dateisystem-funktionen
\ adm:mount ( -- err ) - medium mounten
ifnot: adm:mount
: adm:mount
01 adm:fkt!b@ ;
\ adm:diropen ( -- ) - verzeichnisabfrage initialisieren
ifnot: adm:diropen
: adm:diropen
02 adm:fkt! ;
\ adm:nextfile ( -- st )
\ st = 0 - keine gültige datei
\ st = 1 - dateiname im pad gültig
\ bei gültigem eintrag befindet sich der dateiname im pad
ifnot: adm:nextfile
: adm:nextfile
b[ 03 [a!] [a@] dup if [a.s@] then ]b ;
\ adm:open ( cstr modus -- err ) - datei öffnen
\ modus "R" $52 - Read
\ modus "W" $57 - Write
\ modus "A" $41 - Append
ifnot: adm:open
: adm:open
04 adm:fkt!b!s!b@ ;
\ adm:close ( -- ) - datei schließen
ifnot: adm:close
: adm:close
05 adm:fkt!b@ ;
\ adm:getc ( -- c ) - ein zeichen aus datei lesen
ifnot: adm:getc
: adm:getc
06 adm:fkt!b@ ;
\ adm:putc ( c -- ) - ein zeichen in datei schreiben
ifnot: adm:putc
: adm:putc
07 adm:fkt!b! ;
\ adm:eof ( -- eof ) - abfrage ob end of file erreicht ist
ifnot: adm:eof
: adm:eof
1E adm:fkt!b@ ;
\ adm:getblk ( adr cnt -- ) - datenblock aus datei lesen
\ adm:putblk ( adr cnt -- ) - datenblock in datei schreiben
\ adm:seek ( pos -- ) - position in datei setzen
: adm:seek
0A adm:fkt!l! ;
\ adm:fattrib ( nr -- attrib ) - dateiattribut abfragen
ifnot: adm:fattrib
: adm:fattrib
0B adm:fkt!b!l@ ;
\ adm:volname ( -- ) - name des volumes im pad ablegen
ifnot: adm:volname
: adm:volname
0C adm:fkt!s@ ;
\ adm:checkmounted ( -- t/f )
ifnot: adm:checkmounted
: adm:checkmounted
0D adm:fkt!b@ ;
\ adm:checkopen ( -- t/f )
ifnot: adm:checkopen
: adm:checkopen
0E adm:fkt!b@ ;
\ adm:checkused ( -- used ) - anzahl benutzte sektoren
ifnot: adm:checkused
: adm:checkused
0F adm:fkt!l@ ;
\ adm:checkfree ( -- free ) - anzahl freie sektoren
ifnot: adm:checkfree
: adm:checkfree
10 adm:fkt!l@ ;
\ adm:newfile ( cstr -- err ) - neue datei erstellen
ifnot: adm:newfile
: adm:newfile
11 adm:fkt!s!b@ ;
\ adm:newdir ( cstr -- err ) - neues verzeichnis erstellen
ifnot: adm:newdir
: adm:newdir
12 adm:fkt!s!b@ ;
\ adm:del ( cstr -- err ) - datei/verzeichnis löschen
ifnot: adm:del
: adm:del
13 adm:fkt!s!b@ ;
\ adm:rename ( cstr1.fn1 cstr2.fn2 -- err )
ifnot: adm:rename
: adm:rename
14 adm:fkt!s!s!b@ ;
\ adm:chattrib ( cstr1.fn cstr2.attrib -- err )
ifnot: adm:chattrib
: adm:chattrib
15 adm:fkt!s!s!b@ ;
\ adm:chdir ( cstr -- err ) - verzeichnis öffnen
ifnot: adm:chdir
: adm:chdir
16 adm:fkt!s!b@ ;
\ adm:format ( cstr.label -- err ) - medium formatieren
ifnot: adm:format
: adm:format
17 adm:fkt!s!b@ ;
\ adm:unmount ( -- err ) - medium unmounten
ifnot: adm:unmount
: adm:unmount
18 adm:fkt!b@ ;
\ marker-funktionen
ifnot: adm:dmact \ ( dmnr -- ) - marker aktivieren
: adm:dmact 19 adm:fkt!b!b@ .err ;
ifnot: adm:dmset \ ( dmnr -- ) - marker setzen
: adm:dmset 1A adm:fkt!b! ;
ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen
: adm:dmget 1B adm:fkt!b!l@ ;
ifnot: adm:dmclr \ ( dmnr -- ) - marker löschen
: adm:dmclr 1C adm:fkt!b! ;
ifnot: adm:dmput \ ( dm dmnr -- ) - marker schreiben
: adm:dmput 1D adm:fkt!b!l! ;

93
forth/sfx.lib Normal file
View File

@ -0,0 +1,93 @@
hex
ifnot: lib:sfx
: lib:sfx ;
\ kommandoformen
ifnot: adm:fkt!b! \ ( b fkt -- )
: adm:fkt!b! b[ [a!] [a!] ]b ;
ifnot: adm:fkt!b!b! \ ( b b fkt -- )
: adm:fkt!b!b! b[ [a!] [a!] [a!] ]b ;
ifnot: adm:fkt!b!64b! \ ( ptr b fkt -- )
: adm:fkt!b!64b! b[ [a!] [a!]
31 0 do dup i + C@ [a!] loop drop ]b ;
\ sfx-funktionen
\ sfx:fire( chan slot -- ) - sfx abspielen
\ slot - $00..$0f nummer der freien effektpuffer
\ slot - $f0..f5 vordefinierte effektslots
\ chan - 0/1 stereokanal
\ vordefinierte effekte
\ &f0 - warnton
\ $f1 - signalton
\ $f2 - herzschlag schnell
\ $f3 - herzschlag langsam
\ $f4 - telefon
\ $f5 - phaser :)
\ $f6 - pling
\ $f7 - on
\ $f8 - off
ifnot: sfx:fire
: sfx:fire 6B adm:fkt!b!b! ;
\ ( ptr slot -- ) - sfx setzen
\ slot - $00..$0f nummer der freien effektpuffer
\ ptr - zeiger auf 32 byte effektdaten
\
\ struktur der effektdaten:
\
\ [wav ][len ][freq][vol ] grundschwingung
\ [lfo ][lfw ][fma ][ama ] modulation
\ [att ][dec ][sus ][rel ] hüllkurve
\ [seq ] (optional)
\
\ [wav] wellenform
\ 0 sinus (0..500hz)
\ 1 schneller sinus (0..1khz)
\ 2 dreieck (0..500hz)
\ 3 rechteck (0..1khz)
\ 4 schnelles rechteck (0..4khz)
\ 5 impulse (0..1,333hz)
\ 6 rauschen
\ [len] tonlänge $0..$fe, $ff endlos
\ [freq] frequenz $00..$ff
\ [vol] lautstärke $00..$0f
\
\ [lfo] low frequency oscillator $ff..$01
\ [lfw] low frequency waveform
\ $00 sinus (0..8hz)
\ $01 fast sine (0..16hz)
\ $02 ramp up (0..8hz)
\ $03 ramp down (0..8hz)
\ $04 square (0..32hz)
\ $05 random
\ $ff sequencer data (es folgt eine sequenzfolge [seq])
\ [fma] frequency modulation amount
\ $00 no modulation
\ $01..$ff
\ [ama] amplitude modulation amount
\ $00 no modulation
\ $01..$ff
\ [att] attack $00..$ff
\ [dec] decay $00..$ff
\ [sus] sustain $00..$ff
\ [rel] release $00..$ff
ifnot: sfx:setslot
: sfx:setslot
6C adm:fkt!b!64b! ;
\ sfx:keyoff ( chan -- ) - release-phase einleiten
ifnot: sfx:keyoff
: sfx:keyoff
6D adm:fkt!b! ;
\ sfx:stop ( chan -- )
ifnot: sfx:stop
: sfx:stop
6E adm:fkt!b! ;

116
forth/splay.mod Normal file
View File

@ -0,0 +1,116 @@
\ achtung: vor verwendung muss der administra-code mit sidcog
\ geladen werden:
\ sys tools.mod
\ sys splay.mod <--- sid-player laden
\ aload admsid.adm <--- administra-code mit sidcog laden
\ splay xyz.dmp <--- sid-datei abspielen
hex
ifnot: mod:splay
: mod:splay ;
\ kommandoformen
ifnot: adm:fkt! \ ( fkt -- )
: adm:fkt! b[ [a!] ]b ;
ifnot: adm:fkt!b! \ ( b fkt -- )
: adm:fkt!b! b[ [a!] [a!] ]b ;
ifnot: adm:fkt!b@ \ ( fkt -- b )
: adm:fkt!b@ b[ 0 [a!] [a!] [a@] ]b ;
ifnot: adm:fkt!s! \ ( s fkt -- )
: adm:fkt!s! b[ [a!] [a.s!] ]b ;
ifnot: adm:fkt!s!b@ \ ( s fkt -- err )
: adm:fkt!s! b[ [a!] [a.s!] [b@] ]b ;
ifnot: adm:fkt!b!l@ \ ( b fkt -- l )
: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ;
\ dm-funktionen
ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen
: adm:dmget 1B adm:fkt!b!l@ ;
\ adm:dmact ( dmnr -- ) - marker aktivieren
: adm:dmact 19 adm:fkt!b!b@ drop ;
\ adm-funktionen
\ adm:aload ( cstr -- ) - neuen administra-code laden
ifnot: adm:aload
: adm:aload
60 adm:fkt!s! ;
\ tools
ifnot: aload
: aload
mount? parsenw dup
if 1 adm:dmact adm:aload 0 else drop 23 then .err ;
\ sid-funktionen
ifnot: sid:play
: sid:play \ ( cstr -- err )
9E adm:fkt!s!b@ ;
ifnot: sid:stop
: sid:stop \ ( -- )
9F adm:fkt! ;
ifnot: sid:status
: sid:status \ ( -- status )
A1 adm:fkt!b@ ;
ifnot: sid:mute
\ 1 - sid1
\ 2 - sid2
\ 3 - sid1 & sid2
: sid:mute \ ( sidnr -- )
A3 adm:fkt!b! ;
\ send? ( -- t/f )
ifnot: send?
: send?
begin 50 delms key? dup if key drop then sid:status 0= or
until ;
\ (splay) ( cstr -- )
ifnot: (splay)
: (splay) \ ( cstr -- )
." Datei : " dup .cstr cr sid:play .err
send? sid:stop 3 sid:mute adm:close drop ;
\ files? ( -- cnt ) - anzahl dateien im dir
ifnot: files?
: files?
adm:diropen
0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ;
\ filenr? ( nr -- )
ifnot: filenr?
: filenr?
adm:diropen
0 do adm:nextfile drop loop ;
\ splay name.dmp ( -- ) - sid-datei abspielen
ifnot: splay
: splay
parsenw (splay) ;
\ sdirplay ( -- ) - gesamtes verzeichnis abspielen
\ im verzeichnis dürfen nur sid-dateien sein!
ifnot: sdirplay
: sdirplay
files? dup ." Dateien : " . cr
0 do i dup 1 + . 3 + filenr? pad (splay) loop padbl ;
ifnot: smute
: smute
sid:stop 3 sid:mute ;

152
forth/tools.mod Normal file
View File

@ -0,0 +1,152 @@
hex
ifnot: mod:tools
: mod:tools ;
\ kommandoformen
ifnot: adm:fkt!b!l@ \ ( b fkt -- l )
: adm:fkt!b!l@ b[ [a!] [a!] [a.l@] ]b ;
ifnot: adm:fkt!b!b@ \ ( b fkt -- b )
: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ;
ifnot: adm:fkt!s! \ ( s fkt -- )
: adm:fkt!s! b[ [a!] [a.s!] ]b ;
\ dm-funktionen
ifnot: adm:dmget \ ( dmnr -- dm ) - marker lesen
: adm:dmget 1B adm:fkt!b!l@ ;
ifnot: adm:dmact \ adm:dmact ( dmnr -- ) - marker aktivieren
: adm:dmact 19 adm:fkt!b!b@ drop ;
\ adm-funktionen
\ adm:aload ( cstr -- ) - neuen administra-code laden
ifnot: adm:load
: adm:load
60 adm:fkt!s! ;
\ bel-funktionen
\ bel:load ( cstr -- ) - bellatrix-code laden
\ achtung: die gesamte loader-operation ist eine atomare
\ operation über alle drei propellerchips, kann also auch
\ nicht aufgetrennt werden!
ifnot: bel:load
: bel:load
52 adm:open .err \ datei öffnen
b[
0 [b!] 57 [b!] \ bella-loader starten
10 0 do 06 [a!] [a@] [b!] loop \ header einlesen
0A [a!] 0 [a.l!] \ 0 adm:seek
[b@] <8 [b@] or \ dateilänge empfangen
0 do 06 [a!] [a@] [b!] loop \ datei senden
]b
adm:close .err \ datei schließen
;
\ ------------------------------------ mod:tools
ifnot: aload
: aload \ name ( -- ) - administra-code laden
mount? parsenw dup
if adm:load 0 else drop 23 then .err ;
ifnot: bload
: bload \ name ( -- ) - bellatrix-code laden
mount? parsenw dup
if bel:load 0 else drop 23 then .err ;
ifnot: .dmstatus \ ( dm -- ) - ausgabe marker-status
: .dmstatus -1 = if ." frei" else ." gesetzt" then cr ;
ifnot: dm?
: dm?
." [root] : " 0 adm:dmget .dmstatus
." [sys ] : " 1 adm:dmget .dmstatus
." [usr ] : " 2 adm:dmget .dmstatus
." [ A ] : " 3 adm:dmget .dmstatus
." [ B ] : " 4 adm:dmget .dmstatus
." [ C ] : " 5 adm:dmget .dmstatus ;
\ open name ( -- ) - datei lesend öffnen und auf fehler prüfen
ifnot: open
: open
mount? parsenw dup
if 52 adm:open else drop 23 then .err ;
\ close ( -- ) - geöffnete datei schließen
ifnot: close
: close
adm:close .err ;
\ (cat) ( -- ) - alle zeichen der geöffneten datei ab
\ lesemarke auf ausgabekanal bis zum eof ausgeben
ifnot: (cat)
: (cat) begin adm:getc emit adm:eof until ;
\ cat name ( -- ) - datei "name" komplett ausgeben
ifnot: cat
: cat open (cat) close ;
\ nextline ( -- ) - ausgabe der nächsten textzeile aus der
\ geöffneten datei
ifnot: nextline
: nextline
begin adm:getc dup emit 0d = adm:eof or until ;
\ nextlines ( n -- ) - ausgabe von n zeilen
ifnot: nextlines
: nextlines
0 do adm:eof 0= if nextline then loop ;
\ less name ( -- ) - zeilenweise ausgabe der datei
ifnot: less
: less
open begin 10 nextlines key 71 = adm:eof or until close ;
\ #C ( c1 -- ) prepend the character c1 to the number
\ currently being formatted
ifnot: #C
: #C -1 >out W+! pad>out C! ;
\ .cogch ( n1 n2 -- ) print as x(y)
ifnot: .cogch
: .cogch <# 29 #C # 28 #C drop # #> .cstr ;
\ j ( -- n1 ) the second most current loop counter
ifnot: j
: j _rsptr COG@ 5 + COG@ ;
\ cog? ( -- )
ifnot: cog?
: cog?
8 0 do ." Cog:" i dup . ." #io chan:"
dup cognchan . cogstate C@
dup 4 and if version W@ .cstr then
dup 10 and if i cognumpad version W@ C@ over C@ -
spaces .cstr then
14 and if i cogio i cognchan 0 do
i 4* over + 2+ W@ dup 0= if drop else
space space j i .cogch ." ->" io>cogchan .cogch
then
loop
drop then cr loop ;
\ jede erweiterung legt ein wort als startmarke
\ nmit folgendem namen an:
\ mod:xxx - softwaremodule
\ drv:xxx - treiber
\ lib:xxx - bibliotheken
\ so kann mit den folgenden kommandos eine schnelle liste der
\ vorhandenen erweiterungen abgerufen und mit forget
\ aus dem system entfernt werden
\ mod? ( -- ) - anzeige der module
ifnot: mod?
: mod? c" mod:" _words ;
\ lib? ( -- ) - anzeige der bibliotheken
ifnot: lib?
: lib? c" lib:" _words ;

48
forth/tpix.f Normal file
View File

@ -0,0 +1,48 @@
\ requires bel.lib
\ requires g0.lib
\ requires ari.lib
hex
: it ; \ fuer forget
variable colortab 40 4* 4 - allot
variable tiletab g0:xtiles g0:ytiles * 2* 4 - allot
: fillcolortab
colortab
40 0 do
i dup + 4 + 0F and 00001010 * 0D060D02 +
over L! 4+
loop drop
;
: filltilescreen
tiletab g0:disp_base 6 rshift
g0:ytiles 0 do
g0:xtiles 0 do
swap 2dup W! 2+ swap g0:ytiles +
loop 341 +
loop 2drop ;
decimal
: setscreen
fillcolortab filltilescreen
tiletab colortab g0:setscreen
;
: tpix
g0:load setscreen g0:static
g0:clear 14 g0:width 1 g0:color
g0:xtiles 0 do i 16 * 8 +
g0:ytiles 0 do i 16 * 8 + over g0:plot loop drop
loop
key g0:clear
2000 0 do
rnd 31 and g0:width rnd 3 and g0:color
rnd rnd g0:plot
loop
key g0:reboot
cr ." erledigt" cr
;

325
forth/v1.mod Normal file
View File

@ -0,0 +1,325 @@
: mod:vortrag ;
24 constant rows
64 constant cols
wvariable lcol 7 lcol W!
ifnot: adm:fkt!s!b@ \ ( s fkt -- b )
: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ;
ifnot: adm:fkt!b!b@ \ ( b fkt -- b )
: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ;
ifnot: adm:fkt!b@ \ ( fkt -- b )
: adm:fkt!b@ b[ [a!] [a@] ]b ;
ifnot: bel:char \ ( b -- )
: bel:char b[ [b!] ]b ;
ifnot: bel:ctrl!b! \ ( b ctrl -- )
: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ;
ifnot: bel:fkt!b!b! \ ( b b fkt -- )
: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ;
ifnot: scr:bs \ ( -- ) - backspace
: scr:bs 08 bel:char ;
ifnot: scr:tab \ ( -- ) - tabulator
: scr:tab 09 bel:char ;
ifnot: scr:pos1 \ ( -- ) - cursor an zeilenanfang
: scr:pos1 03 bel:char ;
ifnot: scr:setcol \ ( colnr -- ) - farbe wählen 0..15
: scr:setcol 06 bel:ctrl!b! ;
ifnot: scr:sline \ ( row -- ) - anfangszeile scrollbereich
: scr:sline 07 bel:ctrl!b! ;
ifnot: scr:setx \ ( x -- ) - cursor position x setzen
: scr:setx 02 bel:ctrl!b! ;
ifnot: scr:sety \ ( y -- ) - cursor position y setzen
: scr:sety 03 bel:ctrl!b! ;
ifnot: scr:curon \ ( -- ) - cursor anschalten
: scr:curon 04 bel:char ;
ifnot: scr:curoff \ ( -- ) - cursor abschalten
: scr:curoff 05 bel:char ;
ifnot: scr:logo \ ( y x -- ) - hive logo
: scr:logo 5 bel:fkt!b!b! ;
\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten
\ sfkt:
\ 0: hss-engine abschalten
\ 1: hss-engine anschalten
\ 2: dac-engine abschalten
\ 3: dac-engine anschalten
\ sstat - status/cognr startvorgang
ifnot: adm:setsound
: adm:setsound
5C adm:fkt!b!b@ ;
\ wav:start ( cstr -- err )
ifnot: wav:start
: wav:start
96 adm:fkt!s!b@ ;
\ wav:stop ( -- )
ifnot: wav:stop
: wav:stop
97 adm:fkt!b@ drop ;
\ won
ifnot: won
: won
0 adm:setsound 3 adm:setsound 2drop ;
\ woff
ifnot: woff
: woff
2 adm:setsound 1 adm:setsound 2drop ;
: lcol@ lcol W@ ; \ ( -- col )
: lines \ ( n -- )
0 do cr loop ;
: waitkey
scr:curoff cr key drop scr:bs scr:bs scr:bs scr:curon ;
: nextpage
scr:curoff scr:pos1 lcol@ spaces ." -->" key drop scr:bs scr:bs scr:bs scr:curon ;
: .head \ ( -- )
4 scr:setcol scr:pos1 lcol@ spaces ;
: .bullet \ ( -- )
0 scr:setcol scr:pos1 lcol@ spaces 0f emit space ;
: .number \ ( n -- n )
0 scr:setcol scr:pos1 lcol@ spaces dup . 1+
2e emit space ;
: .line \ ( -- )
cr 0 scr:setcol scr:pos1 lcol@ 2+ spaces ;
: .sub \ ( -- )
0 scr:setcol scr:pos1 lcol@ 2+ spaces ;
wvariable xpos 1 xpos W!
wvariable ypos 1 ypos W!
: pos! \ ( x y -- )
ypos W! xpos W! ;
: pos@ \ ( -- x y )
xpos W@ ypos W@ ;
: nextline
ypos W@ 1+ ypos W! ;
: move \ ( x y -- )
1 delms pos@ scr:sety scr:setx ;
: btop0 \ ( -- )
move 9f emit 6 0 do 90 emit loop 9e emit nextline ;
: bbot0 \ ( -- )
move 9d emit 6 0 do 90 emit loop 9c emit nextline ;
: btop1 \ ( -- )
move 2 spaces 9f emit 6 0 do 90 emit loop 9e emit nextline ;
: bbot1 \ ( -- )
move 2 spaces 9d emit 6 0 do 90 emit loop 9c emit nextline ;
: bmid0 \ ( -- )
move 91 emit ." COG " 95 emit 90 emit bb emit nextline
move 91 emit ." " 95 emit 90 emit aa emit nextline ;
: bmid1 \ ( -- )
move a9 emit 90 emit 94 emit ." COG " 91 emit nextline
move ba emit 90 emit 94 emit ." " 91 emit nextline ;
: bmid2 \ ( -- )
move a9 emit 90 emit 94 emit ." SER "
95 emit 90 emit bb emit ." [TERMINAL]" nextline
move ba emit 90 emit 94 emit ." " 91 emit nextline ;
: bmid3 \ ( -- )
move a9 emit 90 emit 94 emit ." VGA "
95 emit 90 emit bb emit ." [BELLATRIX]" nextline
move ba emit 90 emit 94 emit ." KBD " 91 emit nextline ;
: bmid4 \ ( -- )
move 91 emit ." COG " 95 emit 90 emit bb emit
." Zeichenausgabekanal (emit)" nextline
move 91 emit ." " 95 emit 90 emit aa emit
." Zeicheneingabekanal (key)" nextline ;
: cog0 \ ( x y -- )
0 scr:setcol pos! btop0 bmid0 bbot0 ;
: cog1 \ ( x y -- )
0 scr:setcol pos! btop1 bmid1 bbot1 ;
: cog3 \ ( x y -- )
0 scr:setcol pos! btop0 bmid4 bbot0 ;
: cogext \ ( x y -- )
0 scr:setcol pos! btop1 bmid2 bbot1 ;
: cogint \ ( x y -- )
0 scr:setcol pos! btop1 bmid3 bbot1 ;
: drvser
0 scr:setcol 2dup cog0 swap a + swap cogext ;
: drvint
0 scr:setcol 2dup cog0 swap a + swap cogint ;
: p0
0 scr:sline cls 5 lines
14 1c scr:curoff scr:logo won c" woodz.wav" wav:start drop
key drop scr:curon wav:stop woff ;
: i1
0 scr:sline cls 3 lines
.head ." Implementierungsvarianten" cr waitkey
.bullet ." Forth-Diamond: Master & Slaves = PropForth" waitkey cr
.sub ." Nachteil: Programmierung aller Treiber in Forth" waitkey cr
.bullet ." Forth-Spin: Forth mit SPIN-Interface" waitkey cr
.sub ." Vorteil: Nutzung fertiger Treiber" waitkey
.sub ." Nachteil: hoher Ressourcenverbrauch" waitkey cr
.bullet ." Forth-Funktionskomplexe: " cr cr
.sub ." Master = Forth" cr
.sub ." Slaves = Spin-Funktionsbibliotheken" cr
.sub ." Interface Forth <--> Spin = 8Bit-Bus" cr cr
nextpage ;
: i2
0 scr:sline cls 3 lines
.head ." Implementierungsvarianten" cr cr
.bullet ." Forth-Funktionskomplexe: " cr cr
.sub ." Master = Forth" cr
.sub ." Slaves = Spin-Funktionsbibliotheken" cr
.sub ." Interface Forth <--> Spin = 8Bit-Bus" cr waitkey
.bullet ." Nachteile:" cr cr
.sub ." Spin --> Compiler noch auf Host" cr waitkey
.bullet ." Vorteile:" cr cr
.sub ." Code ist schon vorhanden (TriOS)" waitkey
.sub ." Gegenseitige Befruchtung von Forth & TriOS" waitkey
.sub ." Maximale Ressourcen für Forth im Master" waitkey
.sub ." Spin-Code kann später auch durch Forth ersetzt werden" cr
nextpage ;
: i3
0 scr:sline cls 3 lines
.head ." Ablauf der Implementierung" cr waitkey
.bullet ." Ausgangslage: " cr cr
.sub ." Forth mit Terminalzugriff" cr waitkey
.bullet ." Plan:" cr cr
.sub ." 1. Busroutine um auf Slaves zuzugreifen" waitkey
.sub ." 2. Integration VGA/Keyboard/SD-Card" waitkey
.sub ." 3. Autostart" cr cr
nextpage ;
: p1
0 scr:sline cls 1 lines
.head ." Buszugriff" cr cr
.bullet ." ! ( n adr -- ) store - Wert im RAM speichern" cr
.bullet ." @ ( adr -- n ) fetch - Wert aus RAM lesen" cr waitkey
.bullet ." c! c@ p! p@ - Abwandlungen der Grundform" cr waitkey
.bullet ." s! ( c adr -- ) - Byte an Slave senden" cr
.bullet ." s@ ( adr -- c ) - Byte von Slave empfangen" cr waitkey
.bullet ." b! ( c -- ) - Byte an Bellatrix senden" cr
.bullet ." b@ ( -- c ) - Byte von Bellatrix empfangen" cr
.bullet ." a! ( c -- ) - Byte an Administra senden" cr
.bullet ." a@ ( -- c ) - Byte von Administra empfangen" cr cr
.head ." Beispiele :" cr cr
.bullet ." 01 b! - Bildschirm löschen" waitkey
.bullet ." : cls 01 b! ; " waitkey
.bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr
nextpage ;
: p2
0 scr:sline cls 5 lines
.head ." IO-Kanäle/Pipes" cr waitkey
9 8 cog3 key drop
9 c cog3
.line ." ..."
9 11 cog3
cr cr
nextpage ;
: p3
0 scr:sline cls 5 lines
.head ." Serieller Treiber" cr cr
9 8 drvser
9 c cog3
.line ." ..."
9 11 cog3
cr cr
nextpage ;
: p4
0 scr:sline cls 5 lines
.head ." VGA/Keyboard-Treiber" cr cr
9 8 drvser
9 c drvint
.line ." ..."
9 11 cog3
cr cr
nextpage ;
: p5
0 scr:sline cls 5 lines
.head ." Treiber: VGA" cr cr
9 8 drvint cr
.line ." : drv-vga "
.line ." begin"
.line ." key?"
.line ." if key b! then"
.line ." 0 until ;"
cr cr
nextpage ;
: p6
0 scr:sline cls 5 lines
.head ." Treiber: Keyboard" cr cr
9 8 drvint cr
.line ." : drv-key"
.line ." begin"
.line ." bel:keystat"
.line ." if bel:key emit then"
.line ." 0 until ;"
cr cr
nextpage ;
: p7
0 scr:sline cls 5 lines
.head ." Treiber: Gesamt" cr cr
9 8 drvint cr
.line ." : drv:int"
.line ." begin"
.line ." \ input --> vga/video"
.line ." 200 0 do key?"
.line ." if key b[ [b!] ]b then loop"
.line ." \ output <-- keyboard"
.line ." b[ [key?]"
.line ." if [key] [emit] then ]b"
.line ." 0 until ;"
cr cr
nextpage ;
: p8
0 scr:sline cls 5 lines
.head ." Semaphoren" cr waitkey
.bullet ." : bel:key 0 b! 2 b! b@ ; \ ( -- key )" cr waitkey
.bullet ." : bel:key bon 0 b! 2 b! b@ boff ;" cr waitkey
.bullet ." [ ... ]" cr waitkey
.bullet ." b[ ... ]b" cr waitkey
.bullet ." : bel:key b[ 0 b! 2 b! b@ ]b ;" cr waitkey
.bullet ." : bel:key b[ 0 [b!] 2 [b!] [b@] ]b ;" cr waitkey
.bullet ." : bel:key 2 0 b[ [b!] [b!] [b@] ]b ;" cr cr
cr cr
nextpage ;
: run
begin p0 i1 i2 i3 p1 p2 p3 p4 p5 p6 p7 p8 0 until ;

54
forth/wav.lib Normal file
View File

@ -0,0 +1,54 @@
hex
ifnot: lib:wav
: lib:wav ;
\ kommandoformen
ifnot: adm:fkt!b@ \ ( fkt -- b )
: adm:fkt!b@ b[ [a!] [a@] ]b ;
ifnot: adm:fkt!s!b@ \ ( s fkt -- b )
: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ;
ifnot: adm:fkt!l@l@ \ ( fkt -- l l )
: adm:fkt!l@l@ b[ [a!] [a.l@] [a.l@] ]b ;
\ wave-funktionen
\ wav:start ( cstr -- err )
ifnot: wav:start
: wav:start
96 adm:fkt!s!b@ ;
\ wav:stop ( -- )
ifnot: wav:stop
: wav:stop
97 adm:fkt!b@ drop ;
\ wav:status ( -- status )
ifnot: wav:status
: wav:status
98 adm:fkt!b@ ;
\ wav:leftvol ( vol -- )
ifnot: wav:leftvol
: wav:leftvol
99 adm:fkt!b! ;
\ wav:rightvol ( vol -- )
ifnot: wav:rightvol
: wav:rightvol
9A adm:fkt!b! ;
\ wav:pause ( -- )
ifnot: wav:pause
: wav:pause
9B adm:fkt!b@ drop ;
\ wav:position ( -- len pos )
ifnot: wav:position
: wav:position
9C adm:fkt!l@l@ ;

49
forth/win.lib Normal file
View File

@ -0,0 +1,49 @@
hex
ifnot: lib:win
: lib:win ;
\ kommandoformate
ifnot: bel:char \ ( b -- )
: bel:char b[ [b!] ]b ;
ifnot: bel:fkt! \ ( fkt -- )
: bel:fkt! b[ 0 [b!] [b!] ]b ;
ifnot: bel:fkt!b! \ ( b fkt -- )
: bel:fkt!b! b[ 0 [b!] [b!] [b!] ]b ;
ifnot: bel:fkt!b@ \ ( fkt -- b )
: bel:fkt!b@ b[ 0 [b!] [b!] [b@] ]b ;
ifnot: bel:fkt!b!b! \ ( b b fkt -- )
: bel:fkt!b!b! b[ 0 [b!] [b!] [b!] [b!] ]b ;
ifnot: bel:fkt!5b! \ ( b b b b b fkt -- )
: bel:fkt!5b! b[ 0 [b!] [b!] [b!] [b!] [b!] [b!] [b!] ]b ;
ifnot: bel:ctrl! \ ( ctrl -- )
: bel:ctrl! b[ 0 [b!] 3 [b!] [b!] ]b ;
ifnot: bel:ctrl!b! \ ( b ctrl -- )
: bel:ctrl!b! b[ 0 [b!] 3 [b!] [b!] [b!] ]b ;
ifnot: bel:ctrl!b@ \ ( ctrl -- b@ )
: bel:ctrl!b@ b[ 0 [b!] 3 [b!] [b!] [b@] ]b ;
ifnot: bel:ctrl!b!b! \ ( b b ctrl -- )
: bel:ctrl!b!b! b[ 0 [b!] 3 [b!] [b!] [b!] [b!] [b!] ]b ;
\ fensterfunktionen
ifnot: win:define \ ( yn xn y0 x0 w ) - fenster definieren
: win:define
50 bel:fkt!5b! ;
ifnot: win:set \ ( w -- ) - fenster auswählen
: win:set 52 bel:fkt!b! ;
ifnot: win:getcols \ ( -- cols ) - anzahl spalten im fenster abfragen
: win:getcols 54 bel:fkt!b@ ;
ifnot: win:getrows \ ( -- rows ) - anzahl zeilen im fenster abfragen
: win:getrows 55 bel:fkt!b@ ;
ifnot: win:oframe \ ( -- ) - rahmen um fenster zeichnen
: win:oframe 56 bel:fkt! ;

16
forth/words.mod Normal file
View File

@ -0,0 +1,16 @@
fl
\ _words ( cstr -- ) prints the words in the forth dictionary starting with cstr, 0 prints all
: _words lastnfa
begin
2dup swap dup if npfx else 2drop -1 then
if dup .strname space then
nfa>next dup 0=
until 2drop cr ;
\ words ( -- ) prints the words in the forth dictionary, if the pad has another string following, with that prefix
: words parsenw _xwords ;
: t1 1000 0 do i . loop ;
: t2 1000 0 do ." test " loop ;

93
forth/wplay.mod Normal file
View File

@ -0,0 +1,93 @@
hex
ifnot: mod:wplay
: mod:wplay ;
\ kommandoformate
ifnot: adm:fkt!s!b@ \ ( s fkt -- b )
: adm:fkt!s!b@ b[ [a!] [a.s!] [a@] ]b ;
ifnot: adm:fkt!b!b@ \ ( b fkt -- b )
: adm:fkt!b!b@ b[ [a!] [a!] [a@] ]b ;
ifnot: adm:fkt!b@ \ ( fkt -- b )
: adm:fkt!b@ b[ [a!] [a@] ]b ;
\ wave-funktionen
\ wav:start ( cstr -- err )
ifnot: wav:start
: wav:start
96 adm:fkt!s!b@ ;
\ wav:stop ( -- )
ifnot: wav:stop
: wav:stop
97 adm:fkt!b@ drop ;
\ wav:status ( -- status )
ifnot: wav:status
: wav:status
98 adm:fkt!b@ ;
\ adm-funktionen
\ adm:setsound ( sfkt -- sstat ) - soundsystem verwalten
\ sfkt:
\ 0: hss-engine abschalten
\ 1: hss-engine anschalten
\ 2: dac-engine abschalten
\ 3: dac-engine anschalten
\ sstat - status/cognr startvorgang
ifnot: adm:setsound
: adm:setsound
5C adm:fkt!b!b@ ;
\ metafunktionen
\ won
ifnot: won
: won
0 adm:setsound 3 adm:setsound 2drop ;
\ woff
ifnot: woff
: woff
2 adm:setsound 1 adm:setsound 2drop ;
\ wend? ( -- t/f )
ifnot: wend?
: wend?
begin 50 delms key? dup if key drop then wav:status 0= or until ;
\ (wplay) ( cstr -- )
ifnot: (wplay)
: (wplay) \ ( cstr -- )
." Datei : " dup .cstr cr wav:start .err wend? wav:stop ;
\ wplay name ( -- )
ifnot: wplay
: wplay
won parsenw (wplay) woff ;
\ files? ( -- cnt ) - anzahl dateien im dir
ifnot: files?
: files?
adm:diropen
0 begin adm:nextfile swap 1+ swap 0= until 3 - padbl ;
\ filenr? ( nr -- )
ifnot: filenr?
: filenr?
adm:diropen
0 do adm:nextfile drop loop ;
\ wdirplay ( -- ) - gesamtes verzeichnis abspielen
\ im verzeichnis dürfen nur wav-dateien sein!
ifnot: wdirplay
: wdirplay
won files? dup ." Dateien : " . cr
0 do i dup 1 + . 3 + filenr? pad (wplay) loop padbl woff ;

275
installation.txt Normal file
View File

@ -0,0 +1,275 @@

1. Installation des Grundsystems
2. Regime im Überblick
3. Forth im Überblick
1. Installation des Grundsystems:
=================================
TriOS kann in zwei Versionen installiert werden: Mit oder ohne Forth als integrierte Programmiersprache. Als Standard wird das System ohne Forth installiert. Die Installation ist so für den Einsteiger einfacher. Möchte man auch PropForth installieren, muß nur eine Konfiguration geändert werden und ein Basiswortschatz im Forth selbst kompiliert werden.
WICHTIG: Das System kann nur mit Brat's Spin Tool - kurz BST - compiliert werden. In den Einstellungen des Compilers (Tools/Compiler Preferences/Search Paths) muss das lib-Verzeichnis eingetragen werden.
Downloadlink BST: http://www.fnarfbargle.com/bst.html
Installation ohne Forth (Standard):
-----------------------------------
1. Mikrocontroller flashen:
\flash\administra\admflash.spin --> Administra
\flash\bellatrix\belflash.spin --> Bellatrix
\flash\regnatix\regflash.spin --> Regnatix
Installation mit Forth:
-----------------------
1. Mikrocontroller flashen:
\flash\administra\admflash.spin --> Administra
\flash\bellatrix\belflash.spin --> Bellatrix
\flash\regnatix\regflash.spin --> Regnatix
2. Der Schalter bleibt ab jetzt auf Regnatix stehen. Ein Terminalprogramm (ich verwende Tera Term) starten und 57600 Baud auf die Schnittstelle vom Hive (DIP steht auf Regnatix!) einstellen. Nach einem Reset meldet sich das Propforth im Terminalprogramm auf dem Hostcomputer. Datei "forth\basics.mod" in einem Editor öffnen, alles markieren, kopieren und im Terminal einfügen. Der Quelltext wird jetzt im Forth compiliert.
3. Im Terminalfenster, also im Forth, dass Kommendo "saveforth" eingeben. Damit wird das gesamte Forthsystem mit der gerade neu compilierten Erweiterungen wieder im EEPROM als Image gespeichert.
Nach einem Reset sollte sich das Forth jetzt komplett mit seinem Prompt sowohl auf dem angeschlossenen VGA-Monitor, als auch im Terminal melden. Im Prinzip benötigen wir nun das Terminalprogramm nicht mehr und können direkt am Hive arbeiten. Später, wenn man in Forth programmiert, ist die vorhandene Terminalschnittstelle aber manchmal sehr nützlich.
Erstellen der SDCard:
---------------------
Im Prinzip kann jede normale FAT16/32 Karte verwendet werden. Lange Dateinamen werden nicht verwendet, Unterverzeichnisse sind kein Problem. Es ist sinnvoll, alle Dateien aus dem Verzeichnis "bin\sd-card\" auf die SD-Karte zu kopieren.
Das Verzeichnis "system" hat eine besondere Bedeutung: Hier sollten sich die Tools, Erweiterungen und Bibliotheken befinden. Im PropForth: Mit dem Kommando "sys name.f" kann aus jedem anderen Verzeichnis ohne Wechsel eine Datei name.f im Verzeichnis System geladen und compiliert werden.
Systemstart:
------------
Beim Systemstart wird immer das Forth aus dem EEPROM gestartet. So kann, wie mit den klassischen Homecomputern, sofort unkompliziert programmiert werden. Neben dem Forth gibt es im TriOS noch ein in Spin programmiertes Betriebssystem, welches sich dem Benutzer durch den Kommandointerpreter Regime präsentiert. Aus dem Forth kann diese mit dem Kommando "regime" gestartet werden. Im Gegenzug kann im laufenden Regime mit dem Kommando "forth" wieder zur integrierten Programmiersprache gewechselt werden.
Wurde TriOS ohne Forth installiert, wird der Loader aus dem EEPROM gestartet und sofort die Kommandozeile "Regime" aus der Datei reg.sys gestartet.
3. Regime im Überblick
======================
Da wir ja drei verschiedene Teilsystem in unserem Computer haben, muss Regime wissen, für welchen Chip eine ausführbare Datei bestimmt ist. Den Typ ausführbarer Dateien kann Regime automatisch anhand der Dateinamenserweiterung unterscheiden:
*.bin Regnatix-Code
*.bel Bellatrix-Code
*.adm Administra-Code
Dabei genügt es, den Namen ohne Erweiterung einzugeben. Dennoch kann es vorkommen, das man eine normale Spin-Datei mit einer beliebigen Erweiterung gespeichert hat. Diese Datei kann man dann mit den Kommandos rload, aload oder bload ganz gezielt in einen Chip laden.
<dateiname> - bin/adm/bel-datei wird gestartet
mount - SD-aufwerk mounten
unmount - SD-Laufwerk freigeben
dir wh - Verzeichnis anzeigen
type <sd:fn> - Anzeige einer Textdatei
aload <sd:fn> - Administra-Code laden
bload <sd:fn> - Bellatrix-Code laden
rload <sd:fn> - Regnatix-Code laden
del <sd:fn> - Datei löschen
cls - Bildschirm löschen
free - Anzeige des freien Speichers auf SD-Card
attrib <sd:fn> ashr - Dateiattribute ändern
cd <sd:dir> - Verzeichnis wechseln
mkdir <sd:dir> - Verzeichnis erstellen
rename <sd:fn1> <sd:fn2> - datei/verzeichnis umbenennen
format <volname> - SD-Laufwerk formatieren
reboot - Hive neu starten
sysinfo - Systeminformationen
color <0..7> - Farbe wählen
cogs - Belegung der COG's anzeigen
dmlist - Anzeige der Verzeichnis-Marker
dm <r/s/u/a/b/c> - Marker-Verzeichnis wechseln
dmset <r/s/u/a/b/c> - Marker setzen
dmclr <r/s/u/a/b/c> - Marker löschen
forth - Forth starten
Marker:
r - Marker für Root-Verzeichnis
s - Marker für System-Verzeichnis
u - Marker für User-Verzeichnis
a/b/c - Benutzerdefinierte Verzeichnismarker
Die r, s, u-Marker werden vom System automatisch gesetzt und intern verwendet.
RAMDISK:
xload <sd:fn> - Datei von SD-Laufwerk in RAM laden
xsave <x:fn> - Datei aus RAM auf SD-Laufwerk speichern
xdir - Verzeichnis im RAM anzeigen
xrename <x:fn1> <x:fn2> - Datei im RAM umbenennen
xdel <x:fn> - Datei im RAM löschen
xtype <x:fn> - Textdatei im RAM anzeigen
EXTERNE KOMMANDOS:
------------------
Die meisten Kommandozeilentools zeigen mit dem Parameter /? eine Liste der Optionen an.
sysconf - Systemeinstellungen
hplay - HSS-Player
wplay - WAV-Player
splay - SID-Player
yplay - Yamaha-Soundchip-Player
sfxtool - HSS-Soundeffekte erstellen
vga.bin - VGA 1024 x 768 Pixel, 64 x 24 Zeichen
htext.bin - VGA 1024 x 768 Pixel, 128 x 48 Zeichen
tv.bin - TV-Textmodus 40 x 13 Zeichen
2. Forth im Überblick:
======================
Einige nützliche Kommandos befinden sich in dem Modul tools.mod. In den meisten Fällen ist es sinnvoll dieses Modul mit der Befehlssequenz "sys tools.mod saveforth" fest im Forth einzubinden.
Wichtige Tastencodes:
---------------------
[ESC]-1 Screen 1, COG 1
[ESC]-2 Screen 2, COG 2
[ESC]-3 Screen 3, COG 3
[ESC]-b Break, Reset der aktuellen COG
[ESC]-r Reset, Neustart Regnatix
Wichtige Kommandos:
-------------------
load <name> - Datei laden und comilieren, Ausgabe Screen 3
dload <name> - wie load, aber Ausgabe aktueller Screen
sys <name> - Datei aus sys-Verzeichnis laden und compilieren
ls - Dateiliste
lsl - Dateiliste- Long-Format
cd <name> - in Verzeichniss wechseln
mount - SD-Card einbinden
unmount - SD-Card freigeben
words - Anzeige Wöterbuch
mod? - (tools.mod) Anzeige compilierter Erweiterungen
lib? - (tools.mod) Anzeige compilierter Bibliotheken
cog? - (tools.mod) Anzeige COG-Liste
cat <name> - (tools.mod) Ausgabe einer Textdatei
less <name> - (tools.mod) Zeilenweise Textausgabe
dm? - (tools.mod) Anzeige der Systemverzeichnisse
regime - CLI starten
aload <name> - Adminsitra-Code laden
bload <name> - Bellatrix-Code laden
spin <name> - Spin-Programm starten
Wichtige Dateien:
-----------------
Die Dateien *.mod und *.lib enthalten ganz normale Forth-Quelltexte. Damit hat man schnell eine Übersicht über die grobe Funktion dieser Quellen: Lib's sind halt reine Sammlungen von Worten zu einer bestimmten Funktionsgruppe und MOD's sind mehr oder weniger fertige und abgeschlossene Programme. Ein Beispiel:
Die Datei hss.lib enthält Worte um die HSS-Funktionen von Administra anzusprechen. Mit diesen Funktionen kann man nun ein Modul (Programm) wie einen HSS-Soundplayer schreiben.
Im Gegensatz dazu die Datei splay.mod: Mit diesem Modul wird ein HSS-Soundplayer ins System eingefügt, welcher Funktionen aus der hss.lib verwendet.
Die Datei benötigt man aber mehr oder weniger nur zur Entwicklung, ein fertiges Modul wie splay.mod enthält dann schon die die entsprechenden HSS-Worte die benötigt werden.
Die ifnot: ... Anweisung sorgt dabei dafür, dass keine Funktionen doppelt in das Wörterbuch compiliert werden. Das ist quasi ein verteiltes und fein granuliertes Konzept analog zu einer DLL. Die Forth-Version funktioniert dabei aber im Gegensatz zu DLL's nicht auf Bibliotheks-, sondern auf Funktionsebene.
*.mod Module, Forth-Erweiterungen für das System
*.lib Bibliotheken, grundlegende Wortsammlungen
*.adm Administra-Code (z.Bsp. admsid.adm für SIDCog-Code)
*.bel Bellatrix-Code
*.bin Spin-Code, im Normalfall zur Ausführung in Regnatix
basics.f - (mod:basics) Hive-Core für PropForth
ari.lib - (lib:ari) Zusätzliche arithmetische Funktionen
cog.lib - (lib:cog) Zusätzliche COG-Funktionen
adm.lib - (lib:adm) Administra-Chipmanagment-Funktionen
hss.lib - (lib:hss) Bibliothek für Hydra-Sound-System
sfx.lib - (lib:sfx) Soundeffekt-Bibliothek
wav.lib - (lib:wav) Wave-Soundbibliothek
bel.lib - (lib:bel) Bellatrix-Chipmanagment-Funktionen
key.lib - (lib:key) Tastatur-Bibliothek
scr.lib - (lib:scr) Screen-Bibliothek
sd0.lib - (lib:sd0) SD-Card-Bibliothek
debug.f - Nützliche Worte zur Fehlersuche und Entwicklung
rom.f - EEPROM-Dateisystem
tools.f - Nützliche Tools (cat, less, dm?...)
hplay.f - HSS-Player
wplay.f - WAV-Player
splay.f - SID-Player
Administra-Codedateien im SYS-Verzeichnis:
admled.adm Testprogramm - HBeat-LED blinken lassen
admsid.adm SidCog-Version (wird von splay benötigt)
admsys.adm Standardcode für ADM mit SD/HSS/WAV
admym.adm Yamaha-Soundchip-Version
aterm96.adm Mini-OS für Administra (Testzwecke)
Reset-Fehlercodes:
------------------
0011FFFF - stack overflow
0012FFFF - return stack overflow
0021FFFF - stack underflow
0022FFFF - return stack underflow
8100FFFF - no free cogs
8200FFFF - no free main memory
8400FFFF - fl no free main memory
8500FFFF - no free cog memory
8800FFFF - eeprom write error
9000FFFF - eeprom read error
.err-Fehlercodes:
-----------------
0 no error
1 fsys unmounted
2 fsys corrupted
3 fsys unsupported
4 not found
5 file not found
6 dir not found
7 file read only
8 end of file
9 end of directory
10 end of root
11 dir is full
12 dir is not empty
13 checksum error
14 reboot error
15 bpb corrupt
16 fsi corrupt
17 dir already exist
18 file already exist
19 out of disk free space
20 disk io error
21 command not found
22 timeout
23 parameter error

327
lib/adm-ay.spin Normal file
View File

@ -0,0 +1,327 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ AYcog - AY-3-891X / YM2149 emulator V0.22 (C) 2010-05 Johannes Ahlebrand │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ TERMS OF USE: Parallax Object Exchange 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
CON
PSG_FREQ = 2_000_000.0 ' Clock frequency input to the chip (Colour Genie EG2000 computer runs at 2.2Mhz)
' WARNING !!
' Don't alter the constants below unless you know what you are doing
'-------------------------------------------------------------------
SAMPLE_RATE = 125_000 ' Sample rate of AYcog
OSC_CORR = trunc(1.05 * PSG_FREQ) ' Calibrates the relative oscillator frequency
NOISE_CORR = OSC_CORR>>1 ' Calibrates the relative noise frequency
ENV_CORR = OSC_CORR>>6 ' Calibrates the relative envelope timing
'
' Reg bits function
' -----------------------------------
' 00 7..0 channel A fine tune
' 01 3..0 channel A coarse tune
' 02 7..0 channel B fine tune
' 03 3..0 channel B coarse tune
' 04 7..0 channel C fine tune
' 05 3..0 channel C coarse tune
' 06 4..0 noise period
' 07 7..0 enable register
' 08 4..0 channel A volume
' 09 4..0 channel B volume
' 10 4..0 channel C volume
' 11 7..0 envelope fine tune
' 12 7..0 envelope coarse tune
' 13 3..0 envelope shape
' 14 7..0 I/O port A value
' 15 7..0 I/O port B value
VAR
long cog
PUB start(right,left,AYregisters)
if (AYregisters & 1) <> 0 ' we need word aligned registers
abort(-1)
arg1 := $18000000 | left
arg2 := $18000000 | right
r1 := ((1<<right) | (1<<left))&!1
sampleRate := clkfreq/SAMPLE_RATE
cog := cognew(@AYEMU,AYregisters) + 1
return cog
PUB stop
if cog
cogstop(cog~ -1)
dat org 0
'
' Assembly AY emulator
'
AYEMU mov AY_Address, par ' Setup everyting
mov dira, r1
mov ctra, arg1
mov ctrb, arg2
mov waitCounter, cnt
add waitCounter, sampleRate
'-----------------------------------------------------------
mainLoop call #getRegisters
call #AY ' Main loop
call #mixer
jmp #mainLoop
'
' Read all AY registers from hub memory and convert
' them to more convenient representations.
'
getRegisters mov tempValue, AY_Address
rdword frequency1, tempValue ' reg 0+1 Read in all 4
shl frequency1, #20 ' frequency registers
add tempValue, #2 ' and make them "32 bits"
rdword frequency2, tempValue ' reg 2+3
shl frequency2, #20
add tempValue, #2
rdword frequency3, tempValue ' reg 4+5
shl frequency3, #20
add tempValue, #2
rdbyte noisePeriod, tempValue ' reg 6
and noisePeriod, #$1f
add tempValue, #1
rdbyte enableRegister, tempValue ' reg 7
min noisePeriod, #1
add tempValue, #1
rdbyte amplitude1, tempValue ' reg 8
and amplitude1, #31
add tempValue, #1
rdbyte amplitude2, tempValue ' reg 9
and amplitude2, #31
add tempValue, #1
rdbyte amplitude3, tempValue ' reg 10
and amplitude3, #31
add tempValue, #1
rdbyte envelopePeriod, tempValue ' reg 11
add tempValue, #1
shl noisePeriod, #20
rdbyte temp1, tempValue ' reg 12
shl temp1, #8
or envelopePeriod, temp1 wz
if_z mov envelopePeriod, half_period ' 0 == half the period of 1
if_nz shl envelopePeriod, #16
add tempValue, #1
rdbyte envelopeShape, tempValue ' reg 13
movd oscValues, enableRegister
getRegisters_ret ret
'
' Calculate AY samples channel 1-3 and store in out1-out3
'
AY
'───────────────────────────────────────────────────────────
'───────────────────────────────────────────────────────────
' Envelope shaping -> envelopeAmplitude
'───────────────────────────────────────────────────────────
Envelope sub envCounter, envSubValue wc ' Handles envelope incrementing
if_c add envCounter, envelopePeriod
if_c add envelopeValue, envelopeInc
'───────────────────────────────────────────────────────────
test envelopeShape, #16 wz ' Handle envelope reset bit ( Extra bit added by Ahle2 )
if_z neg envelopeValue, #0
if_z mov envelopeInc, #1
if_z mov envCounter, envelopePeriod
if_z or envelopeShape, #16
if_z wrbyte envelopeShape, tempValue '<-IMPORTANT, sets bit 5 in hub ram
'───────────────────────────────────────────────────────────
test envelopeShape, #8 wc ' Handle continue = 0
test envelopeShape, #4 wz
if_nc_and_z mov envelopeShape, #9
if_nc_and_nz mov envelopeShape, #15
'───────────────────────────────────────────────────────────
test envelopeShape, #2 wz ' Sets the envelope hold level
muxz envHoldLevel, #15 '
'───────────────────────────────────────────────────────────
test envelopeValue, #16 wz ' Check if > 15
test envelopeShape, #1 wc ' Check hold bit
if_nz_and_c mov envelopeInc, #0 ' Hold envelope
if_nz_and_c mov envelopeValue, envHoldLevel '
'───────────────────────────────────────────────────────────
if_nz test envelopeShape, #2 wc ' Check and handle alternation
if_nz_and_c neg envelopeInc, envelopeInc
if_nz_and_c add envelopeValue, envelopeInc
'───────────────────────────────────────────────────────────
mov envelopeAmplitude, envelopeValue
test envelopeShape, #4 wc ' Check and handle invertion (attack)
if_nc xor envelopeAmplitude, #15 '(Move Value or ~Value to envelopeAmplitude)
'───────────────────────────────────────────────────────────
' Waveform shaping noise -> bit 3 of oscValues
'───────────────────────────────────────────────────────────
Noise1 sub phaseAccumulatorN, noiseSubValue wc ' Noise generator
if_c add phaseAccumulatorN, noisePeriod
if_c add noiseValue, noiseAdd
if_c ror noiseValue, #15 wc
if_c xor oscValues, #8
'───────────────────────────────────────────────────────────
' Waveform shaping channel 1 -> out1
'───────────────────────────────────────────────────────────
Env1 test amplitude1, #16 wz ' Selects envelope or fixed amplitude
if_nz mov amplitude1, envelopeAmplitude ' depending on bit 5 of amplitude register 1
mov arg1, amplitude1
call #getAmplitude
'───────────────────────────────────────────────────────────
Square1 cmp frequency1, freqRef wc
if_nc sub phaseAccumulator1, oscSubValue wc ' Square wave generator
if_c add phaseAccumulator1, frequency1 ' channel 1
if_c xor oscValues, #1
'───────────────────────────────────────────────────────────
test oscValues, mask513 wz ' Handles mixing of channel 1
negnz out1, r1 ' Tone on/off, Noice on/off
test oscValues, mask4104 wz
if_z mov out1, r1 ' arg2 = (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable)
'───────────────────────────────────────────────────────────
' Waveform shaping channel 2 -> out2
'───────────────────────────────────────────────────────────
Env2 test amplitude2, #16 wz ' Selects envelope or fixed amplitude
if_nz mov amplitude2, envelopeAmplitude ' depending on bit 5 of amplitude register 2
mov arg1, amplitude2
call #getAmplitude
'───────────────────────────────────────────────────────────
Square2 cmp frequency2, freqRef wc
if_nc sub phaseAccumulator2, oscSubValue wc ' Square wave generator
if_c add phaseAccumulator2, frequency2 ' channel 2
if_c xor oscValues, #2
'───────────────────────────────────────────────────────────
test oscValues, mask1026 wz ' Handles mixing of channel 2
negz out2, r1 ' Tone on/off, Noice on/off
test oscValues, mask8200 wz
if_z mov out2, r1 ' arg2 = (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable)
'───────────────────────────────────────────────────────────
' Waveform shaping channel 3 -> out3
'───────────────────────────────────────────────────────────
Env3 test amplitude3, #16 wz ' Selects envelope or fixed amplitude
if_nz mov amplitude3, envelopeAmplitude ' depending on bit 5 of amplitude register 3
mov arg1, amplitude3
call #getAmplitude
'───────────────────────────────────────────────────────────
Square3 cmp frequency3, freqRef wc
if_nc sub phaseAccumulator3, oscSubValue wc ' Square wave generator
if_c add phaseAccumulator3, frequency3 ' channel 3
if_c xor oscValues, #4
'───────────────────────────────────────────────────────────
test oscValues, mask2052 wz ' Handles mixing of channel 2
negz out3, r1 ' Tone on/off, Noice on/off
test oscValues, mask16392 wz
if_z mov out3, r1 ' arg2 = (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable)
AY_ret ret
'
' Mix channels and update FRQA/FRQB PWM-values
'
mixer mov r1, val31bit ' DC offset
add r1, out1
add r1, out2
add r1, out3
waitcnt waitCounter, sampleRate ' Wait until the right time to update
mov FRQA, r1 '| Update PWM values in FRQA/FRQB
mov FRQB, r1 '|
mixer_ret ret
'
' Get amplitude table r1 = amplitudTable[arg1]
'
getAmplitude and arg1, #15
add arg1, #amplitudeTable ' Lookup the amplitude according
movs :indexed1, arg1 ' to the current state of the envelope
nop
:indexed1 mov r1, 0
getAmplitude_ret ret
'
' Variables, tables, masks and reference values
'
amplitudeTable long 1634706
long 2452059
long 3678089
long 5517133
long 8275700
long 12413550
long 18620325
long 27930488
long 41895733
long 62843600
long 94265400
long 141398100
long 212097150
long 318145725
long 477218588
long 715827882
'Masks and reference values
mask513 long 513
mask1026 long 1026
mask2052 long 2052
mask4104 long 4104
mask8200 long 8200
mask16392 long 16392
mask32bit long $ffffffff
mask16bit long $ffff
half_period long $00008000
val31bit long $80000000
noiseAdd long $88008800 'Value to add to the noise generator every noise update
sampleRate long 0
freqRef long 10<<20
'Setup and subroutine parameters
arg1 long 0
arg2 long 0
r1 long 0
AY_Address long 0
'AY variables
envCounter long 1
envSubValue long ENV_CORR
oscSubValue long OSC_CORR
noiseSubValue long NOISE_CORR
envelopeValue long 0
envelopeInc long 1
envHoldLevel res 1
oscValues res 1
amplitude1 res 1
amplitude2 res 1
amplitude3 res 1
envelopeAmplitude res 1
enableRegister res 1
envelopeShape res 1
frequency1 res 1
frequency2 res 1
frequency3 res 1
envelopePeriod res 1
noisePeriod res 1
phaseAccumulatorN res 1
phaseAccumulator1 res 1
phaseAccumulator2 res 1
phaseAccumulator3 res 1
noiseValue res 1
noiseOut res 1
out1 res 1
out2 res 1
out3 res 1
waitCounter res 1
tempValue res 1
temp1 res 1
fit

334
lib/adm-com.spin Normal file
View File

@ -0,0 +1,334 @@
'' Singleton version of:
''
''********************************************
''* Full-Duplex Serial Driver v1.2 *
''* Author: Chip Gracey, Jeff Martin *
''* Copyright (c) 2006-2009 Parallax, Inc. *
''* See end of file for terms of use. *
''********************************************
{-----------------REVISION HISTORY-----------------
v1.2 - 5/7/2009 fixed bug in dec method causing largest negative value (-2,147,483,648) to be output as -0.
v1.1 - 3/1/2006 first official release.
}
CON EOL = $a
CON CR = $d
VAR
long cog 'cog flag/id
DAT
rx_head long 0 '9 contiguous longs
rx_tail long 0
tx_head long 0
tx_tail long 0
rx_pin long 0
tx_pin long 0
rxtx_mode long 0
bit_ticks long 0
buffer_ptr long 0
rx_buffer byte 0 [16] 'transmit and receive buffers
tx_buffer byte 0 [16]
PUB start(rxpin, txpin, mode, baudrate) : okay
'' Start serial driver - starts a cog
'' returns false if no cog available
''
'' mode bit 0 = invert rx
'' mode bit 1 = invert tx
'' mode bit 2 = open-drain/source tx
'' mode bit 3 = ignore tx echo on rx
stop
longfill(@rx_head, 0, 4)
longmove(@rx_pin, @rxpin, 3)
bit_ticks := clkfreq / baudrate
buffer_ptr := @rx_buffer
okay := cog := cognew(@entry, @rx_head) + 1
PUB stop
'' Stop serial driver - frees a cog
if cog
cogstop(cog~ - 1)
longfill(@rx_head, 0, 9)
PUB rxflush
'' Flush receive buffer
repeat while rxcheck => 0
PUB rxready
return rx_tail <> rx_head
PUB rxcheck : rxbyte
'' Check if byte received (never waits)
'' returns -1 if no byte received, $00..$FF if byte
rxbyte--
if rx_tail <> rx_head
rxbyte := rx_buffer[rx_tail]
rx_tail := (rx_tail + 1) & $F
PUB rxtime(ms) : rxbyte | t
'' Wait ms milliseconds for a byte to be received
'' returns -1 if no byte received, $00..$FF if byte
t := cnt
repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms
PUB rx : rxbyte
'' Receive byte (may wait for byte)
'' returns $00..$FF
repeat while (rxbyte := rxcheck) < 0
PUB out(txbyte)
tx(txbyte)
PUB tx(txbyte)
if txbyte == EOL
tx(CR)
'' Send byte (may wait for room in buffer)
repeat until (tx_tail <> (tx_head + 1) & $F)
tx_buffer[tx_head] := txbyte
tx_head := (tx_head + 1) & $F
if rxtx_mode & %1000
rx
PUB str(stringptr)
'' Send string
repeat while byte[stringptr]
tx(byte[stringptr++])
PUB dec(value) | i, x
'' Print a decimal number
x := value == NEGX 'Check for max negative
if value < 0
value := ||(value+x) 'If negative, make positive; adjust for max negative
tx("-") 'and output sign
i := 1_000_000_000 'Initialize divisor
repeat 10 'Loop for 10 digits
if value => i
tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative
value //= i 'and digit from value
result~~ 'flag non-zero found
elseif result or i == 1
tx("0") 'If zero digit (or only digit) output it
i /= 10 'Update divisor
PUB hex(value, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB bin(value, digits)
'' Print a binary number
value <<= 32 - digits
repeat digits
tx((value <-= 1) & 1 + "0")
DAT
'***********************************
'* Assembly language serial driver *
'***********************************
org
'
'
' Entry
'
entry mov t1,par 'get structure address
add t1,#4 << 2 'skip past heads and tails
rdlong t2,t1 'get rx_pin
mov rxmask,#1
shl rxmask,t2
add t1,#4 'get tx_pin
rdlong t2,t1
mov txmask,#1
shl txmask,t2
add t1,#4 'get rxtx_mode
rdlong rxtxmode,t1
add t1,#4 'get bit_ticks
rdlong bitticks,t1
add t1,#4 'get buffer_ptr
rdlong rxbuff,t1
mov txbuff,rxbuff
add txbuff,#16
test rxtxmode,#%100 wz 'init tx pin according to mode
test rxtxmode,#%010 wc
if_z_ne_c or outa,txmask
if_z or dira,txmask
mov txcode,#transmit 'initialize ping-pong multitasking
'
'
' Receive
'
receive jmpret rxcode,txcode 'run a chunk of transmit code, then return
test rxtxmode,#%001 wz 'wait for start bit on rx pin
test rxmask,ina wc
if_z_eq_c jmp #receive
mov rxbits,#9 'ready to receive byte
mov rxcnt,bitticks
shr rxcnt,#1
add rxcnt,cnt
:bit add rxcnt,bitticks 'ready next bit period
:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return
mov t1,rxcnt 'check if bit receive period done
sub t1,cnt
cmps t1,#0 wc
if_nc jmp #:wait
test rxmask,ina wc 'receive bit on rx pin
rcr rxdata,#1
djnz rxbits,#:bit
shr rxdata,#32-9 'justify and trim received byte
and rxdata,#$FF
test rxtxmode,#%001 wz 'if rx inverted, invert byte
if_nz xor rxdata,#$FF
rdlong t2,par 'save received byte and inc head
add t2,rxbuff
wrbyte rxdata,t2
sub t2,rxbuff
add t2,#1
and t2,#$0F
wrlong t2,par
jmp #receive 'byte done, receive next byte
'
'
' Transmit
'
transmit jmpret txcode,rxcode 'run a chunk of receive code, then return
mov t1,par 'check for head <> tail
add t1,#2 << 2
rdlong t2,t1
add t1,#1 << 2
rdlong t3,t1
cmp t2,t3 wz
if_z jmp #transmit
add t3,txbuff 'get byte and inc tail
rdbyte txdata,t3
sub t3,txbuff
add t3,#1
and t3,#$0F
wrlong t3,t1
or txdata,#$100 'ready byte to transmit
shl txdata,#2
or txdata,#1
mov txbits,#11
mov txcnt,cnt
:bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode
test rxtxmode,#%010 wc
if_z_and_c xor txdata,#1
shr txdata,#1 wc
if_z muxc outa,txmask
if_nz muxnc dira,txmask
add txcnt,bitticks 'ready next cnt
:wait jmpret txcode,rxcode 'run a chunk of receive code, then return
mov t1,txcnt 'check if bit transmit period done
sub t1,cnt
cmps t1,#0 wc
if_nc jmp #:wait
djnz txbits,#:bit 'another bit to transmit?
jmp #transmit 'byte done, transmit next byte
'
'
' Uninitialized data
'
t1 res 1
t2 res 1
t3 res 1
rxtxmode res 1
bitticks res 1
rxmask res 1
rxbuff res 1
rxdata res 1
rxbits res 1
rxcnt res 1
rxcode res 1
txmask res 1
txbuff res 1
txdata res 1
txbits res 1
txcnt res 1
txcode res 1
{{
+------------------------------------------------------------------------------------------------------------------------------+
¦ 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. ¦
+------------------------------------------------------------------------------------------------------------------------------+
}}

2450
lib/adm-fat.spin Normal file

File diff suppressed because it is too large Load Diff

738
lib/adm-hss.spin Normal file
View File

@ -0,0 +1,738 @@
''*****************************
''* Hydra Sound System v1.2 *
''* (C)2007 Andrew Arsenault *
''*****************************
''http://www.andrewarsenault.com/hss/
''e-mail: ym2413a@yahoo.com
''
'' Cogs used: 2
'' HUB-RAM: ~2.7k
'' Please visit the website for the latest version, documentation, examples and media files.
'' Thank you! --Ym2413a
'' 25.01.2009 Anpassungen für ein komfortableres Interface zur Visualisierung und Steuerung
CON
#0, iEndFlag 'Repeat oder Ende wurde erreicht
iRowFlag 'Flag das Songzeile fertig ist
iEngineC 'Patternzähler
iBeatC 'Beatzähler
iRepeat 'zähler für loops
#5, iChannel
#5, iChannel1
#10, iChannel2
#15, iChannel3
#16, iChannel4
#0, iNote
iOktave
iVolume
iEffekt
iInstrument
VAR
'Interface
word intreg[5 * 5]
'Sound Engine Stack
long hsnd_stack[18]
long cog1, cog2
'WavSynth Parameters
long snd_regs[48] 'Regs for Sound Hardware (8x6)+5dpcm
long dpcm_regs[5]
'DPCM Command Variables
word dpcmreg_ptr
'Global Hmus Player Vars
word tempo
word song_pc
word song_div
word song_ptr
word chfre[4]
byte chfx[4]
byte chvol[4]
byte hmus_state
byte hmvol
byte fxphs
'Sound FX Variables
word runlen[2]
word envamp[2]
word sfx_ptr[2]
byte envphs[2]
byte fmcnt[2], fmfreq[2]
byte loadsfx[2]
CON
'' Hss Master Control
PUB start: okay
okay := cog1 := cognew(@entry, @snd_regs)
okay := cog2 := cognew(hsound, @hsnd_stack)
PUB stop
cogstop(cog2)
cogstop(cog1)
PUB peek(addrptr) : var1
var1 := LONG[@snd_regs][addrptr]
PUB intread(index): wert 'interface: auslesen eines interfaceregisters
wert := intreg[index]
CON
'' Hydra Music Commands
PUB hmus_load(songptr) | z
hmvol := 15
song_div := 0
song_ptr := songptr
song_pc := WORD[songptr][8]
tempo := WORD[songptr][12]
repeat z from 0 to 3
chfx[z] := 0
repeat z from 0 to 5*5 'interface: playerinterface alle werte löschen
intreg[z] := 0
PUB hmus_play
hmus_state := 1
PUB hmus_stop | z
hmus_state := 0
repeat z from 0 to 3
chvol[z] := 0
PUB hmus_pause
hmus_state := 0
PUB hmus_tempo(var1)
tempo := var1
PUB get_hmus_tempo : var1
var1 := tempo
PUB hmus_vol(var1)
hmvol := var1 <# 15 #> 0
PUB get_hmus_vol : var1
var1 := hmvol
CON
'' FXsynth Commands
PUB sfx_play(chan, soundptr)
if(chan == 1)
sfx_ptr[0] := soundptr
loadsfx[0] := 0
if(chan == 2)
sfx_ptr[1] := soundptr
loadsfx[1] := 0
PUB sfx_stop(chan)
if(chan == 1)
sfx_ptr[0] := 0
if(chan == 2)
sfx_ptr[1] := 0
PUB sfx_keyoff(chan)
if(chan == 1)
envphs[0] := 3
if(chan == 2)
envphs[1] := 3
CON
'' Hydra DPCM Commands
PUB dpcm_play(soundptr)
dpcmreg_ptr := soundptr
PUB dpcm_stop
dpcmreg_ptr := 1
CON
''*****************************
''* Hss Sound Engine *
''*****************************
PRI Hsound
repeat
'Update Music Engine
UpdateMus(song_ptr, Hmus_state) 'Update Music Player
'volume/frequenzwerte werden in die soundregister geschrieben
VolumeInterpol 'Delay and Interpolate Volume to Remove Pops and Clicks.
'Update DPCM Engine
if(dpcmreg_ptr)
DpcmUpdate 'Update the DPCM registers
'Update SoundFX Engine
'FX channel A
FXSynth(0,32)
'FX channel B
FXSynth(1, 40)
PRI VolumeInterpol | z, channelmul, musvar, freqval
fxphs += 5
'Volume Interpolation
repeat z from 0 to 3 step 1
channelmul := 4+(8*z)
musvar := (chvol[z]*(hmvol+1))&$F0
snd_regs[channelmul] := (snd_regs[channelmul] & 15)+musvar
'Freq Interpolation
channelmul -= 1 'Jump down a REG to Freq
musvar := chfre[z]<<16
if(chfx[z] == 0) 'None
snd_regs[channelmul] := musvar
elseif(chfx[z] < 3) 'Vibrato (light/hard)
if(fxphs < 128)
snd_regs[channelmul] := musvar+(chfre[z]<<(7+chfx[z]))
else
snd_regs[channelmul] := musvar-(chfre[z]<<(7+chfx[z]))
elseif(chfx[z] == 3) 'Tremolo
if(fxphs < 128)
snd_regs[channelmul] := musvar
else
snd_regs[channelmul] := musvar<<1
else 'Portamento
freqval := snd_regs[channelmul]>>16
if(freqval & $F000 == chfre[z] & $F000)
snd_regs[channelmul] := musvar
elseif(freqval < chfre[z])
snd_regs[channelmul] := snd_regs[channelmul]+(chfx[z]<<22)
else
snd_regs[channelmul] := snd_regs[channelmul]-(chfx[z]<<22)
PRI UpdateMus(songptr, state) | i, channel, channelmul, scrdat, freq, freqoct, flag
if(state == 0)
return ''Song is not playing.
song_div++ 'zeitfaktor; wird erhöht bis...
if(song_div => tempo) 'Tempo Divider 'schwellwert erreicht, dann nächster beat
song_div := 0
flag := 0
intreg[iBeatC] := intreg[iBeatC] + 1 'interface: beatconter erhöhen
intreg[iRowFlag] := 0 'interface: Kennung das Zeile bearbeitet wird
repeat i from 5 to 5*5 'interface: channelwerte löschen
intreg[i] := 0
repeat 'Score Decoder and Processor
scrdat := BYTE[song_ptr][song_pc] 'song_pc ist zeiger auf wert in MusicDat
channel := scrdat & 3 'untere zwei bit enthalten die kanalnummer
channelmul := channel<<3 'jedem channel sind 8 registerwerte zugeordent
intreg[iEngineC] := song_pc 'interface: enginecounter setzen
song_pc++ 'zeiger auf nächsten wert setzen
''Base Commands
if(scrdat == 0) 'End Row 'nächste trackerzeile
intreg[iRowFlag] := 1 'interface: Zeile fertig bearbeitet
quit
if(scrdat == 1) 'Repeat Song 'wiederholt ab MusicLoop (MusicDat ist also die einleitung)
song_pc := WORD[songptr][9]
intreg[iRepeat] := intreg[iRepeat] + 1 'interface: flag das songende erreicht wurde
quit
if(scrdat == 2) 'End Song 'status wird auf 0 gesetzt
intreg[iEndFlag] := 1 'interface: flag das songende erreicht wurde
hmus_stop
quit
if(scrdat == 3) 'Set Flag
flag := 1
next
if((scrdat & $3C) == $20) 'Patch HI Note 'oktave erhöhen und veränderung zu "Change Note"
flag := 2
scrdat := scrdat>>3
scrdat += 64+channel
if(scrdat & 4) 'Change Note
freq := scrdat>>3 'note Bit3 bis Bit7 (32 Noten)
freqoct := freq/12
freq -= freqoct*12
case flag
1 : freqoct += 2
2 : freqoct += 6
other : freqoct += 4
flag := 0
snd_regs[4+channelmul] := snd_regs[4+channelmul] & $FE
intreg[(channel*iChannel)+iChannel+iNote] := freq + 1 'interface: note setzen (0 ist erste note!)
intreg[(channel*iChannel)+iChannel+iOktave] := freqoct 'interface: oktave setzen
'frequenz aus tabelle holen
'je nach oktave wird nach rechts verschoben (/2)
chfre[channel] := NoteFreqs[freq]>>(6-freqoct)
snd_regs[4+channelmul] := (snd_regs[4+channelmul] & $FE)+1
next 'Repeat To Next Datum
if(scrdat & 8) 'Change Evelope / Channel Effect
if(flag)
intreg[(channel*iChannel)+iChannel+iEffekt] := scrdat>>4 + 1 'interface: effektwert setzen
chfx[channel] := scrdat>>4
flag := 0
else
intreg[(channel*iChannel)+iChannel+iVolume] := scrdat>>4 'interface: volume setzen
chvol[channel] := scrdat>>4
next 'Repeat To Next Datum
if(scrdat & 16) 'Change Instrument
freq := (scrdat & $E0)>>3
freq += flag<<5
flag := 0
intreg[(channel*iChannel)+iChannel+iInstrument] := freq>>2 + 1 'interface: instrument setzen
snd_regs[0+channelmul] := songptr+WORD[songptr+32][freq] 'zeiger auf neues instrumentensample
snd_regs[1+channelmul] := WORD[songptr+32][freq+1] 'ende des samples
snd_regs[2+channelmul] := WORD[songptr+32][freq+2] 'loop
snd_regs[4+channelmul] := WORD[songptr+32][freq+3] & $0F 'flags?
next 'Repeat To Next Datum
if(scrdat & 64) 'Detune
chfre[channel] := chfre[channel]+(chfre[channel]>>8)
PRI DpcmUpdate
if(dpcmreg_ptr > 15) 'Play Sample.
dpcm_regs[2] := 65535 'End sample if one was playing
dpcm_regs[0] := dpcmreg_ptr+8
dpcm_regs[4] := 128
dpcm_regs[3] := LONG[dpcmreg_ptr][1] 'Get sampling rate
dpcm_regs[1] := WORD[dpcmreg_ptr][1] 'Get length
dpcm_regs[2] := 0 'Reset play counter
elseif(dpcmreg_ptr == 1) 'Stop Sample
dpcm_regs[2] := 65535 'End sample
dpcm_regs[4] := 128
dpcmreg_ptr := 0
PRI FXSynth(SoundVars, ChannelFX) | TimeCnt, SoundFX, Modwav, FMwav, AMwav
TimeCnt := Cnt
SoundFX := sfx_ptr[SoundVars]
if(loadsfx[SoundVars] == 0)
'Setup OSC WaveForm
case BYTE[SoundFX][0]
$00: 'Sine
snd_regs[ChannelFX] := @SineTable
snd_regs[1+ChannelFX] := 64
$01: 'Fast Sine
snd_regs[ChannelFX] := @FastSine
snd_regs[1+ChannelFX] := 32
$02: 'Sawtooth
snd_regs[ChannelFX] := @Sawtooth
snd_regs[1+ChannelFX] := 64
$03: 'Square
snd_regs[ChannelFX] := @SqrTable
snd_regs[1+ChannelFX] := 32
$04: 'Fast Square
snd_regs[ChannelFX] := @FastSqr
snd_regs[1+ChannelFX] := 8
$05: 'Buzz
snd_regs[ChannelFX] := @NoteFreqs
snd_regs[1+ChannelFX] := 24
$06: 'Noise
snd_regs[ChannelFX] := $F002
snd_regs[1+ChannelFX] := 3000
snd_regs[2+ChannelFX] := 0
snd_regs[4+ChannelFX] := $01
loadsfx[SoundVars] := 1
runlen[SoundVars] := 0
fmcnt[SoundVars] := 0
fmfreq[SoundVars] := 0
envamp[SoundVars] := 0
envphs[SoundVars] := 0
''Modulation Code
fmfreq[SoundVars]++
if(fmfreq[SoundVars] => BYTE[SoundFX][4])
fmfreq[SoundVars] := 0
fmcnt[SoundVars]++
fmcnt[SoundVars] := fmcnt[SoundVars] & $3F
case BYTE[SoundFX][5]
$00:
Modwav := BYTE[@SineTable][fmcnt[SoundVars]]
$01:
Modwav := BYTE[@FastSine][fmcnt[SoundVars] & 31]
$02:
Modwav := fmcnt[SoundVars]<<2
$03:
Modwav := !fmcnt[SoundVars]<<2
$04:
if(fmcnt[SoundVars] & 8)
Modwav := $ff
else
Modwav := $00
$05:
Modwav := BYTE[$F002][fmcnt[SoundVars]]
$FF:
Modwav := BYTE[SoundFX+12][fmcnt[SoundVars] & 15]
fmwav := Modwav/(BYTE[SoundFX][6]) 'FM amount
amwav := 256-(Modwav/(BYTE[SoundFX][7])) 'AM amount
amwav := (BYTE[SoundFX][3]*amwav)>>8
''Envelope Generator
if(envphs[SoundVars] == 0) 'Attack
envamp[SoundVars] += BYTE[SoundFX][8]
if(envamp[SoundVars] > 8191)
envamp[SoundVars] := 8191
envphs[SoundVars] := 1
if(BYTE[SoundFX][8] == $ff)
envamp[SoundVars] := 8191
if(envphs[SoundVars] == 1) 'Decay
envamp[SoundVars] -= BYTE[SoundFX][9]
if(envamp[SoundVars] & $8000)
envphs[SoundVars] := 2
if(envamp[SoundVars] =< (BYTE[SoundFX][10]<<5))
envphs[SoundVars] := 2
if(envphs[SoundVars] == 2) 'Sustain
envamp[SoundVars] := (BYTE[SoundFX][10]<<5)
if(envphs[SoundVars] == 3) 'Release
envamp[SoundVars] -= BYTE[SoundFX][11]
if(envamp[SoundVars] & $8000)
envamp[SoundVars] := 4
amwav := ((envamp[SoundVars]>>9)*(amwav+1))>>4
''Run Length and Outputing
if(SoundFX > 15)
runlen[SoundVars]++
snd_regs[3+ChannelFX] := (BYTE[SoundFX][2]+fmwav)<<24 'Update Frequency
snd_regs[4+ChannelFX] := (amwav<<4)+(snd_regs[4+ChannelFX] & $0F) 'Update Amplitude
else
snd_regs[4+ChannelFX] := $00 'Mute
if(BYTE[SoundFX][1] == $ff) '$ff = never stop
runlen[SoundVars] := 0
if(runlen[SoundVars] > (BYTE[SoundFX][1]<<5)) 'Duration KeyOff
envphs[SoundVars] := 3
WaitCnt(TimeCnt + 52_000) ''Delay for Synth Engine Update.
DAT
SineTable byte $80, $8c, $98, $a5, $b0, $bc, $c6, $d0
byte $da, $e2, $ea, $f0, $f5, $fa, $fd, $fe
byte $ff, $fe, $fd, $fa, $f5, $f0, $ea, $e2
byte $da, $d0, $c6, $bc, $b0, $a5, $98, $8c
byte $80, $73, $67, $5a, $4f, $43, $39, $2f
byte $25, $1d, $15, $0f, $0a, $05, $02, $01
byte $00, $01, $02, $05, $0a, $0f, $15, $1d
byte $25, $2f, $39, $43, $4f, $5a, $67, $73
Sawtooth byte $ff, $fb, $f7, $f3, $ef, $eb, $e7, $e3
byte $df, $db, $d7, $d3, $cf, $cb, $c7, $c3
byte $bf, $bb, $b7, $b3, $af, $ab, $a7, $a3
byte $9f, $9b, $97, $93, $8f, $8b, $87, $83
byte $80, $7c, $78, $74, $70, $6c, $68, $64
byte $60, $5c, $58, $54, $50, $4c, $48, $44
byte $40, $3c, $38, $34, $30, $2c, $28, $24
byte $20, $1c, $18, $14, $10, $0c, $08, $04
FastSine byte $80, $98, $b0, $c6, $da, $ea, $f5, $fd
byte $ff, $fd, $f5, $ea, $da, $c6, $b0, $98
byte $80, $67, $4f, $39, $25, $15, $0a, $02
byte $00, $02, $0a, $15, $25, $39, $4f, $67
SqrTable byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
byte $00, $00, $00, $00, $00, $00, $00, $00
byte $00, $00, $00, $00, $00, $00, $00, $00
FastSqr byte $ff, $ff, $ff, $ff, $00, $00, $00, $00
'Note LookupTable.
NoteFreqs word $85F3, $8DEA, $965B, $9F4B, $A8C4, $B2CD, $BD6F, $C8B3, $D4A2, $E147, $EEAC, $FCDE 'Top Octave Lookup
CON
''*****************************
''* WaveTable Synth v1.2 *
''* DPCM Synth v1.1 *
''* (C)2006 Andrew Arsenault *
''*****************************
DAT
org
entry mov dira,Port_Pins 'Setup output pins
mov ctra,Right_ctra 'Setup Right Audio Channel
mov ctrb,Left_ctra 'Setup Left Audio Channel
mov ChlA_wave,#256 'Set channel signals.
mov ChlA_offset,#0 'Set channel's offset.
mov ChlA_counter,#0
mov Time,#10
add Time,cnt 'Prepare for asm type WAITCNT loop.
'MAIN LOOP
update waitcnt Time,Timing_delay 'Wait for CNT = D, then add S into D
'Transfer Sound Registers
mov addrregs,par
mov y,NumberOfChannels
'Fetch Channel's Registers
transferchl rdlong ChlAp_sampptr,addrregs
add addrregs,#4
rdlong ChlAp_sampend,addrregs
add addrregs,#4
rdlong Ch1Ap_samplpp,addrregs
add addrregs,#4
rdlong Ch1Ap_freq,addrregs
add addrregs,#4
rdlong ChlAp_keyon,addrregs
'Fetch Channel's Static Variables
add addrregs,#8
rdlong ChlA_offset,addrregs
add addrregs,#4
rdlong ChlA_counter,addrregs
'Run Synth Engine on Channel
call #wvsynth
'Store Channel's Static Variables (Tucked Center X move to Wave)
wrlong ChlA_counter,addrregs
sub addrregs,#4
sub x,#256
wrlong ChlA_offset,addrregs
sub addrregs,#4
mov ChlA_wave,x 'Doesn't Waste anything doing this.
wrlong ChlA_wave,addrregs
add addrregs,#12
'Loop Until All Channel's Are Done.
djnz y,#transferchl
'Run DPCM Engine
call #dpcm
'Mix Channels Together
mov addrregs,par
mov ChlA_wave,#0
add addrregs,#5*4
mov y,NumberOfChannels
mixchls rdlong x,addrregs
add ChlA_wave,x
add addrregs,#8*4
djnz y,#mixchls
mov x,DPCM_wave 'Add DPCM
shl x,#2
add ChlA_wave,x
shl ChlA_wave,#20 'Convert 12bit singal into a 32bit one.
'Update output Channels then repeat again.
mov frqa,ChlA_wave
mov frqb,ChlA_wave
jmp #update
'-------------------------Dpcm Engine-------------------------'
dpcm mov addrregs,par
add addrregs,#192
rdlong DPCM_address,addrregs 'Start Address
add addrregs,#4
rdlong DPCM_runlen,addrregs 'File Lenght
add addrregs,#4
rdlong DPCM_offset,addrregs 'File Offset
add addrregs,#4
rdlong DPCM_freq,addrregs 'Playback Speed
add addrregs,#4
rdlong DPCM_wave,addrregs 'Waveform Amp
'Check for if keyon/length is set.
cmp DPCM_offset,DPCM_runlen wc
if_ae jmp #mute_dpcm 'End of file
'Freq Timer/Divider and Increase sampling offset
add DPCM_counter,DPCM_freq wc
if_nc jmp #done_dpcm
'Decode DPCM
add DPCM_address,DPCM_offset
rdbyte x,DPCM_address 'Fetch Datum
mov DPCM_delta,x
shr DPCM_delta,#6
mov y,#1
shl y,DPCM_delta
mov DPCM_delta,y
mov y,#1
shl y,DPCM_phs
test x,y wc
if_c add DPCM_wave,DPCM_delta
if_nc sub DPCM_wave,DPCM_delta
add DPCM_phs,#1
cmp DPCM_phs,#6 wc
if_b jmp #done_dpcm
mov DPCM_phs,#0
add DPCM_offset,#1
jmp #done_dpcm
mute_dpcm mov DPCM_wave, #128
done_dpcm mov addrregs,par
add addrregs,#200
wrlong DPCM_offset,addrregs 'File Offset
add addrregs,#8
wrlong DPCM_wave,addrregs 'Wave
dpcm_ret ret
'-----------------------Dpcm Engine End-----------------------'
'-------------------------Sound Engine-------------------------'
'Freq Timer/Divider and Increase sampling offset
wvsynth add ChlA_counter,Ch1Ap_freq wc
if_c add ChlA_offset,#1
'Reset sample position and lock at zero if Keyoff.
test ChlAp_keyon,#%0001 wc
if_nc mov ChlA_offset,#0
'Reset(loop) if needed
cmp ChlA_offset,ChlAp_sampend wc
if_ae mov ChlA_offset,Ch1Ap_samplpp
'Check BitRate and Set Offset
mov x,ChlA_offset
test ChlAp_keyon,#%0010 wc
if_c shr x,#1
'Fetch WaveTable
mov ChlA_wave,ChlAp_sampptr
add ChlA_wave,x
rdbyte ChlA_wave,ChlA_wave
'Check BitRate and Skip if 8bit
test ChlAp_keyon,#%0010 wc
if_nc jmp #skip_4bitsam
'Convert 4bit to 8bit
test ChlA_offset,#%0001 wc
if_c shr ChlA_wave,#4
if_nc and ChlA_wave,#%00001111
mov x,ChlA_wave
shl ChlA_wave,#4
add ChlA_wave,x
'Center Amplitude and mute if Keyoff.
skip_4bitsam test ChlAp_keyon,#%0001 wc
if_nc mov ChlA_wave,#128
'Volume Multiply
mov x,#0
test ChlAp_keyon,#%10000000 wc
if_c add x,ChlA_wave
if_nc add x,#128
shr ChlA_wave,#1
test ChlAp_keyon,#%01000000 wc
if_c add x,ChlA_wave
if_nc add x,#64
add x,#64
shr ChlA_wave,#1
test ChlAp_keyon,#%00100000 wc
if_c add x,ChlA_wave
if_nc add x,#32
add x,#96
shr ChlA_wave,#1
test ChlAp_keyon,#%00010000 wc
if_c add x,ChlA_wave
if_nc add x,#16
add x,#112
'Return Audio as X.
wvsynth_ret ret
'-----------------------Sound Engine End-----------------------'
Port_Pins long %00000000_00000000_00000011_00000000
'- CTR PLL -------- BPIN --- APIN
Right_ctra long %0_00110_000_00000000_000000_000_001000
Left_ctra long %0_00110_000_00000000_000000_000_001001
Timing_delay long 2500 'Sampling Rate = 32,000.00hz
NumberOfChannels long 6
Time res 1
addrregs res 1
x res 1
y res 1
'WaveTable Synth Accumulators
ChlA_wave res 1
ChlA_offset res 1
ChlA_counter res 1
ChlAp_sampptr res 1
ChlAp_sampend res 1
Ch1Ap_samplpp res 1
Ch1Ap_freq res 1
ChlAp_keyon res 1
'DPCM Accumulators
DPCM_wave res 1
DPCM_address res 1
DPCM_offset res 1
DPCM_counter res 1
DPCM_freq res 1
DPCM_runlen res 1
DPCM_phs res 1
DPCM_delta res 1

140
lib/adm-plx.spin Normal file
View File

@ -0,0 +1,140 @@
''*******************************************************************
''* Simple Asynchronous Serial Driver v1.3 *
''* Authors: Chip Gracey, Phil Pilgrim, Jon Williams, Jeff Martin *
''* Copyright (c) 2006 Parallax, Inc. *
''* See end of file for terms of use. *
''*******************************************************************
''
'' Performs asynchronous serial input/output at low baud rates (~19.2K or lower) using high-level code
'' in a blocking fashion (ie: single-cog (serial-process) rather than multi-cog (parallel-process)).
''
'' To perform asynchronous serial communication as a parallel process, use the FullDuplexSerial object instead.
''
''
'' v1.3 - May 7, 2009 - Updated by Jeff Martin to fix rx method bug, noted by Mike Green and others, where uninitialized
'' variable would mangle received byte.
'' v1.2 - March 26, 2008 - Updated by Jeff Martin to conform to Propeller object initialization standards and compress by 11 longs.
'' v1.1 - April 29, 2006 - Updated by Jon Williams for consistency.
''
''
'' The init method MUST be called before the first use of this object.
'' Optionally call finalize after final use to release transmit pin.
''
'' Tested to 19.2 kbaud with clkfreq of 80 MHz (5 MHz crystal, 16x PLL)
VAR
long sin, sout, inverted, bitTime, rxOkay, txOkay
PUB init(rxPin, txPin, baud): Okay
{{Call this method before first use of object to initialize pins and baud rate.
• For true mode (start bit = 0), use positive baud value. Ex: serial.init(0, 1, 9600)
For inverted mode (start bit = 1), use negative baud value. Ex: serial.init(0, 1, -9600)
• Specify -1 for "unused" rxPin or txPin if only one-way communication desired.
• Specify same value for rxPin and txPin for bi-directional communication on that pin and connect a pull-up/pull-down resistor
to that pin (depending on true/inverted mode) since pin will set it to hi-z (input) at the end of transmission to avoid
electrical conflicts. See "Same-Pin (Bi-Directional)" examples, below.
EXAMPLES:
Standard Two-Pin Bi-Directional True/Inverted Modes Standard One-Pin Uni-Directional True/Inverted Mode
Ex: serial.init(0, 1, ±9600) Ex: serial.init(0, -1, ±9600) -or- serial.init(-1, 0, ±9600)
┌────────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐
│Propeller P0├─────────────┤I/O Device│ │Propeller P0├───────────────┤I/O Device│
│ P1├─────────────┤ │ └────────────┘ └──────────┘
└────────────┘ └──────────┘
Same-Pin (Bi-Directional) True Mode Same-Pin (Bi-Directional) Inverted Mode
Ex: serial.init(0, 0, 9600) Ex: serial.init(0, 0, -9600)
 ┌────────────┐ ┌──────────┐
│ │Propeller P0├─────┳─────┤I/O Device│
 4.7 kΩ └────────────┘ │ └──────────┘
┌────────────┐ │ ┌──────────┐  4.7 kΩ
│Propeller P0├─────┻─────┤I/O Device│ │
└────────────┘ └──────────┘ 
}}
finalize ' clean-up if restart
rxOkay := rxPin > -1 ' receiving?
txOkay := txPin > -1 ' transmitting?
sin := rxPin & $1F ' set rx pin
sout := txPin & $1F ' set tx pin
inverted := baud < 0 ' set inverted flag
bitTime := clkfreq / ||baud ' calculate serial bit time
return rxOkay | TxOkay
PUB finalize
{{Call this method after final use of object to release transmit pin.}}
if txOkay ' if tx enabled
dira[sout]~ ' float tx pin
rxOkay := txOkay := false
PUB rx: rxByte | t
{{ Receive a byte; blocks caller until byte received. }}
if rxOkay
dira[sin]~ ' make rx pin an input
waitpeq(inverted & |< sin, |< sin, 0) ' wait for start bit
t := cnt + bitTime >> 1 ' sync + 1/2 bit
repeat 8
waitcnt(t += bitTime) ' wait for middle of bit
rxByte := ina[sin] << 7 | rxByte >> 1 ' sample bit
waitcnt(t + bitTime) ' allow for stop bit
rxByte := (rxByte ^ inverted) & $FF ' adjust for mode and strip off high bits
PUB tx(txByte) | t
{{ Transmit a byte; blocks caller until byte transmitted. }}
if txOkay
outa[sout] := !inverted ' set idle state
dira[sout]~~ ' make tx pin an output
txByte := ((txByte | $100) << 2) ^ inverted ' add stop bit, set mode
t := cnt ' sync
repeat 10 ' start + eight data bits + stop
waitcnt(t += bitTime) ' wait bit time
outa[sout] := (txByte >>= 1) & 1 ' output bit (true mode)
if sout == sin
dira[sout]~ ' release to pull-up/pull-down
PUB str(strAddr)
{{ Transmit z-string at strAddr; blocks caller until string transmitted. }}
if txOkay
repeat strsize(strAddr) ' for each character in string
tx(byte[strAddr++]) ' write the character
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

352
lib/adm-rtc.spin Normal file
View File

@ -0,0 +1,352 @@
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Real Time Clock Engine │
│ │
│ Author: Kwabena W. Agyeman │
│ Updated: 11/22/2009 │
│ Designed For: P8X32A │
│ │
│ Copyright (c) 2009 Kwabena W. Agyeman │
│ See end of file for terms of use. │
│ │
│ Driver Info: │
│ │
│ The RTCEngine interfaces with the DS1307RTC. │
│ │
│ The driver is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │
│ so port B will not be operational. │
│ │
│ Nyamekye, │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
CON
''
'' 3.3V
'' 
'' │
''  10KΩ
'' │
Data_Pin = 29 '' ─┻─ SDA
''
'' 3.3V
'' 
'' │
''  10KΩ
'' │
Clock_Pin = 28 '' ─┻─ SCL
RTC_Address = %1101000
CON
' For use with "getDay" and "setDay".
#1, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
' For use with "getMonth" and "setMonth".
#1, January, February, March, April, May, June, July, August, September, October, November, December
PUB getSeconds '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the current second (0 - 59) from the real time clock. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return BCDToNumber(getRAM(0))
PUB getMinutes '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the current minute (0 - 59) from the real time clock. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return BCDToNumber(getRAM(1))
PUB getHours '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the current hour (0 - 23) from the real time clock. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return BCDToNumber(getRAM(2))
PUB getDay '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the current day (1 - 7) from the real time clock. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return BCDToNumber(getRAM(3))
PUB getDate '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the current date (1 - 31) from the real time clock. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return BCDToNumber(getRAM(4))
PUB getMonth '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the current month (1 - 12) from the real time clock. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return BCDToNumber(getRAM(5))
PUB getYear '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the current year (2000 - 2099) from the real time clock. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (BCDToNumber(getRAM(6)) + 2000)
PUB setSeconds(seconds) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the current real time clock seconds. │
'' │ │
'' │ Seconds - Number to set the seconds to between 0 - 59. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(0, numberToBCD(((seconds <# 59) #> 0)))
PUB setMinutes(minutes) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the current real time clock minutes. │
'' │ │
'' │ Minutes - Number to set the minutes to between 0 - 59. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(1, numberToBCD(((minutes <# 59) #> 0)))
PUB setHours(hours) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the current real time clock hours. │
'' │ │
'' │ Hours - Number to set the hours to between 0 - 23. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(2, numberToBCD(((hours <# 23) #> 0)))
PUB setDay(day) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the current real time clock day. │
'' │ │
'' │ Day - Number to set the day to between 1 - 7. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(3, numberToBCD(((day <# 7) #> 1)))
PUB setDate(date) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the current real time clock date. │
'' │ │
'' │ Date - Number to set the date to between 1 - 31. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(4, numberToBCD(((date <# 31) #> 1)))
PUB setMonth(month) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the current real time clock month. │
'' │ │
'' │ Month - Number to set the month to between 1 - 12. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(5, numberToBCD(((month <# 12) #> 1)))
PUB setYear(year) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the current real time clock year. │
'' │ │
'' │ Year - Number to set the year to between 2000 - 2099. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(6, numberToBCD((((year - 2000) <# 99) #> 0)))
PUB setSQWOUTFrequency(frequency) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Turns the square wave on. │
'' │ │
'' │ Frequency - Selects the frequency of the square wave pin. (0 - 1HZ), (1 - 4.096KHZ), (2 - 8.192KHZ), (3 - 32.768KHZ). │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(7, ($10 | ((frequency <# 3) #> 0)))
PUB setSQWOUTState(state) '' 13 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Turns the square wave off. │
'' │ │
'' │ State - Selects the state of the square wave pin. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRAM(7, ((not(not(state))) & $80))
PUB setNVSRAM(index, value) '' 14 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55). │
'' │ │
'' │ Index - The location in NVRAM to set (0 - 55). │
'' │ Value - The value (0 - 255) to change the location to. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
setRam((((index <# 55) #> 0) + 8), value)
PUB getNVSRAM(index) '' 12 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Gets the selected NVSRAM value at the index (0 - 55). │
'' │ │
'' │ Returns the selected location's value (0 - 255). │
'' │ │
'' │ Index - The location in NVRAM to get (0 - 55). │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return getRam(((index <# 55) #> 0) + 8)
PUB pauseForSeconds(number) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Pauses execution for a number of seconds. │
'' │ │
'' │ Returns a puesdo random value derived from the current clock frequency and the time when called. │
'' │ │
'' │ Number - Number of seconds to pause for between 0 and 2,147,483,647. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
result := cnt
repeat (number #> 0)
result += clkfreq
waitcnt(result)
PUB pauseForMilliseconds(number) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Pauses execution for a number of milliseconds. │
'' │ │
'' │ Returns a puesdo random value derived from the current clock frequency and the time when called. │
'' │ │
'' │ Number - Number of milliseconds to pause for between 0 and 2,147,483,647. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
result := cnt
repeat (number #> 0)
result += (clkfreq / 1000)
waitcnt(result)
PRI BCDToNumber(BCD) ' 4 Stack Longs
return (((BCD >> 4) * 10) + (BCD & $F))
PRI numberToBCD(number) ' 4 Stack Longs
return (((number / 10) << 4) + (number // 10))
PRI setRAM(index, value) ' 9 Stack Longs
startDataTransfer
transmitPacket(constant(RTC_Address << 1))
transmitPacket(index)
transmitPacket(value)
stopDataTransfer
PRI getRAM(index) ' 8 Stack Longs
startDataTransfer
transmitPacket(constant(RTC_Address << 1))
transmitPacket(index)
stopDataTransfer
' Repeated Start
startDataTransfer
transmitPacket(constant((RTC_Address << 1) | 1))
result := receivePacket(false)
stopDataTransfer
PRI transmitPacket(value) ' 4 Stack Longs
value := ((!value) >< 8)
repeat 8
dira[constant(((Data_Pin <# 31) #> 0))] := value
dira[constant(((Clock_Pin <# 31) #> 0))] := false
dira[constant(((Clock_Pin <# 31) #> 0))] := true
value >>= 1
dira[constant(((Data_Pin <# 31) #> 0))] := false
dira[constant(((Clock_Pin <# 31) #> 0))] := false
dira[constant(((Clock_Pin <# 31) #> 0))] := true
dira[constant(((Data_Pin <# 31) #> 0))] := true
PRI receivePacket(aknowledge) ' 4 Stack Longs
dira[constant(((Data_Pin <# 31) #> 0))] := false
repeat 8
result <<= 1
dira[constant(((Clock_Pin <# 31) #> 0))] := false
result |= ina[constant(((Data_Pin <# 31) #> 0))]
dira[constant(((Clock_Pin <# 31) #> 0))] := true
dira[constant(((Data_Pin <# 31) #> 0))] := aknowledge
dira[constant(((Clock_Pin <# 31) #> 0))] := false
dira[constant(((Clock_Pin <# 31) #> 0))] := true
dira[constant(((Data_Pin <# 31) #> 0))] := true
PRI startDataTransfer ' 3 Stack Longs
dira[constant(((Data_Pin <# 31) #> 0))] := true
dira[constant(((Clock_Pin <# 31) #> 0))] := true
PRI stopDataTransfer ' 3 Stack Longs
dira[constant(((Clock_Pin <# 31) #> 0))] := false
dira[constant(((Data_Pin <# 31) #> 0))] := false
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

Binary file not shown.

795
lib/adm-sid.spin Normal file
View File

@ -0,0 +1,795 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SIDcog - SID/MOS8580 emulator V0.80 (C) 2010-02 Johannes Ahlebrand │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ TERMS OF USE: Parallax Object Exchange 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
{
11-07-2010-dr235 - änderung in setWaveform
}
CON
PAL = 985248.0
NTSC = 1022727.0
MAXF = 1031000.0
TRIANGLE = 16
SAW = 32
SQUARE = 64
NOISE = 128
C64_CLOCK_FREQ = PAL
' ___
CUTOFF_LIMIT = 1300' │
LP_MAX_CUTOFF = 10' │
BP_MAX_CUTOFF = 11' │ Don't alter these unless you know what you are doing. ;)
FILTER_OFFSET = 27' │
DECAY_DIVIDE_REF = $6C6C6C6C' │
NOISE_ADD = $979D21B5' │
NOISE_ROTATE = 28' ___│
PUB start(right,left)
arg1 := $18000000 | left
arg2 := $18000000 | right
r1 := ((1<<right) | (1<<left))&!1
sampleRate := clkfreq/trunc(C64_CLOCK_FREQ/32.0)
combTableAddr := @combinedWaveforms
cog := cognew(@SIDEMU, @ch1_frequencyLo) + 1
return @ch1_frequencyLo
PUB stop
if cog
cogstop(cog~ -1)
PUB setRegister(reg,val)
byte[@ch1_frequencyLo+(reg+(reg/7))] := val
PUB updateRegisters(source)
bytemove(@ch1_frequencyLo , source , 7)
bytemove(@ch1_frequencyLo+8 , source+7 , 7)
bytemove(@ch1_frequencyLo+16, source+14, 7)
bytemove(@ch1_frequencyLo+24, source+21, 4)
PUB getSample
return long[@SIDSample]
PUB setVolume(value)
byte[@Volume] := (byte[@Volume]&$F0) | (value&$0F)
PUB play(channel, freq, waveform, attack, decay, sustain, release) | offs
offs := channel<<3
word[@ch1_frequencyLo+offs] := freq
byte[@ch1_attackDecay+offs] := (decay&$F) | ((attack&$F)<<4)
byte[@ch1_sustainRelease+offs] := (release&$F) | ((sustain&$F)<<4)
byte[@ch1_controlRegister+offs] := (byte[@ch1_controlRegister+offs]&$0F) | waveform | 1
PUB noteOn(channel, freq) | offs
offs := channel<<3
byte[@ch1_controlRegister+offs] := (byte[@ch1_controlRegister+offs]&$FE) | 1
word[@ch1_frequencyLo+offs] := freq
PUB noteOff(channel)
byte[@ch1_controlRegister+(channel<<3)] &= $FE
PUB setFreq(channel,freq)
word[@ch1_frequencyLo+(channel<<3)] := freq
PUB setWaveform(channel,waveform) | offs
offs := channel<<3
byte[@ch1_controlRegister+offs] := (byte[@ch1_controlRegister+offs]&$0F) | waveform
' byte[@ch1_controlRegister+offs] := (byte[@ch1_controlRegister+offs]&$0F) | (1<<(4+(waveform&3)))
PUB setPWM(channel, value)
word[@ch1_pulseWidthLo+(channel<<3)] := value
PUB setADSR(channel, attack, decay, sustain, release ) | offs
offs := channel<<3
byte[@ch1_attackDecay+offs] := (decay&$F) | ((attack&$F)<<4)
byte[@ch1_sustainRelease+offs] := (release&$F) | ((sustain&$F)<<4)
PUB setResonance(val)
byte[@Filter3] := (byte[@Filter3]&$0F) | (val<<4)
PUB setCutoff(freq)
byte[@Filter1] := freq&$07
byte[@Filter2] := (freq&$07F8)>>3
PUB setFilterMask(ch1,ch2,ch3)
byte[@Filter3] := (byte[@Filter3]&$F0) | (ch1&1) | (ch2&2) | (ch3&4)
PUB setFilterType(lp,bp,hp)
byte[@volume] := (byte[@volume]&$0F) | (lp&16) | (bp&32) | (hp&64)
PUB enableRingmod(ch1,ch2,ch3)
byte[@ch1_controlRegister] := (byte[@ch1_controlRegister]&$FB) | (ch1&4)
byte[@ch2_controlRegister] := (byte[@ch2_controlRegister]&$FB) | (ch2&4)
byte[@ch3_controlRegister] := (byte[@ch3_controlRegister]&$FB) | (ch3&4)
PUB enableSynchronization(ch1,ch2,ch3)
byte[@ch1_controlRegister] := (byte[@ch1_controlRegister]&$FD) | (ch1&2)
byte[@ch2_controlRegister] := (byte[@ch2_controlRegister]&$FD) | (ch2&2)
byte[@ch3_controlRegister] := (byte[@ch3_controlRegister]&$FD) | (ch3&2)
dat org 0
'
' Assembly SID emulator
'
SIDEMU mov dira, r1
mov ctra, arg1
mov ctrb, arg2
mov waitCounter, cnt
add waitCounter, sampleRate
'-----------------------------------------------------------
mainLoop call #getRegisters
call #SID
call #filter
call #mixer
jmp #mainLoop
'-----------------------------------------------------------
'
' Read all SID-registers from hub memory and convert
' them to more convenient representations.
'
getRegisters mov tempValue, par ' Read in first long ( 16bit frequency / 16bit pulse-width )
rdlong frequency1, tempValue
mov pulseWidth1, frequency1
shl pulseWidth1, #4 ' Shift in "12 bit" pulse width value( make it 32 bits )
andn pulseWidth1, mask20bit
and frequency1, mask16bit ' Mask out 16 bit frequency value
shl frequency1, #13
'-----------------------------------------------------------
add tempValue, #4 ' Read in next long ( Control register / ADSR )
rdlong selectedWaveform1, tempValue
mov controlRegister1, selectedWaveform1
'-----------------------------------------------------------
mov arg1, selectedWaveform1 '|
shr arg1, #8 '|
call #getDecay '|
mov decay1, r1 '|
shr arg1, #4 '|
call #getAttack '|
mov attack1, r1 '| Convert 4bit ADSR "presets" to their corresponding
shr arg1, #4 '| 32bit values using attack/decay tables.
call #getDecay '|
mov release1, r1 '|
mov sustain1, selectedWaveform1 '|
shl sustain1, #8 '|
andn sustain1, mask28bit '|
'-----------------------------------------------------------
shr selectedWaveform1, #4 ' Mask out waveform selection
and selectedWaveform1, #15 wz, wc
'-----------------------------------------------------------
test controlRegister1, #1 wc
cmp envelopeState1, #2 wz
if_z_and_c mov envelopeState1, #0
if_nz_and_nc mov envelopeState1, #2
'───────────────────────────────────────────────────────────
' Channel 2
'───────────────────────────────────────────────────────────
add tempValue, #4 ' Read in first long ( 16bit frequency / 16bit pulse-width )
rdlong frequency2, tempValue
mov pulseWidth2, frequency2
shl pulseWidth2, #4 ' Shift in "12 bit" pulse width value( make it 32 bits )
andn pulseWidth2, mask20bit
and frequency2, mask16bit ' Mask out 16 bit frequency value
shl frequency2, #13
'-----------------------------------------------------------
add tempValue, #4 ' Read in next long ( Control register / ADSR )
rdlong selectedWaveform2, tempValue
mov controlRegister2, selectedWaveform2
'-----------------------------------------------------------
mov arg1, selectedWaveform2 '|
shr arg1, #8 '|
call #getDecay '|
mov decay2, r1 '|
shr arg1, #4 '|
call #getAttack '|
mov attack2, r1 '| Convert 4bit ADSR "presets" to their corresponding
shr arg1, #4 '| 32bit values using attack/decay tables.
call #getDecay '|
mov release2, r1 '|
mov sustain2, selectedWaveform2 '|
shl sustain2, #8 '|
andn sustain2, mask28bit '|
'-----------------------------------------------------------
shr selectedWaveform2, #4 ' Mask out waveform selection
and selectedWaveform2, #15 wz, wc
'-----------------------------------------------------------
test controlRegister2, #1 wc
cmp envelopeState2, #2 wz
if_z_and_c mov envelopeState2, #0
if_nz_and_nc mov envelopeState2, #2
'───────────────────────────────────────────────────────────
' Channel 3
'───────────────────────────────────────────────────────────
add tempValue, #4 ' Read in first long ( 16bit frequency / 16bit pulse-width )
rdlong frequency3, tempValue '
mov pulseWidth3, frequency3
shl pulseWidth3, #4 ' Shift in "12 bit" pulse width value( make it 32 bits )
andn pulseWidth3, mask20bit
and frequency3, mask16bit ' Mask out 16 bit frequency value
shl frequency3, #13
'-----------------------------------------------------------
add tempValue, #4 ' Read in next long ( Control register / ADSR )
rdlong selectedWaveform3, tempValue
mov controlRegister3, selectedWaveform3
'-----------------------------------------------------------
mov arg1, selectedWaveform3 '|
shr arg1, #8 '|
call #getDecay '|
mov decay3, r1 '|
shr arg1, #4 '|
call #getAttack '|
mov attack3, r1 '| Convert 4bit ADSR "presets" to their corresponding
shr arg1, #4 '| 32bit values using attack/decay tables.
call #getDecay '|
mov release3, r1 '|
mov sustain3, selectedWaveform3 '|
shl sustain3, #8 '|
andn sustain3, mask28bit '|
'-----------------------------------------------------------
shr selectedWaveform3, #4 ' Mask out waveform selection
and selectedWaveform3, #15 wz, wc
'-----------------------------------------------------------
test controlRegister3, #1 wc
cmp envelopeState3, #2 wz
if_z_and_c mov envelopeState3, #0
if_nz_and_nc mov envelopeState3, #2
'───────────────────────────────────────────────────────────
' Filter / Volume
'───────────────────────────────────────────────────────────
add tempValue, #4 '|
rdlong filterControl, tempValue '|
mov filterCutoff, filterControl '|
'-----------------------------------------------------------
shr filterControl, #16 '| Filter control
'-----------------------------------------------------------
shr filterCutoff, #5 '|
andn filterCutoff, #7 '|
mov tempValue, filterControl '|
and tempValue, #7 '| Filter cutoff frequency
or filterCutoff, tempValue '|
and filterCutoff, mask11bit '|
add filterCutoff, filterOffset '|
'-----------------------------------------------------------
mov filterMode_Volume, filterControl '| Main volume and filter mode
shr filterMode_Volume, #8 '|
'-----------------------------------------------------------
mov filterResonance,filterControl '|
and filterResonance,#$F0 '|
shr filterResonance,#5 '|
add filterResonance,#resTable '| Filter Resonance level (Ariba)
movs rdRes,filterResonance '|
nop '|
rdRes mov filterResonance,0-0 '|
getRegisters_ret ret
'
' Calculate sid samples channel 1-3 and store in out1-out3
'
'───────────────────────────────────────────────────────────
' Increment phase accumulator 1-3 and handle syncing
'───────────────────────────────────────────────────────────
SID add phaseAccumulator1, frequency1 wc ' Add frequency value to phase accumulator 1
if_nc andn controlRegister2, #2
test controlRegister2, #10 wz ' Sync oscilator 2 to oscilator 1 if sync = on
if_nz mov phaseAccumulator2, #0 ' Or reset counter 2 when bit 4 of control register is 1
'-----------------------------------------------------------
add phaseAccumulator2, frequency2 wc
if_nc andn controlRegister3, #2
test controlRegister3, #10 wz ' Sync oscilator 3 to oscilator 2 if sync = on
if_nz mov phaseAccumulator3, #0 ' Or reset oscilator 3 when bit 4 of control register is 1
'-----------------------------------------------------------
add phaseAccumulator3, frequency3 wc
if_nc andn controlRegister1, #2
test controlRegister1, #10 wz ' Sync oscilator 1 to oscilator 3 if sync = on
if_nz mov phaseAccumulator1, #0 ' Or reset oscilator 1 when bit 4 of control register is 1
'───────────────────────────────────────────────────────────
' Waveform shaping channel 1 -> arg1
'───────────────────────────────────────────────────────────
Triangle1 tjz selectedWaveform1, #Triangle2
cmp selectedWaveform1, #1 wz
if_nz jmp #Saw1
abs arg1, phaseAccumulator1
max arg1, mask31bit
test controlRegister1, #4 wc '|
if_c test phaseAccumulator3, val31bit wc '| These 3 lines handles ring modulation
if_c xor arg1, mask32bit '|
shl arg1, #1
jmp #Env_Attack1
'-----------------------------------------------------------
Saw1 cmp selectedWaveform1, #2 wz
if_z mov arg1, phaseAccumulator1
if_z jmp #Env_Attack1
'-----------------------------------------------------------
Square1 cmp selectedWaveform1, #4 wz
if_z sub pulseWidth1, phaseAccumulator1 wc ' C holds the pulse width modulated square wave
if_z muxc arg1, mask32bit
if_z jmp #Env_Attack1
'-----------------------------------------------------------
Noise1 cmp selectedWaveform1, #8 wz
if_nz jmp #Combined1
mov tempValue, phaseAccumulator1
and tempValue, mask28bit
sub tempValue, frequency1 wc
if_z_and_c ror noiseValue1, NOISE_ROTATE
if_z_and_c add noiseValue1, noiseAdd
if_z mov arg1, noiseValue1
jmp #Env_Attack1
'-----------------------------------------------------------
Combined1 sub selectedWaveform1, #4
mins selectedWaveform1, #0
shl selectedWaveform1, #8
mov tempValue, phaseAccumulator1
shr tempValue, #24
add selectedWaveform1, tempValue
add selectedWaveform1, combTableAddr
rdbyte arg1, selectedWaveform1
shl arg1, #24
'───────────────────────────────────────────────────────────
' Envelope shaping channel 1 -> arg2
'───────────────────────────────────────────────────────────
Env_Attack1 cmp envelopeState1, #0 wz
if_nz jmp #InitDecay1
add envelopeLevel1, attack1 wc
if_c mov envelopeLevel1, mask32bit
if_c mov envelopeState1, #1
mov decayDivide1, #0
jmp #Amplitude1
'-----------------------------------------------------------
InitDecay1 mov tempValue, decayDivideRef
shr tempValue, decayDivide1
cmp envelopeLevel1, tempValue wc
if_c add decayDivide1, #1
'-----------------------------------------------------------
Env_Decay1 cmp envelopeState1, #1 wz
if_nz jmp #Env_Release1
shr decay1, decayDivide1
sub envelopeLevel1, decay1
min envelopeLevel1, sustain1 wc
jmp #Amplitude1
'-----------------------------------------------------------
Env_Release1 cmp envelopeState1, #2 wz
if_nz jmp #Amplitude1
shr release1, decayDivide1
cmpsub envelopeLevel1, release1
'───────────────────────────────────────────────────────────
'Calculate sample out1 = arg1 * arg2 (waveform * amplitude)
'───────────────────────────────────────────────────────────
Amplitude1 shr arg1, #16
sub arg1, val15bit
mov arg2, envelopeLevel1
shr arg2, #22
call #multiply
mov out1, r1
'───────────────────────────────────────────────────────────
' Waveform shaping channel 2 -> arg1
'───────────────────────────────────────────────────────────
Triangle2 tjz selectedWaveform2, #Triangle3
cmp selectedWaveform2, #1 wz
if_nz jmp #Saw2
abs arg1, phaseAccumulator2
max arg1, mask31bit
test controlRegister2, #4 wc '|
if_c test phaseAccumulator1, val31bit wc '| These 3 lines handles ring modulation
if_c xor arg1, mask32bit '|
shl arg1, #1
jmp #Env_Attack2
'-----------------------------------------------------------
Saw2 cmp selectedWaveform2, #2 wz
if_z mov arg1, phaseAccumulator2
if_z jmp #Env_Attack2
'-----------------------------------------------------------
Square2 cmp selectedWaveform2, #4 wz
if_z sub pulseWidth2, phaseAccumulator2 wc ' C holds the pulse width modulated square wave
if_z muxc arg1, mask32bit
if_z jmp #Env_Attack2
'-----------------------------------------------------------
Noise2 cmp selectedWaveform2, #8 wz
if_nz jmp #Combined2
mov tempValue, phaseAccumulator2
and tempValue, mask28bit
sub tempValue, frequency2 wc
if_z_and_c ror noiseValue2, NOISE_ROTATE
if_z_and_c add noiseValue2, noiseAdd
if_z mov arg1, noiseValue2
jmp #Env_Attack2
'-----------------------------------------------------------
Combined2 sub selectedWaveform2, #4
mins selectedWaveform2, #0
shl selectedWaveform2, #8
mov tempValue, phaseAccumulator2
shr tempValue, #24
add selectedWaveform2, tempValue
add selectedWaveform2, combTableAddr
rdbyte arg1, selectedWaveform2
shl arg1, #24
'───────────────────────────────────────────────────────────
' Envelope shaping channel 2 -> arg2
'───────────────────────────────────────────────────────────
Env_Attack2 cmp envelopeState2, #0 wz
if_nz jmp #InitDecay2
add envelopeLevel2, attack2 wc
if_c mov envelopeLevel2, mask32bit
if_c mov envelopeState2, #1
mov decayDivide2, #0
jmp #Amplitude2
'-----------------------------------------------------------
InitDecay2 mov tempValue, decayDivideRef
shr tempValue, decayDivide2
cmp envelopeLevel2, tempValue wc
if_c add decayDivide2, #1
'-----------------------------------------------------------
Env_Decay2 cmp envelopeState2, #1 wz
if_nz jmp #Env_Release2
shr decay2, decayDivide2
sub envelopeLevel2, decay2
min envelopeLevel2, sustain2 wc
jmp #Amplitude2
'-----------------------------------------------------------
Env_Release2 cmp envelopeState2, #2 wz
if_nz jmp #Amplitude2
shr release2, decayDivide2
cmpsub envelopeLevel2, release2
'───────────────────────────────────────────────────────────
'Calculate sample out2 = arg1 * arg2 (waveform * amplitude)
'───────────────────────────────────────────────────────────
Amplitude2 shr arg1, #16
sub arg1, val15bit
mov arg2, envelopeLevel2
shr arg2, #22
call #multiply
mov out2, r1
'───────────────────────────────────────────────────────────
' Waveform shaping channel 3 -> arg1
'───────────────────────────────────────────────────────────
Triangle3 tjz selectedWaveform3, #SID_ret
cmp selectedWaveform3, #1 wz
if_nz jmp #Saw3
abs arg1, phaseAccumulator3
max arg1, mask31bit
test controlRegister3, #4 wc '|
if_c test phaseAccumulator2, val31bit wc '| These 3 lines handles ring modulation
if_c xor arg1, mask32bit '|
shl arg1, #1
jmp #Env_Attack3
'-----------------------------------------------------------
Saw3 cmp selectedWaveform3, #2 wz
if_z mov arg1, phaseAccumulator3
if_z jmp #Env_Attack3
'-----------------------------------------------------------
Square3 cmp selectedWaveform3, #4 wz
if_z sub pulseWidth3, phaseAccumulator3 wc ' C holds the pulse width modulated square wave
if_z muxc arg1, mask32bit
if_z jmp #Env_Attack3
'-----------------------------------------------------------
Noise3 cmp selectedWaveform3, #8 wz
if_nz jmp #Combined3
mov tempValue, phaseAccumulator3
and tempValue, mask28bit
sub tempValue, frequency3 wc
if_z_and_c ror noiseValue3, NOISE_ROTATE
if_z_and_c add noiseValue3, noiseAdd
if_z mov arg1, noiseValue3
jmp #Env_Attack3
'-----------------------------------------------------------
Combined3 sub selectedWaveform3, #4
mins selectedWaveform3, #0
shl selectedWaveform3, #8
mov tempValue, phaseAccumulator3
shr tempValue, #24
add selectedWaveform3, tempValue
add selectedWaveform3, combTableAddr
rdbyte arg1, selectedWaveform3
shl arg1, #24
'───────────────────────────────────────────────────────────
' Envelope shaping channel 3 -> arg2
'───────────────────────────────────────────────────────────
Env_Attack3 cmp envelopeState3, #0 wz
if_nz jmp #InitDecay3
add envelopeLevel3, attack3 wc
if_c mov envelopeLevel3, mask32bit
if_c mov envelopeState3, #1
mov decayDivide3, #0
jmp #Amplitude3
'-----------------------------------------------------------
InitDecay3 mov tempValue, decayDivideRef
shr tempValue, decayDivide3
cmp envelopeLevel3, tempValue wc
if_c add decayDivide3, #1
'-----------------------------------------------------------
Env_Decay3 cmp envelopeState3, #1 wz
if_nz jmp #Env_Release3
shr decay3, decayDivide3
sub envelopeLevel3, decay3
min envelopeLevel3, sustain3 wc
jmp #Amplitude3
'-----------------------------------------------------------
Env_Release3 cmp envelopeState3, #2 wz
if_nz jmp #Amplitude3
shr release3, decayDivide3
cmpsub envelopeLevel3, release3
'───────────────────────────────────────────────────────────
'Calculate sample out3 = arg1 * arg2 (waveform * amplitude)
'───────────────────────────────────────────────────────────
Amplitude3 shr arg1, #16
sub arg1, val15bit
mov arg2, envelopeLevel3
shr arg2, #22
call #multiply
mov out3, r1
SID_ret ret
'
' Handle multi-mode filtering
'
filter mov ordinaryOutput, #0 '|
mov highPassFilter, #0 '|
test filterControl, #1 wc '|
if_c add highPassFilter, out1 '|
if_nc add ordinaryOutput, out1 '|
test filterControl, #2 wc '| Route channels trough the filter
if_c add highPassFilter, out2 '| or bypass them
if_nc add ordinaryOutput, out2 '|
test filterControl, #4 wc '|
if_c add highPassFilter, out3 '|
if_nc add ordinaryOutput, out3 '|
'-----------------------------------------------------------
mov tempValue, bandPassFilter '|
sar tempValue, filterResonance '| High pass filter
sub highPassFilter, tempValue '|
sub highPassFilter, lowPassFilter '|
'-----------------------------------------------------------
mov arg1, highPassFilter '|
sar arg1, #BP_MAX_CUTOFF '|
mov arg2, filterCutoff '| Band pass filter
max arg2, maxCutoff
call #multiplyNS '|
add bandPassFilter, r1 '|
'-----------------------------------------------------------
mov arg1, bandPassFilter '|
sar arg1, #LP_MAX_CUTOFF '|
mov arg2, filterCutoff '| Low pass filter
call #multiplyNS '|
add lowPassFilter, r1 '|
'-----------------------------------------------------------
mov filterOutput, #0 '|
test filterMode_Volume, #16 wc '|
if_c add filterOutput, lowPassFilter '|
test filterMode_Volume, #32 wc '| Enable/Disable
if_c add filterOutput, bandPassFilter '| Low/Band/High pass filtering
test filterMode_Volume, #64 wc '|
if_c add filterOutput, highPassFilter '|
filter_ret ret
'
' Mix channels and update FRQA/FRQB PWM-values
'
mixer mov arg1, filterOutput
add arg1, ordinaryOutput
'-----------------------------------------------------------
maxs arg1, clipLevelHigh '|
mins arg1, clipLevelLow '|
mov arg2, filterMode_Volume '| Main volume adjustment
and arg2, #15 '|
call #multiplyNS '|
'-----------------------------------------------------------
add r1, val31bit ' DC offset
waitcnt waitCounter, sampleRate ' Wait until the right time to update
mov FRQA, r1 '| Update PWM values in FRQA/FRQB
mov FRQB, r1 '|
mov tempValue, par
add tempValue, #28
wrlong r1, tempValue '| Write the sample to hub ram
mixer_ret ret
'
' Get attack value r1 = attackTable[arg1]
'
getAttack mov arg2, arg1
and arg1, #15
add arg1, #ADSRTable
movs :indexed1, arg1
mov arg1, arg2
:indexed1 mov r1, 0
getAttack_ret ret
'
' Get decay value r1 = decayTable[arg1]
'
getDecay mov arg2, arg1
and arg1, #15
add arg1, #ADSRTable
movs :indexed2, arg1
mov arg1, arg2
:indexed2 mov r1, 0
getDecay_ret ret
'
' Multiplication r1(I32) = arg1(I32) * arg2(I32)
'
multiply cmp arg1, arg2 wc 'If arg1 is less than arg2 C is set
if_c xor arg1, arg2 'Swap arguments
if_c xor arg2, arg1
if_c xor arg1, arg2
multiplyNS mov r1, #0 'Clear 32-bit product
:multiLoop shr arg2, #1 wc, wz 'Half multiplyer and get LSB of it
if_c add r1, arg1 'Add multiplicand to product on C
shl arg1, #1 'Double multiplicand
if_nz jmp #:multiLoop 'Check nonzero multiplier to continue multiplication
multiplyNS_ret
multiply_ret ret
'
' Variables, tables, masks and reference values
'
ADSRTable long 68719476 '2 ms
long 17179870 '8 ms
long 8589934 '16 ms
long 5726622 '24 ms
long 3616814 '38 ms
long 2454268 '56 ms
long 2021160 '68 ms
long 1717986 '80 ms
long 1374390 '100 ms
long 549754 '250 ms
long 274876 '500 ms
long 171798 '800 ms
long 137438 '1 s
long 45812 '3 s
long 27486 '5 s
long 17180 '8 s
resTable long 0,1,1,1,1,1,2,2 '(Ariba)
'Masks and reference values
mask32bit long $ffffffff
mask31bit long $7fffffff
mask28bit long $fffffff
mask24bit long $ffffff
mask20bit long $fffff
mask16bit long $ffff
mask11bit long $7ff
val31bit long $80000000
val28bit long $10000000
val27bit long $8000000
val16bit long $10000
val15bit long $8000
clipLevelHigh long $8000000
clipLevelLow long-$8000000
noiseAdd long NOISE_ADD 'Value to add to the noise generator every noise update
filterOffset long FILTER_OFFSET
decayDivideRef long DECAY_DIVIDE_REF
maxCutoff long CUTOFF_LIMIT
sampleRate long 0 'clocks between samples ( ~31.250 khz )
combTableAddr long 0
'Setup and subroutine parameters
arg1 long 1
arg2 long 1
r1 long 1
'Sid variables
envelopeLevel1 long 1
envelopeLevel2 long 1
envelopeLevel3 long 1
controlRegister1 res 1
controlRegister2 res 1
controlRegister3 res 1
frequency1 res 1
frequency2 res 1
frequency3 res 1
phaseAccumulator1 res 1
phaseAccumulator2 res 1
phaseAccumulator3 res 1
pulseWidth1 res 1
pulseWidth2 res 1
pulseWidth3 res 1
selectedWaveform1 res 1
selectedWaveform2 res 1
selectedWaveform3 res 1
envelopeState1 res 1
envelopeState2 res 1
envelopeState3 res 1
noiseValue1 res 1
noiseValue2 res 1
noiseValue3 res 1
attack1 res 1
attack2 res 1
attack3 res 1
decay1 res 1
decay2 res 1
decay3 res 1
sustain1 res 1
sustain2 res 1
sustain3 res 1
release1 res 1
release2 res 1
release3 res 1
decayDivide1 res 1
decayDivide2 res 1
decayDivide3 res 1
out1 res 1
out2 res 1
out3 res 1
filterResonance res 1
filterCutoff res 1
highPassFilter res 1
bandPassFilter res 1
lowPassFilter res 1
filterMode_Volume res 1
filterControl res 1
filterOutput res 1
ordinaryOutput res 1
'Working variables
waitCounter res 1
tempValue res 1
fit
dat
combinedWaveforms file "adm-sid-combined-waveforms.bin"
VAR
byte ch1_frequencyLo
byte ch1_frequencyHi
byte ch1_pulseWidthLo
byte ch1_pulseWidthHi
byte ch1_controlRegister
byte ch1_attackDecay
byte ch1_sustainRelease
byte ch1_dummy
byte ch2_frequencyLo
byte ch2_frequencyHi
byte ch2_pulseWidthLo
byte ch2_pulseWidthHi
byte ch2_controlRegister
byte ch2_attackDecay
byte ch2_sustainRelease
byte ch2_dummy
byte ch3_frequencyLo
byte ch3_frequencyHi
byte ch3_pulseWidthLo
byte ch3_pulseWidthHi
byte ch3_controlRegister
byte ch3_attackDecay
byte ch3_sustainRelease
byte ch3_dummy
byte Filter1
byte Filter2
byte Filter3
byte Volume
long SIDSample
byte cog

364
lib/adm-wav.spin Normal file
View File

@ -0,0 +1,364 @@
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Digital To Analog Converter Engine │
│ │
│ Author: Kwabena W. Agyeman │
│ Updated: 1/11/2010 │
│ Designed For: P8X32A │
│ │
│ Copyright (c) 2010 Kwabena W. Agyeman │
│ See end of file for terms of use. │
│ │
│ Driver Info: │
│ │
│ The DACEngine runs a stereo digital to analog converter driver in the next free cog on the propeller chip when called. │
│ │
│ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │
│ so port B will not be operational. │
│ │
│ Nyamekye, │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
CON
''
'' 100Ω 1µF
DAC_Left_Pin = 08 '' ───┳─── Left Out
'' │
'' 10nF
'' │
'' 
''
'' 100Ω 1µF
DAC_Right_Pin = 09 '' ───┳─── Right Out
'' │
'' 10nF
'' │
'' 
VAR
word dataBlock[512]
word callerPointer
word callePointer
byte stopedOrStarted
byte signedOrUnsigned
byte bitsPerSample
byte numberOfChannels
word leftVolume
word rightVolume
long sampleRate
PUB getDataBlockAddress
return @dataBlock
PUB startPlayer '' 3 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Starts/Unpauses the stereo DAC player. The player will begin at whatever point it stopped at before. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
stopedOrStarted := true
PUB stopPlayer '' 3 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Stops/pauses the stereo DAC. The player will remember whatever point it stopped at. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
stopedOrStarted := false
PUB transferData '' 3 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Helps reliably transfers data to the stero DAC to play. Throttles data transfer speed to that of data play speed. │
'' │ │
'' │ Returns address of next data buffer to transfer data to. Does not return until data buffer is ready for transfer. │
'' │ │
'' │ At 8 bits per sample using 1 channel each data buffer is composed of 512 bytes with 512 samples per transfer. │
'' │ │
'' │ At 8 bits per sample using 2 channels each data buffer is composed of 512 bytes with 256 samples per transfer. │
'' │ │
'' │ At 16 bits per sample using 1 channel each data buffer is composed of 256 words with 256 samples per transfer. │
'' │ │
'' │ At 16 bits per sample using 2 channels each data buffer is composed of 256 words with 128 samples per transfer. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat while(callerPointer == callePointer)
result := @dataBlock[256 & callerPointer]
not callerPointer
PUB clearData '' 3 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Clears all data in all player data buffers. │
'' │ │
'' │ Helps prevent old data from being played when changing to a new data transfer source. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
bytefill(@dataBlock, ((not(signedOrUnsigned)) & $80), 1024)
PUB changeLeftChannelVolume(newVolume) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Changes the volume of the left channel. (0 to 100) │
'' │ │
'' │ NewVolume - New volume to output samples at. Samples are scaled by this value. Zero mutes the channel. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
leftVolume := (((newVolume <# 100) #> 0) * constant(65536 / 100))
PUB changeRightChannelVolume(newVolume) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Changes the volume of the right channel. (0 to 100) │
'' │ │
'' │ NewVolume - New volume to output samples at. Samples are scaled by this value. Zero mutes the channel. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
rightVolume := (((newVolume <# 100) #> 0) * constant(65536 / 100))
PUB changeSampleSign(signed) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Changes whether samples are signed or not. │
'' │ │
'' │ Signed - True to make all samples be interpreted as signed. False to make all samples be interpreted as unsigned. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
signedOrUnsigned := signed
PUB changeBitsPerSample(newWidth) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Changes the bits per sample, 8 bits or 16 bits. │
'' │ │
'' │ NewWidth - New bits per sample to output samples at. Samples are sized by this value. (8 or 16) │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
bitsPerSample := (newWidth == 16)
PUB changeNumberOfChannels(newNumber) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Changes the number of channels, 1 channel or 2 channels. │
'' │ │
'' │ When set to 1 channel mode the driver will output samples to both channels at once. │
'' │ │
'' │ When set to 2 channel mode the driver will output samples to both channels at simultaneously. │
'' │ │
'' │ NewNumber - New number of channels to output samples at. Samples are grouped by this value. (1 or 2) │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
numberOfChannels := (newNumber == 2)
PUB changeSampleRate(newRate) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Changes the sample rate. The stereo DAC supportes samples rates from 1HZ to 88.2KHZ. │
'' │ │
'' │ NewRate - New sample rate to out samples at. Samples are outputted at the frequency specified by this value. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
sampleRate := (clkfreq / ((newRate <# 88200) #> 1))
PUB DACEngine(newRate) '' 4 Stack longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Initializes the stereo digital to analog converter driver to run on a new cog. │
'' │ │
'' │ Default mode is 8 bits per sample with unsigned samples, 1 channel with muted volume, and playing stopped. │
'' │ │
'' │ Returns the new cog's ID on sucess or -1 on failure. │
'' │ │
'' │ NewRate - New sample rate to out samples at. Samples are outputted at the frequency specified by this value. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
changeSampleRate(newRate)
dataBlockAddress := @dataBlock
callePointerAddress := @callePointer
stopedOrStartedAddress := @stopedOrStarted
unsignedOrSignedAddress := @signedOrUnsigned
bitsPerSampleAddress := @bitsPerSample
numberOfChannelsAddress := @NumberOfChannels
leftVolumeAddress := @leftVolume
rightVolumeAddress := @rightVolume
return cognew(@initialization, @sampleRate)
DAT
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' Stereo Digital To Analog Converter Driver
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
org
' //////////////////////Initialization/////////////////////////////////////////////////////////////////////////////////////////
initialization mov ctra, #((DAC_Left_Pin <# 31) #> 0) ' Setup counter I/O pins.
mov ctrb, #((DAC_Right_Pin <# 31) #> 0) '
movi ctra, #%0_00110_000 ' Setup counter modes to duty cycle mode.
movi ctrb, #%0_00110_000 '
mov dira, outputMask ' Setup I/O pin directions.
mov playerPointer, dataBlockAddress ' Setup data block pointer.
rdlong timeCounter, par ' Setup timing.
add timeCounter, cnt '
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' Player
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
outerLoop rdbyte buffer, numberOfChannelsAddress wz ' Setup player mode.
muxz playerMode, #$1 '
rdbyte buffer, bitsPerSampleAddress wz '
muxz playerMode, #$2 '
test playerMode, #$1 wc ' Setup counter.
mov counter, #128 '
if_c_or_z add counter, #128 '
if_c_and_z add counter, #256 '
' //////////////////////Inner Loop/////////////////////////////////////////////////////////////////////////////////////////////
innerLoop rdlong buffer, par ' Wait until next sample output period.
waitcnt timeCounter, buffer '
rdbyte buffer, stopedOrStartedAddress ' If stopped loop continously.
tjz buffer, #innerLoop '
movs multiplicand, #leftVolumeAddress ' Get and output value.
call #decode '
mov frqa, sampleBuffer '
test playerMode, #1 wc ' Check number of channels.
if_c mov frqb, frqa '
if_c jmp #nextLoop '
movs multiplicand, #rightVolumeAddress ' Get and output value.
call #decode '
mov frqb, sampleBuffer '
nextLoop djnz counter, #innerLoop ' Loop.
' //////////////////////Outer Loop/////////////////////////////////////////////////////////////////////////////////////////////
rdword buffer, callePointerAddress wz ' Switch data block pointer.
if_z neg buffer, #1 '
if_nz mov buffer, #0 '
wrword buffer, callePointerAddress '
if_nz mov playerPointer, dataBlockAddress ' Setup data block pointer.
jmp #outerLoop ' Loop.
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' Decode Value
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
decode test playerMode, #$2 wc ' Read data depending on size.
if_c rdbyte multiplyBuffer, playerPointer '
if_c add playerPointer, #1 '
if_nc rdword multiplyBuffer, playerPointer '
if_nc add playerPointer, #2 '
rdbyte buffer, unsignedOrSignedAddress wz ' Modify data depending on sign and size.
if_z_and_c sub multiplyBuffer, #$80 '
if_c shl multiplyBuffer, #24 '
if_c sar multiplyBuffer, #16 '
if_z_and_nc sub multiplyBuffer, wordAdjust '
if_nc shl multiplyBuffer, #16 '
if_nc sar multiplyBuffer, #16 '
multiplicand rdword multiplyCounter, 0 ' Setup inputs.
mov sampleBuffer, #0 '
abs multiplyBuffer, multiplyBuffer wc ' Backup sign.
rcr sampleBuffer, #1 wz, nr '
multiplyLoop shr multiplyCounter, #1 wc ' Preform multiplication.
if_c add sampleBuffer, multiplyBuffer '
shl multiplyBuffer, #1 wc '
tjnz multiplyCounter, #multiplyLoop '
negnz sampleBuffer, sampleBuffer ' Restore sign.
add sampleBuffer, longAdjust ' Center output value.
decode_ret ret ' Return.
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' Data
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
wordAdjust long $8000 ' Edits word signed value.
longAdjust long $80000000 ' Edits long unsigend value.
' //////////////////////Pin Masks//////////////////////////////////////////////////////////////////////////////////////////////
outputMask long ((|<((DAC_Left_Pin <# 31) #> 0)) | (|<((DAC_Right_Pin <# 31) #> 0))) ' DAC Outputs.
' //////////////////////Addresses//////////////////////////////////////////////////////////////////////////////////////////////
dataBlockAddress long 0
callePointerAddress long 0
stopedOrStartedAddress long 0
unsignedOrSignedAddress long 0
bitsPerSampleAddress long 0
numberOfChannelsAddress long 0
leftVolumeAddress long 0
rightVolumeAddress long 0
' //////////////////////Run Time Variables/////////////////////////////////////////////////////////////////////////////////////
buffer res 1
counter res 1
playerPointer res 1
playerMode res 1
sampleBuffer res 1
timeCounter res 1
multiplyBuffer res 1
multiplyCounter res 1
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fit 496
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

87
lib/bel-bus.spin Normal file
View File

@ -0,0 +1,87 @@
{{ Bus-Funktionen für Bellatrix }}
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
' 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
gc : "glob-con" 'globale konstanten
PUB init_bus
dira := db_in 'datenbus auf eingabe schalten
outa[gc#bus_hs] := 1 'handshake inaktiv
PUB 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[gc#bus_hs] := 0 'daten gültig
waitpeq(M3,M4,0) 'busclk=0?
dira := db_in 'bus freigeben
outa[gc#bus_hs] := 1 'daten ungültig
PUB 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[gc#bus_hs] := 0 'daten quittieren
waitpeq(M3,M4,0) 'busclk=0?
outa[gc#bus_hs] := 1
CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN
PUB 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 ]
putchar(wert >> 24) '32bit wert senden hsb/lsb
putchar(wert >> 16)
putchar(wert >> 8)
putchar(wert)
PUB 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 := getchar << 24 '32 bit empfangen hsb/lsb
wert := wert + getchar << 16
wert := wert + getchar << 8
wert := wert + getchar

178
lib/bel-gfx1.spin Normal file
View File

@ -0,0 +1,178 @@
DAT
{
video-treiber-frame
- basiert auf dem tollen tutorial von bamse
30-09-2009-dr235 driver 1 - originalcode, anpassung an hive
driver 2 - senkrechte balken
driver 3 - einfarbige fläche
driver 4 - wandernde farbbalken, 1 byte pro pixel :)
driver 5 -
}
CON
_CLKMODE = xtal1 + pll16x
_XINFREQ = 5_000_000
PUB start
cognew(@entry,0) ' neue cog mit video-treiber starten
DAT org 0
entry jmp #Start_of_driver ' Start here...
' NTSC sync stuff.
NTSC_color_freq long 3_579_545 ' NTSC Color Frequency
NTSC_hsync_VSCL long 39 << 12 + 624 ' Used for the Horisontal Sync
NTSC_active_VSCL long 188 << 12 + 3008 ' Used for the Vertical sync
NTSC_hsync_pixels long %%11_0000_1_2222222_11 ' Horizontal sync pixels
NTSC_vsync_high_1 long %%1111111_2222222_11 ' Vertical sync signal part one for lines 1-6 and 13 to 18
NTSC_vsync_high_2 long %%1111111111111111 ' Vertical sync signal part two for lines 1-6 and 13 to 18
NTSC_vsync_low_1 long %%2222222222222222 ' Vertical sync signal part one for lines 7-12
NTSC_vsync_low_2 long %%22_1111111_2222222 ' Vertical sync signal part two for lines 7-12
NTSC_sync_signal_palette long $00_00_02_8A ' The sync Palette
' hbeat --------+ +------------------------- /cs
' clk -------+| |
' /wr ------+|| | +---------------------- videopins
' /hs -----+||| | |
' |||| |--+ -------- d0..d7
tvport_mask long %00000000_01110000_00000000_00000000 ' Maske für Video-Pins am Hive
vsu_cfg long %01110100_00000000_00000100_01110000 ' Wert für VCFG-Register
NTSC_Graphic_Lines long 244 ' Anzahl der sichtbaren Zeilen
NTSC_Graphics_Pixels_VSCL long 16 << 12 + 16 ' 16 clocks per pixel, 64 clocks per frame.
PAL0 long $01
PAL1 long $0E
PAL2 long $0D
PAL3 long $0C
PAL4 long $0B
DIF1 long $00_10
CNT_ANIM long $4
' Loop counters.
line_loop long $0 ' Line counter...
pix_loop long $0
anim_loop long $0
' General Purpose Registers
r0 long $0 ' Initialize to 0
r1 long $0
r2 long $0
r3 long $0
c1 long $0 ' colorregister
c2 long $0
c3 long $0
'========================== Start of the actual driver =============================================
Start_of_driver
' VCFG, setup Video Configuration register and 3-bit tv DAC pins to output
mov VCFG, vsu_cfg ' Konfiguration der VSU
or DIRA, tvport_mask ' Set DAC pins to output
' CTRA, setup Frequency to Drive Video
movi CTRA,#%00001_111 ' pll internal routed to Video, PHSx+=FRQx (mode 1) + pll(16x)
mov r1, NTSC_color_freq ' r1: Color frequency in Hz (3.579_545MHz)
rdlong r2, #0 ' Copy system clock from main memory location 0. (80Mhz)
' perform r3 = 2^32 * r1 / r2
mov r0,#32+1
:loop cmpsub r1,r2 wc
rcl r3,#1
shl r1,#1
djnz r0,#:loop
mov FRQA, r3 ' Set frequency for counter A
'========================== Start of Frame Loop ==============================================
frame_loop
mov anim_loop, CNT_ANIM
frame_loop2
'========================== Screen =============================================
mov line_loop, NTSC_Graphic_Lines ' anzahl der zeilen laden (244)
user_lines
'------ zeilensynchronisation
mov VSCL, NTSC_hsync_VSCL ' Setup VSCL for horizontal sync.
waitvid NTSC_sync_signal_palette, NTSC_hsync_pixels ' Generate sync.
'------ sichtbarer zeileninhalt
mov VSCL, NTSC_Graphics_Pixels_VSCL ' Setup VSCL for user pixels.
'------ verschiedenfarbige balken ausgeben
mov c1, PAL4
add c1, c3
mov pix_loop, #23
bar_loop
add c1, #$10 ' 8 x pixel einzeln! ausgeben
mov c2, c1 ' also 2 tiles
waitvid c2, #0 ' 8 bit pro pixel!
add c2, #1
waitvid c2, #0
add c2, #1
waitvid c2, #0
add c2, #1
waitvid c2, #0
sub c2, #1
waitvid c2, #0
sub c2, #1
waitvid c2, #0
sub c2, #1
waitvid c2, #0
sub c2, #1
waitvid c2, #0
djnz pix_loop, #bar_loop
sub c2, #1
waitvid c2, #0 ' 4 mal extrapixel, für das timing
sub c2, #1 ' also insgesamt 188 pixel pro zeile
waitvid c2, #0
sub c2, #1
waitvid c2, #0
sub c2, #1
waitvid c2, #0
djnz line_loop, #user_lines ' schleife durch alle zeilen
'========================== The 16 lines of Horizontal sync ==================================
mov line_loop, #6 ' Line 244, start of first high sync.
vsync_high1 mov VSCL, NTSC_hsync_VSCL
waitvid NTSC_sync_signal_palette, NTSC_vsync_high_1
mov VSCL, NTSC_active_VSCL
waitvid NTSC_sync_signal_palette, NTSC_vsync_high_2
djnz line_loop, #vsync_high1
mov line_loop, #6 ' Line 250, start of the Seration pulses.
vsync_low mov VSCL, NTSC_active_VSCL
waitvid NTSC_sync_signal_palette, NTSC_vsync_low_1
mov VSCL,NTSC_hsync_VSCL
waitvid NTSC_sync_signal_palette, NTSC_vsync_low_2
djnz line_loop, #vsync_low
mov line_loop, #6 ' Line 256, start of second high sync.
vsync_high2 mov VSCL, NTSC_hsync_VSCL
waitvid NTSC_sync_signal_palette, NTSC_vsync_high_1
mov VSCL, NTSC_active_VSCL
waitvid NTSC_sync_signal_palette, NTSC_vsync_high_2
djnz line_loop, #vsync_high2
'========================== End of Frame Loop =============================================
djnz anim_loop, #frame_loop2
add c3, #$10
'========================== Animation ==================================
jmp #frame_loop ' And repeat for ever...
FIT

2013
lib/bel-graphics-xor.spin Normal file

File diff suppressed because it is too large Load Diff

1669
lib/bel-graphics.spin Normal file

File diff suppressed because it is too large Load Diff

548
lib/bel-htext.spin Normal file
View File

@ -0,0 +1,548 @@
''***************************************
''* VGA High-Res Text Driver v1.0 *
''* Author: Chip Gracey *
''* Copyright (c) 2006 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
''
'' This object generates a 1024x768 VGA signal which contains 128 columns x 64
'' rows of 8x12 characters. Each row can have a unique forground/background
'' color combination and each character can be inversed. There are also two
'' cursors which can be independently controlled (ie. mouse and keyboard). A
'' sync indicator signals each time the screen is refreshed (you may ignore).
''
'' You must provide buffers for the screen, colors, cursors, and sync. Once
'' started, all interfacing is done via memory. To this object, all buffers are
'' read-only, with the exception of the sync indicator which gets written with
'' -1. You may freely write all buffers to affect screen appearance. Have fun!
''
CON
'{
' 1024 x 768 @ 57Hz settings: 128 x 64 characters
hp = 1024 'horizontal pixels
vp = 768 'vertical pixels
hf = 16 'horizontal front porch pixels
hs = 96 'horizontal sync pixels
hb = 176 'horizontal back porch pixels
vf = 1 'vertical front porch lines
vs = 3 'vertical sync lines
vb = 28 'vertical back porch lines
hn = 1 'horizontal normal sync state (0|1)
vn = 1 'vertical normal sync state (0|1)
pr = 60 'pixel rate in MHz at 80MHz system clock (5MHz granularity)
'}
{
' 800 x 600 @ 75Hz settings: 100 x 50 characters
hp = 800 'horizontal pixels
vp = 600 'vertical pixels
hf = 40 'horizontal front porch pixels
hs = 128 'horizontal sync pixels
hb = 88 'horizontal back porch pixels
vf = 1 'vertical front porch lines
vs = 4 'vertical sync lines
vb = 23 'vertical back porch lines
hn = 0 'horizontal normal sync state (0|1)
vn = 0 'vertical normal sync state (0|1)
pr = 50 'pixel rate in MHz at 80MHz system clock (5MHz granularity)
}
{
' 640 x 480 @ 69Hz settings: 80 x 40 characters
hp = 640 'horizontal pixels
vp = 480 'vertical pixels
hf = 24 'horizontal front porch pixels
hs = 40 'horizontal sync pixels
hb = 128 'horizontal back porch pixels
vf = 9 'vertical front porch lines
vs = 3 'vertical sync lines
vb = 28 'vertical back porch lines
hn = 1 'horizontal normal sync state (0|1)
vn = 1 'vertical normal sync state (0|1)
pr = 30 'pixel rate in MHz at 80MHz system clock (5MHz granularity)
}
' columns and rows
cols = hp / 8
rows = vp / 12
VAR long cog[2]
PUB start(BasePin, ScreenPtr, ColorPtr, CursorPtr, SyncPtr) : okay | i, j
'' Start VGA driver - starts two COGs
'' returns false if two COGs not available
''
'' BasePin = VGA starting pin (0, 8, 16, 24, etc.)
''
'' ScreenPtr = Pointer to 8,192 bytes containing ASCII codes for each of the
'' 128x64 screen characters. Each byte's top bit controls color
'' inversion while the lower seven bits provide the ASCII code.
'' Screen memory is arranged left-to-right, top-to-bottom.
''
'' screen byte example: %1_1000001 = inverse "A"
''
'' ColorPtr = Pointer to 64 words which define the foreground and background
'' colors for each row. The lower byte of each word contains the
'' foreground RGB data for that row, while the upper byte
'' contains the background RGB data. The RGB data in each byte is
'' arranged as %RRGGBB00 (4 levels each).
''
'' color word example: %%0020_3300 = gold on blue
''
'' CursorPtr = Pointer to 6 bytes which control the cursors:
''
'' bytes 0,1,2: X, Y, and MODE of cursor 0
'' bytes 3,4,5: X, Y, and MODE of cursor 1
''
'' X and Y are in terms of screen characters
'' (left-to-right, top-to-bottom)
''
'' MODE uses three bottom bits:
''
'' %x00 = cursor off
'' %x01 = cursor on
'' %x10 = cursor on, blink slow
'' %x11 = cursor on, blink fast
'' %0xx = cursor is solid block
'' %1xx = cursor is underscore
''
'' cursor example: 127, 63, %010 = blinking block in lower-right
''
'' SyncPtr = Pointer to long which gets written with -1 upon each screen
'' refresh. May be used to time writes/scrolls, so that chopiness
'' can be avoided. You must clear it each time if you want to see
'' it re-trigger.
'if driver is already running, stop it
stop
'implant pin settings
reg_vcfg := $200000FF + (BasePin & %111000) << 6
i := $FF << (BasePin & %011000)
j := BasePin & %100000 == 0
reg_dira := i & j
reg_dirb := i & !j
'implant CNT value to sync COGs to
sync_cnt := cnt + $10000
'implant pointers
longmove(@screen_base, @ScreenPtr, 3)
font_base := @font
'implant unique settings and launch first COG
vf_lines.byte := vf
vb_lines.byte := vb
font_third := 1
cog[1] := cognew(@d0, SyncPtr) + 1
'allow time for first COG to launch
waitcnt($2000 + cnt)
'differentiate settings and launch second COG
vf_lines.byte := vf+4
vb_lines.byte := vb-4
font_third := 0
cog[0] := cognew(@d0, SyncPtr) + 1
'if both COGs launched, return true
if cog[0] and cog[1]
return true
'else, stop any launched COG and return false
else
stop
PUB stop | i
'' Stop VGA driver - frees two COGs
repeat i from 0 to 1
if cog[i]
cogstop(cog[i]~ - 1)
CON
#1, scanbuff[128], scancode[128*2-1+3], maincode 'enumerate COG RAM usage
main_size = $1F0 - maincode 'size of main program
hv_inactive = (hn << 1 + vn) * $0101 'H,V inactive states
DAT
'*****************************************************
'* Assembly language VGA high-resolution text driver *
'*****************************************************
' This program runs concurrently in two different COGs.
'
' Each COG's program has different values implanted for front-porch lines and
' back-porch lines which surround the vertical sync pulse lines. This allows
' timed interleaving of their active display signals during the visible portion
' of the field scan. Also, they are differentiated so that one COG displays
' even four-line groups while the other COG displays odd four-line groups.
'
' These COGs are launched in the PUB 'start' and are programmed to synchronize
' their PLL-driven video circuits so that they can alternately prepare sets of
' four scan lines and then display them. The COG-to-COG switchover is seemless
' due to two things: exact synchronization of the two video circuits and the
' fact that all COGs' driven output states get OR'd together, allowing one COG
' to output lows during its preparatory state while the other COG effectively
' drives the pins to create the visible and sync portions of its scan lines.
' During non-visible scan lines, both COGs output together in unison.
'
' COG RAM usage: $000 = d0 - used to inc destination fields for indirection
' $001-$080 = scanbuff - longs which hold 4 scan lines
' $081-$182 = scancode - stacked WAITVID/SHR for fast display
' $183-$1EF = maincode - main program loop which drives display
org 'set origin to $000 for start of program
d0 long 1 << 9 'd0 always resides here at $000, executes as NOP
' Initialization code and data - after execution, space gets reused as scanbuff
'Move main program into maincode area
:move mov $1EF,main_begin+main_size-1
sub :move,d0s0 '(do reverse move to avoid overwrite)
djnz main_ctr,#:move
'Build scanbuff display routine into scancode
:waitvid mov scancode+0,i0 'org scancode
:shr mov scancode+1,i1 'waitvid color,scanbuff+0
add :waitvid,d1 'shr scanbuff+0,#8
add :shr,d1 'waitvid color,scanbuff+1
add i0,#1 'shr scanbuff+1,#8
add i1,d0 '...
djnz scan_ctr,#:waitvid 'waitvid color,scanbuff+cols-1
mov scancode+cols*2-1,i2 'mov vscl,#hf
mov scancode+cols*2+0,i3 'waitvid hvsync,#0
mov scancode+cols*2+1,i4 'jmp #scanret
'Init I/O registers and sync COGs' video circuits
mov dira,reg_dira 'set pin directions
mov dirb,reg_dirb
movi frqa,#(pr / 5) << 2 'set pixel rate
mov vcfg,reg_vcfg 'set video configuration
mov vscl,#1 'set video to reload on every pixel
waitcnt sync_cnt,colormask 'wait for start value in cnt, add ~1ms
movi ctra,#%00001_110 'COGs in sync! enable PLLs now - NCOs locked!
waitcnt sync_cnt,#0 'wait ~1ms for PLLs to stabilize - PLLs locked!
mov vscl,#100 'insure initial WAITVIDs lock cleanly
'Jump to main loop
jmp #vsync 'jump to vsync - WAITVIDs will now be locked!
'Data
d0s0 long 1 << 9 + 1
d1 long 1 << 10
main_ctr long main_size
scan_ctr long cols
i0 waitvid x,scanbuff+0
i1 shr scanbuff+0,#8
i2 mov vscl,#hf
i3 waitvid hvsync,#0
i4 jmp #scanret
reg_dira long 0 'set at runtime
reg_dirb long 0 'set at runtime
reg_vcfg long 0 'set at runtime
sync_cnt long 0 'set at runtime
'Directives
fit scancode 'make sure initialization code and data fit
main_begin org maincode 'main code follows (gets moved into maincode)
' Main loop, display field - each COG alternately builds and displays four scan lines
vsync mov x,#vs 'do vertical sync lines
call #blank_vsync
vb_lines mov x,#vb 'do vertical back porch lines (# set at runtime)
call #blank_vsync
mov screen_ptr,screen_base 'reset screen pointer to upper-left character
mov color_ptr,color_base 'reset color pointer to first row
mov row,#0 'reset row counter for cursor insertion
mov fours,#rows * 3 / 2 'set number of 4-line builds for whole screen
'Build four scan lines into scanbuff
fourline mov font_ptr,font_third 'get address of appropriate font section
shl font_ptr,#7+2
add font_ptr,font_base
movd :pixa,#scanbuff-1 'reset scanbuff address (pre-decremented)
movd :pixb,#scanbuff-1
mov y,#2 'must build scanbuff in two sections because
mov vscl,vscl_line2x '..pixel counter is limited to twelve bits
:halfrow waitvid underscore,#0 'output lows to let other COG drive VGA pins
mov x,#cols/2 '..for 2 scan lines, ready for half a row
:column rdbyte z,screen_ptr 'get character from screen memory
ror z,#7 'get inverse flag into bit 0, keep chr high
shr z,#32-7-2 wc 'get inverse flag into c, chr into bits 8..2
add z,font_ptr 'add font section address to point to 8*4 pixels
add :pixa,d0 'increment scanbuff destination addresses
add :pixb,d0
add screen_ptr,#1 'increment screen memory address
:pixa rdlong scanbuff,z 'read pixel long (8*4) into scanbuff
:pixb if_nc xor scanbuff,longmask 'invert pixels according to inverse flag
djnz x,#:column 'another character in this half-row?
djnz y,#:halfrow 'loop to do 2nd half-row, time for 2nd WAITVID
sub screen_ptr,#cols 'back up to start of same row in screen memory
'Insert cursors into scanbuff
mov z,#2 'ready for two cursors
:cursor rdbyte x,cursor_base 'x in range?
add cursor_base,#1
cmp x,#cols wc
rdbyte y,cursor_base 'y match?
add cursor_base,#1
cmp y,row wz
rdbyte y,cursor_base 'get cursor mode
add cursor_base,#1
if_nc_or_nz jmp #:nocursor 'if cursor not in scanbuff, no cursor
add x,#scanbuff 'cursor in scanbuff, set scanbuff address
movd :xor,x
test y,#%010 wc 'get mode bits into flags
test y,#%001 wz
if_nc_and_z jmp #:nocursor 'if cursor disabled, no cursor
if_c_and_z test slowbit,cnt wc 'if blink mode, get blink state
if_c_and_nz test fastbit,cnt wc
test y,#%100 wz 'get box or underscore cursor piece
if_z mov x,longmask
if_nz mov x,underscore
if_nz cmp font_third,#2 wz 'if underscore, must be last font section
:xor if_nc_and_z xor scanbuff,x 'conditionally xor cursor into scanbuff
:nocursor djnz z,#:cursor 'second cursor?
sub cursor_base,#3*2 'restore cursor base
'Display four scan lines from scanbuff
rdword x,color_ptr 'get color pattern for current row
and x,colormask 'mask away hsync and vsync signal states
or x,hv 'insert inactive hsync and vsync states
mov y,#4 'ready for four scan lines
scanline mov vscl,vscl_chr 'set pixel rate for characters
jmp #scancode 'jump to scanbuff display routine in scancode
scanret mov vscl,#hs 'do horizontal sync pixels
waitvid hvsync,#1 '#1 makes hsync active
mov vscl,#hb 'do horizontal back porch pixels
waitvid hvsync,#0 '#0 makes hsync inactive
shr scanbuff+cols-1,#8 'shift last column's pixels right by 8
djnz y,#scanline 'another scan line?
'Next group of four scan lines
add font_third,#2 'if font_third + 2 => 3, subtract 3 (new row)
cmpsub font_third,#3 wc 'c=0 for same row, c=1 for new row
if_c add screen_ptr,#cols 'if new row, advance screen pointer
if_c add color_ptr,#2 'if new row, advance color pointer
if_c add row,#1 'if new row, increment row counter
djnz fours,#fourline 'another 4-line build/display?
'Visible section done, do vertical sync front porch lines
wrlong longmask,par 'write -1 to refresh indicator
vf_lines mov x,#vf 'do vertical front porch lines (# set at runtime)
call #blank
jmp #vsync 'new field, loop to vsync
'Subroutine - do blank lines
blank_vsync xor hvsync,#$101 'flip vertical sync bits
blank mov vscl,hx 'do blank pixels
waitvid hvsync,#0
mov vscl,#hf 'do horizontal front porch pixels
waitvid hvsync,#0
mov vscl,#hs 'do horizontal sync pixels
waitvid hvsync,#1
mov vscl,#hb 'do horizontal back porch pixels
waitvid hvsync,#0
djnz x,#blank 'another line?
blank_ret
blank_vsync_ret ret
'Data
screen_base long 0 'set at runtime (3 contiguous longs)
color_base long 0 'set at runtime
cursor_base long 0 'set at runtime
font_base long 0 'set at runtime
font_third long 0 'set at runtime
hx long hp 'visible pixels per scan line
vscl_line2x long (hp + hf + hs + hb) * 2 'total number of pixels per 2 scan lines
vscl_chr long 1 << 12 + 8 '1 clock per pixel and 8 pixels per set
colormask long $FCFC 'mask to isolate R,G,B bits from H,V
longmask long $FFFFFFFF 'all bits set
slowbit long 1 << 25 'cnt mask for slow cursor blink
fastbit long 1 << 24 'cnt mask for fast cursor blink
underscore long $FFFF0000 'underscore cursor pattern
hv long hv_inactive '-H,-V states
hvsync long hv_inactive ^ $200 '+/-H,-V states
'Uninitialized data
screen_ptr res 1
color_ptr res 1
font_ptr res 1
x res 1
y res 1
z res 1
row res 1
fours res 1
' 8 x 12 font - characters 0..127
'
' Each long holds four scan lines of a single character. The longs are arranged into
' groups of 128 which represent all characters (0..127). There are three groups which
' each contain a vertical third of all characters. They are ordered top, middle, and
' bottom.
' jedes zeichen besteht aus 3 x 4 zeilen zu je 8 pixeln. in den drei unteren blöcken
' ist je für eines der 128 zeichen ein long, welches 4 scanzeilen enthält. der erste
' long jedes blockes enthält also 3 x 4 zeilen des ersten zeichens.
'
' damit ergibt sich 1024 / 8 = 128 Zeichen
' 768 / 12 = 64 Zeilen
'
' erstes zeichen:
' $0C080000 oben
' $080C7E7E mitte
' $00000000 unten
'
' 0C 00001100
' 08 00001000
' 00 00000000
' 00 00000000
' 08 00001000
' 0C 00001100
' 7E 01111110
' 7E 01111110
' 00 00000000
' 00 00000000
' 00 00000000
' 00 00000000
font long
long $0C080000,$30100000,$7E3C1800,$18181800,$81423C00,$99423C00,$8181FF00,$E7C3FF00 'top
long $1E0E0602,$1C000000,$00000000,$00000000,$18181818,$18181818,$00000000,$18181818
long $00000000,$18181818,$18181818,$18181818,$18181818,$00FFFF00,$CC993366,$66666666
long $AA55AA55,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$00000000,$00000000,$00000000
long $00000000,$3C3C1800,$77666600,$7F363600,$667C1818,$46000000,$1B1B0E00,$1C181800
long $0C183000,$180C0600,$66000000,$18000000,$00000000,$00000000,$00000000,$60400000
long $73633E00,$1E181000,$66663C00,$60663C00,$3C383000,$06067E00,$060C3800,$63637F00
long $66663C00,$66663C00,$1C000000,$00000000,$18306000,$00000000,$180C0600,$60663C00
long $63673E00,$66663C00,$66663F00,$63663C00,$66361F00,$06467F00,$06467F00,$63663C00
long $63636300,$18183C00,$30307800,$36666700,$06060F00,$7F776300,$67636300,$63361C00
long $66663F00,$63361C00,$66663F00,$66663C00,$185A7E00,$66666600,$66666600,$63636300
long $66666600,$66666600,$31637F00,$0C0C3C00,$03010000,$30303C00,$361C0800,$00000000
long $0C000000,$00000000,$06060700,$00000000,$30303800,$00000000,$0C6C3800,$00000000
long $06060700,$00181800,$00606000,$06060700,$18181E00,$00000000,$00000000,$00000000
long $00000000,$00000000,$00000000,$00000000,$0C080000,$00000000,$00000000,$00000000
long $00000000,$00000000,$00000000,$18187000,$18181800,$18180E00,$73DBCE00,$18180000
long $080C7E7E,$10307E7E,$18181818,$7E181818,$81818181,$99BDBDBD,$81818181,$E7BD99BD 'middle
long $1E3E7E3E,$1C3E3E3E,$30F0C000,$0C0F0300,$00C0F030,$00030F0C,$00FFFF00,$18181818
long $18FFFF00,$00FFFF18,$18F8F818,$181F1F18,$18FFFF18,$00FFFF00,$CC993366,$66666666
long $AA55AA55,$FFFF0F0F,$F0F00F0F,$0F0F0F0F,$00000F0F,$FFFF0000,$F0F00000,$0F0F0000
long $00000000,$0018183C,$00000033,$7F363636,$66603C06,$0C183066,$337B5B0E,$0000000C
long $0C060606,$18303030,$663CFF3C,$18187E18,$00000000,$00007E00,$00000000,$060C1830
long $676F6B7B,$18181818,$0C183060,$60603860,$307F3336,$60603E06,$66663E06,$0C183060
long $66763C6E,$60607C66,$1C00001C,$00001C1C,$180C060C,$007E007E,$18306030,$00181830
long $033B7B7B,$66667E66,$66663E66,$63030303,$66666666,$06263E26,$06263E26,$63730303
long $63637F63,$18181818,$33333030,$36361E36,$66460606,$63636B7F,$737B7F6F,$63636363
long $06063E66,$7B636363,$66363E66,$66301C06,$18181818,$66666666,$66666666,$366B6B63
long $663C183C,$18183C66,$43060C18,$0C0C0C0C,$30180C06,$30303030,$00000063,$00000000
long $0030381C,$333E301E,$6666663E,$0606663C,$3333333E,$067E663C,$0C0C3E0C,$3333336E
long $66666E36,$1818181C,$60606070,$361E3666,$18181818,$6B6B6B3F,$6666663E,$6666663C
long $6666663B,$3333336E,$066E7637,$300C663C,$0C0C0C7E,$33333333,$66666666,$6B6B6363
long $1C1C3663,$66666666,$0C30627E,$180C060C,$18181818,$18306030,$00000000,$0018187E
long $00000000,$00000000,$00001818,$0000183C,$00003C42,$00003C42,$0000FF81,$0000FFC3 'bottom
long $0002060E,$00000000,$18181818,$18181818,$00000000,$00000000,$00000000,$18181818
long $18181818,$00000000,$18181818,$18181818,$18181818,$00FFFF00,$CC993366,$66666666
long $AA55AA55,$FFFFFFFF,$F0F0F0F0,$0F0F0F0F,$00000000,$FFFFFFFF,$F0F0F0F0,$0F0F0F0F
long $00000000,$00001818,$00000000,$00003636,$0018183E,$00006266,$00006E3B,$00000000
long $00003018,$0000060C,$00000000,$00000000,$0C181C1C,$00000000,$00001C1C,$00000103
long $00003E63,$00007E18,$00007E66,$00003C66,$00007830,$00003C66,$00003C66,$00000C0C
long $00003C66,$00001C30,$0000001C,$0C181C1C,$00006030,$00000000,$0000060C,$00001818
long $00003E07,$00006666,$00003F66,$00003C66,$00001F36,$00007F46,$00000F06,$00007C66
long $00006363,$00003C18,$00001E33,$00006766,$00007F66,$00006363,$00006363,$00001C36
long $00000F06,$00603C36,$00006766,$00003C66,$00003C18,$00003C66,$0000183C,$00003636
long $00006666,$00003C18,$00007F63,$00003C0C,$00004060,$00003C30,$00000000,$FFFF0000
long $00000000,$00006E33,$00003B66,$00003C66,$00006E33,$00003C66,$00001E0C,$1E33303E
long $00006766,$00007E18,$3C666660,$00006766,$00007E18,$00006B6B,$00006666,$00003C66
long $0F063E66,$78303E33,$00000F06,$00003C66,$0000386C,$00006E33,$0000183C,$00003636
long $00006336,$1C30607C,$00007E46,$00007018,$00001818,$00000E18,$00000000,$0000007E
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

1161
lib/bel-keyb.spin Normal file

File diff suppressed because it is too large Load Diff

492
lib/bel-mouse.spin Normal file
View File

@ -0,0 +1,492 @@
''***************************************
''* PS/2 Mouse Driver v1.1 *
''* Author: Chip Gracey *
''* Copyright (c) 2006 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
' v1.0 - 01 May 2006 - original version
' v1.1 - 01 Jun 2006 - bound coordinates added to simplify upper objects
VAR
long cog
long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs)
long par_x 'absolute x read-only (7 contiguous longs)
long par_y 'absolute y read-only
long par_z 'absolute z read-only
long par_buttons 'button states read-only
long par_present 'mouse present read-only
long par_dpin 'data pin write-only
long par_cpin 'clock pin write-only
long bx_min, by_min, bz_min 'min/max must be contiguous
long bx_max, by_max, bz_max
long bx_div, by_div, bz_div
long bx_acc, by_acc, bz_acc
PUB start(dpin, cpin) : okay
'' Start mouse driver - starts a cog
'' returns false if no cog available
''
'' dpin = data signal on PS/2 jack
'' cpin = clock signal on PS/2 jack
''
'' use 100-ohm resistors between pins and jack
'' use 10K-ohm resistors to pull jack-side signals to VDD
'' connect jack-power to 5V, jack-gnd to VSS
stop
par_dpin := dpin
par_cpin := cpin
okay := cog := cognew(@entry, @par_x) + 1
PUB stop
'' Stop mouse driver - frees a cog
if cog
cogstop(cog~ - 1)
longfill(@oldx, 0, 10)
PUB present : type
'' Check if mouse present - valid ~2s after start
'' returns mouse type:
''
'' 3 = five-button scrollwheel mouse
'' 2 = three-button scrollwheel mouse
'' 1 = two-button or three-button mouse
'' 0 = no mouse connected
type := par_present
PUB button(b) : state
'' Get the state of a particular button
'' returns t|f
state := -(par_buttons >> b & 1)
PUB buttons : states
'' Get the states of all buttons
'' returns buttons:
''
'' bit4 = right-side button
'' bit3 = left-side button
'' bit2 = center/scrollwheel button
'' bit1 = right button
'' bit0 = left button
states := par_buttons
PUB abs_x : x
'' Get absolute-x
x := par_x
PUB abs_y : y
'' Get absolute-y
y := par_y
PUB abs_z : z
'' Get absolute-z (scrollwheel)
z := par_z
PUB delta_reset
'' Reset deltas
oldx := par_x
oldy := par_y
oldz := par_z
PUB delta_x : x | newx
'' Get delta-x
newx := par_x
x := newx - oldx
oldx := newx
PUB delta_y : y | newy
'' Get delta-y
newy := par_y
y := newy - oldy
oldy := newy
PUB delta_z : z | newz
'' Get delta-z (scrollwheel)
newz := par_z
z := newz - oldz
oldz := newz
PUB bound_limits(xmin, ymin, zmin, xmax, ymax, zmax) | i
'' Set bounding limits
longmove(@bx_min, @xmin, 6)
PUB bound_scales(x_scale, y_scale, z_scale)
'' Set bounding scales (usually +/-1's, bigger values divide)
longmove(@bx_div, @x_scale, 3)
PUB bound_preset(x, y, z) | i, d
'' Preset bound coordinates
repeat i from 0 to 2
d := ||bx_div[i]
bx_acc[i] := (x[i] - bx_min[i]) * d + d >> 1
PUB bound_x : x
'' Get bound-x
x := bound(0, delta_x)
PUB bound_y : y
'' Get bound-y
y := bound(1, delta_y)
PUB bound_z : z
'' Get bound-z
z := bound(2, delta_z)
PRI bound(i, delta) : b | d
d := bx_div[i]
b := bx_min[i] + (bx_acc[i] := bx_acc[i] + delta * (d < 0) | 1 #> 0 <# (bx_max[i] - bx_min[i] + 1) * ||d - 1) / ||d
DAT
'***************************************
'* Assembly language PS/2 mouse driver *
'***************************************
org
'
'
' Entry
'
entry mov p,par 'load input parameters:
add p,#5*4 '_dpin/_cpin
rdlong _dpin,p
add p,#4
rdlong _cpin,p
mov dmask,#1 'set pin masks
shl dmask,_dpin
mov cmask,#1
shl cmask,_cpin
test _dpin,#$20 wc 'modify port registers within code
muxc _d1,dlsb
muxc _d2,dlsb
muxc _d3,#1
muxc _d4,#1
test _cpin,#$20 wc
muxc _c1,dlsb
muxc _c2,dlsb
muxc _c3,#1
movd :par,#_x 'reset output parameters:
mov p,#5 '_x/_y/_z/_buttons/_present
:par mov 0,#0
add :par,dlsb
djnz p,#:par
'
'
' Reset mouse
'
reset mov dira,#0 'reset directions
mov dirb,#0
mov stat,#1 'set reset flag
'
'
' Update parameters
'
update movd :par,#_x 'update output parameters:
mov p,par '_x/_y/_z/_buttons/_present
mov q,#5
:par wrlong 0,p
add :par,dlsb
add p,#4
djnz q,#:par
test stat,#1 wc 'if reset flag, transmit reset command
if_c mov data,#$FF
if_c call #transmit
'
'
' Get data packet
'
mov stat,#0 'reset state
call #receive 'receive first byte
cmp data,#$AA wz 'powerup/reset?
if_z jmp #init
mov _buttons,data 'data packet, save buttons
call #receive 'receive second byte
test _buttons,#$10 wc 'adjust _x
muxc data,signext
add _x,data
call #receive 'receive third byte
test _buttons,#$20 wc 'adjust _y
muxc data,signext
add _y,data
and _buttons,#%111 'trim buttons
cmp _present,#2 wc 'if not scrollwheel mouse, update parameters
if_c jmp #update
call #receive 'scrollwheel mouse, receive fourth byte
cmp _present,#3 wz 'if 5-button mouse, handle two extra buttons
if_z test data,#$10 wc
if_z_and_c or _buttons,#%01000
if_z test data,#$20 wc
if_z_and_c or _buttons,#%10000
shl data,#28 'adjust _z
sar data,#28
sub _z,data
jmp #update 'update parameters
'
'
' Initialize mouse
'
init call #receive '$AA received, receive id
movs crate,#100 'try to enable 3-button scrollwheel type
call #checktype
movs crate,#200 'try to enable 5-button scrollwheel type
call #checktype
shr data,#1 'if neither, 3-button type
add data,#1
mov _present,data
movs srate,#200 'set 200 samples per second
call #setrate
mov data,#$F4 'enable data reporting
call #transmit
jmp #update
'
'
' Check mouse type
'
checktype movs srate,#200 'perform "knock" sequence to enable
call #setrate '..scrollwheel and extra buttons
crate movs srate,#200/100
call #setrate
movs srate,#80
call #setrate
mov data,#$F2 'read type
call #transmit
call #receive
checktype_ret ret
'
'
' Set sample rate
'
setrate mov data,#$F3
call #transmit
srate mov data,#0
call #transmit
setrate_ret ret
'
'
' Transmit byte to mouse
'
transmit
_c1 or dira,cmask 'pull clock low
movs napshr,#13 'hold clock for ~128us (must be >100us)
call #nap
_d1 or dira,dmask 'pull data low
movs napshr,#18 'hold data for ~4us
call #nap
_c2 xor dira,cmask 'release clock
test data,#$0FF wc 'append parity and stop bits to byte
muxnc data,#$100
or data,dlsb
mov p,#10 'ready 10 bits
transmit_bit call #wait_c0 'wait until clock low
shr data,#1 wc 'output data bit
_d2 muxnc dira,dmask
mov wcond,c1 'wait until clock high
call #wait
djnz p,#transmit_bit 'another bit?
mov wcond,c0d0 'wait until clock and data low
call #wait
mov wcond,c1d1 'wait until clock and data high
call #wait
call #receive_ack 'receive ack byte with timed wait
cmp data,#$FA wz 'if ack error, reset mouse
if_nz jmp #reset
transmit_ret ret
'
'
' Receive byte from mouse
'
receive test _cpin,#$20 wc 'wait indefinitely for initial clock low
waitpne cmask,cmask
receive_ack
mov p,#11 'ready 11 bits
receive_bit call #wait_c0 'wait until clock low
movs napshr,#16 'pause ~16us
call #nap
_d3 test dmask,ina wc 'input data bit
rcr data,#1
mov wcond,c1 'wait until clock high
call #wait
djnz p,#receive_bit 'another bit?
shr data,#22 'align byte
test data,#$1FF wc 'if parity error, reset mouse
if_nc jmp #reset
and data,#$FF 'isolate byte
receive_ack_ret
receive_ret ret
'
'
' Wait for clock/data to be in required state(s)
'
wait_c0 mov wcond,c0 '(wait until clock low)
wait mov q,tenms 'set timeout to 10ms
wloop movs napshr,#18 'nap ~4us
call #nap
_c3 test cmask,ina wc 'check required state(s)
_d4 test dmask,ina wz 'loop until got state(s) or timeout
wcond if_never djnz q,#wloop '(replaced with c0/c1/c0d0/c1d1)
tjz q,#reset 'if timeout, reset mouse
wait_ret
wait_c0_ret ret
c0 if_c djnz q,#wloop '(if_never replacements)
c1 if_nc djnz q,#wloop
c0d0 if_c_or_nz djnz q,#wloop
c1d1 if_nc_or_z djnz q,#wloop
'
'
' Nap
'
nap rdlong t,#0 'get clkfreq
napshr shr t,#18/16/13 'shr scales time
min t,#3 'ensure waitcnt won't snag
add t,cnt 'add cnt to time
waitcnt t,#0 'wait until time elapses (nap)
nap_ret ret
'
'
' Initialized data
'
dlsb long 1 << 9
tenms long 10_000 / 4
signext long $FFFFFF00
'
'
' Uninitialized data
'
dmask res 1
cmask res 1
stat res 1
data res 1
p res 1
q res 1
t res 1
_x res 1 'write-only
_y res 1 'write-only
_z res 1 'write-only
_buttons res 1 'write-only
_present res 1 'write-only
_dpin res 1 'read-only
_cpin res 1 'read-only
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

711
lib/bel-tv.spin Normal file
View File

@ -0,0 +1,711 @@
''***************************************
''* TV Driver v1.1 *
''* Author: Chip Gracey *
''* Copyright (c) 2004 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
' v1.0 - 01 May 2006 - original version
' v1.1 - 17 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient
' character displays utilizing the internal font - see 'tv_mode'
CON
fntsc = 3_579_545 'NTSC color frequency
lntsc = 3640 'NTSC color cycles per line * 16
sntsc = 624 'NTSC color cycles per sync * 16
fpal = 4_433_618 'PAL color frequency
lpal = 4540 'PAL color cycles per line * 16
spal = 848 'PAL color cycles per sync * 16
paramcount = 14
colortable = $180 'start of colortable inside cog
VAR
long cog
PUB start(tvptr) : okay
'' Start TV driver - starts a cog
'' returns false if no cog available
''
'' tvptr = pointer to TV parameters
stop
okay := cog := cognew(@entry, tvptr) + 1
PUB stop
'' Stop TV driver - frees a cog
if cog
cogstop(cog~ - 1)
DAT
'*******************************
'* Assembly language TV driver *
'*******************************
org
'
'
' Entry
'
entry mov taskptr,#tasks 'reset tasks
mov x,#10 'perform task sections initially
:init jmpret taskret,taskptr
djnz x,#:init
'
'
' Superfield
'
superfield mov taskptr,#tasks 'reset tasks
test _mode,#%0001 wc 'if ntsc, set phaseflip
if_nc mov phaseflip,phasemask
test _mode,#%0010 wz 'get interlace into nz
'
'
' Field
'
field mov x,vinv 'do invisible back porch lines
:black call #hsync 'do hsync
waitvid burst,sync_high2 'do black
jmpret taskret,taskptr 'call task section (z undisturbed)
djnz x,#:black 'another black line?
wrlong visible,par 'set status to visible
mov x,vb 'do visible back porch lines
call #blank_lines
mov screen,_screen 'point to first tile (upper-leftmost)
mov y,_vt 'set vertical tiles
:line mov vx,_vx 'set vertical expand
:vert if_z xor interlace,#1 'interlace skip?
if_z tjz interlace,#:skip
call #hsync 'do hsync
mov vscl,hb 'do visible back porch pixels
xor tile,colortable
waitvid tile,#0
mov x,_ht 'set horizontal tiles
mov vscl,hx 'set horizontal expand
:tile rdword tile,screen 'read tile
or tile,line 'set pointer bits into tile
rol tile,#6 'read tile pixels
rdlong pixels,tile '(2 instructions between reads)
shr tile,#10+6 'set tile colors
movs :color,tile
add screen,#2 'point to next tile
mov tile,phaseflip
:color xor tile,colortable
waitvid tile,pixels 'pass colors and pixels to video
djnz x,#:tile 'another tile?
sub screen,hc2x 'repoint to first tile in same line
mov vscl,hf 'do visible front porch pixels
mov tile,phaseflip
xor tile,colortable
waitvid tile,#0
:skip djnz vx,#:vert 'vertical expand?
ror line,linerot 'set next line
add line,lineadd wc
rol line,linerot
if_nc jmp #:line
add screen,hc2x 'point to first tile in next line
djnz y,#:line 'another tile line?
if_z xor interlace,#1 wz 'get interlace and field1 into z
test _mode,#%0001 wc 'do visible front porch lines
mov x,vf
if_nz_and_c add x,#1
call #blank_lines
if_nz wrlong invisible,par 'unless interlace and field1, set status to invisible
if_z_eq_c call #hsync 'if required, do short line
if_z_eq_c mov vscl,hrest
if_z_eq_c waitvid burst,sync_high2
if_z_eq_c xor phaseflip,phasemask
call #vsync_high 'do high vsync pulses
movs vsync1,#sync_low1 'do low vsync pulses
movs vsync2,#sync_low2
call #vsync_low
call #vsync_high 'do high vsync pulses
if_nz mov vscl,hhalf 'if odd frame, do half line
if_nz waitvid burst,sync_high2
if_z jmp #field 'if interlace and field1, display field2
jmp #superfield 'else, new superfield
'
'
' Blank lines
'
blank_lines call #hsync 'do hsync
xor tile,colortable 'do background
waitvid tile,#0
djnz x,#blank_lines
blank_lines_ret ret
'
'
' Horizontal sync
'
hsync test _mode,#%0001 wc 'if pal, toggle phaseflip
if_c xor phaseflip,phasemask
mov vscl,sync_scale1 'do hsync
mov tile,phaseflip
xor tile,burst
waitvid tile,sync_normal
mov vscl,hvis 'setup in case blank line
mov tile,phaseflip
hsync_ret ret
'
'
' Vertical sync
'
vsync_high movs vsync1,#sync_high1 'vertical sync
movs vsync2,#sync_high2
vsync_low mov x,vrep
vsyncx mov vscl,sync_scale1
vsync1 waitvid burst,sync_high1
mov vscl,sync_scale2
vsync2 waitvid burst,sync_high2
djnz x,#vsyncx
vsync_low_ret
vsync_high_ret ret
'
'
' Tasks - performed in sections during invisible back porch lines
'
tasks mov t1,par 'load parameters
movd :par,#_enable '(skip _status)
mov t2,#paramcount - 1
:load add t1,#4
:par rdlong 0,t1
add :par,d0
djnz t2,#:load '+119
mov t1,_pins 'set video pins and directions
test t1,#$08 wc
if_nc mov t2,pins0
if_c mov t2,pins1
test t1,#$40 wc
shr t1,#1
shl t1,#3
shr t2,t1
movs vcfg,t2
shr t1,#6
movd vcfg,t1
shl t1,#3
and t2,#$FF
shl t2,t1
if_nc mov dira,t2
if_nc mov dirb,#0
if_c mov dira,#0
if_c mov dirb,t2 '+18
tjz _enable,#disabled '+2, disabled?
jmpret taskptr,taskret '+1=140, break and return later
movs :rd,#wtab 'load ntsc/pal metrics from word table
movd :wr,#hvis
mov t1,#wtabx - wtab
test _mode,#%0001 wc
:rd mov t2,0
add :rd,#1
if_nc shl t2,#16
shr t2,#16
:wr mov 0,t2
add :wr,d0
djnz t1,#:rd '+54
if_nc movs :ltab,#ltab 'load ntsc/pal metrics from long table
if_c movs :ltab,#ltab+1
movd :ltab,#fcolor
mov t1,#(ltabx - ltab) >> 1
:ltab mov 0,0
add :ltab,d0s1
djnz t1,#:ltab '+17
rdlong t1,#0 'get CLKFREQ
shr t1,#1 'if CLKFREQ < 16MHz, cancel _broadcast
cmp t1,m8 wc
if_c mov _broadcast,#0
shr t1,#1 'if CLKFREQ < color frequency * 4, disable
cmp t1,fcolor wc
if_c jmp #disabled '+11
jmpret taskptr,taskret '+1=83, break and return later
mov t1,fcolor 'set ctra pll to fcolor * 16
call #divide 'if ntsc, set vco to fcolor * 32 (114.5454 MHz)
test _mode,#%0001 wc 'if pal, set vco to fcolor * 16 (70.9379 MHz)
if_c movi ctra,#%00001_111 'select fcolor * 16 output (ntsc=/2, pal=/1)
if_nc movi ctra,#%00001_110
if_nc shl t2,#1
mov frqa,t2 '+147
jmpret taskptr,taskret '+1=148, break and return later
mov t1,_broadcast 'set ctrb pll to _broadcast
mov t2,#0 'if 0, turn off ctrb
tjz t1,#:off
min t1,m8 'limit from 8MHz to 128MHz
max t1,m128
mov t2,#%00001_100 'adjust _broadcast to be within 4MHz-8MHz
:scale shr t1,#1 '(vco will be within 64MHz-128MHz)
cmp m8,t1 wc
if_c add t2,#%00000_001
if_c jmp #:scale
:off movi ctrb,t2
call #divide
mov frqb,t2 '+165
jmpret taskptr,taskret '+1=166, break and return later
mov t1,#%10100_000 'set video configuration
test _pins,#$01 wc '(swap broadcast/baseband output bits?)
if_c or t1,#%01000_000
test _mode,#%1000 wc '(strip chroma from broadcast?)
if_nc or t1,#%00010_000
test _mode,#%0100 wc '(strip chroma from baseband?)
if_nc or t1,#%00001_000
and _auralcog,#%111 '(set aural cog)
or t1,_auralcog
movi vcfg,t1 '+10
mov hx,_hx 'compute horizontal metrics
shl hx,#8
or hx,_hx
shl hx,#4
mov hc2x,_ht
shl hc2x,#1
mov t1,_ht
mov t2,_hx
call #multiply
mov hf,hvis
sub hf,t1
shr hf,#1 wc
mov hb,_ho
addx hb,hf
sub hf,_ho '+52
mov t1,_vt 'compute vertical metrics
mov t2,_vx
call #multiply
test _mode,#%10000 wc 'consider tile size
muxc linerot,#1
mov lineadd,lineinc
if_c shr lineadd,#1
if_c shl t1,#1
test _mode,#%0010 wc 'consider interlace
if_c shr t1,#1
mov vf,vvis
sub vf,t1
shr vf,#1 wc
neg vb,_vo
addx vb,vf
add vf,_vo '+53
xor _mode,#%0010 '+1, flip interlace bit for display
:colors jmpret taskptr,taskret '+1=117/160, break and return later
mov t1,#13 'load next 13 colors into colortable
:colorloop mov t2,:colorreg '5 times = 65 (all 64 colors loaded)
shr t2,#9-2
and t2,#$FC
add t2,_colors
:colorreg rdlong colortable,t2
add :colorreg,d0
andn :colorreg,d6
djnz t1,#:colorloop '+158
jmp #:colors '+1, keep loading colors
'
'
' Divide t1/CLKFREQ to get frqa or frqb value into t2
'
divide rdlong m1,#0 'get CLKFREQ
mov m2,#32+1
:loop cmpsub t1,m1 wc
rcl t2,#1
shl t1,#1
djnz m2,#:loop
divide_ret ret '+140
'
'
' Multiply t1 * t2 * 16 (t1, t2 = bytes)
'
multiply shl t2,#8+4-1
mov m1,#8
:loop shr t1,#1 wc
if_c add t1,t2
djnz m1,#:loop
multiply_ret ret '+37
'
'
' Disabled - reset status, nap ~4ms, try again
'
disabled mov ctra,#0 'reset ctra
mov ctrb,#0 'reset ctrb
mov vcfg,#0 'reset video
wrlong outa,par 'set status to disabled
rdlong t1,#0 'get CLKFREQ
shr t1,#8 'nap for ~4ms
min t1,#3
add t1,cnt
waitcnt t1,#0
jmp #entry 'reload parameters
'
'
' Initialized data
'
m8 long 8_000_000
m128 long 128_000_000
d0 long 1 << 9 << 0
d6 long 1 << 9 << 6
d0s1 long 1 << 9 << 0 + 1 << 1
interlace long 0
invisible long 1
visible long 2
phaseflip long $00000000
phasemask long $F0F0F0F0
line long $00060000
lineinc long $10000000
linerot long 0
pins0 long %11110000_01110000_00001111_00000111
pins1 long %11111111_11110111_01111111_01110111
sync_high1 long %0101010101010101010101_101010_0101
sync_high2 long %01010101010101010101010101010101 'used for black
sync_low1 long %1010101010101010101010101010_0101
sync_low2 long %01_101010101010101010101010101010
'
'
' NTSC/PAL metrics tables
' ntsc pal
' ----------------------------------------------
wtab word lntsc - sntsc, lpal - spal 'hvis
word lntsc / 2 - sntsc, lpal / 2 - spal 'hrest
word lntsc / 2, lpal / 2 'hhalf
word 243, 286 'vvis
word 10, 18 'vinv
word 6, 5 'vrep
word $02_8A, $02_AA 'burst
wtabx
ltab long fntsc 'fcolor
long fpal
long sntsc >> 4 << 12 + sntsc 'sync_scale1
long spal >> 4 << 12 + spal
long 67 << 12 + lntsc / 2 - sntsc 'sync_scale2
long 79 << 12 + lpal / 2 - spal
long %0101_00000000_01_10101010101010_0101 'sync_normal
long %010101_00000000_01_101010101010_0101
ltabx
'
'
' Uninitialized data
'
taskptr res 1 'tasks
taskret res 1
t1 res 1
t2 res 1
m1 res 1
m2 res 1
x res 1 'display
y res 1
hf res 1
hb res 1
vf res 1
vb res 1
hx res 1
vx res 1
hc2x res 1
screen res 1
tile res 1
pixels res 1
lineadd res 1
hvis res 1 'loaded from word table
hrest res 1
hhalf res 1
vvis res 1
vinv res 1
vrep res 1
burst res 1
fcolor res 1 'loaded from long table
sync_scale1 res 1
sync_scale2 res 1
sync_normal res 1
'
'
' Parameter buffer
'
_enable res 1 '0/non-0 read-only
_pins res 1 '%pppmmmm read-only
_mode res 1 '%tccip read-only
_screen res 1 '@word read-only
_colors res 1 '@long read-only
_ht res 1 '1+ read-only
_vt res 1 '1+ read-only
_hx res 1 '4+ read-only
_vx res 1 '1+ read-only
_ho res 1 '0+- read-only
_vo res 1 '0+- read-only
_broadcast res 1 '0+ read-only
_auralcog res 1 '0-7 read-only
fit colortable 'fit underneath colortable ($180-$1BF)
''
''___
''VAR 'TV parameters - 14 contiguous longs
''
'' long tv_status '0/1/2 = off/invisible/visible read-only
'' long tv_enable '0/non-0 = off/on write-only
'' long tv_pins '%pppmmmm = pin group, pin group mode write-only
'' long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only
'' long tv_screen 'pointer to screen (words) write-only
'' long tv_colors 'pointer to colors (longs) write-only
'' long tv_ht 'horizontal tiles write-only
'' long tv_vt 'vertical tiles write-only
'' long tv_hx 'horizontal tile expansion write-only
'' long tv_vx 'vertical tile expansion write-only
'' long tv_ho 'horizontal offset write-only
'' long tv_vo 'vertical offset write-only
'' long tv_broadcast 'broadcast frequency (Hz) write-only
'' long tv_auralcog 'aural fm cog write-only
''
''The preceding VAR section may be copied into your code.
''After setting variables, do start(@tv_status) to start driver.
''
''All parameters are reloaded each superframe, allowing you to make live
''changes. To minimize flicker, correlate changes with tv_status.
''
''Experimentation may be required to optimize some parameters.
''
''Parameter descriptions:
'' _________
'' tv_status
''
'' driver sets this to indicate status:
'' 0: driver disabled (tv_enable = 0 or CLKFREQ < requirement)
'' 1: currently outputting invisible sync data
'' 2: currently outputting visible screen data
'' _________
'' tv_enable
''
'' 0: disable (pins will be driven low, reduces power)
'' non-0: enable
'' _______
'' tv_pins
''
'' bits 6..4 select pin group:
'' %000: pins 7..0
'' %001: pins 15..8
'' %010: pins 23..16
'' %011: pins 31..24
'' %100: pins 39..32
'' %101: pins 47..40
'' %110: pins 55..48
'' %111: pins 63..56
''
'' bits 3..0 select pin group mode:
'' %0000: %0000_0111 - baseband
'' %0001: %0000_0111 - broadcast
'' %0010: %0000_1111 - baseband + chroma
'' %0011: %0000_1111 - broadcast + aural
'' %0100: %0111_0000 broadcast -
'' %0101: %0111_0000 baseband -
'' %0110: %1111_0000 broadcast + aural -
'' %0111: %1111_0000 baseband + chroma -
'' %1000: %0111_0111 broadcast baseband
'' %1001: %0111_0111 baseband broadcast
'' %1010: %0111_1111 broadcast baseband + chroma
'' %1011: %0111_1111 baseband broadcast + aural
'' %1100: %1111_0111 broadcast + aural baseband
'' %1101: %1111_0111 baseband + chroma broadcast
'' %1110: %1111_1111 broadcast + aural baseband + chroma
'' %1111: %1111_1111 baseband + chroma broadcast + aural
'' -----------------------------------------------------------
'' active pins top nibble bottom nibble
''
'' the baseband signal nibble is arranged as:
'' bit 3: chroma signal for s-video (attach via 560-ohm resistor)
'' bits 2..0: baseband video (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal)
''
'' the broadcast signal nibble is arranged as:
'' bit 3: aural subcarrier (sum 560-ohm resistor into network below)
'' bits 2..0: visual carrier (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal)
'' _______
'' tv_mode
''
'' bit 4 selects between 16x16 and 16x32 pixel tiles:
'' 0: 16x16 pixel tiles (tileheight = 16)
'' 1: 16x32 pixel tiles (tileheight = 32)
''
'' bit 3 controls chroma mixing into broadcast:
'' 0: mix chroma into broadcast (color)
'' 1: strip chroma from broadcast (black/white)
''
'' bit 2 controls chroma mixing into baseband:
'' 0: mix chroma into baseband (composite color)
'' 1: strip chroma from baseband (black/white or s-video)
''
'' bit 1 controls interlace:
'' 0: progressive scan (243 display lines for NTSC, 286 for PAL)
'' less flicker, good for motion
'' 1: interlaced scan (486 display lines for NTSC, 572 for PAL)
'' doubles the vertical display lines, good for text
''
'' bit 0 selects NTSC or PAL format
'' 0: NTSC
'' 3016 horizontal display ticks
'' 243 or 486 (interlaced) vertical display lines
'' CLKFREQ must be at least 14_318_180 (4 * 3_579_545 Hz)*
'' 1: PAL
'' 3692 horizontal display ticks
'' 286 or 572 (interlaced) vertical display lines
'' CLKFREQ must be at least 17_734_472 (4 * 4_433_618 Hz)*
''
'' * driver will disable itself while CLKFREQ is below requirement
'' _________
'' tv_screen
''
'' pointer to words which define screen contents (left-to-right, top-to-bottom)
'' number of words must be tv_ht * tv_vt
'' each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr
'' bits 15..10: select the colorset* for the associated pixel tile
'' bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15)
''
'' * colorsets are longs which each define four 8-bit colors
''
'' ** pixelgroups are <tileheight> longs which define (left-to-right, top-to-bottom) the 2-bit
'' (four color) pixels that make up a 16x16 or a 32x32 pixel tile
'' _________
'' tv_colors
''
'' pointer to longs which define colorsets
'' number of longs must be 1..64
'' each long has four 8-bit fields which define colors for 2-bit (four color) pixels
'' first long's bottom color is also used as the screen background color
'' 8-bit color fields are as follows:
'' bits 7..4: chroma data (0..15 = blue..green..red..)*
'' bit 3: controls chroma modulation (0=off, 1=on)
'' bits 2..0: 3-bit luminance level:
'' values 0..1: reserved for sync - don't use
'' values 2..7: valid luminance range, modulation adds/subtracts 1 (beware of 7)
'' value 0 may be modulated to produce a saturated color toggling between levels 1 and 7
''
'' * because of TV's limitations, it doesn't look good when chroma changes abruptly -
'' rather, use luminance - change chroma only against a black or white background for
'' best appearance
'' _____
'' tv_ht
''
'' horizontal number pixel tiles - must be at least 1
'' practical limit is 40 for NTSC, 50 for PAL
'' _____
'' tv_vt
''
'' vertical number of pixel tiles - must be at least 1
'' practical limit is 13 for NTSC, 15 for PAL (26/30 max for interlaced NTSC/PAL)
'' _____
'' tv_hx
''
'' horizontal tile expansion factor - must be at least 3 for NTSC, 4 for PAL
''
'' make sure 16 * tv_ht * tv_hx + ||tv_ho + 32 is less than the horizontal display ticks
'' _____
'' tv_vx
''
'' vertical tile expansion factor - must be at least 1
''
'' make sure <tileheight> * tv_vt * tv_vx + ||tv_vo + 1 is less than the display lines
'' _____
'' tv_ho
''
'' horizontal offset in ticks - pos/neg value (0 for centered image)
'' shifts the display right/left
'' _____
'' tv_vo
''
'' vertical offset in lines - pos/neg value (0 for centered image)
'' shifts the display up/down
'' ____________
'' tv_broadcast
''
'' broadcast frequency expressed in Hz (ie channel 2 is 55_250_000)
'' if 0, modulator is turned off - saves power
''
'' broadcasting requires CLKFREQ to be at least 16_000_000
'' while CLKFREQ is below 16_000_000, modulator will be turned off
'' ___________
'' tv_auralcog
''
'' selects cog to supply aural fm signal - 0..7
'' uses ctra pll output from selected cog
''
'' in NTSC, the offset frequency must be 4.5MHz and the max bandwidth +-25KHz
'' in PAL, the offset frequency and max bandwidth vary by PAL type
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

574
lib/bel-vga.spin Normal file
View File

@ -0,0 +1,574 @@
{{
┌────────────────────────────────────────┬────────────────┬────────────────────────┬──────────────────┐
│ VGA 1024x768 Tile Driver v0.9 │ by Chip Gracey │ (C)2006 Parallax, Inc. │ 11 November 2006 │
├────────────────────────────────────────┴────────────────┴────────────────────────┴──────────────────┤
│ │
│ This object generates a 1024x768 VGA display from a 64x48 array of 16x16-pixel 4-color tiles. │
│ It requires two cogs (or three with optional cursor enabled) and at least 80 MHz. │
│ │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
{{
01-02-2011-dr235 - erweiterung des treibers, um mit einem parameter den anfangszeiger
des bildwiederholspeichers dynamisch zu ändern; wichtig zur
verwaltung von mehreren screens
}}
CON
' 1024 x 768 @ 60Hz settings
hp = 1024 'horizontal pixels
vp = 768 'vertical pixels
hf = 16 'horizontal front porch pixels
hs = 96 'horizontal sync pixels
hb = 176 'horizontal back porch pixels
vf = 1 'vertical front porch lines
vs = 3 'vertical sync lines
vb = 28 'vertical back porch lines
pr = 60 'pixel rate in MHz at 80MHz system clock (5MHz granularity)
ht = hp + hf + hs + hb 'total scan line pixels
' Tile array
xtiles = hp / 16
ytiles = vp / 16
VAR
long cog[3]
long dira_ '9 contiguous longs
long dirb_
long vcfg_
long cnt_
long array_ptr_
long color_ptr_
long cursor_ptr_
long sync_ptr_
long mode_
long scrind_ 'dr235: screenindex
DAT
'' Start driver - starts two or three cogs
'' returns false if cogs not available
''
'' base_pin = First of eight VGA pins, must be a multiple of eight (0, 8, 16, 24, etc):
''
'' 240Ω 240Ω 240Ω 240Ω
'' +7 ───┳─ Red +5 ───┳─ Green +3 ───┳─ Blue +1 ── H
'' 470Ω │ 470Ω │ 470Ω │ 240Ω
'' +6 ───┘ +4 ───┘ +2 ───┘ +0 ── V
''
'' 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
''
'' cursor_ptr = Pointer to 4 longs which will control the cursor, or 0 to disable the
'' cursor. If a pointer is given, an extra cog will be started to generate
'' the cursor overlay. Here are the 4 longs that control the cursor:
''
'' cursor_x - X position of cursor: ..0..1023.. (left to right)
'' cursor_y - Y position of cursor: ..0..767.. (bottom to top)
''
'' cursor_color - Cursor color to be OR'd to background color as %%RGBx:
'' %%3330=white, %%2220 or %%1110=translucent, %%0000=off
''
'' cursor_shape - 0 for arrow, 1 for crosshair, or pointer to a cursor
'' definition. A cursor definition consists of 32 longs
'' containing a 32x32 pixel cursor image, followed by two
'' bytes which define the X and Y center-pixel offsets
'' within the image.
''
'' sync_ptr = Pointer to a long which will be set to -1 after each refresh, or 0 to
'' disable this function. This is useful in advanced applications where
'' awareness of display timing is important.
''
'' mode = 0 for normal 16x16 pixel tiles or 1 for taller 16x32 pixel tiles. Mode 1
'' is useful for displaying the internal font while requiring half the array
'' memory; however, the 3-D bevel characters will not be usable because of
'' the larger vertical tile granularity of this mode.
PUB start(base_pin, array_ptr, color_ptr, cursor_ptr, sync_ptr, mode) : okay | i, j
'If driver is already running, stop it
stop
'Ready i/o settings
i := $FF << (base_pin & %011000)
j := base_pin & %100000 == 0
dira_ := i & j
dirb_ := i & !j
vcfg_ := $300000FF + (base_pin & %111000) << 6
'Ready cnt value to sync cogs by
cnt_ := cnt + $100000
'Ready pointers and mode
longmove(@array_ptr_, @array_ptr, 5)
scrind_ := array_ptr_
'Launch cogs, abort if error
repeat i from 0 to 2
if i == 2 'cursor cog?
ifnot cursor_ptr 'cursor enabled?
quit 'if not, quit loop
waitcnt($2000 + cnt) 'cursor cog, allow prior cog to launch
vcfg_ ^= $10000000 'set two-color mode
array_ptr_~ 'flag cursor function
ifnot cog[i] := cognew(@entry, @dira_ + i << 15) + 1
stop
return {false}
'Successful
return true
PUB stop | i
'' Stop driver - frees cogs
'If already running, stop any VGA cogs
repeat i from 0 to 2
if cog[i]
cogstop(cog[i]~ - 1)
PUB set_scrpointer(array_ptr)
' zeiger auf screenanfang wird neu gesetzt um mehrere screens verwalten zu können
scrind_ := array_ptr
DAT
' ┌─────────────────────────────┐
' │ Initialization - all cogs │
' └─────────────────────────────┘
org
' Move field loop into position
entry mov field,field_code
add entry,d0s0_
djnz regs,#entry
' Acquire settings
mov scrind,par 'dr235: adresse screenindex speichern
cmpsub scrind,bit15 'dr235: bit15 ausblenden
add scrind,#36 'dr235: adresse in scrind speichern
mov regs,par '00 dira_ ─ dira
cmpsub regs,bit15 wc '04 dirb_ ─ dirb
:next movd :read,sprs '08 vcfg_ ─ vcfg
or :read,d8_d4 '12 cnt_ ─ cnt
shr sprs,#4 '16 array_ptr_ ─ ctrb
:read rdlong dira,regs '20 color_ptr_ ─ frqb
add regs,#4 '24 cursor_ptr_ ─ vscl
tjnz sprs,#:next '28 sync_ptr_ ─ phsb
'32 mode_
'36 scrind_ --> scrind
sumc vf_lines,#2 'alter scan line settings by cog
sumnc vb_lines,#2
sumnc tile_line,#2 * 4
rdlong regs,regs wz 'if mode not 0, set tile size to 16 x 32 pixels
if_nz movs tile_bytes,#32 * 4
if_nz shr array_bytes,#1
mov regs,vscl 'save cursor pointer
' Synchronize all cogs' video circuits so that waitvid's will be pixel-locked
movi frqa,#(pr / 5) << 2 'set pixel rate (VCO runs at 2x)
mov vscl,#1 'set video shifter to reload on every pixel
waitcnt cnt,d8_d4 'wait for sync count, add ~3ms - cogs locked!
movi ctra,#%00001_110 'enable PLLs now - NCOs locked!
waitcnt cnt,#0 'wait ~3ms for PLLs to stabilize - PLLs locked!
mov vscl,#100 'subsequent WAITVIDs will now be pixel-locked!
' Determine if this cog is to perform one of two field functions or the cursor function
tjnz ctrb,#vsync 'if array ptr, jump to field function
'else, cursor function follows
' ┌─────────────────────────┐
' │ Cursor Loop - one cog │
' └─────────────────────────┘
' Do vertical sync lines minus three
cursor mov par,#vf + vs + vb - 6
:loop mov vscl,vscl_line
:vsync waitvid ccolor,#0
djnz par,#:vsync
' Do three lines minus horizontal back porch pixels to buy a big block of time
mov vscl,vscl_three_lines_mhb
waitvid ccolor,#0
' Get cursor data
rdlong cx,regs 'get cursor x
add regs,#4
rdlong cy,regs 'get cursor y
add regs,#4
rdlong ccolor,regs 'get cursor color
add regs,#4
rdlong cshape,regs 'get cursor shape
sub regs,#3 * 4
and ccolor,#$FC 'trim and justify cursor color
shl ccolor,#8
' Build cursor pixels
mov par,#32 'ready for 32 cursor segments
movd :pix,#cpix
mov cnt,cshape
:pixloop cmp cnt,#1 wc, wz 'arrow, crosshair, or custom cursor?
if_a jmp #:custom
if_e jmp #:crosshair
cmp par,#32 wz 'arrow
cmp par,#32-21 wc
if_z mov cseg,h80000000
if_nz_and_nc sar cseg,#1
if_nz_and_c shl cseg,#2
mov coff,#0
jmp #:pix
:crosshair cmp par,#32-15 wz 'crosshair
if_ne mov cseg,h00010000
if_e neg cseg,#2
cmp par,#1 wz
if_e mov cseg,#0
mov coff,h00000F0F
jmp #:pix
:custom rdlong cseg,cshape 'custom
add cshape,#4
rdlong coff,cshape
:pix mov cpix,cseg 'save segment into pixels
add :pix,d0
djnz par,#:pixloop 'another segment?
' Compute cursor position
mov cseg,coff 'apply cursor center-pixel offsets
and cseg,#$FF
sub cx,cseg
shr coff,#8
and coff,#$FF
add cy,coff
cmps cx,neg31 wc 'if x out of range, hide cursor via y
if_nc cmps pixels_m1,cx wc
if_c neg cy,#1
mov cshr,#0 'adjust for left-edge clipping
cmps cx,#0 wc
if_c neg cshr,cx
if_c mov cx,#0
mov cshl,#0 'adjust for right-edge clipping
cmpsub cx,pixels_m32 wc
if_c mov cshl,cx
if_c mov cx,pixels_m32
add cx,#hb 'bias x and y for display
sub cy,lines_m1
' Do visible lines with cursor
mov par,lines 'ready for visible scan lines
:line andn cy,#$1F wz, nr 'check if scan line in cursor range
if_z movs :seg,cy 'if in range, get cursor pixels
if_z add :seg,#cpix
if_nz mov cseg,#0 'if out of range, use blank pixels
:seg if_z mov cseg,cpix
if_z rev cseg,#0 'reverse pixels so they map sensibly
if_z shr cseg,cshr 'perform any edge clipping on pixels
if_z shl cseg,cshl
mov vscl,cx 'do left blank pixels (hb+cx)
waitvid ccolor,#0
mov vscl,vscl_cursor 'do cursor pixels (32)
waitvid ccolor,cseg
mov vscl,vscl_line_m32 'do right blank pixels (hp+hf+hs-32-cx)
sub vscl,cx
waitvid ccolor,#0
add cy,#1 'another scan line?
djnz par,#:line
' Do horizontal back porch pixels and loop
mov vscl,#hb
waitvid ccolor,#0
mov par,#vf + vs + vb - 3 'ready to do vertical sync lines
jmp #:loop
' Cursor data
vscl_line long ht 'total pixels per scan line
vscl_three_lines_mhb long ht * 3 - hb 'total pixels per three scan lines minus hb
vscl_line_m32 long ht - 32 'total pixels per scan line minus 32
vscl_cursor long 1 << 12 + 32 '32 pixels per cursor with 1 clock per pixel
lines long vp 'visible scan lines
lines_m1 long vp - 1 'visible scan lines minus 1
pixels_m1 long hp - 1 'visible pixels minus 1
pixels_m32 long hp - 32 'visible pixels minus 32
neg31 long -31
h80000000 long $80000000 'arrow/crosshair cursor data
h00010000 long $00010000
h00000F0F long $00000F0F
' Initialization data
d0s0_ long 1 << 9 + 1 'd and s field increments
regs long $1F0 - field 'number of registers in field loop space
sprs long $DFB91E76 'phsb/vscl/frqb/ctrb/cnt/vcfg/dirb/dira nibbles
bit15 long $8000 'bit15 mask used to differentiate cogs in par
d8_d4 long $0003E000 'bit8..bit4 mask for d field
field_code 'field loop code begins at this offset
' Undefined cursor data
cx res 1
cy res 1
ccolor res 1
cshape res 1
coff res 1
cseg res 1
cshr res 1
cshl res 1
cpix res 32
' ┌─────────────────────────┐
' │ Field Loop - two cogs │
' └─────────────────────────┘
org
' Allocate buffers
palettes res 64 'palettes of colors
colors res xtiles 'colors for tile row
pixels0 res xtiles 'pixels for tile row line +0
pixels1 res xtiles 'pixels for tile row line +1
pixels2 res xtiles 'pixels for tile row line +2
pixels3 res xtiles 'pixels for tile row line +3
' Each cog alternately builds and displays four scan lines
field mov cnt,#ytiles * 4 / 2 'ready number of four-scan-line builds/displays
' Build four scan lines
build_4y movd col0,#colors+0 'reset pointers for scan line buffers
movd col1,#colors+1
movd pix0,#pixels0+0
movd pix1,#pixels1+0
movd pix2,#pixels2+0
movd pix3,#pixels3+0
movd pix4,#pixels0+1
movd pix5,#pixels1+1
movd pix6,#pixels2+1
movd pix7,#pixels3+1
mov ina,#2 'four scan lines require two waitvid's
build_32x mov vscl,vscl_two_lines 'output lows for two scan lines so other cog
:zero waitvid :zero,#0 '..can display while this cog builds (twice)
mov inb,#xtiles / 2 / 2 'build four scan lines for half a row
build_2x rdlong vscl,ctrb 'get pair of words from the tile array
movs col0,vscl 'get color bits from even tile
andn col0,#$1C0
andn vscl,#$3F 'strip color bits and add tile line offset
add vscl,tile_line
col0 mov colors+0,palettes 'get even tile color
add col0,d1
pix0 rdlong pixels0+0,vscl 'get line +0 even tile pixels
add pix0,d1
add vscl,#4
pix1 rdlong pixels1+0,vscl 'get line +1 even tile pixels
add pix1,d1
add vscl,#4
pix2 rdlong pixels2+0,vscl 'get line +2 even tile pixels
add pix2,d1
add vscl,#4
pix3 rdlong pixels3+0,vscl 'get line +3 even tile pixels
add pix3,d1
add ctrb,#2 * 2 'point to next pair of tile words
shr vscl,#16 'shift odd tile word into position
movs col1,vscl 'get color bits from odd tile
andn col1,#$1C0
andn vscl,#$3F 'strip color bits and add tile line offset
add vscl,tile_line
col1 mov colors+1,palettes 'get odd tile color
add col1,d1
pix4 rdlong pixels0+1,vscl 'get line +0 odd tile pixels
add pix4,d1
add vscl,#4
pix5 rdlong pixels1+1,vscl 'get line +1 odd tile pixels
add pix5,d1
add vscl,#4
pix6 rdlong pixels2+1,vscl 'get line +2 odd tile pixels
add pix6,d1
add vscl,#4
pix7 rdlong pixels3+1,vscl 'get line +3 odd tile pixels
add pix7,d1
djnz inb,#build_2x 'loop for next tile pair (48 inst/loop)
djnz ina,#build_32x 'if first half done, loop for 2nd waitvid
sub ctrb,#xtiles * 2 'back up to start of same row
' Display four scan lines
mov inb,#4 'ready for four scan lines
movs :waitvid,#pixels0 'reset waitvid pixel pointer
:line mov ina,#xtiles 'ready for tiles
movd :waitvid,#colors 'reset waitvid color pointer
mov vscl,vscl_tile 'set pixel rate for tiles
:tile cmp ina,#1 wz 'check if last tile
add :waitvid,d0s0 'advance pointers (waitvid already read)
:waitvid waitvid colors,pixels0 'do tile slice
if_nz djnz ina,#:tile 'strange loop allows hsync timing and ina=1
call #hsync 'do horizontal sync (ina=1)
djnz inb,#:line 'another scan line?
' Another four scan lines?
add tile_line,#8 * 4 'advance eight scan lines within tile row
tile_bytes cmpsub tile_line,#16 * 4 wc 'tile row done? (# doubled for mode 1)
if_c add ctrb,#xtiles * 2 'if done, advance array pointer to next row
djnz cnt,#build_4y 'another four scan lines?
' hier kann der index eingearbeitet werden
'sub ctrb,array_bytes 'display done, reset array pointer to top row
rdlong ctrb,scrind 'dr235: stelle pointer wieder auf screenanfang
' Visible section done, handle sync indicator
cmp cnt,phsb wz 'sync enabled? (cnt=0)
if_nz wrlong neg1,phsb 'if so, write -1 to sync indicator
' Do vertical sync lines and loop
vf_lines mov ina,#vf + 2 'do vertical front porch lines (adjusted ±2)
call #blank
vsync mov ina,#vs 'do vertical sync lines
call #blank_vsync
vb_lines mov ina,#vb - 2 'do vertical back porch lines (adjusted ±2)
movs blank_vsync_ret,#field '(loop to field, blank_vsync follows)
' Subroutine - do blank lines
blank_vsync xor hv_sync,#$0101 'flip vertical sync bits
blank mov vscl,vscl_blank 'do horizontal blank pixels
waitvid hv_sync,#0
hsync mov vscl,#hf 'do horizontal front porch pixels
waitvid hv_sync,#0
mov vscl,#hs 'do horizontal sync pixels
waitvid hv_sync,#1
rdlong vscl,frqb 'update another palette
and vscl,color_mask
:palette mov palettes,vscl
add :palette,d0
add frqb,#4
add par,count_64 wc
if_c movd :palette,#palettes
if_c sub frqb,#64 * 4
mov vscl,#hb 'do horizontal back porch pixels
waitvid hv_sync,#0
djnz ina,#blank 'another blank line?
hsync_ret
blank_ret
blank_vsync_ret ret
' Data
d0s0 long 1 << 9 + 1 'd and s field increments
d0 long 1 << 9 'd field increment
d1 long 2 << 9 'd field double increment
tile_line long 2 * 4 'tile line offset (adjusted ±2 * 4)
array_bytes long xtiles * ytiles * 2 'number of bytes in tile array
vscl_two_lines long ht * 2 'total pixels per two scan lines
vscl_tile long 1 << 12 + 16 '16 pixels per tile with 1 clock per pixel
vscl_blank long hp 'visible pixels per scan line
hv_sync long $0200 '+/-H,-V states
count_64 long $04000000 'addend that sets carry every 64th addition
color_mask long $FCFCFCFC 'mask to isolate R,G,B bits from H,V
neg1 long $FFFFFFFF 'negative 1 to be written to sync indicator
scrind long 0 'dr235: adresse des screenindex

60
lib/fm-con.spin Normal file
View File

@ -0,0 +1,60 @@
'' Konstanten
CON
W1X1 = 1
W1X2 = 30
W2X1 = 33
W2X2 = 62
W1Y1 = 2
W1Y2 = 20
W2Y1 = 2
W2Y2 = 20
W3X1 = 0
W3X2 = 63
W3Y1 = 1
W3Y2 = 22
W4X1 = 15
W4X2 = 45
W4Y1 = 10
W4Y2 = 13
WROWS = W2Y2 - 2
W0X_MENU = 8
W0Y_MENU = 0
W0X_STAT = 0
W0Y_STAT = 23
W0X_INFO = 1
W0Y_INFO = 22
W1X_INFO = 33
W1Y_INFO = 22
WAIT_SEC = 5
COL_DEFAULT = 0
COL_MENU = 8
COL_STAT = 8
COL_FOCUS = 3
COL_LOGO = 2
COL_SELECT = 3
MAX_FILES = 128
MAX_LEN = 12 '12345678.123
MAX_BUFFER = MAX_FILES * MAX_LEN
FL_DIR = %1000_0000 'eintrag ist verzeichnisname
FL_SEL = %0000_0001 'eintrag ist selektiert
FL_FOCUS = %0000_0001 'box ist selektiert
DR_SD = 0
DR_RAM = 1
DR_BLK = 2
PUB dummy

456
lib/glob-com.spin Normal file
View File

@ -0,0 +1,456 @@
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Communications Engine │
│ │
│ Author: Kwabena W. Agyeman │
│ Updated: 8/4/2009 │
│ Designed For: P8X32A │
│ │
│ Copyright (c) 2009 Kwabena W. Agyeman │
│ See end of file for terms of use. │
│ │
│ Driver Info: │
│ │
│ The COMEngine runs a COM driver in the next free cog on the propeller chip when called. │
│ │
│ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │
│ so port B will not be operational. │
│ │
│ Nyamekye, │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
CON
''
RX_Pin = 31 '' ── RX Line - This line is driven by the interface chip.
''
TX_Pin = 30 '' ── TX Line - This line is driven by the propeller chip.
Stop_Bits = 1
CON
' For use with "receiveCharacter", "receiveCheck", "transmitCharacter", "transmitCharacters"
#0, Null
#1, Start_Of_Heading, Start_Of_Text, End_Of_Text, End_Of_Transmission
#5, Enquiry, Acknowledge
#7, Bell, Backspace, Horizontal_Tab, Line_Feed, Vertical_Tab, Form_Feed, Carriage_Return
#14, Shift_Out, Shift_In, Data_Link_Escape
#17, Device_Control_1, Device_Control_2, Device_Control_3, Device_Control_4
#21, Negative_Aknowledge, Synchronous_Idle, End_Of_Transmission_Block, Cancel, End_Of_Medium, Substitute, Escapse
#28, File_Seperaor, Group_Seperator, Record_Seperator, Unit_Seperator
#127, Delete
#17, XON, #19, XOFF
VAR
long baudRate
byte inputHead
byte inputTail
byte outputHead
byte outputTail
byte inputBuffer[256]
byte outputBuffer[256]
PUB generateEvenParity(character) '' 8 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Generates an even parity for a character and returns that character with the new parity attached. │
'' │ │
'' │ Character - A character. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (character ^ evenOrOdd(character))
PUB generateOddParity(character) '' 8 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Generates an odd parity for a character and returns that character with the new parity attached. │
'' │ │
'' │ Character - A character. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (character ^ evenOrOdd(character) ^ $80)
PUB generateMarkParity(character) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Generates an mark parity for a character and returns that character with the new parity attached. │
'' │ │
'' │ Character - A character. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (character | $80)
PUB generateSpaceParity(character) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Generates an space parity for a character and returns that character with the new parity attached. │ │
'' │ │
'' │ Character - A character. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (character & $7F)
PUB checkEvenParity(character) '' 8 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns true if the parity is correct and false if it is not. │
'' │ │
'' │ Character - A character with an even parity. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (not(evenOrOdd(character)))
PUB checkOddParity(character) '' 8 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns true if the parity is correct and false if it is not. │
'' │ │
'' │ Character - A character with an odd parity. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
result or= evenOrOdd(character)
PUB checkMarkParity(character) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns true if the parity is correct and false if it is not. │
'' │ │
'' │ Character - A character with an mark parity. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
result or= (character & $80)
PUB checkSpaceParity(character) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns true if the parity is correct and false if it is not. │
'' │ │
'' │ Character - A character with an space parity. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (not(character & $80))
PUB receiveCharacter '' 6 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the next character in the receiver buffer. │
'' │ │
'' │ Waits until there is a character to return if the receiver buffer is empty. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat until(receiveNumber)
return inputBuffer[inputTail++]
PUB receiveNumber '' 3 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the number of characters in the receiver buffer. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return ((inputHead - inputTail) & $FF)
PUB receiveCheck(character) '' 7 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Compares the last character in the receiver buffer with the specified character for equality. │
'' │ │
'' │ Returns true if they are equal and false otherwise. │
'' │ │
'' │ Character - The character to compare the last received character with for equality. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (receiveNumber and (inputBuffer[(inputHead - 1) & $FF] == character))
PUB receiveFull '' 6 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns true if the receiver buffer is full and false if it is not. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (receiveNumber == 255)
PUB receiveFlush '' 3 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Empties the receiver buffer. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
inputTail := inputHead
PUB transmitCharacter(character) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Transmits a character at the speed of the currently specified baud rate. │
'' │ │
'' │ Character - A character to transmit. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat until(outputTail <> ((outputHead + 1) & $FF))
outputBuffer[outputHead++] := character
PUB transmitCharacters(characters) '' 8 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Transmits a string characters at the speed of the currently specified baud rate. │
'' │ │
'' │ Characters - A pointer to the string of characters to transmit. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(characters)
transmitCharacter(byte[characters++])
PUB changeBaudRate(newBaudRate) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Changes the current baud rate. │
'' │ │
'' │ NewBaudRate - The new baud rate to transmit and receive at. Between 1 BPS and 250000 BPS. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat while(outputHead <> outputTail)
if(baudRate)
waitcnt((baudRate * constant((((Stop_Bits <# 32) #> 1) + 8) * 4)) + cnt)
baudRate := ((clkfreq / ((newBaudRate <# 250000) #> 1)) >> 2)
PUB COMEngine(newBaudRate) '' 8 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Initializes the COM driver to run on a new cog. │
'' │ │
'' │ Returns the new cog's ID on sucess or -1 on failure. │
'' │ │
'' │ NewBaudRate - The new baud rate to transmit and receive at. Between 1 BPS and 250000 BPS. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
inputHeadAddress := @inputHead
inputTailAddress := @inputTail
outputHeadAddress := @outputHead
outputTailAddress := @outputTail
inputBufferAddress := @inputBuffer
outputBufferAddress := @outputBuffer
changeBaudRate(newBaudRate)
return cognew(@initialization, @baudRate)
PRI evenOrOdd(character) ' 4 Stack Longs
repeat 8
result += (character & 1)
character >>= 1
return ((result & 1) << 7)
DAT
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' COM Driver
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
org
' //////////////////////Initialization/////////////////////////////////////////////////////////////////////////////////////////
initialization mov transmitterPC, #transmitter ' Setup transmitter.
movi ctra, #%0_00100_000 '
movs ctra, #((TX_Pin <# 31) #> 0) '
neg phsa, #1 '
mov dira, TXPin '
rdlong counter, par ' Setup synchronization.
add counter, cnt '
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' Receiver
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
receiver rdlong quarterRate, par ' Get new settings.
add counter, quarterRate '
waitcnt counter, quarterRate ' Wait for transmitter.
jmpret receiverPC, transmitterPC '
waitcnt counter, quarterRate ' Wait for start bit.
test RXPin, ina wz '
if_nz waitcnt counter, quarterRate ' Wait for start bit.
if_nz test RXPin, ina wc '
if_nz_and_c jmp #receiver ' Repeat.
' //////////////////////Receiver Setup/////////////////////////////////////////////////////////////////////////////////////////
mov receiverCounter, #9 ' Setup loop to receive the packet.
' //////////////////////Receive Packet/////////////////////////////////////////////////////////////////////////////////////////
receive waitcnt counter, quarterRate ' Input bits.
test RXPin, ina wc '
rcl receiverBuffer, #1 '
if_z add counter, quarterRate ' Wait for transmitter.
waitcnt counter, quarterRate '
jmpret receiverPC, transmitterPC '
if_nz add counter, quarterRate '
waitcnt counter, quarterRate '
djnz receiverCounter, #receive ' Ready next bit.
rev receiverBuffer, #24 ' Reverse backwards bits.
' //////////////////////Update Packet//////////////////////////////////////////////////////////////////////////////////////////
rdbyte receiverTail, inputTailAddress ' Check if the buffer is full.
mov buffer, receiverHead '
sub buffer, receiverTail '
and buffer, #$FF '
cmp buffer, #255 wc '
' //////////////////////Set Packet/////////////////////////////////////////////////////////////////////////////////////////////
if_z add counter, quarterRate ' Set packet and synchronize.
if_c mov buffer, inputBufferAddress '
if_c add buffer, receiverHead '
if_c wrbyte receiverBuffer, buffer '
if_c add receiverHead, #1 ' Update receiver head pointer.
if_c and receiverHead, #$FF '
if_c wrbyte receiverHead, inputHeadAddress '
' //////////////////////Repeat/////////////////////////////////////////////////////////////////////////////////////////////////
jmp #receiver ' Repeat
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' Transmitter
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
transmitter jmpret transmitterPC, receiverPC ' Run some code.
loop rdbyte buffer, outputHeadAddress ' Check if the buffer is empty.
sub buffer, transmitterTail '
tjz buffer, #transmitter '
' //////////////////////Get Packet/////////////////////////////////////////////////////////////////////////////////////////////
mov transmitterBuffer, outputBufferAddress ' Get packet and output start bit.
add transmitterBuffer, transmitterTail '
jmpret transmitterPC, receiverPC '
rdbyte phsa, transmitterBuffer '
add transmitterTail, #1 ' Update transmitter tail pointer.
and transmitterTail, #$FF '
wrbyte transmitterTail, outputTailAddress '
' //////////////////////Transmitter Setup///////////////////////////////////////////////////////////////////////////////////////
mov transmitterCounter, #(((Stop_Bits <# 32) #> 1) + 8) ' Setup loop to transmit the packet.
' //////////////////////Transmit Packet////////////////////////////////////////////////////////////////////////////////////////
transmit or phsa, #$100 ' Output bits.
jmpret transmitterPC, receiverPC '
ror phsa, #1 '
djnz transmitterCounter, #transmit ' Ready next bit.
' //////////////////////Repeat/////////////////////////////////////////////////////////////////////////////////////////////////
jmp #loop ' Repeat.
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
' Data
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
receiverHead long 0
transmitterTail long 0
' //////////////////////Pin Masks//////////////////////////////////////////////////////////////////////////////////////////////
RXPin long (|<((RX_Pin <# 31) #> 0)) ' Receiving pin mask.
TXPin long (|<((TX_Pin <# 31) #> 0)) ' Transmitting pin mask.
' //////////////////////Addresses//////////////////////////////////////////////////////////////////////////////////////////////
inputHeadAddress long 0
inputTailAddress long 0
outputHeadAddress long 0
outputTailAddress long 0
inputBufferAddress long 0
outputBufferAddress long 0
' //////////////////////Run Time Variables/////////////////////////////////////////////////////////////////////////////////////
buffer res 1
counter res 1
halfRate res 1
quarterRate res 1
' //////////////////////Receiver Variables/////////////////////////////////////////////////////////////////////////////////////
receiverBuffer res 1
receiverCounter res 1
receiverTail res 1
receiverPC res 1
' //////////////////////Transmitter Variables//////////////////////////////////////////////////////////////////////////////////
transmitterBuffer res 1
transmitterCounter res 1
transmitterHead res 1
transmitterPC res 1
' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fit 496
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

389
lib/glob-con.spin Normal file
View File

@ -0,0 +1,389 @@
{{ Bellatrix-Code
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Autor: Ingo Kripahle │
│ Copyright (c) 2012 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 : trios
Name :
Chip : global
Typ : konstanten
}}
CON 'Signaldefinitionen --------------------------------------------------------------------------
'signaldefinitionen global
#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus
#24, HBEAT 'front-led
BUSCLK 'bustakt
BUS_WR '/wr - schreibsignal
BUS_HS ' '/hs - quittungssignal
I2C_SCL
I2C_SDA
SER_TX
SER_RX
'signaldefinitionen bellatrix
#8, B_VGABASE 'vga-signale (8pin)
#16, B_KEYBC,B_KEYBD 'keyboard-signale
#18, B_MOUSEC,B_MOUSED 'maus-signale
#20, B_VIDBASE 'video-signale(3pin)
#23, B_SELECT 'belatrix-auswahlsignal
'signaldefinitionen administra
#8, A_SOUNDL,A_SOUNDR 'sound (stereo 2 pin)
#10, A_SDD0,A_SDCLK,A_SDCMD,A_SDD3 'sd-cardreader (4 pin)
#23, A_SELECT 'administra-auswahlsignal
CON 'KEY_CODES -------------------------------------------------------------------------------------
KEY_CTRL = 2
KEY_ALT = 4
KEY_OS = 8
KEY_ESC = 27
KEY_TAB = 9
KEY_RETURN = 13
KEY_BS = 8
KEY_POS1 = 6
KEY_CURUP = 04
KEY_CURDOWN = 05
KEY_CURLEFT = 02
KEY_CURRIGHT = 03
KEY_PAGEUP = 160
KEY_PAGEDOWN = 162
KEY_SPACE = 32
KEY_F01 = 208
KEY_F02 = 209
KEY_F03 = 210
KEY_F04 = 211
KEY_F05 = 212
KEY_F06 = 213
KEY_F07 = 214
KEY_F08 = 215
KEY_F09 = 216
KEY_F10 = 217
KEY_F11 = 218
KEY_F12 = 219
CON 'ADMINISTRA-FUNKTIONEN --------------------------------------------------------------------------
' +----------- ays
' |+---------- com
' || +-------- plexbus
' || |+------- rtc
' || ||+------ lan
' || |||+----- sid
' || ||||+---- wav
' || |||||+--- hss
' || ||||||+-- chiploader
' || |||||||+- dateisystem
A_FAT = %00000000_00000000_00000000_00000001
A_LDR = %00000000_00000000_00000000_00000010
A_HSS = %00000000_00000000_00000000_00000100
A_WAV = %00000000_00000000_00000000_00001000
A_SID = %00000000_00000000_00000000_00010000
A_LAN = %00000000_00000000_00000000_00100000
A_RTC = %00000000_00000000_00000000_01000000
A_PLX = %00000000_00000000_00000000_10000000
A_COM = %00000000_00000000_00000001_00000000
A_AYS = %00000000_00000000_00000010_00000000
' |
' ym
' ---------------------------------------------- SD-FUNKTIONEN
#1, a_sdMount 'sd-card mounten '
a_sdOpenDir 'direktory öffnen
a_sdNextFile 'verzeichniseintrag lesen
a_sdOpen 'datei öffnen
a_sdClose 'datei schließen
a_sdGetC 'zeichen lesen
a_sdPutC 'zeichen schreiben
a_sdGetBlk 'block lesen
a_sdPutBlk 'block schreiben
a_sdSeek 'zeiger in datei positionieren
a_sdFAttrib 'dateiattribute übergeben
a_sdVolname 'volumelabel abfragen
a_sdCheckMounted 'test ob volume gemounted ist
a_sdCheckOpen 'test ob eine datei geöffnet ist
a_sdCheckUsed 'test wie viele sektoren benutzt sind
a_sdCheckFree 'test wie viele sektoren frei sind
a_sdNewFile 'neue datei erzeugen
a_sdNewDir 'neues verzeichnis wird erzeugt
a_sdDel 'verzeichnis oder datei löschen
a_sdRename 'verzeichnis oder datei umbenennen
a_sdChAttrib 'attribute ändern
a_sdChDir 'verzeichnis wechseln
a_sdFormat 'medium formatieren
a_sdUnmount 'medium abmelden
a_sdDmAct 'dir-marker aktivieren
a_sdDmSet 'dir-marker setzen
a_sdDmGet 'dir-marker status abfragen
a_sdDmClr 'dir-marker löschen
a_sdDmPut 'dir-marker status setzen
a_sdEOF '30 'eof abfragen
' ---------------------------------------------- COM-FUNKTIONEN
#31, a_comInit
a_comTx
a_comRx '33
' ---------------------------------------------- RTC-FUNKTIONEN
#41, a_rtcGetSeconds 'Returns the current second (0 - 59) from the real time clock.
a_rtcGetMinutes 'Returns the current minute (0 - 59) from the real time clock.
a_rtcGetHours 'Returns the current hour (0 - 23) from the real time clock.
a_rtcGetDay 'Returns the current day (1 - 7) from the real time clock.
a_rtcGetDate 'Returns the current date (1 - 31) from the real time clock.
a_rtcGetMonth 'Returns the current month (1 - 12) from the real time clock.
a_rtcGetYear 'Returns the current year (2000 - 2099) from the real time clock.
a_rtcSetSeconds 'Sets the current real time clock seconds. Seconds - Number to set the seconds to between 0 - 59.
a_rtcSetMinutes 'Sets the current real time clock minutes. Minutes - Number to set the minutes to between 0 - 59.
a_rtcSetHours 'Sets the current real time clock hours. Hours - Number to set the hours to between 0 - 23.
a_rtcSetDay 'Sets the current real time clock day. Day - Number to set the day to between 1 - 7.
a_rtcSetDate 'Sets the current real time clock date. Date - Number to set the date to between 1 - 31.
a_rtcSetMonth 'Sets the current real time clock month. Month - Number to set the month to between 1 - 12.
a_rtcSetYear 'Sets the current real time clock year. Year - Number to set the year to between 2000 - 2099.
a_rtcSetNVSRAM 'Sets the NVSRAM to the selected value (0 - 255) at the index (0 - 55).
a_rtcGetNVSRAM 'Gets the selected NVSRAM value at the index (0 - 55).
a_rtcPauseForSec 'Pauses execution for a number of seconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of seconds to pause for between 0 and 2,147,483,647.
a_rtcPauseForMSec '58 'Pauses execution for a number of milliseconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of milliseconds to pause for between 0 and 2,147,483,647.
' ---------------------------------------------- CHIP-MANAGMENT
#92, a_mgrSetSound 'soundsubsysteme verwalten
a_mgrGetSpec 'spezifikation abfragen
a_mgrSetSysSound 'systemsound ein/ausschalten
a_mgrGetSoundSys 'abfrage welches soundsystem aktiv ist
a_mgrALoad 'neuen code booten
a_mgrGetCogs 'freie cogs abfragen
a_mgrGetVer 'codeversion abfragen
a_mgrReboot '99 'neu starten
' ---------------------------------------------- HSS-FUNKTIONEN
#100, a_hssLoad 'hss-datei in puffer laden
a_hssPlay 'play
a_hssStop 'stop
a_hssPause 'pause
a_hssPeek 'register lesen
a_hssIntReg 'interfaceregister auslesen
a_hssVol 'lautstärke setzen
a_sfxFire 'sfx abspielen
a_sfxSetSlot 'sfx-slot setzen
a_sfxKeyOff
a_sfxStop '110
' ---------------------------------------------- WAV-FUNKTIONEN
#150, a_sdwStart 'spielt wav-datei direkt von sd-card ab
a_sdwStop 'stopt wav-cog
a_sdwStatus 'fragt status des players ab
a_sdwLeftVol 'lautstärke links
a_sdwRightVol 'lautstärke rechts
a_sdwPause 'player pause/weiter-modus
a_sdwPosition '156
' ---------------------------------------------- AY-SOUNDFUNKTIONEN
#200, a_ayStart
a_ayStop
a_ayUpdateRegisters
' ---------------------------------------------- SIDCog: DMP-Player-Funktionen (SIDCog2)
#157, a_s_mdmpplay 'dmp-file mono auf sid2 abspielen
a_s_sdmpplay 'dmp-file stereo auf beiden sids abspielen
a_s_dmpstop 'dmp-player beenden
a_s_dmppause 'dmp-player pausenmodus
a_s_dmpstatus 'dmp-player statusabfrage
a_s_dmppos 'player-position im dumpfile
a_s_mute 'alle register löschen
' ---------------------------------------------- SIDCog1-Funktionen
a_s1_setRegister
a_s1_updateRegisters
a_s1_setVolume
a_s1_play
a_s1_noteOn
a_s1_noteOff
a_s1_setFreq
a_s1_setWaveform
a_s1_setPWM
a_s1_setADSR
a_s1_setResonance
a_s1_setCutoff
a_s1_setFilterMask
a_s1_setFilterType
a_s1_enableRingmod
a_s1_enableSynchronization
' ---------------------------------------------- SIDCog2-Funktionen
a_s2_setRegister
a_s2_updateRegisters
a_s2_setVolume
a_s2_play
a_s2_noteOn
a_s2_noteOff
a_s2_setFreq
a_s2_setWaveform
a_s2_setPWM
a_s2_setADSR
a_s2_setResonance
a_s2_setCutoff
a_s2_setFilterMask
a_s2_setFilterType
a_s2_enableRingmod
a_s2_enableSynchronization
' ---------------------------------------------- Zusatzfunktionen
a_s_dmpreg '196 'soundinformationen senden
CON 'BELLATRIX-FUNKTIONEN --------------------------------------------------------------------------
' +----------
' | +-------- window
' | |+------- vektor
' | ||+------ grafik
' | |||+----- text
' | ||||+---- maus
' | |||||+--- tastatur
' | ||||||+-- vga
' | |||||||+- tv
B_TV = %00000000_00000000_00000000_00000001
B_VGA = %00000000_00000000_00000000_00000010
B_KEY = %00000000_00000000_00000000_00000100
B_MOUSE = %00000000_00000000_00000000_00001000
B_TXT = %00000000_00000000_00000000_00010000
B_PIX = %00000000_00000000_00000000_00100000
B_VEC = %00000000_00000000_00000000_01000000
B_WIN = %00000000_00000000_00000000_10000000
#1, B_KEYSTAT 'tastaturstatus senden
B_KEYCODE 'tastaturzeichen senden
B_PRINTCTRL 'steuerzeichen ($100..$1FF) ausgeben
B_KEYSPEC 'statustasten ($100..$1FF) abfragen
B_PRINTLOGO 'hive-logo ausgeben
B_PRINTQCHAR '6 'zeichen ohne steuerzeichen augeben
#80, B_WDEF
B_WSET
B_WGETCOLS
B_WGETROWS
B_WOFRAME '84
#87, B_MGRLOAD 'neuen bellatrix-code laden
B_MGRWSCR 'setzt screen, in welchen geschrieben wird
B_MGRDSCR 'setzt screen, welcher angezeigt wird
B_MGRGETCOL 'farbregister auslesen
B_MGRSETCOL 'farbregister setzen
B_MGRGETRESX 'x-auflösung abfragen
B_MGRGETRESY 'y-auflösung abfragen
B_MGRGETCOLS 'spaltenanzahl abfragen
B_MGRGETROWS 'zeilenanzahl abfragen
B_MGRGETCOGS 'freie cogs abfragen
B_MGRGETSPEC 'spezifikation abfragen
B_MGRGETVER 'codeversion abfragen
B_MGRREBOOT '99 'bellatrix neu starten
' steuerzeichen
#0, B_CMD 'esc-code für zweizeichen-steuersequenzen
B_CLS
B_HOME
B_POS1
B_CURON
B_CUROFF
B_SCROLLUP
B_SCROLLDOWN
B_BACKSPACE
B_TAB
B_LF
B_FREE1
B_FREE2
B_CRLF
' dreizeichen-steuersequenzen
' [B_CMD][B_SCRCMD][...]
#01, B_SETCUR
B_SETX
B_SETY
B_GETX
B_GETY
B_SETCOL
B_FREE3
B_FREE4
B_SINIT
B_TABSET
B_WSETX
B_WSETY
B_WGETX
B_WGETY
CON 'G0-FUNKTIONEN --------------------------------------------------------------------------
#1, G0_KEYSTAT
G0_KEYCODE
G0_KEYSPEC
#10, G0_CLEAR
G0_COPY
G0_COLOR
G0_WIDTH
G0_COLORWIDTH
G0_PLOT
G0_LINE
G0_ARC
G0_VEC
G0_VECARC
G0_PIX
G0_PIXARC
G0_TEXT
G0_TEXTARC
G0_TEXTMODE
G0_BOX
G0_QUAD
G0_TRI
#93, G0_COLORTAB
G0_SCREEN
G0_DATBLK
G0_DATLEN
G0_DYNAMIC
G0_STATIC
G0_REBOOT
PUB glob_con_dummy
return
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

322
lib/glob-fds.spin Normal file
View File

@ -0,0 +1,322 @@
''********************************************
''* Full-Duplex Serial Driver v1.2 *
''* Author: Chip Gracey, Jeff Martin *
''* Copyright (c) 2006-2009 Parallax, Inc. *
''* See end of file for terms of use. *
''********************************************
{-----------------REVISION HISTORY-----------------
v1.2 - 5/7/2009 fixed bug in dec method causing largest negative value (-2,147,483,648) to be output as -0.
v1.1 - 3/1/2006 first official release.
}
VAR
long cog 'cog flag/id
long rx_head '9 contiguous longs
long rx_tail
long tx_head
long tx_tail
long rx_pin
long tx_pin
long rxtx_mode
long bit_ticks
long buffer_ptr
byte rx_buffer[16] 'transmit and receive buffers
byte tx_buffer[16]
PUB start(rxpin, txpin, mode, baudrate) : okay
'' Start serial driver - starts a cog
'' returns false if no cog available
''
'' mode bit 0 = invert rx
'' mode bit 1 = invert tx
'' mode bit 2 = open-drain/source tx
'' mode bit 3 = ignore tx echo on rx
stop
longfill(@rx_head, 0, 4)
longmove(@rx_pin, @rxpin, 3)
bit_ticks := clkfreq / baudrate
buffer_ptr := @rx_buffer
okay := cog := cognew(@entry, @rx_head) + 1
PUB stop
'' Stop serial driver - frees a cog
if cog
cogstop(cog~ - 1)
longfill(@rx_head, 0, 9)
PUB rxflush
'' Flush receive buffer
repeat while rxcheck => 0
PUB rxcheck : rxbyte
'' Check if byte received (never waits)
'' returns -1 if no byte received, $00..$FF if byte
rxbyte--
if rx_tail <> rx_head
rxbyte := rx_buffer[rx_tail]
rx_tail := (rx_tail + 1) & $F
PUB rxtime(ms) : rxbyte | t
'' Wait ms milliseconds for a byte to be received
'' returns -1 if no byte received, $00..$FF if byte
t := cnt
repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms
PUB rx : rxbyte
'' Receive byte (may wait for byte)
'' returns $00..$FF
repeat while (rxbyte := rxcheck) < 0
PUB tx(txbyte)
'' Send byte (may wait for room in buffer)
repeat until (tx_tail <> (tx_head + 1) & $F)
tx_buffer[tx_head] := txbyte
tx_head := (tx_head + 1) & $F
if rxtx_mode & %1000
rx
PUB str(stringptr)
'' Send string
repeat strsize(stringptr)
tx(byte[stringptr++])
PUB dec(value) | i, x
'' Print a decimal number
x := value == NEGX 'Check for max negative
if value < 0
value := ||(value+x) 'If negative, make positive; adjust for max negative
tx("-") 'and output sign
i := 1_000_000_000 'Initialize divisor
repeat 10 'Loop for 10 digits
if value => i
tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative
value //= i 'and digit from value
result~~ 'flag non-zero found
elseif result or i == 1
tx("0") 'If zero digit (or only digit) output it
i /= 10 'Update divisor
PUB hex(value, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB bin(value, digits)
'' Print a binary number
value <<= 32 - digits
repeat digits
tx((value <-= 1) & 1 + "0")
DAT
'***********************************
'* Assembly language serial driver *
'***********************************
org
'
'
' Entry
'
entry mov t1,par 'get structure address
add t1,#4 << 2 'skip past heads and tails
rdlong t2,t1 'get rx_pin
mov rxmask,#1
shl rxmask,t2
add t1,#4 'get tx_pin
rdlong t2,t1
mov txmask,#1
shl txmask,t2
add t1,#4 'get rxtx_mode
rdlong rxtxmode,t1
add t1,#4 'get bit_ticks
rdlong bitticks,t1
add t1,#4 'get buffer_ptr
rdlong rxbuff,t1
mov txbuff,rxbuff
add txbuff,#16
test rxtxmode,#%100 wz 'init tx pin according to mode
test rxtxmode,#%010 wc
if_z_ne_c or outa,txmask
if_z or dira,txmask
mov txcode,#transmit 'initialize ping-pong multitasking
'
'
' Receive
'
receive jmpret rxcode,txcode 'run a chunk of transmit code, then return
test rxtxmode,#%001 wz 'wait for start bit on rx pin
test rxmask,ina wc
if_z_eq_c jmp #receive
mov rxbits,#9 'ready to receive byte
mov rxcnt,bitticks
shr rxcnt,#1
add rxcnt,cnt
:bit add rxcnt,bitticks 'ready next bit period
:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return
mov t1,rxcnt 'check if bit receive period done
sub t1,cnt
cmps t1,#0 wc
if_nc jmp #:wait
test rxmask,ina wc 'receive bit on rx pin
rcr rxdata,#1
djnz rxbits,#:bit
shr rxdata,#32-9 'justify and trim received byte
and rxdata,#$FF
test rxtxmode,#%001 wz 'if rx inverted, invert byte
if_nz xor rxdata,#$FF
rdlong t2,par 'save received byte and inc head
add t2,rxbuff
wrbyte rxdata,t2
sub t2,rxbuff
add t2,#1
and t2,#$0F
wrlong t2,par
jmp #receive 'byte done, receive next byte
'
'
' Transmit
'
transmit jmpret txcode,rxcode 'run a chunk of receive code, then return
mov t1,par 'check for head <> tail
add t1,#2 << 2
rdlong t2,t1
add t1,#1 << 2
rdlong t3,t1
cmp t2,t3 wz
if_z jmp #transmit
add t3,txbuff 'get byte and inc tail
rdbyte txdata,t3
sub t3,txbuff
add t3,#1
and t3,#$0F
wrlong t3,t1
or txdata,#$100 'ready byte to transmit
shl txdata,#2
or txdata,#1
mov txbits,#11
mov txcnt,cnt
:bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode
test rxtxmode,#%010 wc
if_z_and_c xor txdata,#1
shr txdata,#1 wc
if_z muxc outa,txmask
if_nz muxnc dira,txmask
add txcnt,bitticks 'ready next cnt
:wait jmpret txcode,rxcode 'run a chunk of receive code, then return
mov t1,txcnt 'check if bit transmit period done
sub t1,cnt
cmps t1,#0 wc
if_nc jmp #:wait
djnz txbits,#:bit 'another bit to transmit?
jmp #transmit 'byte done, transmit next byte
'
'
' Uninitialized data
'
t1 res 1
t2 res 1
t3 res 1
rxtxmode res 1
bitticks res 1
rxmask res 1
rxbuff res 1
rxdata res 1
rxbits res 1
rxcnt res 1
rxcode res 1
txmask res 1
txbuff res 1
txdata res 1
txbits res 1
txcnt res 1
txcode res 1
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

819
lib/glob-numbers.spin Normal file
View File

@ -0,0 +1,819 @@
{{
*************************************
* Numbers v1.1 *
* Author: Jeff Martin *
* Copyright (c) 2005 Parallax, Inc. *
* See end of file for terms of use. *
*************************************
{-----------------REVISION HISTORY-----------------
v1.1 - 5/5/2009 fixed formatting bug caused by specifying field width smaller than location of first grouping character.}
}}
VAR
long BCX0, BCX1, BCX2, BCX3 'BCX Workspace
byte Symbols[7] 'Special symbols (7 characters)
byte StrBuf[49] 'Internal String Buffer
PUB Init
''Initialize to default settings. Init MUST be called before first object use.
'' ┌──────────────────────────────────────────────────┐
'' │ DEFAULT SPECIAL SYMBOLS │
'' ├─────┬──────┬─────────────────────────────────────┤
'' │ ID │ Char │ Usage │
'' ├─────┼──────┼─────────────────────────────────────┤
'' │ 1 │ , │ Comma (digit group separator) │
'' │ 2 │ _ │ Underscore (digit group separator) │
'' │ 3 │ $ │ Dollar Sign (Hexadecimal indicator) │
'' │ 4 │ % │ Percent Sign (Binary indicator) │
'' │ 5-7 │ │ Unused (User definable via Config) │
'' └─────┴──────┴─────────────────────────────────────┘
Config(@DefaultSymbols)
PUB Config(SymAddr)
{{Configure for custom symbols.
PARAMETERS: SymAddr = Address of a string of characters (7 or less) to be used as Special Symbols (indexed from 1 to 7). New symbols can be added or
existing symbols can be modified based on regional customs. Note: The first four symbols must always be the logical: 1) digit group separator
(default is ','), 2) general separator (default is '_'), 3) hexadecimal base indicator (default is '$'), and 4) binary base indicator
(default is '%').}}
bytemove(@Symbols, SymAddr, 7)
PUB ToStr(Num, Format): StrAddr
{{Convert long Num to z-string using Format; returns string address.
PARAMETERS: Num = 32-bit signed value to translate to ASCII string.
Format = Indicates output format: base, width, grouping, etc. See "FORMAT SYNTAX" for more information.
RETURNS: Actual length of output string, not including null terminator.}}
BCXToText(Format >> 19 & 7, Format >> 13 & $3F, Format >> 12 & 1, Format >> 11 & 1, Format >> 5 & $3F, BinToBCX(Num, Format & $1F #> 2 <# 16))
StrAddr := @StrBuf
PUB FromStr(StrAddr, Format): Num | Idx, N, Val, Char, Base, GChar, IChar, Field
''Convert z-string (at StrAddr) to long Num using Format.
''PARAMETERS: StrAddr = Address of string buffer containing the numeric string to convert.
'' Format = Indicates input format: base, width, etc. See "FORMAT SYNTAX" for more information. Note: three Format elements are ignored by
'' FromStr(): Zero/Space Padding, Hide/Show Plus Sign, and Digit Group Size. All other elements are actively used during translation.
''RETURNS: Long containing 32-bit signed result.
Base := Format & $1F #> 2 <# 16 'Get base
if GChar := Format >> 13 & 7 'Get grouping character
GChar := Symbols[--GChar #> 0]
if IChar := Format >> 19 & 7 'Get indicator character
IChar := Symbols[--IChar #> 0]
Field := Format >> 5 & $3F - 1 'Get field size, if any (subtract out sign char)
longfill(@Idx, 0, 3) 'Clear Idx, N and Val
repeat while Char := byte[StrAddr][Idx] 'While not null
if (not IChar or (IChar and Val)) and InBaseRange(Char, Base) > 0 'Found first valid digit? (with prefix indicator if required)?
quit ' exit to process digits
else 'else
if not Val := IChar and (Char == IChar) ' look for indicator character (if required)
N := Char == "-" 'Update N flag if not indicator
Idx++
Field += Val 'Subract indicator character from remaining field size
repeat while (Field--) and (Char := byte[StrAddr][Idx++]) and ((Val := InBaseRange(Char, Base)) > 0 or (GChar and (Char == GChar)))
if Val 'While not null and valid digit or grouping char
Num := Num * Base + --Val 'Accumulate if valid digit
if N
-Num 'Negate if necessary
PRI BinToBCX(Num, Base): Digits | N
'Convert signed binary Num to signed BCX value (Binary Coded X ;where X (2..16) is determined by Base)
'Returns: Number of significant Digits (not counting zero-left-padding).
longfill(@BCX0, 0, 4) 'Clear BCX Workspace
N := (Num < 0) & $10000000 'Remember if Num negative
repeat 'Calc all BCX digits
byte[@BCX0][Digits++ >> 1] += ||(Num // Base) << (4 * Digits&1)
while Num /= Base
BCX3 |= N 'If negative, set flag (highest digit of BCX Workspace)
PRI BCXToText(IChar, Group, ShowPlus, SPad, Field, Digits): Size | Idx, GCnt, SChar, GChar, X
'Convert BCX Buffer contents to z-string at StrBuf.
'IChar..Field each correspond to elements of Format. See "FORMAT SYNTAX" for more information.
'If Field = 0, Digits+1+Group is the effective field (always limited to max of 49).
'Digits : Number of significant digits (not counting zero-left-padding).
'RETURNS: Actual Size (length) of output string, not including null terminator.
X := 1-(IChar > 0) 'Xtra char count (1 or 2, for sign and optional base indicator)
IChar := Symbols[--IChar] 'Get base indicator character
SChar := "+" + 2*(BCX3 >> 28) + 11*(not (ShowPlus | (BCX3 >> 28)) or ((Digits == 1) and (BCX0 == 0))) 'Determine sign character ('+', ' ' or '-')
GChar := Symbols[Group & 7 - 1 #> 0] 'Get group character
if Field > 0 and SPad^1 and Digits < 32 'Need to add extra zero-padding?
BCX3 &= $0FFFFFFF ' then clear negative flag and set to 32 digits
Digits := 32
Group := -((Group >>= 3)-(Group > 0))*(Group+1 < Digits) 'Get group size (0 if not enough Digits)
Size := (Field - (Field==0)*(Digits+X+((Digits-1)/Group))) <# 49 'Field = 0? Set Size to Digits+X+Group (max 49).
if Group 'Insert group chars
bytefill(@StrBuf+(Size-Digits-(Digits-1)/Group #> 2), GChar, Digits+(Digits-1)/Group <# Size)
Idx~~ 'Insert digits
repeat while (++Idx < Digits) and (Idx + (GCnt := Idx/Group) < Size-X)
byte[@StrBuf][Size-Idx-1-GCnt] := lookupz(byte[@BCX0][Idx>>1] >> (4 * Idx&1) // 16: "0".."9","A".."F")
bytefill(@StrBuf, " ", Size-Idx-(Idx-1)/Group #> 0) 'Left pad with spaces, if necessary
byte[@StrBuf][Size-X-Idx-(Idx-1)/Group #> 0] := SChar 'Insert sign
if X == 2
byte[@StrBuf][Size-1-Idx-(Idx-1)/Group #> 1] := IChar 'Insert base indicator, if necessary
byte[@StrBuf][Size] := 0 'Zero-terminate string
PRI InBaseRange(Char, Base): Value
'Compare Char against valid characters for Base (1..16) (adjusting for lower-case automatically).
'Returns 0 if Char outside valid Base chars or, if valid, returns corresponding Value+1.
Value := ( Value -= (Char - $2F) * (Char => "0" and Char =< "9") + ((Char &= $DF) - $36) * (Char => "A" and Char =< "F") ) * -(Value < ++Base)
DAT
DefaultSymbols byte ",_$%xxx" 'Special, default, symbols ("x" means unused)
''
''
''**************************
''* FUNCTIONAL DESCRIPTION *
''**************************
''
''The Numbers object converts values in variables (longs) to strings and vice-versa in any base from 2 to 16.
''
''Standard/Default Features:
'' * supports full 32-bit signed values
'' * converts using any base from 2 to 16 (binary to hexadecimal)
'' * defaults to variable widths (ouputs entire number, regardless of size)
'' * uses ' ' or '-' for sign character
''
''Optional Features
'' * allows fixed widths (1 to 49 characters); left padded with either zeros (left justified) or spaces (right justified)
'' * can show plus sign for values > 0
'' * allows digit grouping (each 2 to 8 characters) with customizable separators; ex: 1000000 becomes 1,000,000 and 7AB14B9C becomes 7AB1_4B9C
'' * allows base indicator character (inserted right after sign) with customizable characters; ex: 7AB1 becomes $7AB1 and -1011 becomes -%1011
'' * all special symbols can be customized
''
''
''**************************
''* FORMAT SYNTAX *
''**************************
''
''The Format parameter of ToStr() and FromStr() is a 22-bit value indicating the desired output or input format. Custom values can be used for the Format
''parameter, however, a series of pre-defined constants for common formats as well as each of the elemental building blocks have already been defined by this
''object. These pre-defined constants are listed below, followed by a detailed explanation of the syntax of the Format parameter.
''
''┌────────────────────────────────────────────────────────────────────────────────────────┐ ┌───────────────────────────────────────┐
''│ COMMON FORMAT CONSTANTS │ │ Working Examples │
''├─────────────────────┬───────────┬────────────┬─────────┬─────────────┬─────────────────┤ ├────────────┬────────┬─────────────────┤
''│ CONSTANT │ INDICATED │ DELIMITING │ PADDING │ BASE │ WIDTH │ │ Long Value │ Format │ String Result │
''│ │ BASE │ │ │ │ (incl. symbols) │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DEC │ -1234 │
''│ BIN │ │ │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ DEC │ 1234 │
''│ IBIN │ % │ │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ HEX │ 4D2 │
''│ DBIN │ │ Underscore │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ IHEX │ -$4D2 │
''│ IDBIN │ % │ Underscore │ │ Binary │ Variable │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ BIN │ 10011010010 │
''│ BIN2..BIN33 │ │ │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ IBIN │ -%10011010010 │
''│ IBIN3..IBIN34 │ % │ │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ DDEC │ 1,234 │
''│ DBIN7..DBIN40 │ │ Underscore │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DDEC8 │ -001,234 │
''│ IDBIN8..IDBIN41 │ % │ Underscore │ Zero │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DSDEC8 │ -1,234 │
''│ SBIN3..SBIN33 │ │ │ Space │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ 1234 │ DBIN │ 100_1101_0010 │
''│ ISBIN4..ISBIN34 │ % │ │ Space │ Binary │ Fixed │ ├────────────┼────────┼─────────────────┤
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ │ -1234 │ DBIN15 │ -0100_1101_0010 │
''│ DSBIN7..DSBIN40 │ │ Underscore │ Space │ Binary │ Fixed │ └────────────┴────────┴─────────────────┘
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ *Note: In these examples, all positive
''│ IDSBIN8..IDSBIN41 │ % │ Underscore │ Space │ Binary │ Fixed │ values' output strings have a space
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ for the sign character. Don't forget
''│ DEC │ │ │ │ Decimal │ Variable │ that fact when sizing string buffer
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤ or otherwise using result.
''│ DDEC │ │ Comma │ │ Decimal │ Variable │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ DEC2..DEC11 │ │ │ Zero │ Decimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ SDEC3..SDEC11 │ │ │ Space │ Decimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ DSDEC6..DSDEC14 │ │ Comma │ Space │ Decimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ HEX │ │ │ │ Hexadecimal │ Variable │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ IHEX │ $ │ │ │ Hexadecimal │ Variable │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ DHEX │ │ Underscore │ │ Hexadecimal │ Variable │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ IDHEX │ $ │ Underscore │ │ Hexadecimal │ Variable │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ HEX2..HEX9 │ │ │ Zero │ Hexadecimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ IHEX3..IHEX10 │ $ │ │ Zero │ Hexadecimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ DHEX7..DHEX10 │ │ Underscore │ Zero │ Hexadecimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ IDHEX8..IDHEX11 │ $ │ Underscore │ Zero │ Hexadecimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ SHEX3..SHEX9 │ │ │ Space │ Hexadecimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ ISHEX4..ISHEX10 │ $ │ │ Space │ Hexadecimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ DSHEX7..DSHEX10 │ │ Underscore │ Space │ Hexadecimal │ Fixed │
''├─────────────────────┼───────────┼────────────┼─────────┼─────────────┼─────────────────┤
''│ IDSHEX8..IDSHEX11 │ $ │ Underscore │ Space │ Hexadecimal │ Fixed │
''└─────────────────────┴───────────┴────────────┴─────────┴─────────────┴─────────────────┘
''
''
''If the desired format was not already defined by the Common Format Constants, above, you may use the following constants as building blocks to create
''the customer format you need.
''
''┌─────────────────────────────────────────────────────┐
''│ FORMAT CONSTANT "BUILDING BLOCKS" │
''│ (use these if no equivelant common format exisits) │
''├────────────────────┬────────────────────────────────┤
''│ CONSTANT │ DESCRIPTION │
''├────────────────────┼────────────────────────────────┤
''│ BIN, DEC or HEX │ Binary, Decimal or Hexadecimal │
''├────────────────────┼────────────────────────────────┤
''│ CHAR1..CHAR48 │ Field Width (includes symbols) │
''├────────────────────┼────────────────────────────────┤
''│ <nothing> / SPCPAD │ Zero / Space Pad │
''├────────────────────┼────────────────────────────────┤
''│ <nothing> / PLUS │ Hide / Show Plus │
''├────────────────────┼────────────────────────────────┤
''│ COMMA, USCORE │ Group Character │
''├────────────────────┼────────────────────────────────┤
''│ GROUP2..GROUP8 │ Group Size │
''├────────────────────┼────────────────────────────────┤
''│ BINCHAR or HEXCHAR │ Indicator Character │
''└────────────────────┴────────────────────────────────┘
''
''
''The detailed syntax of the Format parameter is described below.
''
''There are 7 elements of the Format parameter:
'' 1) Base,
'' 2) Field Width,
'' 3) Zero/Space Padding,
'' 4) Hide/Show Plus Sign,
'' 5) Grouping Character ID,
'' 6) Digit Group Size,
'' 7) Indicator Character
''Only the Base element is required, all others are optional.
''
''The 22-bit syntax is as follows:
''
'' III ZZZ GGG P S FFFFFF BBBBB
''
''I : Indicator Character ID (0-7). 0 = no indicator character, 1 = Comma, 2 = Underscore, 3 = Dollar Sign, 4 = Percent Sign, etc., as defined by default Init; may be customized via call to Config().
''Z : Digit Group Size (0-7). 0 = no digit group characters, 1 = every 2 chars, 2 = every 3 chars, etc.
''G : Grouping Character ID (0-7). 0 or 1 = Comma, 2 = Underscore, etc., as defined by default Init; may be customized via call to Config().
''P : Hide/Show Plus Sign (0-1). For Num values > 0, sign char is: ' ' (if P = 0), or '+' (if P = 1).
''S : Zero/Space Pad (0-1). [Ignored unless Field Width > 0]. 0 = left pad with zeros (left justified), 1 = left pad with spaces (right justified).
''F : Field Width (0-48). String field width, including sign character and any special characters (not including zero terminator).
''B : Base (2-16). Base to convert number to; 2 = binary, 10 = decimal, 16 = hexadecimal, etc. This element is required.
''
''Examples:
''
''Conversion to variable-width decimal value:
'' Use Format of: %000_000_000_0_0_000000_01010, or simply %1010 (decimal 10).
''
''Conversion to 5-character wide, fixed-width hexadecimal value (left padded with zeros):
'' Use Format of: %000_000_000_0_0_000101_10000
''
''Conversion to 5-character wide, fixed-width hexadecimal value (left padded with spaces):
'' Use Format of: %000_000_000_0_1_000101_10000
''
''Conversion to variable-width decimal value comma-separated at thousands:
'' Use Format of: %000_010_001_0_0_000000_01010
''
''Conversion to Indicated, 6-character wide, fixed-width hexadecimal value (left padded with spaces):
'' Use Format of: %011_000_000_0_1_000110_10000
''
''For convenience and code readability, a number of pre-defined symbolic constants are included that can be added together for any format
''combination imaginable. See "FORMAT CONSTANT 'BUILDING BLOCKS'", above. For example, using these constants, the above example format values become
''the following, respectively:
'' DEC
'' HEX+CHAR5
'' HEX+CHAR5+SPCPAD
'' DEC+GROUP3+COMMA
'' HEX+CHAR6+HEXCHAR+SPCPAD
''
''
''┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
''│ 32-Bit Statistics for Bases 2 to 16 │
''├──────┬────────────┬────────────────────────────────────────────────────────────────────────────┬───────────────────┤
''│ Base │ Max Digits │ Range (Signed) │ Range Is Shown │
''│ │ w/o symbols│ Minimum │ Maximum │ Grouped By │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 2 │ 32 │ -10000000_00000000_00000000_00000000 │ +1111111_11111111_11111111_11111111 │ Bytes (exact) │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 3 │ 20 │ -12112_12221_21102_02102 │ +12112_12221_21102_02101 │ Bytes │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 4 │ 16 │ -2000_0000_0000_0000 │ +1333_3333_3333_3333 │ Bytes (exact) │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 5 │ 14 │ -13_344223_434043 │ +13_344223_434042 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 6 │ 12 │ -553032_005532 │ +553032_005531 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 7 │ 12 │ -10_41342_11162 │ +10_41342_11161 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 8 │ 11 │ -2_00000_00000 │ +1_77777_77777 │ Words (15 bits) │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 9 │ 10 │ -54787_73672 │ +54787_73671 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 10 │ 10 │ -2,147,483,648 │ +2,147,483,647 │ Thousands (exact) │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 11 │ 9 │ -A_0222_0282 │ +A_0222_0281 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 12 │ 9 │ -4_BB23_08A8 │ +4_BB23_08A7 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 13 │ 9 │ -2_82BA_4AAB │ +2_82BA_4AAA │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 14 │ 9 │ -1_652C_A932 │ +1_652C_A931 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 15 │ 8 │ -C87D_66B8 │ +C87D_66B7 │ Words │
''├──────┼────────────┼──────────────────────────────────────┼─────────────────────────────────────┼───────────────────┤
''│ 16 │ 8 │ -8000_0000 │ +7FFF_FFFF │ Words (exact) │
''└──────┴────────────┴──────────────────────────────────────┴─────────────────────────────────────┴───────────────────┘
CON
'┌──────────────────────────────────────────┐
'│ Format "Building Blocks" │
'└──────────────────────────────────────────┘
' III ZZZ GGG P S FFFFFF BBBBB
CHAR2 = %000_000_000_0_0_000010_00000 'Fixed Width (includes sign and special symbols)
CHAR3 = %000_000_000_0_0_000011_00000
CHAR4 = %000_000_000_0_0_000100_00000
CHAR5 = %000_000_000_0_0_000101_00000
CHAR6 = %000_000_000_0_0_000110_00000
CHAR7 = %000_000_000_0_0_000111_00000
CHAR8 = %000_000_000_0_0_001000_00000
CHAR9 = %000_000_000_0_0_001001_00000
CHAR10 = %000_000_000_0_0_001010_00000
CHAR11 = %000_000_000_0_0_001011_00000
CHAR12 = %000_000_000_0_0_001100_00000
CHAR13 = %000_000_000_0_0_001101_00000
CHAR14 = %000_000_000_0_0_001110_00000
CHAR15 = %000_000_000_0_0_001111_00000
CHAR16 = %000_000_000_0_0_010000_00000
CHAR17 = %000_000_000_0_0_010001_00000
CHAR18 = %000_000_000_0_0_010010_00000
CHAR19 = %000_000_000_0_0_010011_00000
CHAR20 = %000_000_000_0_0_010100_00000
CHAR21 = %000_000_000_0_0_010101_00000
CHAR22 = %000_000_000_0_0_010110_00000
CHAR23 = %000_000_000_0_0_010111_00000
CHAR24 = %000_000_000_0_0_011000_00000
CHAR25 = %000_000_000_0_0_011001_00000
CHAR26 = %000_000_000_0_0_011010_00000
CHAR27 = %000_000_000_0_0_011011_00000
CHAR28 = %000_000_000_0_0_011100_00000
CHAR29 = %000_000_000_0_0_011101_00000
CHAR30 = %000_000_000_0_0_011110_00000
CHAR31 = %000_000_000_0_0_011111_00000
CHAR32 = %000_000_000_0_0_100000_00000
CHAR33 = %000_000_000_0_0_100001_00000
CHAR34 = %000_000_000_0_0_100010_00000
CHAR35 = %000_000_000_0_0_100011_00000
CHAR36 = %000_000_000_0_0_100100_00000
CHAR37 = %000_000_000_0_0_100101_00000
CHAR38 = %000_000_000_0_0_100110_00000
CHAR39 = %000_000_000_0_0_100111_00000
CHAR40 = %000_000_000_0_0_101000_00000
CHAR41 = %000_000_000_0_0_101001_00000
CHAR42 = %000_000_000_0_0_101010_00000
CHAR43 = %000_000_000_0_0_101011_00000
CHAR44 = %000_000_000_0_0_101100_00000
CHAR45 = %000_000_000_0_0_101101_00000
CHAR46 = %000_000_000_0_0_101110_00000
CHAR47 = %000_000_000_0_0_101111_00000
CHAR48 = %000_000_000_0_0_110000_00000
CHAR49 = %000_000_000_0_0_110001_00000
SPCPAD = %000_000_000_0_1_000000_00000 'Space padded
PLUS = %000_000_000_1_0_000000_00000 'Show plus sign '+' for num > 0
COMMA = %000_000_001_0_0_000000_00000 'Comma delimiter
USCORE = %000_000_010_0_0_000000_00000 'Underscore delimiter
HEXCHAR = %011_000_000_0_0_000000_00000 'Hexadecimal prefix '$'
BINCHAR = %100_000_000_0_0_000000_00000 'Binary prefix '%'
GROUP2 = %000_001_000_0_0_000000_00000 'Group digits
GROUP3 = %000_010_000_0_0_000000_00000
GROUP4 = %000_011_000_0_0_000000_00000
GROUP5 = %000_100_000_0_0_000000_00000
GROUP6 = %000_101_000_0_0_000000_00000
GROUP7 = %000_110_000_0_0_000000_00000
GROUP8 = %000_111_000_0_0_000000_00000
'┌──────────────────────────────────────────┐
'│ Common Decimal Formatters │
'└──────────────────────────────────────────┘
DEC = %000_000_000_0_0_000000_01010 'Decimal, variable widths
DDEC = DEC+GROUP3+COMMA 'Decimal, variable widths, delimited with commas
DEC2 = DEC+CHAR2 'Decimal, fixed widths, zero padded
DEC3 = DEC+CHAR3
DEC4 = DEC+CHAR4
DEC5 = DEC+CHAR5
DEC6 = DEC+CHAR6
DEC7 = DEC+CHAR7
DEC8 = DEC+CHAR8
DEC9 = DEC+CHAR9
DEC10 = DEC+CHAR10
DEC11 = DEC+CHAR11
SDEC3 = DEC3+SPCPAD 'Decimal, fixed widths, space padded
SDEC4 = DEC4+SPCPAD
SDEC5 = DEC5+SPCPAD
SDEC6 = DEC6+SPCPAD
SDEC7 = DEC7+SPCPAD
SDEC8 = DEC8+SPCPAD
SDEC9 = DEC9+SPCPAD
SDEC10 = DEC10+SPCPAD
SDEC11 = DEC11+SPCPAD
DSDEC6 = SDEC6+GROUP3+COMMA 'Decimal, fixed widths, space padded, delimited with commas
DSDEC7 = SDEC7+GROUP3+COMMA
DSDEC8 = SDEC8+GROUP3+COMMA
DSDEC9 = SDEC9+GROUP3+COMMA
DSDEC10 = SDEC10+GROUP3+COMMA
DSDEC11 = SDEC11+GROUP3+COMMA
DSDEC12 = DEC+CHAR12+SPCPAD+GROUP3+COMMA
DSDEC13 = DEC+CHAR13+SPCPAD+GROUP3+COMMA
DSDEC14 = DEC+CHAR14+SPCPAD+GROUP3+COMMA
'┌──────────────────────────────────────────┐
'│ Common Hexadecimal Formatters │
'└──────────────────────────────────────────┘
HEX = %000_000_000_0_0_000000_10000 'Hexadecimal, variable widths
DHEX = HEX+GROUP4+USCORE 'Hexadecimal, variable widths, delimited with underscore
HEX2 = HEX+CHAR2 'Hexadecimal, fixed widths, zero padded
HEX3 = HEX+CHAR3
HEX4 = HEX+CHAR4
HEX5 = HEX+CHAR5
HEX6 = HEX+CHAR6
HEX7 = HEX+CHAR7
HEX8 = HEX+CHAR8
HEX9 = HEX+CHAR9
SHEX3 = HEX3+SPCPAD 'Hexadecimal, fixed widths, space padded
SHEX4 = HEX4+SPCPAD
SHEX5 = HEX5+SPCPAD
SHEX6 = HEX6+SPCPAD
SHEX7 = HEX7+SPCPAD
SHEX8 = HEX8+SPCPAD
SHEX9 = HEX9+SPCPAD
DHEX7 = HEX7+GROUP4+USCORE 'Hexadecimal, fixed widths, zero padded, delimited with underscore
DHEX8 = HEX8+GROUP4+USCORE
DHEX9 = HEX9+GROUP4+USCORE
DHEX10 = HEX+CHAR10+GROUP4+USCORE
DSHEX7 = DHEX7+SPCPAD 'Hexadecimal, fixed widths, space padded, delimited with underscore
DSHEX8 = DHEX8+SPCPAD
DSHEX9 = DHEX9+SPCPAD
DSHEX10 = DHEX10+SPCPAD
IHEX = HEX+HEXCHAR 'Indicated hexadecimal, variable widths
IDHEX = DHEX+HEXCHAR 'Indicated hexadecimal, variable widths, delimited with underscore
IHEX3 = HEX3+HEXCHAR 'Indicated hexadecimal, fixed widths, zero padded
IHEX4 = HEX4+HEXCHAR
IHEX5 = HEX5+HEXCHAR
IHEX6 = HEX6+HEXCHAR
IHEX7 = HEX7+HEXCHAR
IHEX8 = HEX8+HEXCHAR
IHEX9 = HEX9+HEXCHAR
IHEX10 = HEX+CHAR10+HEXCHAR
ISHEX4 = SHEX4+HEXCHAR 'Indicated hexadecimal, fixed widths, space padded
ISHEX5 = SHEX5+HEXCHAR
ISHEX6 = SHEX6+HEXCHAR
ISHEX7 = SHEX7+HEXCHAR
ISHEX8 = SHEX8+HEXCHAR
ISHEX9 = SHEX9+HEXCHAR
ISHEX10 = HEX+CHAR10+SPCPAD+HEXCHAR
IDHEX8 = DHEX8+HEXCHAR 'Indicated hexadecimal, fixed widths, zero padded, delimited with underscore
IDHEX9 = DHEX9+HEXCHAR
IDHEX10 = DHEX10+HEXCHAR
IDHEX11 = HEX+CHAR11+GROUP4+USCORE+HEXCHAR
IDSHEX8 = DSHEX8+HEXCHAR 'Indicated hexadecimal, fixed widths, space padded, delimited with underscore
IDSHEX9 = DSHEX9+HEXCHAR
IDSHEX10 = DSHEX10+HEXCHAR
IDSHEX11 = HEX+CHAR11+GROUP4+USCORE+HEXCHAR
'┌──────────────────────────────────────────┐
'│ Common Binary Formatters │
'└──────────────────────────────────────────┘
BIN = %000_000_000_0_0_000000_00010 'Binary, variable widths
DBIN = BIN+GROUP4+USCORE 'Binary, variable widths, delimited with underscores
BIN2 = BIN+CHAR2 'Binary, fixed widths, zero padded
BIN3 = BIN+CHAR3
BIN4 = BIN+CHAR4
BIN5 = BIN+CHAR5
BIN6 = BIN+CHAR6
BIN7 = BIN+CHAR7
BIN8 = BIN+CHAR8
BIN9 = BIN+CHAR9
BIN10 = BIN+CHAR10
BIN11 = BIN+CHAR11
BIN12 = BIN+CHAR12
BIN13 = BIN+CHAR13
BIN14 = BIN+CHAR14
BIN15 = BIN+CHAR15
BIN16 = BIN+CHAR16
BIN17 = BIN+CHAR17
BIN18 = BIN+CHAR18
BIN19 = BIN+CHAR19
BIN20 = BIN+CHAR20
BIN21 = BIN+CHAR21
BIN22 = BIN+CHAR22
BIN23 = BIN+CHAR23
BIN24 = BIN+CHAR24
BIN25 = BIN+CHAR25
BIN26 = BIN+CHAR26
BIN27 = BIN+CHAR27
BIN28 = BIN+CHAR28
BIN29 = BIN+CHAR29
BIN30 = BIN+CHAR30
BIN31 = BIN+CHAR31
BIN32 = BIN+CHAR32
BIN33 = BIN+CHAR33
SBIN3 = BIN3+SPCPAD 'Binary, fixed widths, space padded
SBIN4 = BIN4+SPCPAD
SBIN5 = BIN5+SPCPAD
SBIN6 = BIN6+SPCPAD
SBIN7 = BIN7+SPCPAD
SBIN8 = BIN8+SPCPAD
SBIN9 = BIN9+SPCPAD
SBIN10 = BIN10+SPCPAD
SBIN11 = BIN11+SPCPAD
SBIN12 = BIN12+SPCPAD
SBIN13 = BIN13+SPCPAD
SBIN14 = BIN14+SPCPAD
SBIN15 = BIN15+SPCPAD
SBIN16 = BIN16+SPCPAD
SBIN17 = BIN17+SPCPAD
SBIN18 = BIN18+SPCPAD
SBIN19 = BIN19+SPCPAD
SBIN20 = BIN20+SPCPAD
SBIN21 = BIN21+SPCPAD
SBIN22 = BIN22+SPCPAD
SBIN23 = BIN23+SPCPAD
SBIN24 = BIN24+SPCPAD
SBIN25 = BIN25+SPCPAD
SBIN26 = BIN26+SPCPAD
SBIN27 = BIN27+SPCPAD
SBIN28 = BIN28+SPCPAD
SBIN29 = BIN29+SPCPAD
SBIN30 = BIN30+SPCPAD
SBIN31 = BIN31+SPCPAD
SBIN32 = BIN32+SPCPAD
SBIN33 = BIN33+SPCPAD
DBIN7 = BIN7+GROUP4+USCORE 'Binary, fixed widths, zero padded, delimited with underscores
DBIN8 = BIN8+GROUP4+USCORE
DBIN9 = BIN9+GROUP4+USCORE
DBIN10 = BIN10+GROUP4+USCORE
DBIN11 = BIN11+GROUP4+USCORE
DBIN12 = BIN12+GROUP4+USCORE
DBIN13 = BIN13+GROUP4+USCORE
DBIN14 = BIN14+GROUP4+USCORE
DBIN15 = BIN15+GROUP4+USCORE
DBIN16 = BIN16+GROUP4+USCORE
DBIN17 = BIN17+GROUP4+USCORE
DBIN18 = BIN18+GROUP4+USCORE
DBIN19 = BIN19+GROUP4+USCORE
DBIN20 = BIN20+GROUP4+USCORE
DBIN21 = BIN21+GROUP4+USCORE
DBIN22 = BIN22+GROUP4+USCORE
DBIN23 = BIN23+GROUP4+USCORE
DBIN24 = BIN24+GROUP4+USCORE
DBIN25 = BIN25+GROUP4+USCORE
DBIN26 = BIN26+GROUP4+USCORE
DBIN27 = BIN27+GROUP4+USCORE
DBIN28 = BIN28+GROUP4+USCORE
DBIN29 = BIN29+GROUP4+USCORE
DBIN30 = BIN30+GROUP4+USCORE
DBIN31 = BIN31+GROUP4+USCORE
DBIN32 = BIN32+GROUP4+USCORE
DBIN33 = BIN33+GROUP4+USCORE
DBIN34 = BIN+CHAR34+GROUP4+USCORE
DBIN35 = BIN+CHAR35+GROUP4+USCORE
DBIN36 = BIN+CHAR36+GROUP4+USCORE
DBIN37 = BIN+CHAR37+GROUP4+USCORE
DBIN38 = BIN+CHAR38+GROUP4+USCORE
DBIN39 = BIN+CHAR39+GROUP4+USCORE
DBIN40 = BIN+CHAR40+GROUP4+USCORE
DSBIN7 = DBIN7+SPCPAD 'Binary, fixed widths, space padded, delimited with underscores
DSBIN8 = DBIN8+SPCPAD
DSBIN9 = DBIN9+SPCPAD
DSBIN10 = DBIN10+SPCPAD
DSBIN11 = DBIN11+SPCPAD
DSBIN12 = DBIN12+SPCPAD
DSBIN13 = DBIN13+SPCPAD
DSBIN14 = DBIN14+SPCPAD
DSBIN15 = DBIN15+SPCPAD
DSBIN16 = DBIN16+SPCPAD
DSBIN17 = DBIN17+SPCPAD
DSBIN18 = DBIN18+SPCPAD
DSBIN19 = DBIN19+SPCPAD
DSBIN20 = DBIN20+SPCPAD
DSBIN21 = DBIN21+SPCPAD
DSBIN22 = DBIN22+SPCPAD
DSBIN23 = DBIN23+SPCPAD
DSBIN24 = DBIN24+SPCPAD
DSBIN25 = DBIN25+SPCPAD
DSBIN26 = DBIN26+SPCPAD
DSBIN27 = DBIN27+SPCPAD
DSBIN28 = DBIN28+SPCPAD
DSBIN29 = DBIN29+SPCPAD
DSBIN30 = DBIN30+SPCPAD
DSBIN31 = DBIN31+SPCPAD
DSBIN32 = DBIN32+SPCPAD
DSBIN33 = DBIN33+SPCPAD
DSBIN34 = DBIN34+SPCPAD
DSBIN35 = DBIN35+SPCPAD
DSBIN36 = DBIN36+SPCPAD
DSBIN37 = DBIN37+SPCPAD
DSBIN38 = DBIN38+SPCPAD
DSBIN39 = DBIN39+SPCPAD
DSBIN40 = DBIN40+SPCPAD
IBIN = BIN+BINCHAR 'Indicated binary, variable widths
IDBIN = DBIN+BINCHAR 'Indicated binary, variable widths, delimited with underscores
IBIN3 = BIN3+BINCHAR 'Indicated binary, fixed widths, zero padded
IBIN4 = BIN4+BINCHAR
IBIN5 = BIN5+BINCHAR
IBIN6 = BIN6+BINCHAR
IBIN7 = BIN7+BINCHAR
IBIN8 = BIN8+BINCHAR
IBIN9 = BIN9+BINCHAR
IBIN10 = BIN10+BINCHAR
IBIN11 = BIN11+BINCHAR
IBIN12 = BIN12+BINCHAR
IBIN13 = BIN13+BINCHAR
IBIN14 = BIN14+BINCHAR
IBIN15 = BIN15+BINCHAR
IBIN16 = BIN16+BINCHAR
IBIN17 = BIN17+BINCHAR
IBIN18 = BIN18+BINCHAR
IBIN19 = BIN19+BINCHAR
IBIN20 = BIN20+BINCHAR
IBIN21 = BIN21+BINCHAR
IBIN22 = BIN22+BINCHAR
IBIN23 = BIN23+BINCHAR
IBIN24 = BIN24+BINCHAR
IBIN25 = BIN25+BINCHAR
IBIN26 = BIN26+BINCHAR
IBIN27 = BIN27+BINCHAR
IBIN28 = BIN28+BINCHAR
IBIN29 = BIN29+BINCHAR
IBIN30 = BIN30+BINCHAR
IBIN31 = BIN31+BINCHAR
IBIN32 = BIN32+BINCHAR
IBIN33 = BIN33+BINCHAR
IBIN34 = BIN+CHAR34+BINCHAR
ISBIN4 = SBIN4+BINCHAR 'Indicated binary, fixed widths, space padded
ISBIN5 = SBIN5+BINCHAR
ISBIN6 = SBIN6+BINCHAR
ISBIN7 = SBIN7+BINCHAR
ISBIN8 = SBIN8+BINCHAR
ISBIN9 = SBIN9+BINCHAR
ISBIN10 = SBIN10+BINCHAR
ISBIN11 = SBIN11+BINCHAR
ISBIN12 = SBIN12+BINCHAR
ISBIN13 = SBIN13+BINCHAR
ISBIN14 = SBIN14+BINCHAR
ISBIN15 = SBIN15+BINCHAR
ISBIN16 = SBIN16+BINCHAR
ISBIN17 = SBIN17+BINCHAR
ISBIN18 = SBIN18+BINCHAR
ISBIN19 = SBIN19+BINCHAR
ISBIN20 = SBIN20+BINCHAR
ISBIN21 = SBIN21+BINCHAR
ISBIN22 = SBIN22+BINCHAR
ISBIN23 = SBIN23+BINCHAR
ISBIN24 = SBIN24+BINCHAR
ISBIN25 = SBIN25+BINCHAR
ISBIN26 = SBIN26+BINCHAR
ISBIN27 = SBIN27+BINCHAR
ISBIN28 = SBIN28+BINCHAR
ISBIN29 = SBIN29+BINCHAR
ISBIN30 = SBIN30+BINCHAR
ISBIN31 = SBIN31+BINCHAR
ISBIN32 = SBIN32+BINCHAR
ISBIN33 = SBIN33+BINCHAR
ISBIN34 = BIN+CHAR34+SPCPAD+BINCHAR
IDBIN8 = DBIN8+BINCHAR 'Indicated binary, fixed widths, zero padded, delimited with underscores
IDBIN9 = DBIN9+BINCHAR
IDBIN10 = DBIN10+BINCHAR
IDBIN11 = DBIN11+BINCHAR
IDBIN12 = DBIN12+BINCHAR
IDBIN13 = DBIN13+BINCHAR
IDBIN14 = DBIN14+BINCHAR
IDBIN15 = DBIN15+BINCHAR
IDBIN16 = DBIN16+BINCHAR
IDBIN17 = DBIN17+BINCHAR
IDBIN18 = DBIN18+BINCHAR
IDBIN19 = DBIN19+BINCHAR
IDBIN20 = DBIN20+BINCHAR
IDBIN21 = DBIN21+BINCHAR
IDBIN22 = DBIN22+BINCHAR
IDBIN23 = DBIN23+BINCHAR
IDBIN24 = DBIN24+BINCHAR
IDBIN25 = DBIN25+BINCHAR
IDBIN26 = DBIN26+BINCHAR
IDBIN27 = DBIN27+BINCHAR
IDBIN28 = DBIN28+BINCHAR
IDBIN29 = DBIN29+BINCHAR
IDBIN30 = DBIN30+BINCHAR
IDBIN31 = DBIN31+BINCHAR
IDBIN32 = DBIN32+BINCHAR
IDBIN33 = DBIN33+BINCHAR
IDBIN34 = DBIN34+BINCHAR
IDBIN35 = DBIN35+BINCHAR
IDBIN36 = DBIN36+BINCHAR
IDBIN37 = DBIN37+BINCHAR
IDBIN38 = DBIN38+BINCHAR
IDBIN39 = DBIN39+BINCHAR
IDBIN40 = DBIN40+BINCHAR
IDBIN41 = BIN+CHAR41+GROUP4+USCORE+BINCHAR
IDSBIN8 = DSBIN8+BINCHAR 'Indicated binary, fixed widths, space padded, delimited with underscores
IDSBIN9 = DSBIN9+BINCHAR
IDSBIN10 = DSBIN10+BINCHAR
IDSBIN11 = DSBIN11+BINCHAR
IDSBIN12 = DSBIN12+BINCHAR
IDSBIN13 = DSBIN13+BINCHAR
IDSBIN14 = DSBIN14+BINCHAR
IDSBIN15 = DSBIN15+BINCHAR
IDSBIN16 = DSBIN16+BINCHAR
IDSBIN17 = DSBIN17+BINCHAR
IDSBIN18 = DSBIN18+BINCHAR
IDSBIN19 = DSBIN19+BINCHAR
IDSBIN20 = DSBIN20+BINCHAR
IDSBIN21 = DSBIN21+BINCHAR
IDSBIN22 = DSBIN22+BINCHAR
IDSBIN23 = DSBIN23+BINCHAR
IDSBIN24 = DSBIN24+BINCHAR
IDSBIN25 = DSBIN25+BINCHAR
IDSBIN26 = DSBIN26+BINCHAR
IDSBIN27 = DSBIN27+BINCHAR
IDSBIN28 = DSBIN28+BINCHAR
IDSBIN29 = DSBIN29+BINCHAR
IDSBIN30 = DSBIN30+BINCHAR
IDSBIN31 = DSBIN31+BINCHAR
IDSBIN32 = DSBIN32+BINCHAR
IDSBIN33 = DSBIN33+BINCHAR
IDSBIN34 = DSBIN34+BINCHAR
IDSBIN35 = DSBIN35+BINCHAR
IDSBIN36 = DSBIN36+BINCHAR
IDSBIN37 = DSBIN37+BINCHAR
IDSBIN38 = DSBIN38+BINCHAR
IDSBIN39 = DSBIN39+BINCHAR
IDSBIN40 = DSBIN40+BINCHAR
IDSBIN41 = BIN+CHAR41+SPCPAD+GROUP4+USCORE+BINCHAR
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

528
lib/glob-pst.spin Normal file
View File

@ -0,0 +1,528 @@
{{
─────────────────────────────────────────────────
File: Parallax Serial Terminal.spin
Version: 1.0
Copyright (c) 2009 Parallax, Inc.
See end of file for terms of use.
Authors: Jeff Martin, Andy Lindsay, Chip Gracey
─────────────────────────────────────────────────
}}
{
HISTORY:
This object is made for direct use with the Parallax Serial Terminal; a simple serial communication program
available with the Propeller Tool installer and also separately via the Parallax website (www.parallax.com).
This object is heavily based on FullDuplexSerialPlus (by Andy Lindsay), which is itself heavily based on
FullDuplexSerial (by Chip Gracey).
USAGE:
• Call Start, or StartRxTx, first.
• Be sure to set the Parallax Serial Terminal software to the baudrate specified in Start, and the proper COM port.
• At 80 MHz, this object properly receives/transmits at up to 250 Kbaud, or performs transmit-only at up to 1 Mbaud.
}
CON
''
'' Parallax Serial Terminal
'' Control Character Constants
''─────────────────────────────────────
CS = 16 ''CS: Clear Screen
CE = 11 ''CE: Clear to End of line
CB = 12 ''CB: Clear lines Below
HM = 1 ''HM: HoMe cursor
PC = 2 ''PC: Position Cursor in x,y
PX = 14 ''PX: Position cursor in X
PY = 15 ''PY: Position cursor in Y
NL = 13 ''NL: New Line
LF = 10 ''LF: Line Feed
ML = 3 ''ML: Move cursor Left
MR = 4 ''MR: Move cursor Right
MU = 5 ''MU: Move cursor Up
MD = 6 ''MD: Move cursor Down
TB = 9 ''TB: TaB
BS = 8 ''BS: BackSpace
BP = 7 ''BP: BeeP speaker
CON
BUFFER_LENGTH = 64 'Recommended as 64 or higher, but can be 2, 4, 8, 16, 32, 64, 128 or 256.
BUFFER_MASK = BUFFER_LENGTH - 1
MAXSTR_LENGTH = 49 'Maximum length of received numerical string (not including zero terminator).
VAR
long cog 'Cog flag/id
long rx_head '9 contiguous longs (must keep order)
long rx_tail
long tx_head
long tx_tail
long rx_pin
long tx_pin
long rxtx_mode
long bit_ticks
long buffer_ptr
byte rx_buffer[BUFFER_LENGTH] 'Receive and transmit buffers
byte tx_buffer[BUFFER_LENGTH]
byte str_buffer[MAXSTR_LENGTH+1] 'String buffer for numerical strings
PUB Start(baudrate) : okay
{{Start communication with the Parallax Serial Terminal using the Propeller's programming connection.
Waits 1 second for connection, then clears screen.
Parameters:
baudrate - bits per second. Make sure it matches the Parallax Serial Terminal's
Baud Rate field.
Returns : True (non-zero) if cog started, or False (0) if no cog is available.}}
okay := StartRxTx(31, 30, 0, baudrate)
waitcnt(clkfreq + cnt) 'Wait 1 second for PST
Clear 'Clear display
PUB StartRxTx(rxpin, txpin, mode, baudrate) : okay
{{Start serial communication with designated pins, mode, and baud.
Parameters:
rxpin - input pin; receives signals from external device's TX pin.
txpin - output pin; sends signals to external device's RX pin.
mode - signaling mode (4-bit pattern).
bit 0 - inverts rx.
bit 1 - inverts tx.
bit 2 - open drain/source tx.
bit 3 - ignore tx echo on rx.
baudrate - bits per second.
Returns : True (non-zero) if cog started, or False (0) if no cog is available.}}
stop
longfill(@rx_head, 0, 4)
longmove(@rx_pin, @rxpin, 3)
bit_ticks := clkfreq / baudrate
buffer_ptr := @rx_buffer
okay := cog := cognew(@entry, @rx_head) + 1
PUB Stop
{{Stop serial communication; frees a cog.}}
if cog
cogstop(cog~ - 1)
longfill(@rx_head, 0, 9)
PUB Char(bytechr)
{{Send single-byte character. Waits for room in transmit buffer if necessary.
Parameter:
bytechr - character (ASCII byte value) to send.}}
repeat until (tx_tail <> ((tx_head + 1) & BUFFER_MASK))
tx_buffer[tx_head] := bytechr
tx_head := (tx_head + 1) & BUFFER_MASK
if rxtx_mode & %1000
CharIn
PUB Chars(bytechr, count)
{{Send multiple copies of a single-byte character. Waits for room in transmit buffer if necessary.
Parameters:
bytechr - character (ASCII byte value) to send.
count - number of bytechrs to send.}}
repeat count
Char(bytechr)
PUB CharIn : bytechr
{{Receive single-byte character. Waits until character received.
Returns: $00..$FF}}
repeat while (bytechr := RxCheck) < 0
PUB Str(stringptr)
{{Send zero terminated string.
Parameter:
stringptr - pointer to zero terminated string to send.}}
repeat strsize(stringptr)
Char(byte[stringptr++])
PUB StrIn(stringptr)
{{Receive a string (carriage return terminated) and stores it (zero terminated) starting at stringptr.
Waits until full string received.
Parameter:
stringptr - pointer to memory in which to store received string characters.
Memory reserved must be large enough for all string characters plus a zero terminator.}}
StrInMax(stringptr, -1)
PUB StrInMax(stringptr, maxcount)
{{Receive a string of characters (either carriage return terminated or maxcount in length) and stores it (zero terminated)
starting at stringptr. Waits until either full string received or maxcount characters received.
Parameters:
stringptr - pointer to memory in which to store received string characters.
Memory reserved must be large enough for all string characters plus a zero terminator (maxcount + 1).
maxcount - maximum length of string to receive, or -1 for unlimited.}}
repeat while (maxcount--) 'While maxcount not reached
if (byte[stringptr++] := CharIn) == NL 'Get chars until NL
quit
byte[stringptr+(byte[stringptr-1] == NL)]~ 'Zero terminate string; overwrite NL or append 0 char
PUB Dec(value) | i, x
{{Send value as decimal characters.
Parameter:
value - byte, word, or long value to send as decimal characters.}}
x := value == NEGX 'Check for max negative
if value < 0
value := ||(value+x) 'If negative, make positive; adjust for max negative
Char("-") 'and output sign
i := 1_000_000_000 'Initialize divisor
repeat 10 'Loop for 10 digits
if value => i
Char(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative
value //= i 'and digit from value
result~~ 'flag non-zero found
elseif result or i == 1
Char("0") 'If zero digit (or only digit) output it
i /= 10 'Update divisor
PUB DecIn : value
{{Receive carriage return terminated string of characters representing a decimal value.
Returns: the corresponding decimal value.}}
StrInMax(@str_buffer, MAXSTR_LENGTH)
value := StrToBase(@str_buffer, 10)
PUB Bin(value, digits)
{{Send value as binary characters up to digits in length.
Parameters:
value - byte, word, or long value to send as binary characters.
digits - number of binary digits to send. Will be zero padded if necessary.}}
value <<= 32 - digits
repeat digits
Char((value <-= 1) & 1 + "0")
PUB BinIn : value
{{Receive carriage return terminated string of characters representing a binary value.
Returns: the corresponding binary value.}}
StrInMax(@str_buffer, MAXSTR_LENGTH)
value := StrToBase(@str_buffer, 2)
PUB Hex(value, digits)
{{Send value as hexadecimal characters up to digits in length.
Parameters:
value - byte, word, or long value to send as hexadecimal characters.
digits - number of hexadecimal digits to send. Will be zero padded if necessary.}}
value <<= (8 - digits) << 2
repeat digits
Char(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB HexIn : value
{{Receive carriage return terminated string of characters representing a hexadecimal value.
Returns: the corresponding hexadecimal value.}}
StrInMax(@str_buffer, MAXSTR_LENGTH)
value := StrToBase(@str_buffer, 16)
PUB Clear
{{Clear screen and place cursor at top-left.}}
Char(CS)
PUB ClearEnd
{{Clear line from cursor to end of line.}}
Char(CE)
PUB ClearBelow
{{Clear all lines below cursor.}}
Char(CB)
PUB Home
{{Send cursor to home position (top-left).}}
Char(HM)
PUB Position(x, y)
{{Position cursor at column x, row y (from top-left).}}
Char(PC)
Char(x)
Char(y)
PUB PositionX(x)
{{Position cursor at column x of current row.}}
Char(PX)
Char(x)
PUB PositionY(y)
{{Position cursor at row y of current column.}}
Char(PY)
Char(y)
PUB NewLine
{{Send cursor to new line (carriage return plus line feed).}}
Char(NL)
PUB LineFeed
{{Send cursor down to next line.}}
Char(LF)
PUB MoveLeft(x)
{{Move cursor left x characters.}}
repeat x
Char(ML)
PUB MoveRight(x)
{{Move cursor right x characters.}}
repeat x
Char(MR)
PUB MoveUp(y)
{{Move cursor up y lines.}}
repeat y
Char(MU)
PUB MoveDown(y)
{{Move cursor down y lines.}}
repeat y
Char(MD)
PUB Tab
{{Send cursor to next tab position.}}
Char(TB)
PUB Backspace
{{Delete one character to left of cursor and move cursor there.}}
Char(BS)
PUB Beep
{{Play bell tone on PC speaker.}}
Char(BP)
PUB RxCount : count
{{Get count of characters in receive buffer.
Returns: number of characters waiting in receive buffer.}}
count := rx_head - rx_tail
count -= BUFFER_LENGTH*(count < 0)
PUB RxFlush
{{Flush receive buffer.}}
repeat while rxcheck => 0
PRI RxCheck : bytechr
{Check if character received; return immediately.
Returns: -1 if no byte received, $00..$FF if character received.}
bytechr~~
if rx_tail <> rx_head
bytechr := rx_buffer[rx_tail]
rx_tail := (rx_tail + 1) & BUFFER_MASK
PRI StrToBase(stringptr, base) : value | chr, index
{Converts a zero terminated string representation of a number to a value in the designated base.
Ignores all non-digit characters (except negative (-) when base is decimal (10)).}
value := index := 0
repeat until ((chr := byte[stringptr][index++]) == 0)
chr := -15 + --chr & %11011111 + 39*(chr > 56) 'Make "0"-"9","A"-"F","a"-"f" be 0 - 15, others out of range
if (chr > -1) and (chr < base) 'Accumulate valid values into result; ignore others
value := value * base + chr
if (base == 10) and (byte[stringptr] == "-") 'If decimal, address negative sign; ignore otherwise
value := - value
DAT
'***********************************
'* Assembly language serial driver *
'***********************************
org
'
'
' Entry
'
entry mov t1,par 'get structure address
add t1,#4 << 2 'skip past heads and tails
rdlong t2,t1 'get rx_pin
mov rxmask,#1
shl rxmask,t2
add t1,#4 'get tx_pin
rdlong t2,t1
mov txmask,#1
shl txmask,t2
add t1,#4 'get rxtx_mode
rdlong rxtxmode,t1
add t1,#4 'get bit_ticks
rdlong bitticks,t1
add t1,#4 'get buffer_ptr
rdlong rxbuff,t1
mov txbuff,rxbuff
add txbuff,#BUFFER_LENGTH
test rxtxmode,#%100 wz 'init tx pin according to mode
test rxtxmode,#%010 wc
if_z_ne_c or outa,txmask
if_z or dira,txmask
mov txcode,#transmit 'initialize ping-pong multitasking
'
'
' Receive
'
receive jmpret rxcode,txcode 'run chunk of tx code, then return
test rxtxmode,#%001 wz 'wait for start bit on rx pin
test rxmask,ina wc
if_z_eq_c jmp #receive
mov rxbits,#9 'ready to receive byte
mov rxcnt,bitticks
shr rxcnt,#1
add rxcnt,cnt
:bit add rxcnt,bitticks 'ready next bit period
:wait jmpret rxcode,txcode 'run chunk of tx code, then return
mov t1,rxcnt 'check if bit receive period done
sub t1,cnt
cmps t1,#0 wc
if_nc jmp #:wait
test rxmask,ina wc 'receive bit on rx pin
rcr rxdata,#1
djnz rxbits,#:bit
shr rxdata,#32-9 'justify and trim received byte
and rxdata,#$FF
test rxtxmode,#%001 wz 'if rx inverted, invert byte
if_nz xor rxdata,#$FF
rdlong t2,par 'save received byte and inc head
add t2,rxbuff
wrbyte rxdata,t2
sub t2,rxbuff
add t2,#1
and t2,#BUFFER_MASK
wrlong t2,par
jmp #receive 'byte done, receive next byte
'
'
' Transmit
'
transmit jmpret txcode,rxcode 'run chunk of rx code, then return
mov t1,par 'check for head <> tail
add t1,#2 << 2
rdlong t2,t1
add t1,#1 << 2
rdlong t3,t1
cmp t2,t3 wz
if_z jmp #transmit
add t3,txbuff 'get byte and inc tail
rdbyte txdata,t3
sub t3,txbuff
add t3,#1
and t3,#BUFFER_MASK
wrlong t3,t1
or txdata,#$100 'ready byte to transmit
shl txdata,#2
or txdata,#1
mov txbits,#11
mov txcnt,cnt
:bit test rxtxmode,#%100 wz 'output bit on tx pin
test rxtxmode,#%010 wc 'according to mode
if_z_and_c xor txdata,#1
shr txdata,#1 wc
if_z muxc outa,txmask
if_nz muxnc dira,txmask
add txcnt,bitticks 'ready next cnt
:wait jmpret txcode,rxcode 'run chunk of rx code, then return
mov t1,txcnt 'check if bit transmit period done
sub t1,cnt
cmps t1,#0 wc
if_nc jmp #:wait
djnz txbits,#:bit 'another bit to transmit?
jmp #transmit 'byte done, transmit next byte
'
'
' Uninitialized data
'
t1 res 1
t2 res 1
t3 res 1
rxtxmode res 1
bitticks res 1
rxmask res 1
rxbuff res 1
rxdata res 1
rxbits res 1
rxcnt res 1
rxcode res 1
txmask res 1
txbuff res 1
txdata res 1
txbits res 1
txcnt res 1
txcode res 1
{{
┌──────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────┘
}}

883
lib/glob-sdspi.spin Normal file
View File

@ -0,0 +1,883 @@
{{
Modified Tiny Basic for use with Propeller Demo Board and Hydra.
I2C and SPI driver initialization & interface object derived from Propeller OS.
Copyright (c) 2009 Michael Green. See end of file for terms of use.
}}
'' 2006/09/24 - Corrected action table for i2cRead0Cmd
'' 2006/10/02 - Improved assembly comments. Changed i2cReset, i2cStop
'' 2006/11/02 - Changed data setup time. Changed i2cReset timing
'' 2006/11/03 - Changed read/write method speed to 100KHz
'' 2006/11/04 - Added checkPresence, writeWait, and computeTimes methods
'' 2006/11/06 - Limited boot loading to 32K - 16 (OS uses last 16 bytes)
'' Added ioVerifyCmd and verifyEEPROM method
'' 2006/11/09 - Modified boot and verify to use the minimum of the actual
'' length of the program stored in vbase ($0008) or the
'' specified byte count.
'' Note also that these routines don't know about option bits.
'' 2006/11/10 - Now control block address is passed to start routine
'' 2007/01/09 - Added SPI routines for SD card FAT access
'' 2007/01/13 - Corrected checksum when ioBoot or ioVerify
'' 2007/01/13 - Stores stack marker & clears VAR area on ioBootCmd
'' 2007/02/06 - Stores stack marker & clears VAR area on ioSpiBoot
'' 2007/02/13 - Changed the way verify mode was done, combined code
'' 2007/02/20 - Added ioStopLdr option to stop the loader's cog
'' 2007/02/22 - Corrected bootSDCard. Needs start and initSDCard calls first.
'' 2009/04/04 - spiDoStop modified per Cluso99 to turn off card
'' 2009/07/21 - I2C setup times modified per Nick Mueller's timing tests
'' Default I2C bus timing changed to 400KHz. Thanks Nick.
'' This portion is normally run only once during initialization and the driver remains
'' resident in a cog. These routines can be used completely independently of the rest
'' of the Propeller OS. The start routine here expects the address of a 2 long area
'' to be used for passing information to the I/O routines in the COG. This area should
'' be located in an area of memory not expected to be overlaid by data or a program that
'' might be loaded since the COG routines will be accessing this information after an
'' operation has completed.
'' This object provides an I2C EEPROM read/write routine that can handle both 100KHz and
'' 400KHz bus speeds and EEPROM page sizes of 64, 128, or 256 bytes (or no paging/no delay
'' as with Ramtron serial RAM). The SPIN interpreter can be started after reading, either
'' in the same COG used by these routines or in a free COG. The control information is
'' passed in a 2 long parameter block whose address is passed to the COG when it is started.
'' The parameter block is updated when the operation is completed. Note that these are shown
'' here as they appear in a long value rather than the order of the bytes in memory.
'' -------------------------------------------------------------------
'' | cmd/status | I/O pin / device / address |
'' -------------------------------------------------------------------
'' | byte count | HUB address |
'' -------------------------------------------------------------------
'' The EEPROM address is in the same format used by other routines with the I/O pin pair
'' in bits 21..19, the device address in bits 18..16, and the 64K address in bits 15..0.
'' Note that the I/O pin pair is the number of the SCL pin divided by 2. The SDA pin is
'' always the next higher numbered pin. The command code is in the low order bits of the
'' high order byte of the first long (see ioCmdMask). This is always non-zero to indicate
'' that a command is to be performed by the COG routines. When the command is finished,
'' this is set to zero. The errorFlag bit is set to one if a NAK was read after a write
'' transfer. This is the only error reported by these routines. A read operation and
'' zero-length writes do involve several write transfers for addressing, but the data
'' read transfer has no error checking. When the command is completed, the device address,
'' byte count, and HUB address are all updated to their values at that time. For the
'' verify operation (ioVerifyCmd), an error is reported if the checksum is not zero and
'' the HUB address field is not incremented. It may be used for some other checksum
'' reporting in the future.
'' The pins used for the boot EEPROM I2C bus (at least on Parallax's Demo Board) do not
'' have a pullup on SCL. This requires that SCL be driven both high and low. If the bus
'' used is on pins 28 and 29, SCL is actively driven at all times.
'' These EEPROM read/write routines do not provide for waiting for the write to complete
'' nor do they check for paged writes. All bytes in a multi-byte write must lie within
'' a single EEPROM page since the EEPROM write address counter wraps around at a page
'' boundary. Similarly, for multi-byte reads, all requested bytes must lie within the
'' same device since the sequential read counter wraps around at the device boundary.
'' Command codes are provided for devices with zero, one, or two address bytes following
'' the device selection byte. As for all I2C devices, addressing is done using write
'' mode and the device is reselected in read mode after the last address byte. In the
'' case of ioRead0Cmd, the device is initially selected in read mode. For 8-bit addresses,
'' the device select code is taken from bits 15-8 of the address value. For the case
'' without address bytes, the device select code is taken from bits 7-0 of the address value.
'' These device select codes must have their least significant bit set to zero (for write
'' mode) except in the case of ioRead0Cmd where it must be set to one for proper operation.
'' SPI data is handled a little differently. For ioSpiInit, the 6 bit pin numbers for DO,
'' Clk, DI, and CS are given from MSB to LSB of the 24 bit address field of the command and
'' are used for all further I/O operations (until an ioSpiStop is done).
CON
'' Command code and error information for I2C driver
'' (For convenience in using just OS_loaderInit, these are included here. The "master"
'' copies are considered the ones in OS_loader and these must be kept up-to-date).
ioReadCmd = %00000001 ' Read from EEPROM to HUB RAM (16 bit addresses)
ioWriteCmd = %00000010 ' Write to EEPROM from HUB RAM (16 bit addresses)
ioRead1Cmd = %00000011 ' Read from a device with only 8-bit addresses
ioWrite1Cmd = %00000100 ' Write to a device with only 8-bit addresses
ioRead0Cmd = %00000101 ' Read from a device without address bytes
ioWrite0Cmd = %00000110 ' Write to a device without address bytes
ioBootCmd = %00001000 ' Read from EEPROM to HUB RAM, then start a
' new SPIN interpreter in the COG whose ID is
' supplied in the lower 3 bits of this command
' This COG is stopped before the read is done
' unless it's the one used to execute the loader
ioSpiInit = %00010000 ' Initialize the specified SPI bus and SD card
ioSpiStop = %00010001 ' Change all SD card pins to inputs
ioSpiRead = %00010010 ' Read one or more bytes from the SD card
ioSpiWrite = %00010011 ' Write one or more bytes from the SD card
ioSpiBoot = %00011000 ' Like ioBootCmd, but uses ioSpiRead for loading
ioCmdMask = %00011111 ' Used to mask off command bits
ioSpiMask = %00010000 ' Used to test for SPI command codes
' Options for commands
ioNoStore = %00100000 ' If set, data is not stored into main memory
' If ioBootCmd or ioSpiBoot, no cogs are
' stopped and a new cog is not started.
ioLowSpeed = %01000000 ' If set, I2C runs at 100KHz rather than 400KHz
ioStopLdr = %10000000 ' If set, the loader's cog is stopped after a boot
' Return status
ioWriteErr = %10000000 ' An error occurred during an I2C write (NAK)
ioTestRdy = ioCmdMask << 24 ' Used to test 1st control long for ready
ioTestErr = ioWriteErr << 24 ' Used to test 1st control long for write error
'' Other constants from OS_loader
i2cBootSCL = 28 ' Boot EEPROM SCL pin
bootAddr = i2cBootSCL << 18 ' Address of boot EEPROM
clkfreqVal = $0000 ' Current CLKFREQ value stored here
clksetVal = $0004 ' Current CLKSET value stored here
chksumVal = $0005 ' Checksum over memory stored here
vbase = $0008 ' Length of Spin program loaded (# longs * 4)
dbase = $000A ' Address of start of stack (marker below)
VAR
long cog, control
PUB bootEEPROM(addr) | t, c0, c1 '' Load and run a new SPIN program
if not start(@c0) ' Start up the I/O routines using a
abort ' local control block
long[control][1] := 0 ' Check for the presence of EEPROM
long[control][0] := ioReadCmd << 24 | (addr & $FFFFFF)
repeat while long[control][0] & ioTestRdy ' Wait for check to complete and
if long[control][0] & ioTestErr ' abort if there's an error
abort
repeat t from 0 to 7 ' Stop all COGs except this one and
if (t <> cogid) and (t <> (cog-1)) ' the one with the I2C driver in it
cogstop(t)
t := ioBootCmd | ioStopLdr | cogid ' Tell the I2C driver to load 32K
long[control][1] := $80000000 ' into HUB RAM after stopping
long[control][0] := (t << 24) | (addr & $FFFFFF) ' this calling cog
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB readEEPROM(addr,buffer,count) | t '' Read a block from EEPROM to RAM
t := ioReadCmd
repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish
long[control][1] := (count << 16) | (buffer & $FFFF)
long[control][0] := (t << 24) | (addr & $FFFFFF)
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB writeEEPROM(addr,buffer,count) | t '' Write a block to EEPROM from RAM
t := ioWriteCmd
repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish
long[control][1] := (count << 16) | (buffer & $FFFF)
long[control][0] := (t << 24) | (addr & $FFFFFF)
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB checkPresence(addr) | t
'' This routine checks to be sure there is an I2C bus and an EEPROM at the
'' specified address. Note that this routine cannot distinguish between a
'' 32Kx8 and a 64Kx8 EEPROM since the 16th address bit is a "don't care"
'' for the 32Kx8 devices. Return true if EEPROM present, false otherwise.
t := ioReadCmd
repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish
long[control][1] := 0 ' Attempt to address the device
long[control][0] := (t << 24) | (addr & $FFFFFF)
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) == 0 ' Return false on error
PUB writeWait(addr) | t '' Wait for EEPROM to complete write
t := cnt
repeat until checkPresence(addr) ' Maximum wait time is 20ms
if (cnt - t) > (clkfreq / 50)
return true ' Return true if a timeout occurred
return false ' Otherwise return false
PUB computeTimes '' Set up timing constants in assembly
' (Done this way to avoid overflow)
i2cDataSet1 := ((clkfreq / 10000) * 900) / 100000 ' Data setup time - 900ns (100KHz)
i2cClkLow1 := ((clkfreq / 10000) * 4700) / 100000 ' Clock low time - 4700ns (100KHz)
i2cClkHigh1 := ((clkfreq / 10000) * 4000) / 100000 ' Clock high time - 4000ns (100KHz)
i2cDataSet4 := ((clkfreq / 10000) * 550) / 100000 ' Data setup time - 550ns (400KHz)
i2cClkLow4 := ((clkfreq / 10000) * 1300) / 100000 ' Clock low time - 1300ns (400KHz)
i2cClkHigh4 := ((clkfreq / 10000) * 1000) / 100000 ' Clock high time - 1000ns (400KHz)
i2cPause := clkfreq / 100000 ' Pause between checks for operations
PUB initSDCard(DO,Clk,DI,CS) | t '' Initialize SD card access
t := cnt
repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish
long[control][1] := 0
long[control][0] := ioSpiInit << 24 | DO << 18 | Clk << 12 | DI << 6 | CS
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB stopSDCard '' Stop SD card access
repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish
long[control][1] := 0
long[control][0] := ioSpiStop << 24
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB readSDCard(addr,buffer,count) '' Read block(s) from SD card to RAM
repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish
long[control][1] := (count << 16) | (buffer & $FFFF)
long[control][0] := (ioSpiRead << 24) | (addr & $FFFFFF)
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB writeSDCard(addr,buffer,count) '' Write block(s) to SD card from RAM
repeat while long[control][0] & ioTestRdy ' Wait for previous I/O to finish
long[control][1] := (count << 16) | (buffer & $FFFF)
long[control][0] := (ioSpiWrite << 24) | (addr & $FFFFFF)
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB bootSDCard(addr,count) | t '' Boot from an SD card
if count < 16 ' Must load at least 16 bytes
return true
repeat t from 0 to 7 ' Stop all COGs except this one and
if (t <> cogid) and (t <> (cog-1)) ' the one with the I2C/SPI driver
cogstop(t)
t := ioSpiBoot | ioStopLdr | cogid ' Tell the SD card driver to load
long[control][1] := count << 16 ' into HUB RAM after stopping
long[control][0] := (t << 24) | (addr & $FFFFFF) ' this calling cog
repeat while long[control][0] & ioTestRdy ' Wait for this to finish
return (long[control][0] & ioTestErr) <> 0 ' Return any error code
PUB start(ctrlBlk) | t '' Start the I2C I/O driver (standalone)
control := ctrlBlk '' using address of 2 longs for control
stop ' Stop a previous copy
computeTimes
long[control][0] := 0 ' Initialize the control block
long[control][1] := 0
cog := cognew(@i2cEntryPoint,control) + 1 ' Start a new cog with the I2C driver
return cog > 0 ' Indicate success
PUB stop '' Stop the I2C I/O driver (standalone)
if cog > 0
cogstop(cog - 1)
PUB getControl(i) '' Return a long from the control block
return long[control][i] ' Check for operation completed first
PUB setControl(i,value) '' Set value of a long in the control block
long[control][i] := value ' Always set the first long last
DAT
org 0
i2cEntryPoint mov i2cTemp,i2cPause
add i2cTemp,CNT ' Wait 10us before checking
waitcnt i2cTemp,#0
i2cNewOpFetch rdlong i2cAddr,PAR ' Fetch control information
mov i2cCmd,i2cAddr
shr i2cCmd,#24 ' Isolate command code
mov Options,i2cCmd
and i2cAddr,i2cAddrMask ' Only need address at this point
and i2cCmd,#ioCmdMask wz
if_z jmp #i2cEntryPoint ' Wait for a new operation
mov i2cTemp,PAR
add i2cTemp,#4 ' Now get 2nd long of packet
rdlong i2cCount,i2cTemp
mov i2cBufAdr,i2cCount ' Byte count
rdlong SaveClkFreq,#clkfreqVal ' Save clock frequency and mode
shr i2cCount,#16
and i2cBufAdr,i2cWordMask ' HUB RAM address of buffer
rdbyte SaveClkMode,#clksetVal
movs ShiftData,#0 ' Initialize for saving Preamble
mov StoreLocal,initStore ' on I2C and SPI reads
mov Preamble+0,#0
mov Preamble+1,#0
mov Preamble+2,#0
mov Preamble+3,#0
mov CheckSum,#$EC ' Adjust checksum for stack marker
test Options,#ioNoStore wc
test i2cCmd,#ioBootCmd wz
if_nz_and_nc mov i2cTemp,i2cCmd ' Stop the caller's COG unless
if_nz_and_nc and i2cTemp,#%111 ' it's this one
if_nz_and_nc cogid i2cCogId
if_nz_and_nc cmp i2cCogId,i2cTemp wz
if_nz_and_nc cogstop i2cTemp
test i2cCmd,#ioSpiMask wz ' Check for SPI commands
if_nz jmp #spiEntryPoint
movs :getAction,i2cCmd ' Get command specific action
test i2cCmd,#ioBootCmd wz ' bit sequence. ioBootCmd is
if_nz movs :getAction,#ioReadCmd ' treated as ioReadCmd here
add :getAction,#ActionTbl
mov i2cDataSet,i2cDataSet1
mov i2cClkLow,i2cClkLow1
mov i2cClkHigh,i2cClkHigh1
:getAction mov Action,0-0
test Options,#ioLowSpeed wc ' Set bus speed based on option
if_nc mov i2cDataSet,i2cDataSet4
if_nc mov i2cClkLow,i2cClkLow4
if_nc mov i2cClkHigh,i2cClkHigh4
mov i2cTemp,i2cAddr
shr i2cTemp,#18 ' Determine bit masks for
and i2cTemp,#%11110 ' I/O pins for I2C bus
mov i2cSCL,#1
shl i2cSCL,i2cTemp
mov i2cSDA,i2cSCL ' SDA is next higher pin
shl i2cSDA,#1
test FirstCall,i2cSCL wz ' Is this our first call?
andn FirstCall,i2cSCL ' if so, do a reset
if_nz call #i2cReset
call #i2cStart ' Do a start sequence
test Action,#%000000001 wz
if_z jmp #:skipAction0
mov i2cData,i2cAddr ' Construct a device select
shr i2cData,#15 ' code for EEPROM write mode
and i2cData,#%00001110 ' with 2 address bytes
or i2cData,#%10100000
mov i2cMask,#%10000000
call #i2cWrite ' Send device select code
if_c jmp #:doStop ' Failure if NAK received
:skipAction0 test Action,#%000000010 wz
if_z jmp #:skipAction1
mov i2cData,i2cAddr ' First address byte is most
shr i2cData,#8 ' significant byte of address
mov i2cMask,#%10000000
call #i2cWrite ' Send first address byte
if_c jmp #:doStop ' Failure if NAK received
:skipAction1 test Action,#%000000100 wz
if_z jmp #:skipAction2
mov i2cData,i2cAddr ' Second address byte is least
mov i2cMask,#%10000000 ' significant byte of address
call #i2cWrite ' Send second address byte
if_c jmp #:doStop ' Failure if NAK received
:skipAction2 tjz i2cCount,#:doStop ' If byte count == 0, we're done
test Action,#%000001000 wz
if_nz call #i2cStart ' Do a start sequence if readdressing
:doReadWrite test Action,#%000010000 wz
if_nz rdbyte i2cData,i2cBufAdr ' If writing, fetch the data value
if_nz add i2cBufAdr,#1 ' and increment the hub address
test Action,#%000100000 wz
if_z jmp #:skipAction5
mov i2cData,i2cAddr ' If reading, construct a device select
shr i2cData,#15 ' code for EEPROM read mode with
and i2cData,#%00001110 ' 2 address bytes
or i2cData,#%10100001
:skipAction5 test Action,#%001000000 wz
if_z jmp #:skipAction6
mov i2cData,i2cAddr ' If reading using a single byte address
shr i2cData,#8 ' construct a device select code for
or i2cData,#%00000001 ' read mode given one for write mode
:skipAction6 test Action,#%010000000 wz
if_z jmp #:skipAction7
mov i2cMask,#%10000000 ' Either readdress device for reading
call #i2cWrite ' or write a data value at this point
if_c jmp #:doStop ' Failure if NAK received
:skipAction7 test Action,#%100000000 wz
if_z jmp #:skipAction8
cmp i2cCount,#2 wc ' Carry true if this is the last byte
mov i2cMask,#%10000000
mov i2cData,#0
call #i2cRead
call #StoreData ' Now force carry false to show success
or i2cZero,#0 nr,wc
andn Action,#%011100000 ' No readdressing on subsequent reads
:skipAction8 add i2cAddr,#1
djnz i2cCount,#:doReadWrite ' Repeat for number of bytes requested
:doStop call #i2cStop
if_c or i2cAddr,errorFlag ' Carry true indicates error
jmp #checkEndIO
'' Low level I2C routines. These are designed to work either with a standard I2C bus
'' (with pullups on both SCL and SDA) or the Propellor Demo Board (with a pullup only
'' on SDA). Timing can be set by the caller to 100KHz or 400KHz.
'' Do I2C Reset Sequence. Clock up to 9 cycles. Look for SDA high while SCL
'' is high. Device should respond to next Start Sequence. Leave SCL high.
i2cReset andn dira,i2cSDA ' Pullup drive SDA high
mov i2cBitCnt,#9 ' Number of clock cycles
mov i2cTime,i2cClkLow
add i2cTime,cnt ' Allow for minimum SCL low
:i2cResetClk andn outa,i2cSCL ' Active drive SCL low
or dira,i2cSCL
waitcnt i2cTime,i2cClkHigh
test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus
if_nz or outa,i2cSCL ' Active drive SCL high
if_nz or dira,i2cSCL
if_z andn dira,i2cSCL ' Pullup drive SCL high
waitcnt i2cTime,i2cClkLow ' Allow minimum SCL high
test i2cSDA,ina wz ' Stop if SDA is high
if_z djnz i2cBitCnt,#:i2cResetClk ' Stop after 9 cycles
i2cReset_ret ret ' Should be ready for Start
'' Do I2C Start Sequence. This assumes that SDA is a floating input and
'' SCL is also floating, but may have to be actively driven high and low.
'' The start sequence is where SDA goes from HIGH to LOW while SCL is HIGH.
i2cStart andn dira,i2cSDA ' Pullup drive SDA high
andn outa,i2cSDA ' SDA set to drive low
mov i2cTime,i2cClkLow
add i2cTime,cnt ' Allow for bus free time
waitcnt i2cTime,i2cClkHigh
test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus
if_nz or outa,i2cSCL ' Active drive SCL high
if_nz or dira,i2cSCL
if_z andn dira,i2cSCL ' Pullup drive SCL high
waitcnt i2cTime,i2cClkHigh ' Allow for start setup time
or dira,i2cSDA ' Active drive SDA low
waitcnt i2cTime,#0 ' Allow for start hold time
andn outa,i2cSCL ' Active drive SCL low
or dira,i2cSCL
i2cStart_ret ret
'' Do I2C Stop Sequence. This assumes that SCL is low and SDA is indeterminant.
'' The stop sequence is where SDA goes from LOW to HIGH while SCL is HIGH.
'' i2cStart must have been called prior to calling this routine for initialization.
'' The state of the (c) flag is maintained so a write error can be reported.
i2cStop or dira,i2cSDA ' Active drive SDA low
mov i2cTime,i2cClkLow
add i2cTime,cnt ' Wait for minimum clock low
waitcnt i2cTime,i2cClkLow
test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus
if_nz or outa,i2cSCL ' Active drive SCL high
if_nz or dira,i2cSCL
if_z andn dira,i2cSCL ' Pullup drive SCL high
waitcnt i2cTime,i2cClkHigh ' Wait for minimum setup time
andn dira,i2cSDA ' Pullup drive SDA high
waitcnt i2cTime,#0 ' Allow for bus free time
andn dira,i2cSCL ' Leave SCL and SDA high
i2cStop_ret ret
'' Write I2C data. This assumes that i2cStart has been called and that SCL is low,
'' SDA is indeterminant. The (c) flag will be set on exit from ACK/NAK with ACK == false
'' and NAK == true. Bytes are handled in "little-endian" order so these routines can be
'' used with words or longs although the bits are in msb..lsb order.
i2cWrite mov i2cBitCnt,#8
mov i2cTime,i2cClkLow
add i2cTime,cnt ' Wait for minimum SCL low
:i2cWriteBit waitcnt i2cTime,i2cDataSet
test i2cData,i2cMask wz
if_z or dira,i2cSDA ' Copy data bit to SDA
if_nz andn dira,i2cSDA
waitcnt i2cTime,i2cClkHigh ' Wait for minimum setup time
test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus
if_nz or outa,i2cSCL ' Active drive SCL high
if_nz or dira,i2cSCL
if_z andn dira,i2cSCL ' Pullup drive SCL high
waitcnt i2cTime,i2cClkLow
andn outa,i2cSCL ' Active drive SCL low
or dira,i2cSCL
ror i2cMask,#1 ' Go do next bit if not done
djnz i2cBitCnt,#:i2cWriteBit
andn dira,i2cSDA ' Switch SDA to input and
waitcnt i2cTime,i2cClkHigh ' wait for minimum SCL low
test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus
if_nz or outa,i2cSCL ' Active drive SCL high
if_nz or dira,i2cSCL
if_z andn dira,i2cSCL ' Pullup drive SCL high
waitcnt i2cTime,#0 ' Wait for minimum high time
test i2cSDA,ina wc ' Sample SDA (ACK/NAK) then
andn outa,i2cSCL ' active drive SCL low
or dira,i2cSCL
or dira,i2cSDA ' Leave SDA low
rol i2cMask,#16 ' Prepare for multibyte write
i2cWrite_ret ret
'' Read I2C data. This assumes that i2cStart has been called and that SCL is low,
'' SDA is indeterminant. ACK/NAK will be copied from the (c) flag on entry with
'' ACK == low and NAK == high. Bytes are handled in "little-endian" order so these
'' routines can be used with words or longs although the bits are in msb..lsb order.
i2cRead mov i2cBitCnt,#8
andn dira,i2cSDA ' Make sure SDA is set to input
mov i2cTime,i2cClkLow
add i2cTime,cnt ' Wait for minimum SCL low
:i2cReadBit waitcnt i2cTime,i2cClkHigh
test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus
if_nz or outa,i2cSCL ' Active drive SCL high
if_nz or dira,i2cSCL
if_z andn dira,i2cSCL ' Pullup drive SCL high
waitcnt i2cTime,i2cClkLow ' Wait for minimum clock high
test i2cSDA,ina wz ' Sample SDA for data bits
andn outa,i2cSCL ' Active drive SCL low
or dira,i2cSCL
if_nz or i2cData,i2cMask ' Accumulate data bits
if_z andn i2cData,i2cMask
ror i2cMask,#1 ' Shift the bit mask and
djnz i2cBitCnt,#:i2cReadBit ' continue until done
waitcnt i2cTime,i2cDataSet ' Wait for end of SCL low
if_c andn dira,i2cSDA ' Copy the ACK/NAK bit to SDA
if_nc or dira,i2cSDA
waitcnt i2cTime,i2cClkHigh ' Wait for minimum setup time
test i2cBootSCLm,i2cSCL wz ' Check for boot I2C bus
if_nz or outa,i2cSCL ' Active drive SCL high
if_nz or dira,i2cSCL
if_z andn dira,i2cSCL ' Pullup drive SCL high
waitcnt i2cTime,#0 ' Wait for minimum clock high
andn outa,i2cSCL ' Active drive SCL low
or dira,i2cSCL
or dira,i2cSDA ' Leave SDA low
rol i2cMask,#16 ' Prepare for multibyte read
i2cRead_ret ret
'' SPI routines for Rokicki's SD card FAT file system driver
spiEntryPoint test i2cCmd,#ioBootCmd wc ' Check for boot
if_c jmp #spiDoRead ' (Treat like read)
cmp i2cCmd,#ioSpiStop wc,wz
if_c jmp #spiDoInit ' Decode operation
if_z jmp #spiDoStop
cmp i2cCmd,#ioSpiWrite wc
if_c jmp #spiDoRead
jmp #spiDoWrite
'' Initialize SPI communications. The pin numbers of the 4 I/O pins are
'' provided in the 24 bit address field of the control packet. From MSB to
'' LSB, these are DO - Data Out, Clk - Clock, DI - Data In, CS - Card Select.
spiDoInit movd :moveIt,#spiMaskCS
mov spiBlkCnt,#4
:makeMask mov i2cMask,#1
mov i2cTemp,i2cAddr ' Only use lower 5 bits of
and i2cTemp,#%11111 ' 6 bit shift count field
shl i2cMask,i2cTemp
:moveIt mov 0-0,i2cMask ' Store the bit mask for the pin
cmp spiBlkCnt,#1 wz
if_ne or outa,i2cMask ' Make all pins high outputs
if_ne or dira,i2cMask ' except DO is an input since
if_e andn dira,i2cMask ' input/output is card relative
sub :moveIt,incrDst
ror i2cAddr,#6
djnz spiBlkCnt,#:makeMask
rol i2cAddr,#24 ' Leave i2cAddr unchanged
mov i2cTime,cnt ' Set up a 1 second timeout
mov spiBlkCnt,spiInitCnt
:initRead call #spiRecvByte ' Output a stream of 32K clocks
djnz spiBlkCnt,#:initRead ' in case SD card left in some
mov spiOp,#0 ' undefined state
mov spiParm,#0
call #spiSendCmd ' Send a reset command and deselect
or outa,spiMaskCS ' to get SD card into SPI mode
:waitIdle mov spiOp,#55
call #spiSendCmd ' APP_CMD (Application Specific)
mov spiOp,#41
call #spiSendCmd ' SEND_OP_COND (Initialization)
or outa,spiMaskCS
cmp i2cData,#1 wz ' Wait until response not In Idle
if_e jmp #:waitIdle
tjz i2cData,#i2cGoUpdate ' Initialization complete
or i2cAddr,errorFlag
jmp #i2cGoUpdate ' Could not initialize the card
'' Stop SPI communications. Any previously used I/O pins are set to input mode and
'' the masks for the I/O pins are zeroed. The card is clocked so it turns off.
spiDoStop or outa,spiMaskCS ' Make sure /CS is high
call #spiRecvByte ' Put out a few clocks
call #spiRecvByte ' to turn off the card
andn dira,spiMaskDO
andn dira,spiMaskDI ' Set all the card pins
andn dira,spiMaskCS ' to inputs so they can
andn dira,spiMaskClk ' be used for some other
mov spiMaskDO,#0 ' purpose when the card
mov spiMaskDI,#0 ' is removed. All should
mov spiMaskCS,#0 ' have pullups to +3.3V.
mov spiMaskClk,#0
jmp #i2cGoUpdate
'' Read one or more 512 byte blocks and store the specified number of bytes
'' into the HUB location given. The block number is provided in the 24 bit
'' address field and incremented after every block is read. Partial blocks are
'' allowed and any extra bytes read are discarded.
spiDoRead mov spiOp,#17 ' READ_SINGLE_BLOCK
:readRepeat mov i2cTime,cnt ' Save start of timeout
mov spiParm,i2cAddr
call #spiSendCmd ' Read from specified block
call #spiResponse
mov spiBlkCnt,spiBlkSize ' Transfer a block at a time
:getRead call #spiRecvByte
tjz i2cCount,#:skipStore ' Check for count exhausted
call #StoreData
sub i2cCount,#1
:skipStore djnz spiBlkCnt,#:getRead ' Are we done with the block?
call #spiRecvByte
call #spiRecvByte ' Yes, finish with 16 clocks
add i2cAddr,#1
or outa,spiMaskCS ' Increment address, deselect card
tjnz i2cCount,#:readRepeat ' and check for more blocks to do
checkEndIO test i2cCmd,#ioBootCmd wc
if_nc jmp #i2cGoUpdate ' If not booting, we're done
test i2cAddr,errorFlag wc
and CheckSum,#$FF wz ' If booting, no errors can occur
if_z_and_nc jmp #nowBootSpin ' and checksum must be zero
or i2cAddr,errorFlag
test Options,#noStore wc
if_c jmp #i2cGoUpdate ' Return error status if noStore
stopThisCOG cogid i2cCogId ' If an unrecoverable error occurs,
cogstop i2cCogId ' stop this cog
'' Write one or more 512 byte blocks with the specified number of bytes from
'' the HUB location given. The block number is provided in the 24 bit address
'' field and incremented after every block is written. Partial blocks are
'' allowed and are padded with zeroes.
spiDoWrite mov spiOp,#24 ' WRITE_BLOCK
mov i2cTime,cnt ' Setup timeout
mov spiParm,i2cAddr
call #spiSendCmd ' Write to specified block
mov i2cData,#$FE ' Ask to start data transfer
call #spiSendByte
mov spiBlkCnt,spiBlkSize ' Transfer a block at a time
:putWrite mov i2cData,#0 ' padding with zeroes if needed
tjz i2cCount,#:padWrite ' Check for count exhausted
rdbyte i2cData,i2cBufAdr ' If not, get the next data byte
add i2cBufAdr,#1
sub i2cCount,#1
:padWrite call #spiSendByte
djnz spiBlkCnt,#:putWrite ' Are we done with the block?
call #spiRecvByte
call #spiRecvByte ' Yes, finish with 16 clocks
call #spiResponse
and i2cData,#$1F ' Check the response status
cmp i2cData,#5 wz
if_ne or i2cAddr,errorFlag ' Must be Data Accepted
if_ne jmp #i2cGoUpdate
movs spiWaitData,#0 ' Wait until not busy
call #spiWaitBusy
add i2cAddr,#1
or outa,spiMaskCS ' Increment block address and go
tjnz i2cCount,#spiDoWrite ' to next if more data remains
jmp #i2cGoUpdate
'' Mid level SPI I/O
spiSendCmd andn outa,spiMaskCS ' Send command sequence. Begin by
call #spiRecvByte ' selecting card and clocking
mov i2cData,spiOp
or i2cData,#$40 ' Send command byte (1st 2 bits %01)
call #spiSendByte
mov i2cData,spiParm
shr i2cData,#15 ' Supplied address is sector number
call #spiSendByte
mov i2cData,spiParm ' Send to SD card as byte address,
shr i2cData,#7 ' in multiples of 512 bytes
call #spiSendByte
mov i2cData,spiParm ' Total length of this address is
shl i2cData,#1 ' four bytes
call #spiSendByte
mov i2cData,#0
call #spiSendByte
mov i2cData,#$95 ' CRC code (for 1st command only)
call #spiSendByte
spiResponse movs spiWaitData,#$FF ' Wait for response from card
spiWaitBusy call #spiRecvByte
mov i2cTemp,cnt
sub i2cTemp,i2cTime ' Check for expired timeout (1 sec)
cmp i2cTemp,SaveClkFreq wc
if_nc or i2cAddr,errorFlag
if_nc jmp #i2cGoUpdate
spiWaitData cmp i2cData,#0-0 wz ' Wait for some other response
if_e jmp #spiWaitBusy ' than that specified
spiSendCmd_ret
spiResponse_ret
spiWaitBusy_ret ret
'' Low level byte I/O
spiSendByte mov i2cMask,#%10000000
:sendBit test i2cMask,i2cData wc
andn outa,spiMaskClk ' Send data bytes MSB first
muxc outa,spiMaskDI
or outa,spiMaskClk
shr i2cMask,#1 ' When mask shifted out, we're done
tjnz i2cMask,#:sendBit
or outa,spiMaskDI ' Leave DI in idle (high) state
spiSendByte_ret ret
spiRecvByte mov i2cMask,#%10000000
:recvBit andn outa,spiMaskClk ' Receive data bytes MSB first
or outa,spiMaskClk ' Copy DO to data bit
test spiMaskDO,ina wc
muxc i2cData,i2cMask
shr i2cMask,#1 ' When mask shifted out, we're done
tjnz i2cMask,#:recvBit
and i2cData,#%11111111 ' Eight bits received
spiRecvByte_ret ret
'' For both I2C and SPI, store data on a read operation unless ioNoStore is set.
'' Accumulate a checksum and always save a copy of the first 16 bytes read.
'' If this is an ioBootCmd or ioSpiBoot, adjust the amount to be read based
'' on the value in the program preamble in the word at vbase ($0008).
StoreData test Options,#ioNoStore wc
if_nc wrbyte i2cData,i2cBufAdr ' Store data in specified location
add i2cBufAdr,#1 ' and increment the address
add CheckSum,i2cData ' Accumulate checksum for ioBootCmd
ShiftData shl i2cData,#0-0
StoreLocal or Preamble+0,i2cData ' Store a local copy of the program
add ShiftData,#8 ' preamble for when we're reading
cmp ShiftData,testIns wz ' in a new Spin program
if_z movs ShiftData,#0 ' Pack the data into successive longs
if_z add StoreLocal,incrDst
if_z cmp StoreLocal,testDst wz ' Stop after saving $0010 bytes
if_z mov StoreLocal,noStore
if_z test i2cCmd,#ioBootCmd wc ' If we're reading in a new program,
if_c_and_z mov i2cCount,Preamble+2 ' change i2cCount to vbase adjusted
if_c_and_z and i2cCount,i2cWordMask ' by number of bytes loaded so far.
if_c_and_z sub i2cCount,#16 - 1 ' i2cCount will be decremented again
StoreData_ret ret
'' After reading is finished for a boot, the stack marker is added below dbase
'' and memory is cleared between that and vbase (the end of the loaded program).
'' Memory beyond the stack marker is not cleared. Note that if ioNoStore is set,
'' we go through the motions, but don't actually change memory or the clock.
nowBootSpin test Options,#ioNoStore wc
mov i2cTemp,Preamble+2
shr i2cTemp,#16 ' Get dbase value
sub i2cTemp,#4
if_nc wrlong StackMark,i2cTemp ' Place stack marker at dbase
sub i2cTemp,#4
if_nc wrlong StackMark,i2cTemp
mov i2cOther,Preamble+2 ' Get vbase value
and i2cOther,i2cWordMask
sub i2cTemp,i2cOther
shr i2cTemp,#2 wz ' Compute number of longs between
:zeroIt if_nz_and_nc wrlong i2cZero,i2cOther ' vbase and below stack marker
if_nz_and_nc add i2cOther,#4
if_nz_and_nc djnz i2cTemp,#:zeroIt ' Zero that space (if any)
mov i2cTemp,Preamble
cmp i2cTemp,SaveClkFreq wz ' Is the clock frequency the same?
mov i2cTemp,Preamble+1
and i2cTemp,#$FF ' Is the clock mode the same also?
if_ne jmp #:changeClock
cmp i2cTemp,SaveClkMode wz ' If both same, just go start COG
if_e jmp #:justStartUp
:changeClock and i2cTemp,#$F8 ' Force use of RCFAST clock while
if_nc clkset i2cTemp ' letting requested clock start
mov i2cTemp,time_xtal
:startupDelay djnz i2cTemp,#:startupDelay ' Allow 20ms@20MHz for xtal/pll to settle
mov i2cTemp,Preamble+1
and i2cTemp,#$FF ' Then switch to selected clock
if_nc clkset i2cTemp
:justStartUp mov i2cOther,i2cCmd ' Use the COG supplied as the caller's
and i2cOther,#%111 ' to start up the SPIN interpreter
test Options,#ioStopLdr wz ' If ioStopLdr is set and ioNoStore is
if_nz cogid i2cOther ' clear, then use this cog for SPIN
or i2cOther,interpreter
if_nc coginit i2cOther
'' The operation has completed, with or without errors. Update the control block
'' in main memory and wait for the next operation to be requested.
i2cGoUpdate and i2cBufAdr,i2cWordMask ' Copy updated information
shl i2cCount,#16 ' back to control packet
or i2cCount,i2cBufAdr
mov i2cTemp,PAR
add i2cTemp,#4
wrlong i2cCount,i2cTemp
wrlong i2cAddr,PAR ' Indicate operation is done
jmp #i2cEntryPoint ' and go wait for a new one
'' This action table contains bit sequences for controlling device addressing and read/write
'' mode selection for each of the commands possible. From LSB to MSB, the actions are:
'' 0 - Write the EEPROM device select code for write mode and 2 address bytes
'' 1 - Write the MSB device address or (for ioRead1Cmd/ioWrite1Cmd) a device select code
'' 2 - Write the LSB device address or (for ioRead0Cmd/ioWrite0Cmd) a device select code
'' 3 - Output a Start Sequence prior to reselecting in read mode
'' 4 - Fetch a data value for writing
'' 5 - Construct an EEPROM device select code for read mode and 2 address bytes
'' 6 - Construct a read mode device select code from the MSB of the 16 bit device address
'' 7 - Write the data value or read mode device select code
'' 8 - Read a byte of data from the device and store it
i2cZero
ActionTbl long %0000000000 ' Command not used (indicates done)
long %0110101111,%0010010111 ' Read/Write with 2 bytes of addressing
long %0111001110,%0010010110 ' Read/Write with 1 byte of addressing
long %0100000100,%0010010100 ' Read/Write data only
'' Constants for all routines
i2cWordMask long $0000FFFF
i2cAddrMask long $00FFFFFF
errorFlag long $80000000 ' NAK received during write cycle
speedMask long $40000000 ' One if 100KHz bus, zero if 400KHz
time_xtal long 20 * 20000 / 4 / 1 ' 20ms (@20MHz, 1 inst/loop)
interpreter long ($0004 << 16) | ($F004 << 2) | %0000
i2cBootSCLm long |<i2cBootSCL ' Bit mask for pin 28 SCL use
spiBlkSize ' Number of bytes in an SD card block
incrDst long %10_00000000 ' Used to increment destination field
testIns shl i2cData,#32 ' Used to compare for end of word packing
initStore or Preamble+0,i2cData ' Used to initialize packing instruction
testDst or Preamble+4,i2cData ' Used to check for end of packing buffer
noStore jmp #StoreData_ret ' Used after all data stored into Preamble
spiInitCnt long 32768 / 8 ' Initial SPI clocks produced
StackMark long $FFF9FFFF ' Two of these mark the base of the stack
'' Variables for all routines
Preamble long 0, 0, 0, 0 ' Private copy of program preamble
Action long 0
i2cOther
i2cCogId long 0
i2cCmd long 0
FirstCall long -1 ' One if I2C pins not initialized yet
i2cTemp long 0
i2cCount long 0
i2cBufAdr long 0
i2cAddr long 0
i2cDataSet long 0 ' Minumum data setup time (ticks)
i2cClkLow long 0 ' Minimum clock low time (ticks)
i2cClkHigh long 0 ' Minimum clock high time (ticks)
i2cDataSet1 long 0 ' Minumum data setup time (ticks) 100KHz
i2cClkLow1 long 0 ' Minimum clock low time (ticks) 100KHz
i2cClkHigh1 long 0 ' Minimum clock high time (ticks) 100KHz
i2cDataSet4 long 0 ' Minumum data setup time (ticks) 400KHz
i2cClkLow4 long 0 ' Minimum clock low time (ticks) 400KHz
i2cClkHigh4 long 0 ' Minimum clock high time (ticks) 400KHz
i2cPause long 0 ' Pause before re-fetching next operation
SaveClkFreq long 0 ' Initial clock frequency (clkfreqVal)
SaveClkMode long 0 ' Initial clock mode value (clksetVal)
spiBlkCnt long 0 ' Number of SD card bytes to go in block
CheckSum long 0 ' Checksum of bytes for ioBootCmd
Options long 0 ' Option bits (ioNoStore, ioLowSpeed)
'' Local variables for low level I2C routines
spiOp ' Operation code for SPI command
i2cSCL long 0 ' Bit mask for SCL
spiParm ' Parameter value for SPI command
i2cSDA long 0 ' Bit mask for SDA
i2cTime long 0 ' Used for timekeeping
i2cData long 0 ' Data to be transmitted / received
i2cMask long 0 ' Bit mask for bit to be tx / rx
i2cBitCnt long 0 ' Number of bits to tx / rx
'' Additional local variables for SPI SD Card access
spiMaskDO long 0
spiMaskClk long 0
spiMaskDI long 0
spiMaskCS long 0
fit
{{
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.
}}

492
lib/glob-string.spin Normal file
View File

@ -0,0 +1,492 @@
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ String Engine │
│ │
│ Author: Kwabena W. Agyeman │
│ Updated: 7/10/2009 │
│ Designed For: P8X32A │
│ │
│ Copyright (c) 2009 Kwabena W. Agyeman │
│ See end of file for terms of use. │
│ │
│ Driver Info: │
│ │
│ The string engine provides string functions. │
│ │
│ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │
│ so port B will not be operational. │
│ │
│ Nyamekye, │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
VAR
byte characterToCharacters[257]
byte characterToCharactersPointer
long charactersPointer
long characterIndex
byte decimalCharacters[12]
byte hexadecimalCharacters[9]
byte binaryCharacters[33]
PUB putCharacter(character) '' 4 Stack longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Builds a string from individual characters. If more than 256 characters are entered the string will be reset. │
'' │ │
'' │ Character - The next character to include in the string, handles backspace by removing the last entered character. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
ifnot(characterToCharactersPointer)
bytefill(@characterToCharacters, 0, 257)
if(characterToCharactersPointer and (character == 8))
characterToCharacters[--characterToCharactersPointer] := 0
case character
9 .. 13, 32 .. 127: characterToCharacters[characterToCharactersPointer++] := character
PUB getCharacters '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Resets putCharacter for building a new string and returns the address of the old built string. │
'' │ │
'' │ Returns a pointer to the string of characters built from putCharacter. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
characterToCharactersPointer := 0
return @characterToCharacters
PUB alphabeticallyBefore(characters, charactersBefore) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Compares two strings to see if one comes alphabetically before the other. │
'' │ │
'' │ Returns true if yes and false if no. │
'' │ │
'' │ Characters - A pointer to a string of characters. │
'' │ CharactersBefore - A pointer to a string of characters that comes alphabetically before the other string of characters. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat
if(byte[characters] > byte[charactersBefore])
return true
ifnot(byte[characters] and byte[charactersBefore] and (byte[characters++] > byte[charactersBefore++]))
quit
PUB alphabeticallyAfter(characters, charactersAfter) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Compares two strings to see if one comes alphabetically after the other. │
'' │ │
'' │ Returns true if yes and false if no. │
'' │ │
'' │ Characters - A pointer to a string of characters. │
'' │ CharactersAfter - A pointer to a string of characters that comes alphabetically after the other string of characters. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat
if(byte[characters] < byte[charactersAfter])
return true
ifnot(byte[characters] and byte[charactersAfter] and (byte[characters++] < byte[charactersAfter++]))
quit
PUB startsWithCharacter(charactersToSearch, characterToFind) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Checks if the string of characters begins with the specified character. │
'' │ │
'' │ Returns true if yes and false if no. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharacterToFind - The character to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (byte[charactersToSearch] == characterToFind)
PUB startsWithCharacters(charactersToSearch, charactersToFind)
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Checks if the string of characters begins with the specified characters. │
'' │ │
'' │ Returns true if yes and false if no. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharactersToFind - A pointer to the string of characters to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (charactersToSearch == findCharacters(charactersToSearch, charactersToFind))
PUB endsWithCharacter(charactersToSearch, characterToFind) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Checks if the string of characters ends with the specified character. │
'' │ │
'' │ Returns true if yes and false if no. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharacterToFind - The character to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return (byte[charactersToSearch + strsize(charactersToSearch) - 1] == characterToFind)
PUB endsWithCharacters(charactersToSearch, charactersToFind)
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Checks if the string of characters ends with the specified characters. │
'' │ │
'' │ Returns true if yes and false if no. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharactersToFind - A pointer to the string of characters to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return ((charactersToSearch + (strsize(charactersToSearch) - strsize(charactersToFind)) - 2) == findCharacters(charactersToSearch, charactersToFind))
PUB findCharacter(charactersToSearch, characterToFind) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Searches a string of characters for the first occurence of the specified character. │
'' │ │
'' │ Returns the address of that character if found and zero if not found. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharacterToFind - The character to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(charactersToSearch--)
if(byte[++charactersToSearch] == characterToFind)
return charactersToSearch
PUB replaceCharacter(charactersToSearch, characterToReplace, characterToReplaceWith) '' 11 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Replaces the first occurence of the specified character in a string of characters with another character. │
'' │ │
'' │ Returns the address of the next character after the character replaced sucess and zero on failure. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharacterToReplace - The character to find in the string of characters to search. │
'' │ CharacterToReplaceWith - The character to replace the character found in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
result := findCharacter(charactersToSearch, characterToReplace)
if(result)
byte[result++] := characterToReplaceWith
PUB replaceAllCharacter(charactersToSearch, characterToReplace, characterToReplaceWith) '' 17 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Replaces all occurences of the specified character in a string of characters with another character. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharacterToReplace - The character to find in the string of characters to search. │
'' │ CharacterToReplaceWith - The character to replace the character found in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat while(charactersToSearch)
charactersToSearch := replaceCharacter(charactersToSearch, characterToReplace, characterToReplaceWith)
PUB findCharacters(charactersToSearch, charactersToFind) : buffer | counter '' 6 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Searches a string of characters for the first occurence of the specified string of characters. │
'' │ │
'' │ Returns the address of that string of characters if found and zero if not found. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharactersToFind - A pointer to the string of characters to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(charactersToSearch--)
if(byte[++charactersToSearch] == byte[CharactersToFind])
repeat counter from 0 to (strsize(charactersToFind) - 1)
if(byte[charactersToSearch][counter] <> byte[charactersToFind][counter])
buffer~~
ifnot(buffer~)
return charactersToSearch
PUB replaceCharacters(charactersToSearch, charactersToReplace, charactersToReplaceWith) '' 12 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Replaces the first occurence of the specified string of characters in a string of characters with another string of │
'' │ characters. Will not enlarge or shrink a string of characters. │
'' │ │
'' │ Returns the address of the next character after the string of characters replaced on sucess and zero on failure. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharactersToReplace - A pointer to the string of characters to find in the string of characters to search. │
'' │ CharactersToReplaceWith - A pointer to the string of characters that will replace the string of characters found in the │
'' │ string characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
result := findCharacters(charactersToSearch, charactersToReplace)
if(result)
charactersToSearch := strsize(charactersToReplaceWith)
if(strsize(charactersToReplace) < charactersToSearch)
charactersToSearch := strsize(charactersToReplace)
repeat charactersToSearch
byte[result++] := byte[charactersToReplaceWith++]
PUB replaceAllCharacters(charactersToSearch, charactersToReplace, charactersToReplaceWith) '' 18 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Replaces all occurences of the specified string of characters in a string of characters with another string of │
'' │ characters. Will not enlarge or shrink a string of characters. │
'' │ │
'' │ CharactersToSearch - A pointer to the string of characters to search. │
'' │ CharactersToReplace - A pointer to the string of characters to find in the string of characters to search. │
'' │ CharactersToReplaceWith - A pointer to the string of characters that will replace the string of characters found in the │
'' │ string characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat while(charactersToSearch)
charactersToSearch := replaceCharacters(charactersToSearch, charactersToReplace, charactersToReplaceWith)
PUB trimCharacters(characters) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Removes white space and new lines from the begining and end of a string of characters. │
'' │ │
'' │ Returns a pointer to the trimed string of characters. │
'' │ │
'' │ Characters - A pointer to a string of characters to be trimed. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat while((1 =< byte[characters]) and (byte[characters] =< 32) or (byte[characters] == 127))
characters += 1
result := characters
characters := (characters + strsize(characters) - 1)
repeat while((1 =< byte[characters]) and (byte[characters] =< 32) or (byte[characters] == 127))
byte[characters--] := 0
PUB tokenizeCharacters(characters) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Removes white space and new lines from in between of a string of characters. │
'' │ │
'' │ Through repeated calls on the same string of characters a new string to each sub string of characters is returned. │
'' │ │
'' │ Returns a pointer to a new tokenized sub string on each call and null when out of sub strings. │
'' │ │
'' │ Characters - A pointer to a string of characters to be tokenized. Null after the first call to continue. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
if(characters)
charactersPointer := characters
characterIndex := 0
result := (charactersPointer + characterIndex)
repeat while((33 =< byte[charactersPointer][characterIndex]) and (byte[charactersPointer][characterIndex] =< 126))
characterIndex += 1
repeat while((1 =< byte[charactersPointer][characterIndex]) and (byte[charactersPointer][characterIndex] =< 32) or (byte[charactersPointer][characterIndex] == 127))
byte[charactersPointer][characterIndex++] := 0
PUB charactersToLowerCase(characters) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Demotes all upper case characters in the set of ("A","Z") to their lower case equivalents. │
'' │ │
'' │ Characters - A pointer to a string of characters to convert to lowercase. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(characters--)
result := byte[++characters]
if((result => "A") and (result =< "Z"))
byte[characters] := (result + 32)
PUB charactersToUpperCase(characters) '' 4 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Promotes all lower case characters in the set of ("a","z") to their upper case equivalents. │
'' │ │
'' │ Characters - A pointer to a string of characters to convert to uppercase. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(characters--)
result := byte[++characters]
if((result => "a") and (result =< "z"))
byte[characters] := (result - 32)
PUB numberToDecimal(number, length) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Converts an integer number to the decimal string of that number padded with zeros. │
'' │ │
'' │ Returns a pointer to the converted string. │
'' │ │
'' │ Number - A 32 bit signed integer number to be converted to a string. │
'' │ Length - The length of the number in the converted string. " " or "-" will be tacked onto the front of the string. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
length := ((length <# 10) #> 0)
decimalCharacters := " "
if(number < 0)
-number
decimalCharacters := "-"
if(number == negx)
bytemove(@decimalCharacters, string("-2147483648"), 12)
else
repeat result from 10 to 1
decimalCharacters[result] := ((number // 10) + "0")
number /= 10
bytemove(@decimalCharacters[1], @decimalCharacters[(11 - length)], (length + 1))
return @decimalCharacters
PUB numberToHexadecimal(number, length) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Converts an integer number to the hexadecimal string of that number padded with zeros. │
'' │ │
'' │ Returns a pointer to the converted string. │
'' │ │
'' │ Number - A 32 bit signed integer number to be converted to a string. │
'' │ Length - The length of the converted string, negative numbers need a length of 8 for sign extension. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat result from 7 to 0
hexadecimalCharacters[result] := lookupz((number & $F): "0".."9", "A".."F")
number >>= 4
return @hexadecimalCharacters[(8 - ((length <# 8) #> 0))]
PUB numberToBinary(number, length) '' 5 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Converts an integer number to the binary string of that number padded with zeros. │
'' │ │
'' │ Returns a pointer to the converted string. │
'' │ │
'' │ Number - A 32 bit signed integer number to be converted to a string. │
'' │ Length - The length of the converted string, negative numbers need a length of 32 for sign extension. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat result from 31 to 0
binaryCharacters[result] := ((number & $1) + "0")
number >>= 1
return @binaryCharacters[(32 - ((length <# 32) #> 0))]
PUB decimalToNumber(characters) | buffer, counter '' 6 Stack Longs.
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Converts a decimal string into an integer number. │
'' │ │
'' │ Returns the converted integer. │
'' │ │
'' │ Characters - A pointer to the decimal string to convert. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
buffer := byte[characters]
counter := (strsize(characters) <# 11)
repeat while(counter--)
result *= 10
result += lookdownz(byte[characters++]: "0".."9")
if(buffer == "-")
-result
PUB hexadecimalToNumber(characters) : buffer | counter '' 5 Stack Longs.
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Converts a hexadecimal string into an integer number. │
'' │ │
'' │ Returns the converted integer. │
'' │ │
'' │ Characters - A pointer to the hexadecimal string to convert. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
counter := (strsize(characters) <# 8)
repeat while(counter--)
buffer <<= 4
buffer += lookdownz(byte[characters++]: "0".."9", "A".."F")
PUB binaryToNumber(characters) : buffer | counter '' 5 Stack Longs.
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Converts a binary string into an integer number. │
'' │ │
'' │ Returns the converted integer. │
'' │ │
'' │ Characters - A pointer to the binary string to convert. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
counter := (strsize(characters) <# 32)
repeat while(counter--)
buffer <<= 1
buffer += lookdownz(byte[characters++]: "0", "1")
{{
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

150
lib/gui-dlbox.spin Normal file
View File

@ -0,0 +1,150 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name :
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios : "reg-ios"
fm : "fm-con"
CON
VAR
byte box_win,box_x0,box_y0,box_x1,box_y1
long box_ladr,box_fadr
byte box_view,box_maxpos,box_pos
byte box_cols
byte box_stat
PUB define(win,x0,y0,x1,y1,ladr,fadr,view,maxpos)
box_win := win 'fensternummer
box_x0 := x0 'koordinaten
box_x1 := x1
box_y0 := y0
box_y1 := y1
box_view := view 'position in der liste
box_pos := 0 'position im fenster
box_maxpos := maxpos 'max. anzahl in liste
box_ladr := ladr 'adresse dateinamenliste
box_fadr := fadr 'adresse dateiflags
box_cols := (box_x1-box_x0)/(fm#MAX_LEN+2)
box_stat := 0
ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1)
ios.winset(box_win)
ios.printcls
PUB draw
ios.winset(box_win)
ios.printcls
redraw
PUB redraw | i
ios.winset(box_win)
if box_stat & fm#FL_FOCUS
ios.setcolor(fm#COL_FOCUS)
ios.winoframe
ios.curhome
ios.curoff
ios.setcolor(fm#COL_DEFAULT)
i := 0
repeat fm#WROWS
repeat box_cols
print_file(box_view+i,i)
i++
ios.printnl
PUB setpos(pos)
box_pos := pos
redraw
PUB setview(view)
box_view := view
redraw
PUB getcols: cols
return box_cols
PUB focus
ios.winset(box_win)
box_stat := box_stat | fm#FL_FOCUS
redraw
PUB defocus
ios.winset(box_win)
box_stat := box_stat & !fm#FL_FOCUS
redraw
PRI print_file(fnr,posnr) | i,c
i := 0
c := fm#COL_DEFAULT
if byte[box_fadr+fnr] & fm#FL_SEL 'eintrag selektiert?
c := fm#COL_SELECT
if (posnr == box_pos) & (box_stat & fm#FL_FOCUS) 'eintrag an cursorpos?
ios.setcolor(c+8)
else
ios.setcolor(c)
if byte[box_fadr+fnr] & fm#FL_DIR 'eintrag verzeichnis?
ios.printq(string(" ▶"))
else
ios.print(string(" "))
repeat fm#MAX_LEN
ios.bus_putchar2(byte[box_ladr][fnr*fm#MAX_LEN+i])
i++
ios.setcolor(fm#COL_DEFAULT)
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

96
lib/gui-input.spin Normal file
View File

@ -0,0 +1,96 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name :
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios : "reg-ios"
fm : "fm-con"
gc : "glob-con"
CON
VAR
byte box_win,box_x0,box_y0,box_x1,box_y1
byte input_len
byte input_str[64]
PUB define(win,x0,y0,x1,y1,len)
box_win := win 'fensternummer
box_x0 := x0 'koordinaten
box_x1 := x1
box_y0 := y0
box_y1 := y1
input_len := len
ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1)
ios.winset(box_win)
ios.printcls
PUB draw(stradr1):stradr2 | key,bnr
input_str[0] := 0
ios.winset(box_win)
ios.printcls
ios.winoframe
ios.curhome
ios.curoff
ios.setcolor(fm#COL_DEFAULT)
ios.printchar(" ")
ios.print(stradr1)
ios.printnl
ios.printnl
ios.printchar(" ")
repeat input_len
ios.printchar("_")
ios.curpos1
ios.printchar(" ")
ios.curon
ios.input(@input_str,input_len)
ios.curoff
return @input_str
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

119
lib/gui-pbar.spin Normal file
View File

@ -0,0 +1,119 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name :
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios : "reg-ios"
fm : "fm-con"
CON
VAR
byte box_win,box_x0,box_y0,box_x1,box_y1
long box_maxbar
byte box_barlen
byte box_bar
byte box_skal
PUB define(win,x0,y0,x1,y1)
box_win := win 'fensternummer
box_x0 := x0 'koordinaten
box_x1 := x1
box_y0 := y0
box_y1 := y1
box_barlen := x1 - x0 - 4
box_bar := 0
box_skal := 1
ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1)
ios.winset(box_win)
ios.printcls
PUB setmaxbar(maxbar)
box_maxbar := maxbar
box_skal := 1
if box_maxbar => box_barlen
box_skal := box_maxbar / box_barlen
PUB draw(stradr1,stradr2,bar)
ios.winset(box_win)
ios.printcls
ios.winoframe
ios.curhome
ios.curoff
ios.setcolor(fm#COL_DEFAULT)
ios.printchar(" ")
ios.print(stradr1)
ios.printnl
ios.printchar(" ")
ios.print(stradr2)
ios.printnl
update(bar)
{
box_bar := bar / box_skal
ios.printchar(" [")
repeat box_bar
ios.printqchar("‣")
repeat box_barlen - box_bar
ios.printqchar(" ")
ios.printchar("]")
}
PUB update(bar)
ios.winset(box_win)
ios.curpos1
box_bar := bar / box_skal
ios.print(string(" ["))
repeat box_bar <# box_barlen
ios.printqchar("‣")
repeat box_barlen - box_bar #> 0
ios.printqchar(" ")
ios.printchar("]")
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

112
lib/gui-wbox.spin Normal file
View File

@ -0,0 +1,112 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name :
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios : "reg-ios"
fm : "fm-con"
gc : "glob-con"
CON
VAR
byte box_win,box_x0,box_y0,box_x1,box_y1
PUB define(win,x0,y0,x1,y1)
box_win := win 'fensternummer
box_x0 := x0 'koordinaten
box_x1 := x1
box_y0 := y0
box_y1 := y1
ios.windefine(box_win,box_x0,box_y0,box_x1,box_y1)
ios.winset(box_win)
ios.printcls
PUB draw(stradr1,stradr2,stradr3):button | key,bnr
ios.winset(box_win)
ios.printcls
ios.winoframe
ios.curhome
ios.curoff
ios.setcolor(fm#COL_DEFAULT)
ios.printchar(" ")
ios.print(stradr1)
ios.printnl
ios.printnl
bnr := 1
repeat
draw_buttons(stradr2,stradr3,bnr)
key := ios.keywait
case key
gc#KEY_CURLEFT: bnr := 1
gc#KEY_CURRIGHT: bnr := 2
until key == gc#KEY_RETURN
return bnr
PRI draw_buttons(stradr2,stradr3,bnr)
ios.curpos1
ios.setcolor(fm#COL_DEFAULT)
ios.printchar(" ")
if bnr == 1
ios.setcolor(fm#COL_DEFAULT + 8)
else
ios.setcolor(fm#COL_DEFAULT)
ios.print(stradr2)
ios.setcolor(fm#COL_DEFAULT)
ios.print(string(" "))
if bnr == 2
ios.setcolor(fm#COL_DEFAULT + 8)
else
ios.setcolor(fm#COL_DEFAULT)
ios.print(stradr3)
ios.setcolor(fm#COL_DEFAULT)
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

227
lib/m-glob-con.spin Normal file
View File

@ -0,0 +1,227 @@
{{ Bellatrix-Code
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Autor: Ingo Kripahle │
│ Copyright (c) 2012 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 : mental
Name :
Chip : global
Typ : Konstanten
}}
con ' signaldefinitionen
'signaldefinitionen global
#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus
#24, HBEAT 'front-led
BUSCLK 'bustakt
BUS_WR '/wr - schreibsignal
BUS_HS ' '/hs - quittungssignal
I2C_SCL
I2C_SDA
SER_TX
SER_RX
'signaldefinitionen bellatrix
#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
'signaldefinitionen administra
#8, ADM_SOUNDL,ADM_SOUNDR 'sound (stereo 2 pin)
#10, ADM_SDD0,ADM_SDCLK,ADM_SDCMD,ADM_SDD3 'sd-cardreader (4 pin)
#23, ADM_SELECT 'administra-auswahlsignal
con ' administra-funktionen
ADM_OPT = 0
'sdcard-funktionen
ADM_SD_MOUNT = 1
ADM_SD_CHECKMOUNTED = 2
ADM_SD_UNMOUNT = 3
ADM_SD_OPEN = 4
ADM_SD_CLOSE = 5
ADM_SD_GETC = 6
ADM_SD_PUTC = 7
ADM_SD_EOF = 8
ADM_SD_GETBLK = 9
ADM_SCR_FILL = 11 'screenpuffer mit zeichen füllen
ADM_SCR_READ = 12 'screen in den puffer laden
ADM_SCR_WRITE = 13 'screen auf disk schreiben
ADM_SCR_GETNR = 14 'nummer des aktuellen screens abfragen
ADM_SCR_SETPOS = 15 'zeiger auf position im puffer setzen
ADM_SCR_GETPOS = 16 'aktuelle position im puffer abfragen
ADM_SCR_GETC = 17 'zeichen wird aus dem puffer gelesen
ADM_SCR_PUTC = 18 'zeichen wird in den puffer geschrieben
ADM_SCR_ERR = 19 'fehlerstatus abfragen
ADM_SCR_MAXSCR = 20 'anzahl screens des containers abfragen
ADM_SCR_EOS = 21 'end of screen abfragen
ADM_SCR_CALL = 22 'subscreen aufrufen
ADM_SCR_RET = 23 'subscreen beenden
ADM_SCR_USE = 24 'tape öffnen
ADM_SCR_TAPES = 25 'tapeliste abfragen
ADM_M_PARSE = 30 'nächstes token aus screen parsen
ADM_M_SETBASE = 31 'zahlenbasis setzen
ADM_COM_TX = 40 'com: zeichen senden
ADM_COM_RX = 41 'com: zeichen empfangen
adm_m_run = 50 'plx: polling aktivieren
adm_m_halt = 51 'plx: polling anhalten
adm_m_setctrl = 52
adm_m_in = 53
adm_m_out = 54
adm_m_ad_ch = 55
adm_m_getreg = 56
adm_m_setreg = 57
adm_m_start = 58
adm_m_stop = 59
adm_m_write = 60
adm_m_read = 61
adm_m_ping = 62
adm_m_joy = 63
adm_m_paddle = 64
adm_m_pad = 65
adm_m_setjoy = 66
adm_m_setpad = 67
adm_m_getspec = 97 'spezifikation abfragen
adm_m_getver = 98 'codeversion abfragen
adm_m_reboot = 99 'neu starten
'plexbus
adm_sda = 19 'i2c-datenpin
adm_scl = 20 'i2c-clockpin
adm_int1 = 21 'interrupt port 1&2
adm_int2 = 22 'interrupt port 3
con ' bellatrix-funktionen
' ---------------------------------------------- FUNKTIONEN
bel_key_stat = 1 'tastaturstatus abfragen
bel_key_code = 2 'tastaturzeichen abfragen
bel_key_spec = 3 'sondertasten abfragen
bel_key_wait = 4 'auf tastaturzeichen warten
bel_pchar = 5 'zeichen ohne steuerzeichen augeben
bel_setx = 6 'x-position setzen
bel_sety = 7 'y-position setzen
bel_getx = 8 'x-position abfragen
bel_gety = 9 'y-position abfragen
bel_color = 10 'farbe setzen
bel_sline = 11 'startzeile scrollbereich
bel_eline = 12 'endzeile scrollbereich
bel_settab = 13 'tabulatorposition setzen
bel_cls = 1
bel_home = 2
bel_pos1 = 3
bel_curon = 4
bel_curoff = 5
bel_up = 6
bel_down = 7
bel_bs = 8
bel_tab = 9
bel_nl = 13
' ---------------------------------------------- M-FUNKTIONEN
bel_m_parse = 20 'nächstes token von eingabezeile parsen
bel_m_setbase = 21 'base setzen
bel_m_dot = 22 'formatierte ausgabe eines zahlenwertes
bel_m_error = 23 'm fehlermeldung
' ---------------------------------------------- SCREENEDITOR
bel_scr_edit = 24 'screeneditor
bel_scr_put = 25 'screen empfangen
bel_scr_get = 26 'screen senden
bel_scr_setnr = 27 'screennummer setzen
' ---------------------------------------------- CHIP-MANAGMENT
bel_mgr_setcolor= 97 'neuen bellatrix-code laden
bel_mgr_load = 98 'farbregister setzen
bel_reboot = 99 'bellatrix neu starten
con ' color-tags
M_C_TAG1 = $16 'wort ausführen
M_C_TAG2 = $17 'wort definieren
M_C_TAG3 = $18 'wort compilieren
M_C_TAG4 = $19 'zahl
M_C_TAG5 = $1A 'zahl literal
M_C_TAG6 = $1B 'string
M_C_TAG7 = $1C 'string literal
M_C_TAG8 = $1D 'data
M_C_TAG9 = $1E 'kommentar
M_C_TAG10 = $1F 'eos/cursor
M_C_EXECUTE = M_C_TAG1
M_C_CREATE = M_C_TAG2
M_C_COMPILE = M_C_TAG3
M_C_NUMBER = M_C_TAG4
M_C_NUMBERLIT = M_C_TAG5
M_C_STRING = M_C_TAG6
M_C_STRINGLIT = M_C_TAG7
M_C_DATA = M_C_TAG8
M_C_REMARK = M_C_TAG9
M_C_MAX = M_C_TAG9 ' tag mit höchstem wert
M_C_EOS = M_C_TAG10 ' end of screen tag für den adm-parser
con ' farbzuordnung
C_EXECUTE = 0
C_CREATE = 1
C_COMPILE = 2
C_NUMBER = 3
C_NUMBERLIT = 4
C_STRING = 5
C_STRINGLIT = 6
C_DATA = 7
C_REMARK = 8
C_CURSOR = 15 ' cursorfarbe
C_NORMAL = 0 ' normale ausgabefarbe
C_INFO = 8 ' farbe für infos
C_ATTENTION = 1 ' farbe für hinweise
con ' fehlercodes
M_ERR_NO = 0 ' kein fehler
M_ERR_RS = 1 ' returnstack fehler
M_ERR_DS = 2 ' datenstack fehler
M_ERR_IN = 3 ' fehler interpreter
M_ERR_CP = 4 ' fehler compiler
M_ERR_SI = 5 ' strukturfehler
M_ERR_SD = 6 ' datenträgerfehler
M_ERR_RW = 7 ' schreib/lesefehler
M_ERR_NF = 8 ' not found
M_ERR_ST = 9 ' stackfehler
pub dummy
' diese routine muss vorhanden sein,
' da sonst kein objekt erzeugt und eingebunden wird

2993
lib/reg-ios.spin Normal file

File diff suppressed because it is too large Load Diff

23
lizenz.txt Normal file
View File

@ -0,0 +1,23 @@
Hive-Project
-------------------------------------------------------------------------
Der Hive ist ein Open-Hardware und Free-Software DIY-Computersystem auf
der Basis von drei Parallax P8X32 "Propeller" Mikrocontrollern.
Lizenze
-------------------------------------------------------------------------
Das Betriebssystem TriOS steht unter MIT-Lizenz. Die Schaltung und das
Board-Layout ist unter Creative-Commons CC-BY-SA 3.0 lizensiert.
MIT-Lizenz: http://www.opensource.org/licenses/mit-license.php
CC-BY-SA 3.0: http://creativecommons.org/licenses/by-sa/3.0/de/
Informationen zum Projekt
-------------------------------------------------------------------------
http://hive-project.de
Urheberrechtsangabe
-------------------------------------------------------------------------
Copyright (c) 2009 Ingo Kripahle

380
logbuch.txt Normal file
View File

@ -0,0 +1,380 @@
r56 - 11-05-2013-dr235
und weiter gehts mit dem frühjahresputz:
- umstellung administra-codes (admflash, admay, admsid) auf externe konstantendefinitionen
belflash:
- fehler im loader behoben
lib:
- gui-objekte für textoberfläche eingefügt:
gui-dlbox - listenbox für dateien
gui-input - einfaches eingabefenster
gui-pbar - hinweisdialog mit progress-bar (z.bsp. für kopieraktionen)
gui-wbox - warnbox mit auswahloptionen
system/regnatix:
- filemanager fm zugefügt
- metal-loader m zugefügt
- tool zum erstellen von tapes (mental-containerdateien) zugefügt
- wplay: kleinen darstellungsfehler behoben
- yplay: konstanten ausgelagert
system/sonstiges:
- manual zugefügt: error, fm
r55 - 15-04-2013-dr235
fällige aufräumarbeitem im quelltext:
- umstellung bildschirmcodes/g0-treiber auf externe konstantendefinitionen
- umstellung signaldefinitionen für belflash/g0key
- alle funktionsnummern für bella werden nun in lib\glob-con.spin verwaltet und gepflegt
- screeninit gibt jetzt keine kopfzeile mehr aus, geht jetzt über fensterfunktionen
- anpassung div. tools
system\regnatix\regime:
- leere eingaben werden jetzt ignoriert
- mit der Cursortaste kann jetzt der letzte Befehl wiederholt werden
r54 - 15-04-2013-dr235:
flash\admflash.spin
- grundlegende com-funktionen eingefügt
lib\reg-ios.spin
- com-funktionen
- ios.screeninit: kein logo im v-modus
system\administra\admay\admay.spin
- sd_dmput eingefügt
- sd_eof eingefügt
system\regnatix\admtest.spin
- korrektur bei fehlerhaftem screeninit
system\regnatix\beltest.spin
- menü eingefügt um einzelnen tests auszuführen
- anpassung an tv-modus
- neuer test für fensterfunktionen
system\regnatix
- tool man eingefügt
- umstrukturierung aller tool-hilfen an man
- anpassung der meisten tools an tv-modus
system\sonstiges
- man-hilfetexte eingefügt
r53 - 20.02.2013 dr235/u-held:
flash\admflash.spin
- scr-funktionen ausgefügt
flash\belflash.spin:
- fehler im loader behoben (cog0 wurde nicht in allen fällen beendet) dank dafür geht an pic :)
- farbtabellen auf 16 farben ergänzt, normalfarbe ist jetz mal retro-green :)
flash\regflash.spin:
- pause für slaves zur initialisierung eingefügt, damit diese bei installation ohne forth sauber starten
forth\bel.lib:
- korrektur wort bel:load
forth\sd0.lib:
- div. fehlerhafte stackkommentare korrigiert
forth\tools.lib:
- korrektur wort bel:load
forth\g0.lib: zugefügt
forth\tpix.f: zugefügt
forth\win.lib: zugefügt
lib\reg-ios.spin:
- fehler in g0 printdec behoben
- neue sidcog-funktion: sid_dmpreg
system\administra\admsid\admsid.spin:
- funktion sid_dmpreg eingefügt (für triborg-player)
- funktion sd_dmput aus maincode übernommen
- funktion sd_eof aus maincode übernommen
system\regnatix\g0test.spin:
- neue test's & effekte eingefügt
system\regnatix\sysconf.spin:
- "sysconf /ci" zeigt nun alle 16 farben an
system\sonstiges\green.col:
- grüne retro-farbtabelle eingefügt
r52:
g0key.spin - Bug bei horizontaler Textzentrierung beseitigt
belflash.spin - Interface VGA/TV vereinheitlicht, umschaltbar beim Compilieren (siehe make.bat)
belf-tv.spin, belf-vga.spin - treiberspezifische Konstanten und Funktionen für belflash.spin
bel-bus.spin - Auslagerung der Bus-Routinen aus Bellatrix-Sicht
beltest.spin - Anpassung an belflash.spin, auch im TV-Modus nutzbar
make.bat - tv.bel wird jetzt aus belflash.spin erzeugt; Einführung einer Variablen für den Compiler-Aufruf
reg-ios.spin - hmm... habsch vergessen, was da geändert wurde :-(
r51:
belflash.spin:
- verzögertes Scrolling bei abgeschaltetem Cursor
- Window-Funktionen
glob-con.spin:
- Auslagerung von globalen Konstanten (ansatzweise)
reg-ios.spin:
- Einbindung der neuen Bellatrix-Funktionen
beltest.spin:
- sline/eline-Test entfernt, Window-Test eingefügt
27.11.2011-dr235
- bellatrix-code für grafikmodus 0 + keyboard hinzugefügt
- g0test - testprogramm für g0-modus hinzugefügt
- reg-ios - g0-funktionen eingearbeitet
- make.bat angepasst
13.11.2011-dr235
- rtc-routinen neu eingefügt
- admterm entfernt, hat im trios keine funktion
11.11.2011-dr235
- umfangreicher umbau der verzeichnisstruktur: alle universellen quellen wie treiber oder klassische bibliotheken werden nun im verzeichnis "lib" gespeichert und können so an einer stelle gepflegt werden.
- alle anwendungen die nichts mit trios zu tun haben werden nun aus dem projekt entfernt und in einer toolbox-serie veröffentlicht. damit wird trios stark entschlackt und wieder übersichtlich.
- überarbeitung der make.bat; es werden nun auch die alternativen slave-codes wie zum beispiel admsid erstellt.
- in der standardkonfiguration ist jetzt forth deaktiviert - das ist einfacher für den einsteiger. forth ist dann "level 2".
WICHTIG: im bst muß nun der compiler-suchpfad für trios auf das verzeichnis "lib" eingestellt werden.
09.11.2011-dr235
- fehler in regflash.spin behoben, konfiguration ohne forth konnte nicht compiliert werden
- standartkonfiguration ist jetzt ohne forth, ist einfacher für den einstieg
- div. demos entfernt, diese werden später getrennt in einer toolbox-serie veröffentlicht
06.11.2011-dr235
- fehlersuche zum problem mit dem neuen bella-loader: einige bel-dateien (guidemo, 4-boing) wurden nicht korrekt initialisiert, also starteten nicht sauber. parameter und ladevorgang ist korrekt, ursache ist wahrscheinlich eine falsche initialisierung der stackwerte im pasm-teil des loaders. als lösung kann man diese bel-dateien als eeprom-image abspeichern, diese starten korrekt.
23.04.2011-dr235
- integration von propforth in trios
15-04-2011-dr235
- flash-tool/rom: damit kann unter anderem eine bin-datei (z. bsp. basic) in den hi-rom (64k eeprom erforderlich!) gespeichert und mit rom gestartet werden
- übernahme der rtc-routinen von stephan
- time-kommando: anzeige/änderung datum/zeit
- perplex: experimentelles tool für plexbus (scan/open/close/get/put)
- fterm: primitiv-terminal für forth-hive
18-09-2010-dr235
- regime: free zeigt jetzt auch die speicherbelegung des eram an
- speicherverwaltung/ramdisk integriert (beispielcode siehe eram.spin & regime.spin)
- eram.bin kann jetzt auch mit ramdisk umgehen
- regime: neue kommandos für ramdisk
- egalisierung der namen für den ramzugriff (älterer code muß leicht angepasst werden)
- user- und systemmode für ramzugriff eingefügt
- erste version eine make-batch um das gesamte system zu kompilieren (nur grundsystem)
- änderung zur ios: da bst eine pfadliste zu bibliotheksordnern unterstützt, liegt (soweit das möglich ist) die ios nun nur noch unter system\regnatix
WICHTIG: Pfad zur ios.spin im bst einstellen
23-08-2010-dr040
- integration ay-emulator (admay.adm) und yplay
19-07-2010-dr235
- booten eines alternativen administra-codes: befindet sich auf der karte in der root eine datei "adm.sys", so wird diese datei automatisch in administra geladen
11-07-2010-dr235
- integration sid1/2-funktionen in admsid/ios
- anpassung sid-demo von ahle2 als regnatix-code (verzeichnis demo)
- diverse graphics-spielereien (verzeichnis demo)
- sysconf /af - administra neu booten (admflash.adm wird dadurch überflüssig)
27-06-2010-dr085/235
- admin mountet nun automatisch nach einem boot
26-06-2010-dr235
- div. demos zugefügt
- shooter angepasst und eingefügt
20-06-2010-dr235
- erste lauffähige SID-Player-Version für die Kommandozeile (splay)
14-06-2010-dr085/235
- Semaphoren in FATEngine korrekt eingesetzt
- Abfrage des Volume-Labels korrigiert
10-06-2010-dr235
- Kommando "ramtest" zugefügt
09-06-2010-dr085
- Fehler in Administra-Bootfunktion behoben
-----------------------------------------------------------------------------------------------
23-04-2011-dr235
Ein neuer Meilenstein: PropForth ist jetzt in TriOS integriert. Als Nebeneffekt starten nun wieder, wie bei meiner ersten SpinOS-Version, alle drei Chips ihren initialen Code aus ihrem EEPROM und nicht mehr vom SD-Laufwerk. Damit gibt es vom Einschalten bis zum Forth-Prompt quasi keine fühlbare Bootzeit mehr. So gehört es sich für einen richtigen Homecomputer. Es ist nun möglich, unmittelbar nach dem Einschalten sofort zu programmieren. Erst wenn man zu Regime wechselt wird kurz reg.sys nachgeladen. Aber selbst die Ladezeiten sind nun durch Verwendung des SD-Blocktransfer erfreulich kurz.
Obwohl das Grundsystem vom Forth den halben hRAM belegt, ist es als genormte Sprache doch eine wunderbare Geschichte im Hive. Viele der Ressourcen sind jetzt schon problemlos in Forth nutzbar und man kann sehr unkompliziert experimentieren.
02-10-2010-dr235
Speicherverwaltung:
In dieser Version ist eine erste Beta-Version der Speicherverwaltung des externen RAM's enthalten. Der Speicher kann dabei in einem einfachen oder einem strukturierten Modus verwendet werden. Klingt kompliziert, ist aber ganz einfach.
Einfacher Modus:
Hierbei kann ein Programm auf den eRAM über die IOS-Routinen ios.ram_* zugreifen. Wahlweise kann der Speicher im Systemmode direkt von 0 bis $07FFFF angesprochen werden, oder nur der Userbereich. Im Systemmodus ist darauf zu achten, dass eine eventuell vorhandene Ramdisk und die Systemvariablen nicht überschrieben werden, man sollte also wissen was man tut... ;) Die Ramdisk wird ab der physischen Adresse 0 als verkettete Liste verwaltet, die Systemvariablen befinden sich ab $07FFFF abwärts.
ios.ram_wrbyte(ios#sysmod,0,ios#MAGIC)
- Schreibt den Wert 0 in die Systemvariable, um einen Kaltstart auszulösen.
ios.ram_wrbyte(ios#sysmod,$20,$100)
- Schreibt den Wert $20 an die physische Adresse $100 im eRAM.
Da es nun mühsam ist in einem kleinen Code solche Konflikte mit dem Systemspeicher zu vermeiden, gibt es den Usermodus. Im Usermodus wird nur genau jener freie Speicher adressiert, welcher sich zwischen Ramdisk und Systemvariablen befindet. In diesem Fall ist die Adressierung also virtualisiert.
ios.ram_wrbyte(ios#usrmod,0,$100)
- Schreibt den Wert 0 an die Adresse $100 im Userspeicher!
In Regime kann man mit dem Kommando "free" jetzt auch die wichtigsten Systemvariablen der Speicherverwaltung anzeigen.
RBAS
- erste physische Adresse des Userspeichers
REND
- Physische Adresse der letzten freien Speicherstelle des Userspeichers.
USER
- Grösse des Userspeichers (REND - RBAS).
RAMDRV
0 - Ramdisk ist nicht initialisiert
1 - Ramdisk ist initialisiert
SYSVAR
- Erste physische Adresse der Systemvariablen.
Noch genauer kann man sich die Speicherbelegung mit dem Tool "eram" anschauen. Nur ein paar Beispiele:
"d" Anzeige des Speichers. Es werden zwei Adressspalten angezeigt. Die zweite schwarze Adresse in jeder Zeile zeigt die physische Adresse, die erste grüne Adresse die virtuelle Adresse im Userspeicher. Man kann sehr gut erkennen, ab welcher Adrese der Userbereich anfängt und wo er endet.
"d 100" Anzeige ab physischer Adresse $100
"d bas" Anzeige vom Start des Userspeichers.
"n" Anzeige inkrementell fortsetzen
Die Nutzung des Userspeichers ist sehr einfach. Es sind dabei nur folgende Regeln zu beachten:
Man muss selbst darauf achten die Speichergrenzen nicht zu überschreiten. Bei Überschreitung kann aber nichts passieren - die IOS-Routinen brechen einfach ab, allerdings werden die eigenen Daten halt nicht korrekt verarbeitet. Es werden also die Systemvariablen und die Daten in der Ramdisk geschützt.
Der Userbereich im eRAM ist nur zur Laufzeit der Anwendung gültig. Wird die Anwendung beendet, so kann durch Regime oder eine andere Anwendung mit den Daten der Ramdisk gearbeitet werden, wodurch sich der physische Bereich des Userbereiches verändert. Wer also residente Daten über die Laufzeit der Anwendung hinaus braucht, muss im strukturierten Modus mit der Ramdisk arbeiten.
In einer Anwendung nicht den einfachen oder strukturierten Modus mischen - das gibt Chaos, wenn man nicht ganz genau aufpasst
Ansonsten kann man wie gehabt die schon bekannten IOS-Routinen verwenden, einzig der Übergabeparameter zur Wahl des System- oder Usermodus sind hinzugekommen. Als Beispiel kann man sich die Soundplayer anschauen, die ihre Dateiliste im Userspeicher ablegen.
Strukturierter Modus:
Was ist aber, wenn wir einen kleinen Texteditor schreiben wollen, der seine Textdaten resident im eRAM speichern kann? Ich möchte also den Texteditor verlassen können, um in Regime zum Beispiel einen Assembler aufzurufen, welcher den Text dann assembliert. Darauf folgend möchte ich meinen Texteditor wieder starten und an dem Text weiter arbeiten. Dafür muss es meiner Anwendung - dem Textprogramm - möglich sein, einen Speicherbereich im eRAM zu reservieren, der von System und anderen Anwendungen respektvoll behandelt wird.
Gedacht, getan: Im strukturierten Modus wird der Speicher in Form einer Ramdisk verwaltet. Die Dateien/Daten können über ihren Namen angesprochen werden. Es kann mit put & get sequentiell, oder mit read & write direkt adressierbar auf die Daten in der Datei zugegriffen werden.
Als erstes praktisches Beispiel mögen die neuen Kommandos in Regime selbst dienen, mit denen man die Ramdisk verwalten kann:
Neue Regime-Kommandos:
xload <sd:fn> - datei in ram laden
xsave <x:fn> - datei aus ram speichern
xdir - verzeichnis im ram anzeigen
xrename <x:fn1> <x:fn2> - datei im ram umbenennen
xdel <x:fn> - datei im ram löschen
xtype <x:fn> - text im ram anzeigen
So ist es also möglich, sich in der Kommandozeile anzuschauen, welche residenten Daten die Programme aktuell angelegt haben. Sofern es Textdaten sind, können diese Daten auch einafch angezeigt werden.
Die Speicherverwaltung ist allerdings noch sehr experimentell - was bedeutet, dass wohl noch einige Bugs drin sein dürften. :)
MAKE.BAT
Diese Batchdatei im obersten Verzeichnis kompiliert das Grundsystem, bestehend aus den drei Flashdateien und den grundlegenden Kommandos im Systemverzeichnis. Ist ein erster Versuch. Was noch fehlt ist ein Fehlerlog und vielleicht noch die anderen Programme.
09-06-2010-dr235
Nach nur zwei Tagen hat drohne085 (frida) das Geheimnis um die Bootroutine gelöst: Die Ursache lag in einer von der FATEngine verwendeten Semaphore, welche fest auf den Lock 0 "verdrahtet" war. Diese Semaphore wird an diversen Stellen in der Engine verwendet, wurde aber beim Bootvorgang nicht gelöscht oder freigegeben! Gedacht war sie, um den Bus zur SD-Card bei einem Zugriff zu verriegeln, falls mehrere Instanzen der Engine laufen, und gleichzeitig zugreifen wollen. Somit hat sich die Engine quasi selbst verriegelt und nach dem Bootvorgang als "neue Instanz" nun auch keinen Zugriff mehr - so schön kann praktische Parallelverarbeitung sein... ;)
Hier nun eine neue und aktuelle Version mit einer temporären funktionierenden Lösung des Problems.
Im System-Ordner gibt es jetzt folgende ausführbare Administra-Dateien:
admflash.adm Standard-Flash, welches auch im EEProm gespeichert ist
admini.adm Mini-Flash ohne Sound, nor SDCard + Managment-Routinen
admled.adm Das Heartbeat-LED-Testprogramm zum direkten laden
aterm96.adm Die leicht modifizierte Kommandozeile vom Programmierer der FATEngine. Mit
diesem Administra-Code kann man direkt über die Hostschnittstelle (9600 Baud)
mit dem Chip kommunizieren. Dokumentation der Kommandos findet man im
Verzeichnis "komponenten/fat/fatengine beta"
07-06-2010-dr235
Hier der aktuelle Stand von TriOS. Momentan kämpfe ich an einem
Komplexfehler mit dem Bootloader von Administra. Das Problem ist recht
einfach zu reproduzieren, aber leider (für mich) nur schwer zu
erfasen: Die verwendete FATEngine besitzt eine Bootfunktion um einen
neuen BIN-Objektcode in den Propeller zu laden. Dieser Code funktioniert
auch teilweise. So kann man das Administra-Bios selbst laden und dann
auch per Regime-Kommandos verwenden: Die Kommandos "cogs" und "sysinfo"
sprechen Administra-Funktionen an, welche auch korrekt ausgeführt werden.
Das Problem: Nach dem Bootprozess kann man keine SD-Card mehr mounten.
Es ist auch möglich den Fehler noch weiter einzugrenzen: Wenn man die
originale FATEngine (im Verzeichnis komponenten/fat) vom Host direkt in
Administra startet, meldet sich diese in Form einer einfachen Kommando-
zeile per Hostschnittstelle. Versucht man dort eine erzeugte BIN-Datei
genau dieser Kommandozeile (demo.spin) zu booten, so hat man das gleiche
Ergebnis.
Verzeichnisstruktur:
bin - BIN-Dateien für die Flash's und die SD-Card
doku -
flash - Quelltexte für die Software in den EEProms
system - Quelltext für ausführbare BIN-Dateien
zubehör - Kleine Zusatzprogramme (StarTracker, Boulder Dash...)
komponenten - Div. verwendete Objekte (FATEngine, SIDCog...)
Installation:
1. Flashen der drei EEProms mit den BIN-Dateien aus "bin/flash" oder
über das Propellertool aus den Quellen "flash".
2. SD-Card erstellen: Einfach alles aus "bin/sd-card" auf eine FAT16/32
Karte kopieren.
Das System bootet Regnatix und Bellatrix beim Systemstart aus den Dateien
"adm.sys", "reg.sys" bzw. "bel.sys". Diese Dateien können auch das Hidden-Bit gesetzt
haben. Externe Kommandos bzw. ausführbare BIN-Dateien werden im aktuellen
UND im System-Verzeichnis gesucht - alle Systemkommandos können also in das
System-Verzeichnis kopiert werden.
Hilfe gibt es meist über das Kommando "help" oder den Parameter "/h".

79
make.bat Normal file
View File

@ -0,0 +1,79 @@
echo on
date /T
time /T
REM Pfade
set sd=".\bin\sdcard"
set sd-sys=".\bin\sdcard\system"
set flash=".\bin\flash"
set libpath=".\lib"
set BSTC=bstc.exe
REM ----------------------------------------------------------------
REM Alte Versionen löschen
del %flash%\*.* /Q
del %sd%\*.* /Q
del %sd-sys%\*.* /Q
REM ----------------------------------------------------------------
REM Flashdateien erzeugen
REM --> \bin\flash
%BSTC% -L %libpath% -b -O a .\flash\administra\admflash.spin
copy admflash.binary %flash%
rename admflash.binary admsys.adm
move admsys.adm %sd-sys%
%BSTC% -L %libpath% -D __VGA -b -O a .\flash\bellatrix\belflash.spin
copy belflash.binary %flash%
rename belflash.binary vga.bel
move vga.bel %sd-sys%
%BSTC% -L %libpath% -D __TV -b -O a .\flash\bellatrix\belflash.spin
rename belflash.binary tv.bel
move tv.bel %sd-sys%
%BSTC% -L %libpath% -b -O a .\flash\regnatix\regflash.spin
move regflash.binary %flash%
REM ----------------------------------------------------------------
REM Startdateie erzeugen
REM reg.sys (Regime)
REM --> \bin\sdcard\
%BSTC% -L %libpath% -b -O a .\system\regnatix\regime.spin
rename regime.binary reg.sys
move reg.sys %sd%
REM ----------------------------------------------------------------
REM Slave-Dateien erzeugen
REM admsid, admay, admterm
REM htxt, g0key
%BSTC% -L %libpath% -b -O a .\system\administra\admsid\admsid.spin
%BSTC% -L %libpath% -b -O a .\system\administra\admay\admay.spin
rename *.binary *.adm
%BSTC% -L %libpath% -b -O a .\system\bellatrix\bel-htext\htext.spin
%BSTC% -L %libpath% -b -O a .\system\bellatrix\bel-g0\g0key.spin
rename *.binary *.bel
move *.adm %sd-sys%
move *.bel %sd-sys%
REM ----------------------------------------------------------------
REM Systemdateien erzeugen
REM - div. externe Kommandos
REM - div. Systemdateien (Farbtabellen usw.)
REM --> \bin\sdcard\system\
for %%x in (.\system\regnatix\*.spin) do %BSTC% -L %libpath% -b -O a %%x
rename *.binary *.bin
move *.bin %sd-sys%
copy .\forth\*.* %sd-sys%
copy .\system\sonstiges %sd-sys%
echo off

6
makelog.bat Normal file
View File

@ -0,0 +1,6 @@
echo off
echo Erstelle TriOS...
call make.bat > make.log
echo Fertig!
pause

View File

@ -0,0 +1,871 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Autor: Ingo Kripahle, V.Pohlers (AY-Einbau) │
│ 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 : TriOS
Name : Administra-Flash
Chip : Administra
Typ : Flash
Version : 00
Subversion : 01
Funktion : Diese Codeversion basiert auf admini.spin und wird durch eine YM-Chip-Emulation als
Soundfunktion erweitert.
Dieser Code wird von Administra nach einem Reset aus dem EEProm in den hRAM kopiert
und gestartet. Im Gegensatz zu Bellatrix und Regnatix, die einen Loader aus dem EEProm
laden und entsprechende Systemdateien vom SD-Cardlaufwerk booten, also im
wesentlichen vor dem Bootvorgang keine weiter Funktionalität als die Ladeprozedur
besitzen, muß das EEProm-Bios von Administra mindestens die Funktionalität des
SD-Cardlaufwerkes zur Verfügung stellen können. Es erscheint deshalb sinnvoll, dieses
BIOS gleich mit einem ausgewogenen Funktionsumfang auszustatten, welcher alle Funktionen
für das System bietet. Durch eine Bootoption kann dieses BIOS aber zur Laufzeit
ausgetauscht werden, um das Funktionssetup an konkrete Anforderungen anzupassen.
Chip-Managment-Funktionen
- Bootfunktion für Administra
- Abfrage und Verwaltung des aktiven Soundsystems
- Abfrage Version und Spezifikation
SD-Funktionen:
- FAT32 oder FAT16
- Partitionen bis 1TB und Dateien bis 2GB
- Verzeichnisse
- Verwaltung aller Dateiattribute
- DIR-Marker System
- Verwaltung eines Systemordners
- Achtung: Keine Verwaltung von mehreren geöffneten Dateien!
Komponenten : FATEngine 01/18/2009 Kwabena W. Agyeman MIT Lizenz
RTCEngine 11/22/2009 Kwabena W. Agyeman MIT Lizenz
COG's : MANAGMENT 1 COG
FAT/RTC 1 COG
-------------------
2 Cogs
Logbuch :
06-05-2010-dr235 - erste version aus admflash.spin extrahiert
09-06-2010-dr085 - frida hat den fehler gefunden, welcher eine korrekte funktion der fatengine
nach einem bootvorgang von administra verhinderte :)
13-06-2010-dr235 - fehler in sd_volname korrigiert
- free/used auf fast umgestellt
18-06-2010-dr085 - fehler bei der businitialisierung: beim systemstart wurde ein kurzer impuls
auf der hs-leitung erzeugt, wodurch ein buszyklus verloren ging (symptom:
flashte man admin, so lief das system erst nach einem reset an)
- fatengine: endgültige beseitigung der feherhaften volname-abfrage
17-08-2010-dr040 - YM-Einschluss
Kommandoliste :
Notizen :
Bekannte Fehler :
}}
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
' +----------
' | +------- system
' | | +---- version (änderungen)
' | | | +- subversion (hinzufügungen)
CHIP_VER = $00_01_01_01
CHIP_SPEC = gc#A_FAT|gc#A_LDR|gc#A_AYS
'
' hbeat --------+
' clk -------+|
' /wr ------+||
' /hs -----+||| +------------------------- /cs
' |||| | +------+ d0..d7
' |||| | | |
DB_IN = %00001001_00000000_00000000_00000000 'dira-wert für datenbuseingabe
DB_OUT = %00001001_00000000_00000000_11111111 'dira-wert für datenbusausgabe
M1 = %00000010_00000000_00000000_00000000 'busclk=1? & /prop1=0?
M2 = %00000010_10000000_00000000_00000000 'maske: busclk & /cs (/prop1)
M3 = %00000000_00000000_00000000_00000000 'busclk=0?
M4 = %00000010_00000000_00000000_00000000 'maske: busclk
LED_OPEN = gc#HBEAT 'led-pin für anzeige "dateioperation"
SD_BASE = gc#A_SDD0 'baspin cardreader
'index für dmarker
#0, RMARKER 'root
SMARKER 'system
UMARKER 'programmverzeichnis
AMARKER
BMARKER
CMARKER
OBJ
sdfat : "adm-fat" 'fatengine
ay : "adm-ay" 'AYcog - AY-3-891X / YM2149 emulator
gc : "glob-con" 'globale konstanten
VAR
long dmarker[6] 'speicher für dir-marker
byte tbuf[20] 'stringpuffer
byte tbuf2[20]
' byte sfxdat[16 * 32] 'sfx-slotpuffer
' byte fl_eof '1 = eof
byte AYregs[16] 'AY-Register
CON ''------------------------------------------------- ADMINISTRA
PUB main | cmd,err 'chip: kommandointerpreter
''funktionsgruppe : chip
''funktion : kommandointerpreter
''eingabe : -
''ausgabe : -
init_chip 'bus/vga/keyboard/maus initialisieren
repeat
cmd := bus_getchar 'kommandocode empfangen
err := 0
case cmd
0: !outa[LED_OPEN] 'led blinken
' ---------------------------------------------- SD-FUNKTIONEN
gc#a_sdMount: sd_mount("M") 'sd-card mounten '
gc#a_sdOpenDir: sd_opendir 'direktory öffnen
gc#a_sdNextFile: sd_nextfile 'verzeichniseintrag lesen
gc#a_sdOpen: sd_open 'datei öffnen
gc#a_sdClose: sd_close 'datei schließen
gc#a_sdGetC: sd_getc 'zeichen lesen
gc#a_sdPutC: sd_putc 'zeichen schreiben
gc#a_sdGetBlk: sd_getblk 'block lesen
gc#a_sdPutBlk: sd_putblk 'block schreiben
gc#a_sdSeek: sd_seek 'zeiger in datei positionieren
gc#a_sdFAttrib: sd_fattrib 'dateiattribute übergeben
gc#a_sdVolname: sd_volname 'volumelabel abfragen
gc#a_sdCheckMounted: sd_checkmounted 'test ob volume gemounted ist
gc#a_sdCheckOpen: sd_checkopen 'test ob eine datei geöffnet ist
gc#a_sdCheckUsed: sd_checkused 'test wie viele sektoren benutzt sind
gc#a_sdCheckFree: sd_checkfree 'test wie viele sektoren frei sind
gc#a_sdNewFile: sd_newfile 'neue datei erzeugen
gc#a_sdNewDir: sd_newdir 'neues verzeichnis wird erzeugt
gc#a_sdDel: sd_del 'verzeichnis oder datei löschen
gc#a_sdRename: sd_rename 'verzeichnis oder datei umbenennen
gc#a_sdChAttrib: sd_chattrib 'attribute ändern
gc#a_sdChDir: sd_chdir 'verzeichnis wechseln
gc#a_sdFormat: sd_format 'medium formatieren
gc#a_sdUnmount: sd_unmount 'medium abmelden
gc#a_sdDmAct: sd_dmact 'dir-marker aktivieren
gc#a_sdDmSet: sd_dmset 'dir-marker setzen
gc#a_sdDmGet: sd_dmget 'dir-marker status abfragen
gc#a_sdDmClr: sd_dmclr 'dir-marker löschen
gc#a_sdDmPut: sd_dmput 'dir-marker status setzen
gc#a_sdEOF: sd_eof 'eof abfragen
' ---------------------------------------------- CHIP-MANAGMENT
gc#a_mgrGetSpec: mgr_getspec 'spezifikation abfragen
gc#a_mgrALoad: mgr_aload 'neuen code booten
gc#a_mgrGetCogs: mgr_getcogs 'freie cogs abfragen
gc#a_mgrGetVer: mgr_getver 'codeversion abfragen
gc#a_mgrReboot: reboot 'neu starten
' ---------------------------------------------- AY-SOUNDFUNKTIONEN
gc#a_ayStart: ay_start
gc#a_ayStop: ay_stop
gc#a_ayUpdateRegisters: ay_updateRegisters
PUB init_chip|i 'chip: initialisierung des administra-chips
''funktionsgruppe : chip
''funktion : - initialisierung des businterface
'' - grundzustand definieren (hss aktiv, systemklänge an)
''eingabe : -
''ausgabe : -
repeat i from 0 to 7 'evtl. noch laufende cogs stoppen
ifnot i == cogid
cogstop(i)
'debugverbindung
'debugx.start(115200) ' Start des Debug-Terminals
'businterface initialisieren
outa[gc#bus_hs] := 1 'handshake inaktiv ,frida
dira := db_in 'datenbus auf eingabe schalten ,frida
'sd-card starten
clr_dmarker 'dir-marker löschen
sdfat.FATEngine
sd_mount("B")
PUB bus_putchar(zeichen) 'chip: ein byte über bus ausgeben
''funktionsgruppe : chip
''funktion : senderoutine für ein byte zu regnatix über den systembus
''eingabe : byte zeichen
''ausgabe : -
waitpeq(M1,M2,0) 'busclk=1? & /prop1=0?
dira := db_out 'datenbus auf ausgabe stellen
outa[7..0] := zeichen 'daten ausgeben
outa[gc#bus_hs] := 0 'daten gültig
waitpeq(M3,M4,0) 'busclk=0?
outa[gc#bus_hs] := 1 'daten ungültig
dira := db_in 'bus freigeben
PUB bus_getchar : zeichen 'chip: ein byte über bus empfangen
''funktionsgruppe : chip
''funktion : emfangsroutine für ein byte von regnatix über den systembus
''eingabe : -
''ausgabe : byte zeichen
waitpeq(M1,M2,0) 'busclk=1? & /prop1=0?
zeichen := ina[7..0] 'daten einlesen
outa[gc#bus_hs] := 0 'daten quittieren
outa[gc#bus_hs] := 1
waitpeq(M3,M4,0) 'busclk=0?
PUB clr_dmarker| i 'chip: dmarker-tabelle löschen
''funktionsgruppe : chip
''funktion : dmarker-tabelle löschen
''eingabe : -
''ausgabe : -
i := 0
repeat 6 'alle dir-marker löschen
dmarker[i++] := TRUE
CON ''------------------------------------------------- SUBPROTOKOLL-FUNKTIONEN
PUB sub_getstr | i,len 'sub: string einlesen
''funktionsgruppe : sub
''funktion : subprotokoll um einen string von regnatix zu empfangen und im
'' : textpuffer (tbuf) zu speichern
''eingabe : -
''ausgabe : -
''busprotokoll : [get.len][get.byte(1)]..[get.byte(len)]
'' : len - länge des dateinamens
repeat i from 0 to 19 'puffer löschen und kopieren
tbuf2[i] := tbuf[i]
tbuf[i] := 0
len := bus_getchar 'längenbyte name empfangen
repeat i from 0 to len - 1 'dateiname einlesen
tbuf[i] := bus_getchar
PUB sub_putstr(strptr)|len,i 'sub: string senden
''funktionsgruppe : sub
''funktion : subprotokoll um einen string an regnatix zu senden
''eingabe : strptr - zeiger auf einen string (0-term)
''ausgabe : -
''busprotokoll : [put.len][put.byte(1)]..[put.byte(len)]
'' : len - länge des dateinamens
len := strsize(strptr)
bus_putchar(len)
repeat i from 0 to len - 1 'string übertragen
bus_putchar(byte[strptr][i])
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
PUB mgr_aload | err 'cmgr: neuen administra-code booten
''funktionsgruppe : cmgr
''funktion : administra mit neuem code booten
''eingabe :
''ausgabe :
''busprotokoll : [096][sub_getstr.fn]
'' : fn - dateiname des neuen administra-codes
sub_getstr
err := \sdfat.bootPartition(@tbuf, "C")
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 : [097][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 getcogs: cogs |i,c,cog[8] 'cmgr: abfragen wie viele cogs in benutzung sind
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
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)
''version : $00_00_00_00
''
sub_putlong(CHIP_VER)
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 : [089][sub_putlong.spec]
'' : spec - spezifikation
''
'' +---------- com
'' | +-------- i2c
'' | |+------- rtc
'' | ||+------ lan
'' | |||+----- sid
'' | ||||+---- wav
'' | |||||+--- hss
'' | ||||||+-- bootfähig
'' | |||||||+- dateisystem
''spezifikation : %00000000_00000000_00000000_01001111
sub_putlong(CHIP_SPEC)
CON ''------------------------------------------------- SD-LAUFWERKS-FUNKTIONEN
PUB sd_mount(mode) | err 'sdcard: sd-card mounten frida
''funktionsgruppe : sdcard
''funktion : eingelegtes volume mounten
''eingabe : -
''ausgabe : -
''busprotokoll : [001][put.error]
'' : error - fehlernummer entspr. list
ifnot sdfat.checkPartitionMounted 'frida
err := \sdfat.mountPartition(0,0) 'karte mounten
'bus_putchar(err) 'fehlerstatus senden
if mode == "M" 'frida
bus_putchar(err) 'fehlerstatus senden
ifnot err
dmarker[RMARKER] := sdfat.getDirCluster 'root-marker setzen
err := \sdfat.changeDirectory(string("system"))
ifnot err
dmarker[SMARKER] := sdfat.getDirCluster 'system-marker setzen
sdfat.setDirCluster(dmarker[RMARKER]) 'root-marker wieder aktivieren
else 'frida
bus_putchar(0) 'frida
PUB sd_opendir | err 'sdcard: verzeichnis öffnen
''funktionsgruppe : sdcard
''funktion : verzeichnis öffnen
''eingabe : -
''ausgabe : -
''busprotokoll : [002]
err := \sdfat.listReset
PUB sd_nextfile | strpt 'sdcard: nächsten eintrag aus verzeichnis holen
''funktionsgruppe : sdcard
''funktion : nächsten eintrag aus verzeichnis holen
''eingabe : -
''ausgabe : -
''busprotokoll : [003][put.status=0]
'' : [003][put.status=1][sub_putstr.fn]
'' : status - 1 = gültiger eintrag
'' : 0 = es folgt kein eintrag mehr
'' : fn - verzeichniseintrag string
strpt := \sdfat.listName 'nächsten eintrag holen
if strpt 'status senden
bus_putchar(1) 'kein eintrag mehr
sub_putstr(strpt)
else
bus_putchar(0) 'gültiger eintrag folgt
PUB sd_open | err,modus 'sdcard: datei öffnen
''funktionsgruppe : sdcard
''funktion : eine bestehende datei öffnen
''eingabe : -
''ausgabe : -
''busprotokoll : [004][get.modus][sub_getstr.fn][put.error]
'' : modus - "A" Append, "W" Write, "R" Read
'' : fn - name der datei
'' : error - fehlernummer entspr. list
modus := bus_getchar 'modus empfangen
sub_getstr
err := \sdfat.openFile(@tbuf, modus)
bus_putchar(err) 'ergebnis der operation senden
outa[LED_OPEN] := 1
PUB sd_close | err 'sdcard: datei schließen
''funktionsgruppe : sdcard
''funktion : die aktuell geöffnete datei schließen
''eingabe : -
''ausgabe : -
''busprotokoll : [005][put.error]
'' : error - fehlernummer entspr. list
err := \sdfat.closeFile
bus_putchar(err) 'ergebnis der operation senden
outa[LED_OPEN] := 0
PUB sd_getc | n 'sdcard: zeichen aus datei lesen
''funktionsgruppe : sdcard
''funktion : zeichen aus datei lesen
''eingabe : -
''ausgabe : -
''busprotokoll : [006][put.char]
'' : char - gelesenes zeichen
n := \sdfat.readCharacter
bus_putchar(n)
PUB sd_putc 'sdcard: zeichen in datei schreiben
''funktionsgruppe : sdcard
''funktion : zeichen in datei schreiben
''eingabe : -
''ausgabe : -
''busprotokoll : [007][get.char]
'' : char - zu schreibendes zeichen
\sdfat.writeCharacter(bus_getchar)
PRI sd_eof 'sdcard: eof abfragen
''funktionsgruppe : sdcard
''funktion : eof abfragen
''eingabe : -
''ausgabe : -
''busprotokoll : [030][put.eof]
'' : eof - eof-flag
bus_putchar(sdfat.getEOF)
PUB sd_getblk 'sdcard: block aus datei lesen
''funktionsgruppe : sdcard
''funktion : block aus datei lesen
''eingabe : -
''ausgabe : -
''busprotokoll : [008][sub_getlong.count][put.char(1)]..[put.char(count)]
'' : count - anzahl der zu lesenden zeichen
'' : char - gelesenes zeichen
repeat sub_getlong
bus_putchar(\sdfat.readCharacter)
PUB sd_putblk 'sdcard: block in datei schreiben
''funktionsgruppe : sdcard
''funktion : block in datei schreiben
''eingabe : -
''ausgabe : -
''busprotokoll : [009][sub_getlong.count][put.char(1)]..[put.char(count)]
'' : count - anzahl der zu schreibenden zeichen
'' : char - zu schreibende zeichen
repeat sub_getlong
\sdfat.writeCharacter(bus_getchar)
PUB sd_seek | wert 'sdcard: zeiger in datei positionieren
''funktionsgruppe : sdcard
''funktion : zeiger in datei positionieren
''eingabe : -
''ausgabe : -
''busprotokoll : [010][sub_getlong.pos]
'' : pos - neue zeichenposition in der datei
wert := sub_getlong
\sdfat.setCharacterPosition(wert)
PUB sd_fattrib | anr,wert 'sdcard: dateiattribute übergeben
''funktionsgruppe : sdcard
''funktion : dateiattribute abfragen
''eingabe : -
''ausgabe : -
''busprotokoll : [011][get.anr][sub_putlong.wert]
'' : anr - 0 = Dateigröße
'' : 1 = Erstellungsdatum - Tag
'' : 2 = Erstellungsdatum - Monat
'' : 3 = Erstellungsdatum - Jahr
'' : 4 = Erstellungsdatum - Sekunden
'' : 5 = Erstellungsdatum - Minuten
'' : 6 = Erstellungsdatum - Stunden
'' : 7 = Zugriffsdatum - Tag
'' : 8 = Zugriffsdatum - Monat
'' : 9 = Zugriffsdatum - Jahr
'' : 10 = Änderungsdatum - Tag
'' : 11 = Änderungsdatum - Monat
'' : 12 = Änderungsdatum - Jahr
'' : 13 = Änderungsdatum - Sekunden
'' : 14 = Änderungsdatum - Minuten
'' : 15 = Änderungsdatum - Stunden
'' : 16 = Read-Only-Bit
'' : 17 = Hidden-Bit
'' : 18 = System-Bit
'' : 19 = Direktory
'' : 20 = Archiv-Bit
'' : wert - wert des abgefragten attributes
anr := bus_getchar
case anr
0: wert := \sdfat.listSize
1: wert := \sdfat.listCreationDay
2: wert := \sdfat.listCreationMonth
3: wert := \sdfat.listCreationYear
4: wert := \sdfat.listCreationSeconds
5: wert := \sdfat.listCreationMinutes
6: wert := \sdfat.listCreationHours
7: wert := \sdfat.listAccessDay
8: wert := \sdfat.listAccessMonth
9: wert := \sdfat.listAccessYear
10: wert := \sdfat.listModificationDay
11: wert := \sdfat.listModificationMonth
12: wert := \sdfat.listModificationYear
13: wert := \sdfat.listModificationSeconds
14: wert := \sdfat.listModificationMinutes
15: wert := \sdfat.listModificationHours
16: wert := \sdfat.listIsReadOnly
17: wert := \sdfat.listIsHidden
18: wert := \sdfat.listIsSystem
19: wert := \sdfat.listIsDirectory
20: wert := \sdfat.listIsArchive
sub_putlong(wert)
PUB sd_volname 'sdcard: volumenlabel abfragen
''funktionsgruppe : sdcard
''funktion : name des volumes überragen
''eingabe : -
''ausgabe : -
''busprotokoll : [012][sub_putstr.volname]
'' : volname - name des volumes
'' : len - länge des folgenden strings
sub_putstr(\sdfat.listVolumeLabel) 'label holen und senden
PUB sd_checkmounted 'sdcard: test ob volume gemounted ist
''funktionsgruppe : sdcard
''funktion : test ob volume gemounted ist
''eingabe : -
''ausgabe : -
''busprotokoll : [013][put.flag]
'' : flag - 0 = unmounted, 1 mounted
bus_putchar(\sdfat.checkPartitionMounted)
PUB sd_checkopen 'sdcard: test ob eine datei geöffnet ist
''funktionsgruppe : sdcard
''funktion : test ob eine datei geöffnet ist
''eingabe : -
''ausgabe : -
''busprotokoll : [014][put.flag]
'' : flag - 0 = not open, 1 open
bus_putchar(\sdfat.checkFileOpen)
PUB sd_checkused 'sdcard: anzahl der benutzten sektoren senden
''funktionsgruppe : sdcard
''funktion : anzahl der benutzten sektoren senden
''eingabe : -
''ausgabe : -
''busprotokoll : [015][sub_putlong.used]
'' : used - anzahl der benutzten sektoren
sub_putlong(\sdfat.checkUsedSectorCount("F"))
PUB sd_checkfree 'sdcard: anzahl der freien sektoren senden
''funktionsgruppe : sdcard
''funktion : anzahl der freien sektoren senden
''eingabe : -
''ausgabe : -
''busprotokoll : [016][sub_putlong.free]
'' : free - anzahl der freien sektoren
sub_putlong(\sdfat.checkFreeSectorCount("F"))
PUB sd_newfile | err 'sdcard: eine neue datei erzeugen
''funktionsgruppe : sdcard
''funktion : eine neue datei erzeugen
''eingabe : -
''ausgabe : -
''busprotokoll : [017][sub_getstr.fn][put.error]
'' : fn - name der datei
'' : error - fehlernummer entspr. liste
sub_getstr
err := \sdfat.newFile(@tbuf)
bus_putchar(err) 'ergebnis der operation senden
PUB sd_newdir | err 'sdcard: ein neues verzeichnis erzeugen
''funktionsgruppe : sdcard
''funktion : ein neues verzeichnis erzeugen
''eingabe : -
''ausgabe : -
''busprotokoll : [018][sub_getstr.fn][put.error]
'' : fn - name des verzeichnisses
'' : error - fehlernummer entspr. liste
sub_getstr
err := \sdfat.newDirectory(@tbuf)
bus_putchar(err) 'ergebnis der operation senden
PUB sd_del | err 'sdcard: eine datei oder ein verzeichnis löschen
''funktionsgruppe : sdcard
''funktion : eine datei oder ein verzeichnis löschen
''eingabe : -
''ausgabe : -
''busprotokoll : [019][sub_getstr.fn][put.error]
'' : fn - name des verzeichnisses oder der datei
'' : error - fehlernummer entspr. liste
sub_getstr
err := \sdfat.deleteEntry(@tbuf)
bus_putchar(err) 'ergebnis der operation senden
PUB sd_rename | err 'sdcard: datei oder verzeichnis umbenennen
''funktionsgruppe : sdcard
''funktion : datei oder verzeichnis umbenennen
''eingabe : -
''ausgabe : -
''busprotokoll : [020][sub_getstr.fn1][sub_getstr.fn2][put.error]
'' : fn1 - alter name
'' : fn2 - neuer name
'' : error - fehlernummer entspr. liste
sub_getstr 'fn1
sub_getstr 'fn2
err := \sdfat.renameEntry(@tbuf2,@tbuf)
bus_putchar(err) 'ergebnis der operation senden
PUB sd_chattrib | err 'sdcard: attribute ändern
''funktionsgruppe : sdcard
''funktion : attribute einer datei oder eines verzeichnisses ändern
''eingabe : -
''ausgabe : -
''busprotokoll : [021][sub_getstr.fn][sub_getstr.attrib][put.error]
'' : fn - dateiname
'' : attrib - string mit attributen
'' : error - fehlernummer entspr. liste
sub_getstr
sub_getstr
err := \sdfat.changeAttributes(@tbuf2,@tbuf)
bus_putchar(err) 'ergebnis der operation senden
PUB sd_chdir | err 'sdcard: verzeichnis wechseln
''funktionsgruppe : sdcard
''funktion : verzeichnis wechseln
''eingabe : -
''ausgabe : -
''busprotokoll : [022][sub_getstr.fn][put.error]
'' : fn - name des verzeichnisses
'' : error - fehlernummer entspr. list
sub_getstr
err := \sdfat.changeDirectory(@tbuf)
bus_putchar(err) 'ergebnis der operation senden
PUB sd_format | err 'sdcard: medium formatieren
''funktionsgruppe : sdcard
''funktion : medium formatieren
''eingabe : -
''ausgabe : -
''busprotokoll : [023][sub_getstr.vlabel][put.error]
'' : vlabel - volumelabel
'' : error - fehlernummer entspr. list
sub_getstr
err := \sdfat.formatPartition(0,@tbuf,0)
bus_putchar(err) 'ergebnis der operation senden
PUB sd_unmount | err 'sdcard: medium abmelden
''funktionsgruppe : sdcard
''funktion : medium abmelden
''eingabe : -
''ausgabe : -
''busprotokoll : [024][put.error]
'' : error - fehlernummer entspr. list
err := \sdfat.unmountPartition
bus_putchar(err) 'ergebnis der operation senden
ifnot err
clr_dmarker
PUB sd_dmact|markernr 'sdcard: einen dir-marker aktivieren
''funktionsgruppe : sdcard
''funktion : ein ausgewählter dir-marker wird aktiviert
''eingabe : -
''ausgabe : -
''busprotokoll : [025][get.dmarker][put.error]
'' : dmarker - dir-marker
'' : error - fehlernummer entspr. list
markernr := bus_getchar
ifnot dmarker[markernr] == TRUE
sdfat.setDirCluster(dmarker[markernr])
bus_putchar(sdfat#err_noError)
else
bus_putchar(sdfat#err_noError)
PUB sd_dmset|markernr 'sdcard: einen dir-marker setzen
''funktionsgruppe : sdcard
''funktion : ein ausgewählter dir-marker mit dem aktuellen verzeichnis setzen
''eingabe : -
''ausgabe : -
''busprotokoll : [026][get.dmarker]
'' : dmarker - dir-marker
markernr := bus_getchar
dmarker[markernr] := sdfat.getDirCluster
PUB sd_dmget|markernr 'sdcard: einen dir-marker abfragen
''funktionsgruppe : sdcard
''funktion : den status eines ausgewählter dir-marker abfragen
''eingabe : -
''ausgabe : -
''busprotokoll : [027][get.dmarker][sub_putlong.dmstatus]
'' : dmarker - dir-marker
'' : dmstatus - status des markers
markernr := bus_getchar
sub_putlong(dmarker[markernr])
PRI sd_dmput|markernr 'sdcard: einen dir-marker übertragen
''funktionsgruppe : sdcard
''funktion : den status eines ausgewählter dir-marker übertragen
''eingabe : -
''ausgabe : -
''busprotokoll : [029][get.dmarker][sub_getlong.dmstatus]
'' : dmarker - dir-marker
'' : dmstatus - status des markers
markernr := bus_getchar
dmarker[markernr] := sub_getlong
PUB sd_dmclr|markernr 'sdcard: einen dir-marker löschen
''funktionsgruppe : sdcard
''funktion : ein ausgewählter dir-marker löschen
''eingabe : -
''ausgabe : -
''busprotokoll : [028][get.dmarker]
'' : dmarker - dir-marker
markernr := bus_getchar
dmarker[markernr] := TRUE
DAT ' AY-Routinen
PUB ay_start
ay.start( gc#A_SOUNDR, gc#A_SOUNDL, @AYregs ) 'audioR, audioL, @AYregs
PUB ay_stop
ay.stop
PUB ay_updateRegisters | i
repeat i from 0 to 13
AYregs[i] := bus_getchar
ifnot AYregs[13] == 255
AYregs[13] := AYregs[13]&15
DAT 'dummyroutine für getcogs
org
'
' Entry: dummy-assemblercode fuer cogtest
'
entry jmp entry 'just loops
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,935 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : VGA-Text-Treiber 1024x768 Pixel, 128x64 Zeichen
Chip : Bellatrix
Typ : Treiber
Version : 00
Subversion : 01
Funktion : VGA-Text- und Tastatur-Treiber
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
Kommandoliste:
0 1 Tastaturstatus abfragen
0 2 Tastaturzeichen holen
0 3 n Screensteuerzeichen
0 3 0 CLS
0 3 1 Home
0 3 2 Backspace
0 3 3 TAB
0 3 4 n SETCUR Cursorzeichen auf n setzen
0 3 5 POS1
0 3 6 x SETX
0 3 7 y SETY
0 3 8 (x) GETX
0 3 9 (y) GETY
0 3 10 c SETCOL
0 3 11 n SLINE
0 3 13 SCREENINIT
0 3 14 CURON
0 3 15 CUROFF
0 3 16 SCROLLUP
0 3 17 SCROLLDOWN
0 3 18 n0..n7 SETTABS
0 4 (status) Status der Sondertasten abfragen
0 5 x y Hive-Logo ausgeben
0 90 cnr (c0) (c1) Farbregister auslesen
0 91 cnr c0 c1 Farbregister setzen
0 92 (res-x)
0 93 (res-y)
0 94 (cols)
0 95 (rows)
0 96 (cogs) Status der belegten COG's abfragen
0 97 (spez) Spezifikation abfragen
0 98 (ver) Version abfragen
0 99 Reboot und neuen Treiber laden
1..255 Zeichenausgabe
Notizen:
- setheader
ACHTUNG: row ist nicht die Zeilenposition, da zwei tiles untereinander ein zeichen
bilden. vielmehr ist die reale zeilenposition row/2.
}}
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_01_01
'
' +----------
' | +--------
' | |+------- vektor
' | ||+------ grafik
' | |||+----- text
' | ||||+---- maus
' | |||||+--- tastatur
' | ||||||+-- vga
' | |||||||+- tv
CHIP_SPEC = %00000000_00000000_00000000_00010110
COLS = VGA#cols 'anzahl der spalten
ROWS = VGA#rows 'anzahl der zeilen
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
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
' 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-htext"
keyb : "bel-keyb"
VAR
long keycode 'letzter tastencode
long col, row, color 'spalten-, zeilenposition und zeichenfarbe
byte cursor 'cursorzeichen
byte curstat 'cursorstatus 1 = ein
byte sline 'startzeile des scrollfensters (0 = 1. zeile)
byte eline 'endzeile des scrollfensters (0 = 1. zeile)
byte tab[TABANZ] 'tabulatorpositionen
word user_charbase 'adresse der userzeichen
' htext-variablen
byte array[TILES] 'bildschirmspeicher
byte VGACogStatus 'status des vga-treiber-cogs
byte cx0, cy0, cm0 'x, y, mode von cursor 0
byte cx1, cy1, cm1 'x, y, mode von cursor 1
word colors[rows] 'zeilenfarbenspeicher
long ScreenIndex 'index im bildschirmspeicher
long RowIndex 'zeilenindex
long ColumnIndex 'spaltenindex
long sync 'gets signal for vertical refresh sync
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
' ---------------------------------------------- CHIP-MANAGMENT
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 'codeversion abfragen
98: mgr_getver '5: Belegte Cogs abfragen
99: reboot '99: 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
start_htext(vga_basport, @sync) 'vga-treiber starten
print_char($100) 'bildschirm löschen
cursor := CURSORCHAR 'cursorzeichen setzen
curstat := 1 'cursor anschalten
sline := 2 'startzeile des scrollbereichs setzen
eline := rows 'enbdzeile des scrollbereichs setzen
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
PUB start_htext(BasePin,pSyncAddress)| ColorIndex
vga.stop 'stopt ein bereits laufenden vga-task
cm0 := %000 'cursor 0 aus
cm1 := %110 'cursor 1 unterstrich blinkend
print_char($0E) 'bildschirm löschen
ColorIndex := 0 'graue balken auf scharzem grund
repeat rows
colors[ColorIndex++] := %00000100_01101000 'rrggbb00_rrggbb00
VGACogStatus := VGA.Start(BasePin,@array, @colors, @cx0, pSyncAddress) 'startet vga-treiber (2cogs)
return true
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
outa[bus_hs] := 1
waitpeq(M3,M4,0) 'busclk=0?
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
PUB mgr_getcolor|cnr 'cmgr: farbregister auslesen
''funktionsgruppe : cmgr
''funktion : farbregister auslesen
''eingabe : -
''ausgabe : -
''busprotokoll : [0][091][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
''
''
'' +----------
'' | +--------
'' | |+------- vektor
'' | ||+------ grafik
'' | |||+----- text
'' | ||||+---- maus
'' | |||||+--- tastatur
'' | ||||||+-- vga
'' | |||||||+- tv
''CHIP_SPEC = %00000000_00000000_00000000_00010110
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_01_01
sub_putlong(CHIP_VER)
CON ''------------------------------------------------- KEYBOARD-FUNKTIONEN
PUB key_stat 'key: tastaturstatus abfragen
bus_putchar(keyb.gotkey)
PUB key_code 'key: tastencode abfragen
keycode := keyb.key
bus_putchar(keycode)
PUB key_spec 'key: statustaten vom letzten tastencode abfragen
bus_putchar(keycode >> 8)
CON ''------------------------------------------------- SCREEN-FUNKTIONEN
PUB print_char(c) | code,n 'screen: zeichen auf bildschirm ausgeben
{{zeichen auf bildschirm ausgeben}}
case c
$0A: 'LF ausblenden
return
$00..$0C:
schar(c)
$0D: 'return?
newline
$0E..$FF: 'character?
schar(c)
PUB home
'' move writing place to upper left without clearing screen
SetXY(0,sline)
PUB SetXY(x,y)
ColumnIndex := x <# cols 'setzt spalte mit begrenzung auf spaltenzahl
RowIndex := y <# rows 'setzt zeile mit begrenzung auf zeilenzahl
ScreenIndex := ColumnIndex + (RowIndex * cols) 'berechnet bildschirmindex
PUB print_ctrl(c) | code,n,m 'screen: steuerzeichen ausgeben
case c
$00: 'clear screen?
ScreenIndex := 0
n := sline * cols
repeat TILES - n
array[n + ScreenIndex++] := 32
home
{
if curstat == 1 'cursor ausschalten?
schar($20)
n := sline * cols
'wordfill(@array + n, spacetile, tiles - n)
wordfill(@array.word[n], spacetile, tiles-n)
row := sline
col := 0
if curstat == 1 'cursor einschalten
schar(cursor)
}
$01: 'home?
row := sline
col := 0
$02: 'backspace?
if col
col--
$03: 'tab
repeat n from 0 to TABANZ-1
if col < tab[n]
col := tab[n]
quit
$04: 'setcur
code := bus_getchar
cursor := code
$05: 'pos1
col := 0
$06: 'setx
col := bus_getchar
$07: 'sety
row := bus_getchar * 2 + sline '2 tiles pro zeichen!
$08: 'getx
bus_putchar(col)
$09: 'gety
bus_putchar(row / 2)
$10: 'setcolor
color := bus_getchar
$11: 'sline
sline := bus_getchar * 2
$12: 'eline
eline := bus_getchar * 2
$13: 'screeninit
ScreenIndex := 0
repeat TILES
array[ScreenIndex++] := 32
RowIndex := 0
ColumnIndex := 0
sline := 0
{
wordfill(@array, spacetile, tiles)
row := 0
col := 0
sline := 0
}
$14: 'curon
curstat := 1
$15: 'curoff
curstat := 0
$16: 'scrollup
scrollup
$17: 'scrolldown
scrolldown
$18: 'tabulator setzen
n := bus_getchar
m := bus_getchar
if n =< (TABANZ-1)
tab[n] := m
PRI xschar(c)| i,k 'screen: schreibt zeichen an aktuelle position ohne cursor
k := color << 1 + c & 1
i := $8000 + (c & $FE) << 6 + k
array.word[row * cols + col] := i 'oberes tile setzen
array.word[(row + 1) * cols + col] := i | $40 'unteres tile setzen
PRI schar(c) 'schreibt zeichen an aktuelle position ohne cursorposition zu verändern
array[RowIndex * cols + ColumnIndex] := c
if ++ColumnIndex == cols
newline
cx1 := ColumnIndex
cy1 := RowIndex
PRI xpchar(c) 'screen: schreibt zeichen mit cursor an aktuelle position
schar(c)
if ++col == cols
newline
PRI pchar(c)
'schreibt zeichen an aktuelle position z?hlt position weiter
schar(c)
if ++ColumnIndex == cols
newline
PUB xnewline | i 'screen: zeilenwechsel, inkl. scrolling am screenende
col := 0
if (row += 2) => eline
row -= 2
'scroll lines
repeat i from sline to eline-3
wordmove(@array.word[i*cols], @array.word[(i+2)*cols], cols) 'wordmove(dest,src,cnt)
'clear new line
wordfill(@array.word[(eline-2)*cols], spacetile, cols<<1)
PUB newline | i
ColumnIndex := 0
if (RowIndex += 1) == rows
RowIndex -= 1
'scroll lines
repeat i from sline to rows-2
bytemove(@array[i*cols], @array[(i+1)*cols], cols) 'BYTEMOVE (DestAddress, SrcAddress, Count)
'clear new line
' bytefill(@array[(rows-1)*cols], 32, cols<<1) 'BYTEFILL (StartAddress, Value, Count)
' code fehlerhaft, zähler ist falsch gesetzt!
bytefill(@array[(rows-1)*cols], 32, cols) 'BYTEFILL (StartAddress, Value, Count)
PUB scrollup | i 'screen: scrollt den screen nach oben
'scroll lines
wordmove(@array.word[sline*cols],@array.word[(sline+2)*cols],(eline-1-sline)*cols) 'wordmove(dest,src,cnt)
'clear new line
wordfill(@array.word[(eline-2)*cols], spacetile, cols<<1)
PUB scrolldown | i 'screen: scrollt den screen nach unten
'scroll lines
i := eline - 1
repeat eline-sline-1
wordmove(@array.word[i*cols], @array.word[(i-2)*cols], cols) 'wordmove(dest,src,cnt)
i--
'clear new line
wordfill(@array.word[(sline)*cols], spacetile, cols<<1)
PRI print_logo|padr,x,y 'screen: hive-logo ausgeben
x := bus_getchar
y := bus_getchar
padr := @hive+user_charbase-@uchar
DrawBitmap(padr, x, y, 8, 2, 1) 'logo zeichnen
PRI DrawBitmap(pBitmap, xPos, yPos, xSize, ySize, clr)|c,i,j,pcol,prow '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
}
prow:=yPos
pcol:=xPos
c:=0
repeat j from 0 to (ySize-1)
repeat i from 0 to (xSize-1)
array.word[prow * cols + pcol] := pBitmap + (c<<6) + clr
c++
pcol++
prow++
pcol:=xPos
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

Binary file not shown.

75
system/license.spin Normal file
View File

@ -0,0 +1,75 @@
{{
Template für TriOS-Quelltextdateien
Diese Datei ist eine Vorlage für die Quelltexte. Alle Komponenten für das Hive-Projekt und auch alle
Objekte aus dem Object Exchange (OBEX) der Firma Parallax unterliegen durchgängig der MIT-Lizenz.
Die Dateien bestehen aus drei Teilen:
1. Urheberrechtsvermerk
2. Technische Informationen
3. Erlaubnisvermerk
Urheberrechtsvermerk und die technischen Informationen befinden sich am Anfang, Erlaubnisvermerk am
Ende des Quelltextes. Die technischen Informationen sind in vielen Fällen nur in der Hauptdatei nötig
und werden in den Unterdateien von eingebundenen Objekten nicht benötigt - oder es sind dort eigene
spezifische technische Informationen nötig. Die Hauptdatei enthält in diesen Fällen aber als Teil der
technischen Informationen Verweise und Versionsinformationen der Unterdateien.
Es ist wichtig, dass jede Datei korrekte Urheberrechts- und Erlaubnisvermerk enthält, um dem
Gesamtprojekt den Open Source Status zu gewähren.
}}
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Autor: <autor(en)> │
│ Copyright (c) <Jahr> <Urheber> │
│ See end of file for terms of use. │
│ Die Nutzungsbedingungen befinden sich am Ende der Datei. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
Informationen : hive-project.de
Kontakt :
System : TriOS
Name :
Chip : <Administra/Bellatrix/Regnatix>
Typ : <Flash/Programm/Objekt/Treiber>
Version :
Subversion :
Funktion :
Komponenten : <Liste der verwendeten Objekte & Lizenzen>
COG's : <Liste der verwendeten COG's>
Logbuch :
Kommandoliste :
Notizen :
}}
CON
VAR
OBJ
PUB object_code
PRI private_code
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,763 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : Administra-Test
Chip : Regnatix
Typ : Programm
Version : 01
Subversion : 01
Funktion : Testroutinen für die Administra-Funktionen
Komponenten : stringEngine 7/10/2009 Kwabena W. Agyeman MIT Lizenz
COG's : -
Logbuch :
21-03-2010-dr235 - erste version
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
str: "glob-string"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
byte tbuf[32]
PUB main | fnr
ios.start
repeat
ios.screeninit
ios.print(string("Hive: Administra-Test [Auswahl Funktionskomplex]"))
ios.print(string(13,"1. chip-managment"))
ios.print(string(13,"2. sd-laufwerksfunktionen"))
ios.print(string(13,"3. hss-funktionen"))
ios.print(string(13,"4. wav-funktionen",13))
ios.print(string(13,"99 testprogramm beenden",13,13))
fnr := str.decimalToNumber(fInput(string("Funktion wählen : ")))
case fnr
1: menu_mgr
2: menu_sd
3: menu_hss
4: menu_wav
99: ios.stop
PUB menu_mgr | fnr
repeat
ios.screeninit
ios.print(string("▶ Hive: Administra-Test [Chip-Managment]"))
ios.print(string(13,"1. getver, getspez, getcogs"))
ios.print(string(13,"2. neuen administra-code booten (admled.adm)"))
ios.print(string(13,"88 alle tests"))
ios.print(string(13,"99 zurück",13,13))
fnr := str.decimalToNumber(fInput(string("Funktion wählen : ")))
case fnr
1: \fTest10
2: \fTest11
88:
99: return
PUB menu_sd | fnr
repeat
ios.screeninit
ios.print(string("▶ Hive: Administra-Test [SD-Laufwerksfunktionen]"))
ios.print(string(13,"1. mount, volname, free, unused, checkmount"))
ios.print(string(13,"2. daten schreiben + lesen"))
ios.print(string(13,"3. block schreiben + lesen"))
ios.print(string(13,"4. inhaltsverzeichnis"))
ios.print(string(13,"5. dateien/verzeichnisse erzeugen, umbenennen, löschen"))
ios.print(string(13,"6. positionieren in der datei"))
ios.print(string(13,"7. dateiattribute verändern"))
ios.print(string(13,"8. verzeichnis wechseln"))
ios.print(string(13,"9. format + unmount",13))
ios.print(string(13,"88 alle tests"))
ios.print(string(13,"99 zurück",13,13))
fnr := str.decimalToNumber(fInput(string("Funktion wählen : ")))
case fnr
1: \fTest1
2: \fTest2
3: \fTest3
4: \fTest4
5: \fTest5
6: \fTest6
7: \fTest7
8: \fTest8
9: \fTest9
88: \loop_sd
99: return
PUB menu_hss
PUB menu_wav
PUB loop_mgr
repeat
fTest10 'getver,getspec,getcogs
fTest11 'administra-code booten
PUB loop_sd
repeat
fTest1 'mount, volname, free, unused, checkmounted
fTest2 'daten schreiben + lesen
fTest3 'block schreiben + lesen
fTest4 'inhaltsverzeichnis
fTest5 'dateien erzeugen, umbenennen, löschen
fTest6 'seek
fTest7 'attribute ändern
fTest8 'cd
fTest9 'format + unmount
DAT 'test 1: mount & unmount
t1_s1 byte "Test1: Volume mounten",0
t1_s2 byte "[sdmount]",0
t1_s3 byte "[sdvolname] = ",0
t1_s4 byte "[sdcheckmounted] = ",0
t1_s5 byte "[sdcheckused] = ",0
t1_s6 byte "[sdcheckfree] = ",0
PRI fTest1 | err
fScreen(@t1_s1)
repeat
ios.print(@t1_s2) 'sdmount
err := ios.sdmount
fError(err)
fPrintResultDec(@t1_s4,ios.sdcheckmounted)
ifnot err
fPrintResultStr(@t1_s3,ios.sdvolname)
fPrintResultDec(@t1_s5,ios.sdcheckused)
fPrintResultDec(@t1_s6,ios.sdcheckfree)
until fAktion
DAT 'test 2: daten schreiben & lesen
t2_s1 byte "Test2: Daten schreiben und lesen ",0
t2_s2 byte "[sdopen-w]",0
t2_s3 byte "[sdputc] = ",0
t2_s4 byte "[sdclose]",0
t2_s5 byte "[sdnewfile]",0
t2_s6 byte "[sdgetc] = ",0
t2_s7 byte "[sdopen-r]",0
t2_s8 byte "Daten lesen...",0
t2_fn byte "admtest.dat",0
PRI fTest2 | err,i
fScreen(@t2_s1)
repeat
ios.print(@t1_s2) 'sdmount
err := ios.sdmount
fError(err)
ios.print(@t2_s5) 'sdnewfile
err := ios.sdnewfile(@t2_fn)
fError(err)
ios.print(@t2_s2)
err := ios.sdopen("W",@t2_fn) 'sdopen
fError(err)
ifnot err
ios.print(@t2_s3)
ios.printnl
i := 0
repeat 256
ios.printhex(i,2)
ios.printchar(" ")
ios.sdputc(i++) 'sdputc
ios.printnl
ios.print(@t2_s4)
fError(ios.sdclose) 'sdclose
fPause(@t2_s8)
ios.print(@t2_s7)
err := ios.sdopen("R",@t2_fn) 'sdopen
fError(err)
ifnot err
ios.print(@t2_s6)
ios.printnl
repeat 256
ios.printhex(ios.sdgetc,2) 'sdgetc
ios.printchar(" ")
ios.printnl
ios.print(@t2_s4)
fError(ios.sdclose) 'sdclose
until fAktion
DAT 'test 3: Block schreiben & lesen
t3_s1 byte "Test3: Block schreiben & lesen",0
t3_s2 byte "[sdnewfile]",0
t3_s3 byte "[sdopen-w]",0
t3_s4 byte "[sdopen-r]",0
t3_s5 byte "[sdclose]",0
t3_s6 byte "[sdputblk]",0
t3_s7 byte "[sdgetblk]",0
t3_s8 byte "Puffer mit Werten füllen...",0
t3_s9 byte "Puffer löschen...",0
t3_s10 byte "Puffer = ",0
t3_fn byte "admtest.dat",0
CON
blkcount = 256
VAR
byte buffer[blkcount]
PRI fTest3 | i,err
fScreen(@t3_s1)
repeat
i := 0
ios.print(@t3_s8) 'puffer mit werten füllen
ios.printnl
repeat blkcount
byte[@buffer][i++] := i
i := 0
ios.print(@t3_s10) 'puffer anzeigen
repeat blkcount
ios.printhex(byte[@buffer][i++],2)
ios.printchar(":")
fPause(@t3_s8)
ios.print(@t3_s3) 'puffer --> datei
err := ios.sdopen("W",@t3_fn)
fError(err)
ifnot err
ios.print(@t3_s6)
ios.printnl
ios.sdputblk(blkcount,@buffer)
ios.print(@t3_s5)
ios.sdclose
ios.printnl
i := 0
ios.print(@t3_s9) 'puffer löschen
repeat blkcount
byte[@buffer][i++] := 0
ios.print(@t3_s4) 'puffer <-- datei
err := ios.sdopen("R",@t3_fn)
fError(err)
ifnot err
ios.print(@t3_s6)
ios.printnl
ios.sdgetblk(blkcount,@buffer)
ios.print(@t3_s5)
ios.sdclose
ios.printnl
i := 0
ios.print(@t3_s10) 'puffer anzeigen
repeat blkcount
ios.printhex(byte[@buffer][i++],2)
ios.printchar(":")
until fAktion
DAT 'test 4: Inhaltsverzeichnis
t4_s1 byte "Test4: Inhaltsverzeichnis (einfach)",0
t4_s2 byte "[sddir] ",0
t4_s3 byte "[sdnext] = ",0
t4_s4 byte "Test4: Inhaltsverzeichnis (Attribute)",0
t4_s5 byte "DIR ▶ ",0
t4_s6 byte " ",0
PRI fTest4 | stradr
fScreen(@t4_s1)
repeat
fMount
ios.print(@t4_s2)
ios.sddir
repeat while (stradr := ios.sdnext)
ios.printnl
ios.print(@t4_s3)
ios.print(stradr)
fPause(@t4_s4)
ios.print(@t4_s2)
ios.sddir
repeat while (stradr := ios.sdnext)
ios.printnl
if ios.sdfattrib(ios#F_DIR) 'verzeichnisname
ios.print(@t4_s5)
ios.print(stradr)
else 'dateiname
ios.print(@t4_S6)
ios.print(stradr)
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_SIZE),10)) 'dateigröße
ios.printchar(" ") 'attribute
if ios.sdfattrib(ios#F_READONLY)
ios.printchar("r")
else
ios.printchar("-")
if ios.sdfattrib(ios#F_HIDDEN)
ios.printchar("h")
else
ios.printchar("-")
if ios.sdfattrib(ios#F_SYSTEM)
ios.printchar("s")
else
ios.printchar("-")
if ios.sdfattrib(ios#F_ARCHIV)
ios.printchar("a")
else
ios.printchar("-")
ios.printchar(" ") 'änderungsdatum
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CDAY),2))
ios.printchar(".")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMONTH),2) + 1)
ios.printchar(".")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CYEAR),4) + 1)
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CHOUR),2))
ios.printchar(":")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMIN),2) + 1)
ios.printchar(":")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CSEC),2) + 1)
until fAktion
DAT 'test 4: dateien/verzeichnisse erzeugen, umbenennen, löschen
t5_s1 byte "Test5: Dateien/Verzeichnisse erzeugen, umbenennen, löschen ",0
t5_s2 byte "[sdnewdir] : admtest",0
t5_s3 byte "[sdnewfile] : admtest.dat",0
t5_s4 byte "[sddel] : admtest + admtest.dat",0
t5_s5 byte "[sdrename] admtest -> admtest2",0
t5_s6 byte "admtest",0
t5_s7 byte 13,"pause ",0
t5_s8 byte "admtest.dat",0
t5_s9 byte "admtest2.dat",0
t5_s10 byte "admtest2",0
PRI fTest5 | err
fScreen(@t5_s1)
repeat
fMount
fPause(@t5_s7)
fDir
fPause(@t5_s7)
ios.print(@t5_s2)
ios.printnl
fError(ios.sdnewdir(@t5_s6))
fPause(@t5_s7)
fDir
fPause(@t5_s7)
ios.print(@t5_s3)
ios.printnl
fError(ios.sdnewfile(@t5_s8))
fPause(@t5_s7)
fDir
fPause(@t5_s7)
ios.print(@t5_s5)
ios.printnl
fError(ios.sdrename(@t5_s6,@t5_s10))
fError(ios.sdrename(@t5_s8,@t5_s9))
fPause(@t5_s7)
fDir
fPause(@t5_s7)
ios.print(@t5_s4)
ios.printnl
fError(ios.sddel(@t5_s10))
fError(ios.sddel(@t5_s9))
fPause(@t5_s7)
fDir
until fAktion
DAT 'test 6: seek
t6_s1 byte "Test6: seek ",0
t6_s2 byte "[sdopen] : test2.txt",0
t6_s3 byte "test2.txt",0
t6_s4 byte "Jetzt Test mit steigendem seek-Wert...",0
t6_s5 byte "[seek] = ",0
PRI fTest6 | i
fScreen(@t6_s1)
repeat
fMount
fError(ios.sdopen("R",@t6_s3))
repeat 128
ios.printchar(ios.sdgetc)
ios.sdclose
ios.printnl
fPause(@t6_s4)
repeat i from 0 to 64
ios.printcls
ios.print(@t6_s5)
ios.printdec(i)
ios.printnl
ios.printnl
ios.sdopen("R",@t6_s3)
ios.sdseek(i)
repeat 128
ios.printchar(ios.sdgetc)
ios.sdclose
' fWait(1)
until fAktion
DAT 'test 7: attribute ändern
t7_s1 byte "Test7: Attribute ändern ",0
t7_s2 byte "Testdatei [admtest.dat] erzeugen ",0
t7_s3 byte "admtest.dat",0
t7_s4 byte 13,"Attributstring eingeben <ASHR> : ",0
PRI fTest7
fScreen(@t7_s1)
fMount
ios.print(@t7_s2)
ios.printnl
fError(ios.sdnewfile(@t7_s3))
repeat
fDir
fError(ios.sdchattrib(@t7_s3,fInput(@t7_s4)))
until fAktion
fError(ios.sddel(@t7_s3))
DAT 'test 8: verzeichnis wechseln
t8_s1 byte "Test8: Verzeichnis wechseln ",0
t8_s2 byte "Testverzeichnis [admtest] erzeugen ",0
t8_s3 byte "admtest",0
t8_s4 byte 13,"pause",13,0
t8_s5 byte "..",0
PRI fTest8
fScreen(@t8_s1)
fMount 'medium mounten
ios.print(@t8_s2)
ios.printnl
fError(ios.sdnewdir(@t8_s3)) 'testverzeichnis erzeugen
repeat
fDir
fPause(@t8_s4)
fError(ios.sdchdir(@t8_s3)) 'in testverzeichnis wechseln
fDir
fPause(@t8_s4)
fError(ios.sdchdir(@t8_s5)) 'und wieder zurück zur wurzel
fDir
until fAktion
fError(ios.sddel(@t8_s3)) 'testverzeichnis löschen
DAT 'test 9: medium formatieren + abmelden
t9_s1 byte "Test9: Medium formatieren + abmelden ",0
t9_s2 byte "ACHTUNG: Medium wird jetzt formatiert!",13,"Testcard einlegen und bestätigen <JA> : ",0
t9_s3 byte "JA",0
t9_s4 byte "ADMTEST",0
t9_s5 byte "[sdformat] ... ",13,0
t9_s6 byte "[sdunmount] Medium wird jetzt abgemeldet...",13,0
PRI fTest9 | stradr
fScreen(@t9_s1)
repeat
stradr := fInput(@t9_s2)
fMount
if strcomp(stradr, @t9_s3)
ios.print(@t9_s5)
fError(ios.sdformat(@t9_s4))
ios.print(@t9_s6)
fError(ios.sdunmount)
until fAktion
DAT 'test 10: getver, getpsec, getcogs
t10_s1 byte "Test10: getver, getspec, getcogs ",0
t10_s2 byte 13,"Version : $",0
t10_s3 byte 13,"Specifikation : %",0
t10_s4 byte 13,"COGs : ",0
PRI fTest10
fScreen(@t10_s1)
repeat
ios.print(@t10_s2)
ios.printhex(ios.admgetver,8)
ios.print(@t10_s3)
ios.printbin(ios.admgetspec,32)
ios.print(@t10_s4)
ios.printhex(ios.admgetcogs,8)
until fAktion
DAT 'test 11: administra-code booten
t11_s1 byte "Test11: administra-code booten ",0
t11_s2 byte "admled.adm",0
PRI fTest11
fScreen(@t11_s1)
fMount
repeat
ios.admload(@t11_s2)
until fAktion
DAT 'test x:
tx_s1 byte "Testx: Beschreibung ",0
PRI fTestx
repeat
fPause(@tx_s1)
until fAktion
DAT 'fInput: stringeingabe
PRI fInput(stradr1): stradr2
ios.print(stradr1)
ios.input(@tbuf,32)
return @tbuf
DAT 'fWait: wartet eine def.zeit
PUB fWait(sek)
waitcnt(clkfreq * sek + cnt)
DAT 'fDir: Verzeichnis anzeigen
PUB fDir | stradr
ios.sddir
repeat while (stradr := ios.sdnext)
ios.printnl
if ios.sdfattrib(ios#F_DIR) 'verzeichnisname
ios.print(@t4_s5)
ios.print(stradr)
else 'dateiname
ios.print(@t4_S6)
ios.print(stradr)
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_SIZE),10)) 'dateigröße
ios.printchar(" ") 'attribute
if ios.sdfattrib(ios#F_READONLY)
ios.printchar("r")
else
ios.printchar("-")
if ios.sdfattrib(ios#F_HIDDEN)
ios.printchar("h")
else
ios.printchar("-")
if ios.sdfattrib(ios#F_SYSTEM)
ios.printchar("s")
else
ios.printchar("-")
if ios.sdfattrib(ios#F_ARCHIV)
ios.printchar("a")
else
ios.printchar("-")
ios.printchar(" ") 'änderungsdatum
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CDAY),2))
ios.printchar(".")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMONTH),2) + 1)
ios.printchar(".")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CYEAR),4) + 1)
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CHOUR),2))
ios.printchar(":")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CMIN),2) + 1)
ios.printchar(":")
ios.print(str.numberToDecimal(ios.sdfattrib(ios#F_CSEC),2) + 1)
DAT 'fMount: Medium einbinden
i_s1 byte 13,"Medium wird eingebunden...",0
PRI fMount | err
ios.print(@i_s1) 'sdmount
err := ios.sdmount
fError(err)
ifnot err
fPrintResultStr(@t1_s3,ios.sdvolname)
DAT 'fAktion: Aktion abfragen
a_s1 byte "<E>nde, <N>ochmal, <W>eiter : ",0
PRI fAktion: aktion
ios.printnl
ios.print(@a_s1)
case ios.keywait
"e": abort
"w": aktion := 1
"n": aktion := 0
ios.printnl
DAT 'fPause: Printausgabe und Pause
p_s1 byte "Weiter? <*> :",0
PRI fPause(strptr)
ios.print(strptr)
ios.printnl
ios.print(@p_s1)
ios.keywait
ios.printnl
DAT 'fScreen: Initialisierung neuer Test
s_s1 byte "Weiter? <*> :",0
PRI fScreen(strptr)
ios.screeninit
ios.print(strptr)
ios.print(@s_s1)
ios.keywait
ios.printnl
DAT 'fPrintResultStr: Testanzeige von Stringresultaten
PRI fPrintResultStr(strptr1,strptr2)
ios.print(strptr1)
ios.print(strptr2)
ios.printnl
DAT 'fPrintResultDec: Testanzeige von Dezimalwerten
PRI fPrintResultDec(strptr, wert)
ios.print(strptr)
ios.printdec(wert)
ios.printnl
DAT 'fError: Fehler ausgeben
f_s1 byte "Fehlernummer : ",0
f_s2 byte "Fehler : ",0
err0 byte "no error",0
err1 byte "fsys unmounted",0
err2 byte "fsys corrupted",0
err3 byte "fsys unsupported",0
err4 byte "not found",0
err5 byte "file not found",0
err6 byte "dir not found",0
err7 byte "file read only",0
err8 byte "end of file",0
err9 byte "end of directory",0
err10 byte "end of root",0
err11 byte "dir is full",0
err12 byte "dir is not empty",0
err13 byte "checksum error",0
err14 byte "reboot error",0
err15 byte "bpb corrupt",0
err16 byte "fsi corrupt",0
err17 byte "dir already exist",0
err18 byte "file already exist",0
err19 byte "out of disk free space",0
err20 byte "disk io error",0
errx byte "undefined",0
PRI fError(err)
ios.printnl
ios.print(@f_s1)
ios.printdec(err)
ios.print(string(" : $"))
ios.printhex(err,2)
ios.printnl
ios.print(@f_s2)
case err
0: ios.print(@err0)
1: ios.print(@err1)
2: ios.print(@err2)
3: ios.print(@err3)
4: ios.print(@err4)
5: ios.print(@err5)
6: ios.print(@err6)
7: ios.print(@err7)
8: ios.print(@err8)
9: ios.print(@err9)
10: ios.print(@err10)
11: ios.print(@err11)
12: ios.print(@err12)
13: ios.print(@err13)
14: ios.print(@err14)
15: ios.print(@err15)
16: ios.print(@err16)
17: ios.print(@err17)
18: ios.print(@err18)
19: ios.print(@err19)
20: ios.print(@err20)
OTHER: ios.print(@errx)
ios.printnl
DAT
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,572 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : Bellatrix-Test
Chip : Regnatix
Typ : Programm
Version : 00
Subversion : 01
Funktion : Test für die grundlegenden Textausgabe- und Tastaturfunktionen.
Komponenten : -
COG's : -
Logbuch :
22-03-2010-dr235 - anpassung trios
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
str: "glob-string"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
OS_TIBLEN = 64 'größe des inputbuffers
VAR
'systemvariablen
byte tib[OS_TIBLEN] 'tastatur-input-buffer
byte tibpos 'aktuelle position im tib
byte tbuf[32]
long cols,rows
byte vidmod 'videomodus: 0 - vga, 1 - tv
PUB main|fnr
ios.start
os_testvideo
repeat
ios.print(string("0 - Alle Tests",13))
ios.print(string("1 - Zeichensatz",13))
ios.print(string("2 - Hive-Logo",13))
ios.print(string("3 - Funktion TAB",13))
ios.print(string("4 - Funktion CLS",13))
ios.print(string("5 - Scrolling",13))
ios.print(string("6 - Funktion SCREENINIT",13))
ios.print(string("7 - Funktion SETCOLOR",13))
ios.print(string("8 - Funktion SETX/SETY",13))
ios.print(string("9 - Windows",13))
ios.print(string("10 - Funktion INPUT/BACKSPACE",13))
ios.print(string("11 - Funktion HOME/POS1/CURCHAR",13))
ios.print(string("99 - Ende "))
fnr := str.decimalToNumber(fInput(string(" Funktion : ")))
case fnr
0: test_all
1: test_charmap
2: test_logo
3: test_tab
4: test_cls
5: test_scroll
6: test_screeninit
7: test_setcolor
8: test_setxy
9: test_windows
10: test_inputbackspace
11: test_home
test_pos1
test_curchar
99: ios.stop
pri os_testvideo 'sys: passt div. variablen an videomodus an
vidmod := ios.belgetspec & 1
rows := ios.belgetrows 'zeilenzahl bei bella abfragen
cols := ios.belgetcols 'spaltenzahl bei bella abfragen
pri fInput(stradr1): stradr2
ios.setcolor(1)
ios.printq(string("▶"))
ios.print(stradr1)
ios.input(@tbuf,32)
ios.setcolor(0)
ios.printnl
return @tbuf
pri test_all
test_charmap
test_logo
test_tab
test_cls
test_scroll
test_screeninit
test_setcolor
test_setxy
test_windows
test_inputbackspace
test_home
test_pos1
test_curchar
pri test_charmap|i,j
ios.print(string("Zeichensatz:"))
ios.printnl
ios.print(string(" 0123456789ABCDEF0123456789ABCDEF"))
ios.printnl
ios.print(string(" ┌────────────────────────────────┐"))
repeat i from 0 to 7
ios.printnl
ios.printhex(i*j,2)
ios.printchar("│")
repeat j from 0 to 31
ios.printqchar((i*31)+j)
ios.printchar("│")
ios.printnl
ios.print(string(" └────────────────────────────────┘"))
weiter
pri test_logo
ios.print(string("Hive-Logo:"))
ios.printcls
ios.printlogo(0,0)
weiter
pri test_tab|a,b,i,j
ios.print(string("Test TAB:"))
if cols < 50
a := 3
b := 5
else
a := 3
b := 7
repeat j from a to b
repeat i from 0 to 7
ios.settabs(i,j*i)
ios.printcls
repeat 8
ios.print(string("tab"))
ios.printtab
ios.printnl
repeat i from 1 to 5
repeat 8
ios.printdec(i)
ios.printtab
ios.printnl
waitcnt(10_000_000+cnt)
weiter
pri test_cls
ios.print(string("Test CLS:"))
ios.printcls
repeat 10
charset
ios.printnl
ios.printnl
ios.print(string("Bildschirm wird gleich gelöscht..."))
waitcnt(cnt + clkfreq*3)
ios.printcls
ios.print(string("Bildschirm löschen OK"))
weiter
pri test_scroll
ios.print(string("Test ScrollUp:"))
repeat 10
charset
repeat 20
waitcnt(10_000_000+cnt)
ios.scrollup
ios.printnl
ios.printnl
'------------------------------------------------------------------------------------
ios.print(string("Test ScrollDown:"))
weiter
repeat 10
charset
repeat 15 <# rows - 2
waitcnt(10_000_000+cnt)
ios.scrolldown
repeat 16
repeat 15 <# rows - 2
waitcnt(1_000_000+cnt)
ios.scrollup
repeat 15 <# rows - 2
waitcnt(1_000_000+cnt)
ios.scrolldown
weiter
pri test_screeninit
ios.print(string("Test SCREENINIT:"))
ios.screeninit
ios.print(string("▶Funktionstest Bellatrix-BIOS [SCREENINIT OK]"))
weiter
pri test_setcolor|i,j,n
if vidmod == ios#TV
n := 7
else
n := 15
ios.print(string("Test SETCOLOR:",13))
repeat i from 0 to n
repeat j from 0 to 32
ios.setcolor(i)
ios.printchar(j + 65)
ios.printchar(":")
ios.printdec(i)
ios.printchar(":")
ios.printhex(i,2)
ios.printnl
ios.setcolor(0)
weiter
pri test_setxy|i,j,n
ios.print(string("Test SETX/SETY (CURON/CUROFF):"))
ios.printcls
ios.printnl
ios.curoff
repeat n from 1 to 50
repeat j from 1 to 5
repeat i from 1 to 8 <# cols/5-1
ios.cursetx(i * 5)
ios.cursety(j * 2)
ios.printchar(":")
ios.printdec(n)
ios.cursetx(5)
ios.cursety(12 <# rows)
ios.printchar(":")
ios.printdec(j)
ios.printchar(":")
ios.printdec(i)
ios.printchar(":")
ios.printdec(n)
ios.curon
ios.printnl
weiter
pri test_windows
ios.print(string("Test Windows:"))
windows1
windows2
ios.printcls
weiter
pri test_inputbackspace
ios.print(string("Test Eingabe/Backspace (bis Enter): "))
input
ios.printnl
ios.print(string("Eingabe :"))
ios.print(@tib)
weiter
pri test_home|i
ios.printcls
ios.print(string("Test Home:"))
repeat i from 0 to 1000
ios.curhome
ios.printdec(i)
weiter
pri test_pos1|i
ios.print(string("Test POS1:"))
ios.printnl
repeat i from 0 to 1000
ios.curpos1
ios.printdec(i)
weiter
pri test_curchar|i
ios.print(string("Test CURCHAR: "))
repeat i from 1 to 100
ios.curchar(i)
waitcnt(cnt + clkfreq/20)
ios.curchar($0E)
weiter
PRI weiter | tast
ios.printnl
ios.print(string("Weiter [q|*] : "))
tast := ios.keywait
if tast == "q" OR tast == "Q"
ios.stop
ios.printnl
PUB charset | i,j
repeat i from 20 to 255
ios.printchar(i)
PUB input | charc
repeat
if ios.keystat > 0 'taste gedrückt?
charc := ios.key 'tastencode holen
if (tibpos + 1) < OS_TIBLEN 'tastaturpuffer voll?
case charc
ios#CHAR_BS: 'backspace
if tibpos > 0
tibpos--
tib[tibpos] := $0 'letztes zeichen im puffer löschen
ios.printbs 'steuerzeichen anterminal senden
other: ios.bus_putchar2(charc) 'sonstige zeichen
if (charc <> ios#CHAR_NL) & (charc <> ios#CHAR_BS) 'ausser sonderzeichen alles in tib
if (tibpos + 1) < OS_TIBLEN 'tastaturpuffer voll?
tib[tibpos++] := charc
tib[tibpos] := $0
until charc == $0D 'schleife bis RETURN
VAR
long h[3], z[3], r[3]
PUB windows1 | gx, gy, i, j, tast
cols := ios.belgetcols
rows := ios.belgetrows
gx := cols / 2
gy := rows * 2 / 3
ios.printcls
ios.print(string(" ### Window-Test ###"))
ios.windefine(1, 2, 3, gx - 1, gy - 1)
ios.windefine(2, gx + 2, 3, cols - 2, gy - 1)
ios.windefine(3, 2, gy + 2, cols - 2, rows - 2)
repeat i from 1 to 3
ios.winset(i)
ios.printcls
ios.winoframe
waitcnt(cnt + clkfreq)
repeat i from 1 to 3
ios.winset(i)
repeat 3
charset
waitcnt(cnt + clkfreq)
repeat i from 1 to 3
ios.winset(i)
j := ios.wingetrows
repeat 8
repeat 15 <# j - 2
waitcnt(1_000_000+cnt)
ios.scrollup
repeat 15 <# j - 2
waitcnt(1_000_000+cnt)
ios.scrolldown
repeat i from 0 to 2
ios.winset(i+1)
h[i] := ios.wingetrows - 2
z[i] := 0
r[i] := 1
repeat 3
charset
i := 0
repeat 16*3*4
i := (i + 1) // 3
ios.winset(i+1)
z[i] += r[i]
if r[i] > 0
ios.scrollup
else
ios.scrolldown
if z[i] == 0 or z[i] == h[i]
r[i] *= -1
waitcnt(1_000_000+cnt)
ios.winset(3)
ios.printcls
ios.print(string("Test Screen 2"))
weiter
screen2
repeat i from 1 to 3
ios.winset(i)
ios.printcls
ios.curoff
ios.winset(1)
ios.printcls
ios.print(string("Test relative Positionierung"))
weiter
ios.winset(2)
repeat j from 2 to 3
ios.winset(j)
repeat i from 1 to 3
setpos(i, i)
waitcnt(cnt + clkfreq/2)
setpos(-i, -i)
waitcnt(cnt + clkfreq/2)
ios.winset(1)
ios.curon
ios.printnl
ios.printnl
ios.print(string("Weiter */<Q>uit : "))
tast := ios.keywait
ios.screeninit
if tast == "q" OR tast == "Q"
ios.stop
PUB windows2 | gx, gy, i, j, tast
cols := ios.belgetcols
rows := ios.belgetrows
gx := cols / 2
gy := rows * 2 / 3
ios.printcls
ios.print(string(" ### Window-Test - Randkollision ###"))
ios.windefine(1, 2, 3, gx - 1, gy - 1)
ios.windefine(2, gx + 2, 3, cols + 4, gy - 1)
ios.windefine(3, 2, gy + 2, cols + 4, rows + 4)
repeat i from 1 to 3
ios.winset(i)
ios.printcls
ios.winoframe
waitcnt(cnt + clkfreq)
repeat i from 1 to 3
ios.winset(i)
repeat 3
charset
waitcnt(cnt + clkfreq)
repeat i from 1 to 3
ios.winset(i)
j := ios.wingetrows
repeat 8
repeat 15 <# j - 2
waitcnt(1_000_000+cnt)
ios.scrollup
repeat 15 <# j - 2
waitcnt(1_000_000+cnt)
ios.scrolldown
repeat i from 0 to 2
ios.winset(i+1)
h[i] := ios.wingetrows - 2
z[i] := 0
r[i] := 1
repeat 3
charset
i := 0
repeat 16*3*4
i := (i + 1) // 3
ios.winset(i+1)
z[i] += r[i]
if r[i] > 0
ios.scrollup
else
ios.scrolldown
if z[i] == 0 or z[i] == h[i]
r[i] *= -1
waitcnt(1_000_000+cnt)
ios.winset(3)
ios.printcls
ios.print(string("Test Screen 2"))
weiter
screen2
repeat i from 1 to 3
ios.winset(i)
ios.printcls
ios.curoff
ios.winset(1)
ios.printcls
ios.print(string("Test relative Positionierung"))
weiter
ios.winset(2)
repeat j from 2 to 3
ios.winset(j)
repeat i from 1 to 3
setpos(i, i)
waitcnt(cnt + clkfreq/2)
setpos(-i, -i)
waitcnt(cnt + clkfreq/2)
ios.winset(1)
ios.curon
ios.printnl
ios.printnl
ios.print(string("Weiter */<Q>uit : "))
tast := ios.keywait
ios.screeninit
if tast == "q" OR tast == "Q"
ios.stop
PRI setpos(x, y)
ios.wincursetx(x)
ios.wincursety(y)
printpos(x, y)
PRI printpos(x, y)
ios.printqchar(15)
waitcnt(cnt + clkfreq/3)
if x < 0
ios.curpos1
else
ios.printqchar(2)
ios.printchar("(")
ios.printdec(x)
ios.printchar(",")
ios.printdec(y)
ios.printchar(")")
if x < 0
ios.printqchar(3)
PRI screen2
ios.set_wscr(2)
ios.set_dscr(2)
ios.print(string("hier ist Screen 2"))
ios.printnl
' Window anzeigen, Scrolling
ios.print(string("definiere Window 2 abweichend zu Screen 1: (8, 2)-(30, 8)"))
ios.printnl
ios.windefine(2, 8, 2, 30, 8)
ios.print(string("weiter mit beliebiger Taste..."))
ios.keywait
ios.winset(2)
ios.winoframe
ios.printcls
ios.print(string("Ausgabe in Window 2"))
ios.printnl
ios.print(string("zurück zu Screen 1 mit beliebiger Taste..."))
ios.keywait
ios.set_wscr(1)
ios.set_dscr(1)
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,76 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : Ausgabe einer Zeichentabelle
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
PUB main | c,i,j
ios.start
'ios.startram 'code für test im ram, sollte bei bin-datei auskommentiert werden
ios.printnl
ios.print(string(" 0123456789ABCDEF0123456789ABCDEF"))
ios.printnl
ios.print(string(" ┌────────────────────────────────┐"))
repeat i from 0 to 7
ios.printnl
ios.printhex(i*j,2)
ios.printchar("│")
repeat j from 0 to 31
ios.printqchar((i*31)+j)
ios.printchar("│")
ios.printnl
ios.print(string(" └────────────────────────────────┘"))
ios.printnl
ios.stop
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

686
system/regnatix/eram.spin Normal file
View File

@ -0,0 +1,686 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : eram-tool
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Logbuch :
Kommandoliste:
Notizen:
}}
OBJ
num: "glob-numbers"
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
OS_TIBLEN = 64 'gr??e des inputbuffers
ERAM = 1024 * 512 * 2 'gr??e eram
HRAM = 1024 * 32 'gr??e hram
RMON_ZEILEN = 16 'speichermonitor - angezeigte zeilen
RMON_BYTES = 8 'speichermonitor - zeichen pro byte
VAR
'systemvariablen
byte tib[OS_TIBLEN] 'tastatur-input-buffer
byte cmdstr[OS_TIBLEN] 'kommandostring f?r interpreter
byte token1[OS_TIBLEN] 'parameterstring 1 für interpreter
byte token2[OS_TIBLEN] 'parameterstring 2 für interpreter
byte tibpos 'aktuelle position im tib
long ppos 'puffer für adresse
long pcnt 'puffer für zeilenzahl
PUB main | wflag
ios.start 'ios initialisieren
' ios.startram
ios.printnl
repeat
os_cmdinput 'kommandoeingabe
os_cmdint 'kommandozeileninterpreter
PUB os_cmdinput | charc 'sys: stringeingabe eine zeile
''funktionsgruppe : sys
''funktion : stringeingabe eine zeile
''eingabe : -
''ausgabe : -
''variablen : tib - eingabepuffer zur string
'' : tibpos - aktuelle position im tib
ios.print(@prompt2)
tibpos := 0 'tibposition auf anfang setzen
repeat until (charc := ios.keywait) == $0D 'tasten einlesen bis return
if (tibpos + 1) < OS_TIBLEN 'zeile noch nicht zu lang?
case charc
ios#CHAR_BS: 'backspace
if tibpos > 0 'noch nicht anfang der zeile erreeicht?
tib[tibpos--] := 0 'ein zeichen aus puffer entfernen
ios.printbs 'steuerzeichen an terminal senden
other: 'zeicheneingabe
tib[tibpos++] := charc 'zeichen speichern
ios.printchar(charc) 'zeichen ausgeben
ios.printnl
tib[tibpos] := 0 'string abschließen
tibpos := charc := 0 'werte rücksetzen
PUB os_nxtoken1: stradr 'sys: token 1 von tib einlesen
''funktionsgruppe : sys
''funktion : nächsten token im eingabestring suchen und stringzeiger übergeben
''eingabe : -
''ausgabe : stradr - adresse auf einen string mit dem gefundenen token
''variablen : tib - eingabepuffer zur string
'' : tibpos - aktuelle position im tib
'' : token - tokenstring
stradr := os_tokenize(@token1)
PUB os_nxtoken2: stradr 'sys: token 2 von tib einlesen
''funktionsgruppe : sys
''funktion : nächsten token im eingabestring suchen und stringzeiger übergeben
''eingabe : -
''ausgabe : stradr - adresse auf einen string mit dem gefundenen token
''variablen : tib - eingabepuffer zur string
'' : tibpos - aktuelle position im tib
'' : token - tokenstring
stradr := os_tokenize(@token2)
PUB os_tokenize(token):stradr | i 'sys: liest nächsten token aus tib
i := 0
if tib[tibpos] <> 0 'abbruch bei leerem string
repeat until tib[tibpos] > ios#CHAR_SPACE 'führende leerzeichen ausbenden
tibpos++
repeat until (tib[tibpos] == ios#CHAR_SPACE) or (tib[tibpos] == 0) 'wiederholen bis leerzeichen oder stringende
byte[token][i] := tib[tibpos]
tibpos++
i++
else
token := 0
byte[token][i] := 0
stradr := token
PUB os_nextpos: tibpos2 'sys: setzt zeiger auf nächste position
''funktionsgruppe : sys
''funktion : tibpos auf nächstes token setzen
''eingabe : -
''ausgabe : tibpos2 - position des nächsten tokens in tib
''variablen : tib - eingabepuffer zur string
'' : tibpos - aktuelle position im tib
if tib[tibpos] <> 0
repeat until tib[tibpos] > ios#CHAR_SPACE 'führende leerzeichen ausbenden
tibpos++
return tibpos
PUB os_cmdint 'sys: kommandointerpreter
''funktionsgruppe : sys
''funktion : kommandointerpreter; zeichenkette ab tibpos wird als kommando interpretiert
'' : tibpos wird auf position hinter token gesetzt
''eingabe : -
''ausgabe : -
''variablen : tib - eingabepuffer zur string
'' : tibpos - aktuelle position im tib
repeat 'kommandostring kopieren
cmdstr[tibpos] := tib[tibpos]
tibpos++
until (tib[tibpos] == ios#CHAR_SPACE) or (tib[tibpos] == 0) 'wiederholen bis leerzeichen oder stringende
cmdstr[tibpos] := 0 'kommandostring abschließen
os_cmdexec(@cmdstr) 'interpreter aufrufen
tibpos := 0 'tastaturpuffer zurücksetzen
tib[0] := 0
PUB os_cmdexec(stradr) 'sys: kommando im ?bergebenen string wird als kommando interpretiert
{{os_smdexec - das kommando im ?bergebenen string wird als kommando interpretiert
stradr: adresse einer stringvariable die ein kommando enth?lt}}
if strcomp(stradr,string("help")) 'help
ios.print(string("help: man eram"))
elseif strcomp(stradr,string("d")) 'd display - speicheranzeige
ram_disp
elseif strcomp(stradr,string("dl")) 'd display long - speicheranzeige
ram_displong
elseif strcomp(stradr,string("n")) 'n next - anzeige fortsetzen
ram_next
elseif strcomp(stradr,string("m")) 'm modify - speicher modifizieren
ram_mod
elseif strcomp(stradr,string("l")) 'l modify - long
ram_lmod
elseif strcomp(stradr,string("info"))
ram_info
elseif strcomp(stradr,string("f"))
ram_fill
elseif strcomp(stradr,string("fu")) 'fill im userbereich
ram_fillusr
elseif strcomp(stradr,string("rbas"))
ram_setrbas
elseif strcomp(stradr,string("sysvar"))
ram_sysvar
elseif strcomp(stradr,string("load")) 'load -
ram_load
elseif strcomp(stradr,string("cls")) 'cls -
ios.printcls
elseif strcomp(stradr,string("bye")) 'bye
ios.stop
elseif strcomp(stradr,string("xinit")) 'rdisk initialisieren
rd_init
elseif strcomp(stradr,string("xnew")) 'neue ram-datei erstellen
rd_new
elseif strcomp(stradr,string("xhead")) 'header der dateien anzeigen
rd_header
elseif strcomp(stradr,string("xdel")) 'ram-datei löschen
rd_del
elseif strcomp(stradr,string("xren")) 'ram- datei umbenennen
rd_rename
elseif strcomp(stradr,string("xdir")) 'ram-dateien liste anzeigen
rd_dir
elseif strcomp(stradr,string("xftab")) 'tabelle geöffnete dateien anzeigen
rd_ftab
elseif strcomp(stradr,string("xopen")) 'ram-datei öffnen
rd_open
elseif strcomp(stradr,string("xsave")) 'ram-datei auf sd speichern
rd_save
elseif strcomp(stradr,string("xclose")) 'ram-datei schliessen
rd_close
elseif strcomp(stradr,string("xseek")) 'dateizeiger setzen
rd_seek
elseif strcomp(stradr,string("xput")) 'wert in geöffnete datei schreiben
rd_put
elseif strcomp(stradr,string("xget")) 'wert aus geöffneter datei lesen
rd_get
elseif strcomp(stradr,string("xwrite")) 'wert an def. adresse in datei schreiben
rd_write
elseif strcomp(stradr,string("xread")) 'wert von def. adresse aus datei lesen
rd_read
elseif strcomp(stradr,string("xload")) 'ram-datei von sd laden
rd_load
elseif strcomp(stradr,string("xtype")) 'ram-datei (text) ausgeben
rd_type
elseif strcomp(stradr,string("debug"))
debug
else 'kommando nicht gefunden
ios.print(stradr)
ios.print(@prompt3)
ios.printnl
PRI debug
ios.rd_init
ios.rd_newfile(string("d1"),8)
ios.rd_newfile(string("d2"),8)
ios.rd_newfile(string("d3"),8)
ios.rd_newfile(string("d4"),8)
ios.rd_newfile(string("d5"),8)
rd_dir
PRI rd_type | stradr,len,fnr 'rd: text ausgeben
stradr := os_nxtoken1 'dateinamen von kommandozeile holen
fnr := ios.rd_open(stradr) 'datei öffnen
ifnot fnr == -1
len := ios.rd_len(fnr)
ios.rd_seek(fnr,0)
repeat len
ios.printchar(ios.rd_get(fnr))
ios.rd_close(fnr)
PRI rd_load | stradr,len,fnr 'rd: datei in ramdisk laden
stradr := os_nxtoken1 'dateinamen von kommandozeile holen
ifnot os_error(ios.sdopen("r",stradr)) 'datei öffnen
len := ios.sdfattrib(ios#F_SIZE)
ios.rd_newfile(stradr,len) 'datei erzeugen
fnr := ios.rd_open(stradr)
ios.rd_seek(fnr,0)
repeat len 'datei einlesen
ios.rd_put(fnr,ios.sdgetc)
ios.sdclose
ios.rd_close(fnr)
PRI rd_save | stradr, fnr, len 'rd: datei aus ramdisk speichern
stradr := os_nxtoken1
fnr := ios.rd_open(stradr)
ifnot fnr == -1
len := ios.rd_len(fnr)
ifnot os_error(ios.sdnewfile(stradr))
ifnot os_error(ios.sdopen("W",stradr))
ios.print(string("Schreibe Datei..."))
repeat len
ios.sdputc(ios.rd_get(fnr))
ios.sdclose
ios.print(string(" ok"))
ios.printnl
ios.rd_close(fnr)
PRI rd_rename
os_error(ios.rd_rename(os_nxtoken1,os_nxtoken2))
PRI rd_seek | fnr,wert 'rd: dateizeiger setzen
fnr := num.FromStr(os_nxtoken1,num#HEX)
wert := num.FromStr(os_nxtoken1,num#HEX)
ios.rd_seek(fnr,wert)
PRI rd_put | fnr,wert,chars 'rd: werte ausgeben
fnr := num.FromStr(os_nxtoken1,num#HEX)
wert := num.FromStr(os_nxtoken1,num#HEX)
chars := num.FromStr(os_nxtoken1,num#HEX)
repeat chars
ios.rd_put(fnr,wert)
PRI rd_get | fnr,chars,i,j 'rd: werte einlesen
fnr := num.FromStr(os_nxtoken1,num#HEX)
chars := num.FromStr(os_nxtoken1,num#HEX)
i := j := 0
repeat chars
ifnot i
ios.printnl
ios.printhex(j,4)
ios.printchar(":")
ios.printhex(ios.rd_get(fnr),2)
ios.printchar(" ")
if i++ == 7
i := 0
j++
ios.printnl
PRI rd_write | fnr,adr,wert 'rd: wert schreiben
fnr := num.FromStr(os_nxtoken1,num#HEX)
adr := num.FromStr(os_nxtoken1,num#HEX)
wert := num.FromStr(os_nxtoken1,num#HEX)
ios.rd_wrbyte(fnr,wert,adr)
PRI rd_read | fnr,adr 'rd: wert lesen
fnr := num.FromStr(os_nxtoken1,num#HEX)
adr := num.FromStr(os_nxtoken1,num#HEX)
ios.printhex(ios.rd_rdbyte(fnr,adr),2)
ios.printnl
PRI rd_close 'rd: datei schliessen
ios.rd_close(num.FromStr(os_nxtoken1,num#HEX))
PRI rd_open 'rd: datei öffnen
ifnot ios.rd_open(os_nxtoken1)
os_error(5)
PRI rd_ftab | i 'rd: anzeige ftab
i := 0
repeat ios#FILES
ios.printnl
ios.printhex(i,2)
ios.printchar(":")
ios.printhex(ios.rd_getftab(i*3+0),6)
ios.printchar(" ")
ios.printhex(ios.rd_getftab(i*3+1),6)
ios.printchar(" ")
ios.printhex(ios.rd_getftab(i*3+2),6)
ifnot i
ios.print(string(" user"))
i++
ios.printnl
PRI rd_del | adr 'rd: datei löschen
os_error(ios.rd_del(os_nxtoken1))
PRI rd_dir | stradr,len 'rd: dir anzeigen
if ios.ram_rdbyte(ios#sysmod,ios#RAMDRV)
ios.rd_dir
repeat
len := ios.rd_dlen
stradr := ios.rd_next
if stradr
ios.print(stradr)
ios.printtab
ios.printdec(len)
ios.printnl
until stradr == 0
else
os_error(1)
PRI rd_header|hp,nx,len,i 'rd: header
hp := ios#STARTRD
repeat
nx := ios.ram_rdlong(ios#sysmod,hp)
len := ios.ram_rdlong(ios#sysmod,hp+4)
ios.print(string("[adr-header] = $"))
ios.printhex(hp,8)
ios.printnl
ios.print(string("[adr-next ] = $"))
ios.printhex(nx,8)
ios.printnl
ios.print(string("[len ] = $"))
ios.printhex(len,8)
ios.printchar(" ")
ios.printdec(len)
ios.printnl
ios.print(string("[name ] = "))
i := 0
repeat 12
ios.printchar(ios.ram_rdbyte(ios#sysmod,hp+8+i++))
hp := nx
ios.print(string(" <*/q> : "))
if ios.keywait == "q"
quit
ios.printnl
until nx == 0
ios.printnl
PRI rd_new 'rd: new file
ios.rd_newfile(os_nxtoken1,num.FromStr(os_nxtoken2,num#DEC))
PRI rd_init 'rd: rdisk initialisieren
ios.rd_init
PRI ram_sysvar | i 'ram: systemvariablen anzeigen
ios.print(string("LOADERPTR = "))
ios.printchar("[")
ios.printhex(ios#LOADERPTR,6)
ios.print(string("] : "))
ios.printhex(ios.ram_rdlong(0,ios#LOADERPTR),6)
ios.printnl
ios.print(string("MAGIC = "))
ios.printchar("[")
ios.printhex(ios#MAGIC,6)
ios.print(string("] : "))
ios.printhex(ios.ram_rdbyte(0,ios#MAGIC),6)
ios.printnl
ios.print(string("SIFLAG = "))
ios.printchar("[")
ios.printhex(ios#SIFLAG,6)
ios.print(string("] : "))
ios.printhex(ios.ram_rdbyte(0,ios#SIFLAG),6)
ios.printnl
ios.print(string("BELDRIVE = "))
i := ios#BELDRIVE
repeat 12
ios.printchar(ios.ram_rdbyte(0,i++))
ios.printnl
ios.print(string("PARAM = "))
i := ios#PARAM
repeat 32
ios.printchar(ios.ram_rdbyte(0,i++))
ios.printnl
ios.print(string("RAMEND = "))
ios.printchar("[")
ios.printhex(ios#RAMEND,6)
ios.print(string("] : "))
ios.printhex(ios.ram_getend,6)
ios.printnl
ios.print(string("RAMBAS = "))
ios.printchar("[")
ios.printhex(ios#RAMBAS,6)
ios.print(string("] : "))
ios.printhex(ios.ram_getbas,6)
ios.printnl
PRI ram_setrbas 'ram: basisadresse setzen
ios.ram_setbas(num.FromStr(os_nxtoken1,num#HEX))
PRI ram_fill | adr,len,wert 'ram: speicherbereich füllen
adr := ram_symbols
len := num.FromStr(os_nxtoken1,num#HEX)
wert := num.FromStr(os_nxtoken1,num#HEX)
repeat len
ios.ram_wrbyte(ios#sysmod,wert,adr++)
PRI ram_fillusr | adr,len,wert 'ram: speicherbereich füllen
adr := ram_symbols
len := num.FromStr(os_nxtoken1,num#HEX)
wert := num.FromStr(os_nxtoken1,num#HEX)
repeat len
ios.ram_wrbyte(ios#usrmod,wert,adr++)
PRI ram_info 'ram: infos anzeigen
ios.print(string("RBAS : $"))
ios.printhex(ios.ram_getbas,6)
ios.print(string(" REND : $"))
ios.printhex(ios.ram_getend,6)
ios.print(string(" RLEN : $"))
ios.printhex(ios.ram_getend - ios.ram_getbas,6)
ios.print(string(" RDRV : $"))
ios.printhex(ios.ram_rdbyte(ios#sysmod,ios#RAMDRV),2)
ios.printnl
PRI ram_mod | wert,adresse,stradr 'ram: rambereich beschreiben
{{rmodify <adr b1 b2 b3 ...> - rambereich beschreiben, adresse und werte
folgen auf kommandozeile}}
adresse := ram_symbols 'adresse von kommandozeile holen
repeat
if (stradr := os_nxtoken1)
wert := num.FromStr(stradr,num#HEX) 'nächstes byte von kommandozeile holen
ios.ram_wrbyte(0,wert,adresse++) 'wert in eram schreiben
until stradr == 0 'keine parameter mehr?
PRI ram_lmod | wert,adresse,stradr 'ram: rambereich beschreiben (long)
{{rmodify <adr l1 l2 l3 ...> - rambereich beschreiben, adresse und werte
folgen auf kommandozeile}}
adresse := ram_symbols 'adresse von kommandozeile holen
repeat
if (stradr := os_nxtoken1)
wert := num.FromStr(stradr,num#HEX) 'nächstes byte von kommandozeile holen
ios.ram_wrlong(0,wert,adresse) 'long in eram schreiben
adresse := adresse + 4
until stradr == 0 'keine parameter mehr?
PRI ram_disp | adresse,zeilen,sadr 'ram: rambereich anzeigen
{{rdisplay <adr anz> - rambereich anzeigen, adresse und zeilenzahl folgt auf kommandozeile}}
adresse := ram_symbols
zeilen := num.FromStr(os_nxtoken1,num#HEX) 'zeilenzahl von kommandozeile holen
if zeilen == 0
zeilen := RMON_ZEILEN
ram_print(adresse,zeilen)
PRI ram_symbols:adresse | sadr 'ram: adresse auflösen
sadr := os_nxtoken1
if strcomp(sadr,string("bas"))
adresse := ios.ram_getbas
elseif strcomp(sadr,string("end"))
adresse := ios.ram_getend
elseif strcomp(sadr,string("sys"))
adresse := ios.ram_getend + 1
elseif strcomp(sadr,string("rd:"))
adresse := ios.rd_searchdat(os_nxtoken1)
else
adresse := num.FromStr(sadr,num#HEX) 'adresse von kommandozeile holen
PRI ram_displong | sadr,adresse,wert 'ram: rambereich als long anzeigen
adresse := ram_symbols
repeat
ios.printnl
if (adresse => ios.ram_getbas) & (adresse =< ios.ram_getend)
ios.setcolor(2)
ios.printhex(adresse - ios.ram_getbas,6)
ios.setcolor(0)
else
ios.print(string("------"))
ios.printchar("-")
ios.printhex(adresse,6) 'adresse ausgeben
ios.printchar(" ")
wert := ios.ram_rdlong(0,adresse)
ios.printhex(wert,6)
ios.printchar(":")
ios.printbin(wert,32)
ios.print(string(" <*/q> : "))
adresse += 4
until ios.keywait == "q"
ios.printnl
PRI ram_next 'ram: anzeige fortsetzen
ram_print(ppos,pcnt)
PRI ram_print(adresse,zeilen)|wert,pbas,pend 'ram: ausgabe
pbas := ios.ram_getbas 'rbas vom system sichern
pend := ios.ram_getend
repeat zeilen 'zeilen
if (adresse => pbas) & (adresse =< pend)
ios.setcolor(2)
ios.printhex(adresse-pbas,6)
ios.setcolor(0)
else
ios.print(string("------"))
ios.printchar("-")
ios.printhex(adresse,6) 'adresse ausgeben
ios.printchar(ios#CHAR_SPACE)
repeat RMON_BYTES 'hexwerte ausgeben
wert := ios.ram_rdbyte(0,adresse++)
ios.printhex(wert,2) 'byte ausgeben
ios.printchar(":")
adresse := adresse - rmon_bytes
ios.printchar(ios#CHAR_SPACE)
repeat RMON_BYTES 'zeichen ausgeben
wert := ios.ram_rdbyte(0,adresse++)
if wert < $20
wert := 46
ios.printchar(wert) 'byte ausgeben
ios.printchar($0D)
ppos := adresse
pcnt := zeilen
PRI ram_load | adr,len,stradr,status,char,i 'ram: lade datei nach eramadr
{{sdload - adr len dateiname lade datei nach eram-adr}}
adr := num.FromStr(os_nxtoken1,num#HEX) 'adresse von kommandozeile holen
len := num.FromStr(os_nxtoken1,num#HEX) 'l?nge von kommandozeile holen
stradr := os_nxtoken1 'dateinamen von kommandozeile holen
status := ios.sdopen("r",stradr) 'datei ?ffnen
if status > 0
ios.print(string("Status : "))
ios.printdec(status)
ios.printnl
if status == 0
repeat i from 0 to len
char := ios.sdgetc
ios.ram_wrbyte(0,char,adr + i)
ios.sdclose
PUB os_error(err):error 'sys: fehlerausgabe
if err
ios.printnl
ios.print(@err_s1)
ios.printdec(err)
ios.print(string(" : $"))
ios.printhex(err,2)
ios.printnl
ios.print(@err_s2)
case err
0: ios.print(@err0)
1: ios.print(@err1)
2: ios.print(@err2)
3: ios.print(@err3)
4: ios.print(@err4)
5: ios.print(@err5)
6: ios.print(@err6)
7: ios.print(@err7)
8: ios.print(@err8)
9: ios.print(@err9)
10: ios.print(@err10)
11: ios.print(@err11)
12: ios.print(@err12)
13: ios.print(@err13)
14: ios.print(@err14)
15: ios.print(@err15)
16: ios.print(@err16)
17: ios.print(@err17)
18: ios.print(@err18)
19: ios.print(@err19)
20: ios.print(@err20)
OTHER: ios.print(@errx)
ios.printnl
error := err
DAT
prompt1 byte "ok ", $0d, 0
prompt2 byte ": ", 0
prompt3 byte "? ",0
wait1 byte "<WEITER? */q:>",0
err_s1 byte "Fehlernummer : ",0
err_s2 byte "Fehler : ",0
err0 byte "no error",0
err1 byte "fsys unmounted",0
err2 byte "fsys corrupted",0
err3 byte "fsys unsupported",0
err4 byte "not found",0
err5 byte "file not found",0
err6 byte "dir not found",0
err7 byte "file read only",0
err8 byte "end of file",0
err9 byte "end of directory",0
err10 byte "end of root",0
err11 byte "dir is full",0
err12 byte "dir is not empty",0
err13 byte "checksum error",0
err14 byte "reboot error",0
err15 byte "bpb corrupt",0
err16 byte "fsi corrupt",0
err17 byte "dir already exist",0
err18 byte "file already exist",0
err19 byte "out of disk free space",0
err20 byte "disk io error",0
err21 byte "command not found",0
errx byte "undefined",0

432
system/regnatix/flash.spin Normal file
View File

@ -0,0 +1,432 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : flash
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : Flash-Tool
Komponenten : -
COG's : -
Logbuch :
09-04-2011-dr235 - erste version
Kommandoliste :
/? : Hilfe
/fh <fn> : Datei in HI-ROM flashen
/fl <fn> : Datei in LO-ROM flashen
/dh : Dump HI-ROM
/dl : Dump LO-ROM
/vh <fn> : Vergleich Datei <--> HI-ROM
/ch : HI-ROM löschen
/cl : LO-ROM löschen
/sh <fn> : HI-ROM speichern
/sl <fn> : LO-ROM speichern
Notizen :
}}
OBJ
ios : "reg-ios"
sdspi : "glob-sdspi"
num : "glob-numbers"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
DCOL = 8 'dump spaltenzahl
DROW = 16 'dump zeilenzahl
PAGESIZE = 32
BUFFERSIZE = DCOL * DROW
LO_EEPROM = $0000 ' based upon 24LC512 (64KB)
HI_EEPROM = $8000
IMAGESIZE = $8000 'größe eines rom-images
VAR
byte buffer[BUFFERSIZE]
byte parastr[64]
byte input[64]
long ioControl[2]
PUB main
ios.start 'ios initialisieren
ios.parastart 'parameterübergabe starten
sdspi.start(@iocontrol) 'spi-treiber starten
repeat while ios.paranext(@parastr) 'parameter einlesen
if byte[@parastr][0] == "/" 'option?
case byte[@parastr][1]
"?": ios.print(string("help: man flash")) '/?
"f": case byte[@parastr][2]
"h": flash(HI_EEPROM) '/fh - in oberen rom flashen
"l": flash(LO_EEPROM) '/fl - in unteren rom flashen
"d": case byte[@parastr][2]
"h": dump(HI_EEPROM) '/dh - dump des oberen rom
"l": dump(LO_EEPROM) '/dl - dump des unteren rom
"v": case byte[@parastr][2]
"h": verify(HI_EEPROM) '/vh - vergleih oberen rom
"c": case byte[@parastr][2]
"h": clear(HI_EEPROM) '/ch - oberen rom löschen
"l": clear(LO_EEPROM) '/cl - unteren rom löschen
"s": case byte[@parastr][2]
"h": save(HI_EEPROM) '/sh - oberen rom speichern
"l": save(LO_EEPROM) '/sl - unteren rom speichern
"t": testsave(HI_EEPROM)
sdspi.stop
' ios.ram_wrbyte(ios#sysmod,0,ios#SIFLAG)
' reboot
ios.stop
PRI dump(eeAdr)|key,i,j,n 'flash: azeige rom-inhalt
eeAdr += sdspi#bootAddr ' always use boot EEPROM
repeat
sdspi.readEEPROM(eeAdr,@buffer,BUFFERSIZE)
i := j := 0
repeat DROW 'zeilen
ios.printhex(eeAdr+j*DCOL,4)
ios.printchar(" ")
repeat DCOL 'bytes
n := byte[@buffer][i++]
ios.printhex(n,2)
ios.printchar(":")
ios.printchar(" ")
i := i - DCOL
repeat DCOL 'zeichen
n := byte[@buffer][i++]
ios.printqchar(n)
ios.printnl
j++
ios.print(string("CMD? [b]ack[q]uit[a]dr[n]ext : "))
key := ios.keywait
case key
"b": eeAdr := eeAdr - BUFFERSIZE
"a": eeAdr := inputhex + sdspi#bootAddr
"n": eeAdr := eeAdr + BUFFERSIZE
ios.printnl
ios.printnl
until key == "q"
PRI flash(eeAdr)|i,len,pos,dif,pcnt 'flash: datei flashen
eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen
if ios.paranext(@parastr)
ios.printnl
ios.print(@msg0)
ios.print(@msg1)
ios.print(@parastr)
ios.printnl
ifnot ios.sdopen("R",@parastr)
'programmlänge ermitteln
repeat i from 0 to PAGESIZE - 1 'erste page --> puffer
byte[@buffer][i] := ios.sdgetc
len := word[@buffer+$A] '$a ist stackposition und damit länge der objektdatei
ios.sdclose
'datei kpl. einlesen und flashen
ios.print(@msg8)
ios.printhex(eeAdr,8)
ios.printnl
ios.print(@msg4)
ios.printdec(len)
ios.printnl
ios.print(@msg5)
ios.printdec(len/PAGESIZE)
ios.printnl
ios.print(@msg2)
pcnt := len / PAGESIZE / 10
ios.curchar("▶")
ios.sdopen("R",@parastr)
repeat pos from 0 to len - 1 step PAGESIZE
dif := (len - pos) <# PAGESIZE
repeat i from 0 to dif - 1 'page --> puffer
byte[@buffer][i] := ios.sdgetc
sdspi.writeEEPROM(eeAdr+pos,@buffer,dif) 'puffer --> eeprom
sdspi.writeWait(eeAdr+pos) 'warte auf ende des schreibvorgangs
pcnt--
if pcnt == 0
ios.printchar("•")
pcnt := len / PAGESIZE / 10
ios.sdclose
ios.curchar("‣")
ios.print(@msg3)
else
printErr(@err2)
else
printErr(@err1)
PRI verify(eeAdr)|a,b,pos,len,i 'flash: vergleichen
eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen
len := IMAGESIZE
if ios.paranext(@parastr)
ios.printnl
ios.print(@msg0)
ios.print(@msg1)
ios.print(@parastr)
ios.printnl
ifnot ios.sdopen("R",@parastr)
ios.print(@msg7)
ios.print(@msg4)
ios.printdec(IMAGESIZE)
ios.printnl
ios.print(@msg5)
ios.printdec(len/PAGESIZE)
ios.printnl
'vergleich starten
repeat pos from 0 to IMAGESIZE-1 step PAGESIZE
sdspi.readEEPROM(eeAdr+pos,@buffer,PAGESIZE) 'page einlesen
repeat i from 0 to PAGESIZE-1
a := byte[@buffer][i]
b := ios.sdgetc
if a <> b
ios.printhex(eeAdr+pos+i,4)
ios.print(string(" : "))
ios.printhex(a,2)
ios.print(string(" <> "))
ios.printhex(b,2)
ios.print(string(" CMD? [q]uit[*]next : "))
case ios.keywait
"q": return
ios.printnl
ios.sdclose
else
printErr(@err2)
else
printErr(@err1)
PRI save(eeAdr)|pos,len,i,j,pcnt,blk 'flash: speichern
eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen
len := IMAGESIZE
blk := len/BUFFERSIZE
pcnt := blk/10
if ios.paranext(@parastr)
ios.printnl
ios.print(@msg9)
ios.print(@msg1)
ios.print(@parastr)
ios.printnl
ifnot ios.sdnewfile(@parastr)
ios.sdopen("W",@parastr)
ios.print(@msg8)
ios.printhex(eeAdr,8)
ios.printnl
ios.print(@msg4)
ios.printdec(IMAGESIZE)
ios.printnl
ios.print(@msg5)
ios.printdec(blk)
ios.printnl
ios.print(@msgA)
ios.curchar("▶")
j := 0
repeat blk+1
sdspi.readEEPROM(eeAdr,@buffer,BUFFERSIZE) 'puffer einlesen
ios.sdputblk(BUFFERSIZE,@buffer)
eeAdr := eeAdr + BUFFERSIZE
pcnt--
if pcnt == 0
ios.printchar("•")
pcnt := len / BUFFERSIZE / 10
ios.sdputc(0) 'provisorischer patch für fatengine:
'bei 32kb-grenze gibt es einen fehler!
ios.sdclose
ios.curchar("‣")
ios.print(@msg3)
else
printErr(@err2)
else
printErr(@err1)
PRI testsave(eeAdr)|pos,len,i,j,pcnt,blk 'flash: speichern
eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen
len := IMAGESIZE
blk := len/BUFFERSIZE
pcnt := blk/10
if ios.paranext(@parastr)
ios.printnl
ios.print(@msg0)
ios.print(@msg1)
ios.print(@parastr)
ios.printnl
ifnot ios.sdnewfile(@parastr)
ios.sdopen("W",@parastr)
ios.print(@msg9)
ios.print(@msg8)
ios.printhex(eeAdr,8)
ios.printnl
ios.print(@msg4)
ios.printdec(IMAGESIZE)
ios.printnl
ios.print(@msg5)
ios.printdec(blk)
ios.printnl
ios.print(@msgA)
ios.curchar("▶")
j := 0
repeat blk+1
repeat i from 0 to BUFFERSIZE-1
ios.sdputc(j)
ios.printdec(j++)
ios.printchar(" ")
ios.sdclose
ios.curchar("‣")
ios.print(@msg3)
else
printErr(@err2)
else
printErr(@err1)
PRI printbuf(eeAdr)|i,j,n
i := j := 0
repeat DROW 'zeilen
ios.printhex(eeAdr+j*DCOL,4)
ios.printchar(" ")
repeat DCOL 'bytes
n := byte[@buffer][i++]
ios.printhex(n,2)
ios.printchar(":")
ios.printchar(" ")
i := i - DCOL
repeat DCOL 'zeichen
n := byte[@buffer][i++]
ios.printqchar(n)
ios.printnl
j++
DAT 'sys: strings
msg0 byte "Funktion : Datei --> ROM",13,0
msg1 byte "Datei : ",0
msg2 byte "Flash : ",0
msg3 byte " ok",13,0
msg4 byte "Länge : ",0
msg5 byte "Blöcke : ",0
msg6 byte "Funktion : ROM löschen",13,0
msg7 byte "Funktion : Datei <--> ROM vergleichen",13,0
msg8 byte "Adresse : $",0
msg9 byte "Funktion : ROM --> Datei",13,0
msgA byte "Image : ",0
PRI clear(eeAdr)|len,pcnt,i,pos 'flash: löschen
eeAdr += sdspi#bootAddr 'deviceadresse hinzufügen
len := IMAGESIZE
pcnt := len / PAGESIZE / 10
ios.printnl
ios.print(@msg6)
ios.print(@msg4)
ios.printdec(IMAGESIZE)
ios.printnl
ios.print(@msg5)
ios.printdec(len/PAGESIZE)
ios.printnl
ios.print(@msg2)
ios.curchar("▶")
'puffer löschen
repeat i from 0 to BUFFERSIZE-1
byte[@buffer][i] := 0
'rom löschen
repeat pos from 0 to IMAGESIZE-1 step PAGESIZE
sdspi.writeEEPROM(eeAdr+pos,@buffer,PAGESIZE)
sdspi.writeWait(eeAdr+pos)
pcnt--
if pcnt == 0
ios.printchar("•")
pcnt := len / PAGESIZE / 10
ios.curchar("‣")
ios.print(@msg3)
return
DAT 'sys: fehermeldungen
err0 byte 13,"Fehler : "
err1 byte "Zu wenig Parameter!",13,0
err2 byte "Datei nicht gefunden!",13,0
PRI printErr(stradr) 'sys: feherbehandlung
ios.print(@err0)
ios.print(stradr)
ios.print(string("help: man flash"))
PRI inputhex:hexnum 'sys: eingabe hexwert
ios.curchar("_")
ios.print(string("Adresse : $"))
ios.input(@input,8) 'nummer eingeben
ios.curchar("‣")
hexnum := num.FromStr(@input,num#HEX) 'string in hexwert wandeln
return
DAT 'lizenz
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

551
system/regnatix/fm.spin Normal file
View File

@ -0,0 +1,551 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : Filemanager
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
- view nach f9
- tab in wbox
}}
OBJ
ios : "reg-ios"
dlbox[2] : "gui-dlbox"
pbar : "gui-pbar"
wbox : "gui-wbox"
input : "gui-input"
fm : "fm-con"
gc : "glob-con"
str : "glob-string"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
byte rows,cols,vidmod
byte fname[fm#MAX_LEN+1]
byte dir 'richtung der cursorbewegung
byte fl_mounted '1 = sd mounted
byte fl_full '1 = linkes fenster maximiert
byte w_sel 'nr des fokusierten fensters
byte w_pos[2] 'positionen im fenster
byte w_view[2] 'startposition des fensters
byte w_cols[2] 'anzahl der spalten im fenster
byte w_drives[2] 'zugeordnete drives
byte w0_list[fm#MAX_BUFFER] 'aktuelles verzeichnis
byte w0_flags[fm#MAX_FILES] 'selected, directory usw.
long w0_len[fm#MAX_FILES] 'dateilängen
byte w0_number 'anzahl der files
byte w1_list[fm#MAX_BUFFER]
byte w1_flags[fm#MAX_FILES]
long w1_len[fm#MAX_FILES]
byte w1_number
PUB main | key
init
dlbox[0].focus
dlbox[0].draw
dlbox[1].draw
info_print
repeat
key := ios.keywait
case key
gc#KEY_CURUP: f_curup
gc#KEY_CURDOWN: f_curdown
gc#KEY_CURLEFT: f_curleft
gc#KEY_CURRIGHT: f_curright
gc#KEY_PAGEUP: f_pageup
gc#KEY_PAGEDOWN: f_pagedown
gc#KEY_RETURN: f_open
gc#KEY_BS: f_back
gc#KEY_SPACE: f_select
gc#KEY_ESC:
gc#KEY_TAB: f_focus
gc#KEY_POS1: f_pos1
gc#KEY_F01: f_view
gc#KEY_F02: f_del
gc#KEY_F03: f_load
gc#KEY_F04: f_save
gc#KEY_F05: f_empty
gc#KEY_F06: f_mount
gc#KEY_F07: f_mkdir
gc#KEY_F08: f_selall
gc#KEY_F09: f_full
gc#KEY_F10: f_quit
PRI init
ios.start
testvideo
dir := 1
fl_mounted := 1
fl_full := 0
w_sel := 0
w_pos[0] := w_pos[1] := 0
w_view[0] := w_view[1] := 0
w_cols[0] := (fm#W1X2-fm#W1X1)/(fm#MAX_LEN+2)
w_cols[1] := (fm#W2X2-fm#W2X1)/(fm#MAX_LEN+2)
w_drives[0] := fm#DR_SD
w_drives[1] := fm#DR_RAM
fname[0] := 0
frame_draw
w0_clrlist
w1_clrlist
w0_readdir
w1_readdir
dlbox[0].define(1,fm#W1X1,fm#W1Y1,fm#W1X2,fm#W1Y2,@w0_list,@w0_flags,0,fm#MAX_FILES) 'linkes fenster
dlbox[1].define(2,fm#W2X1,fm#W2Y1,fm#W2X2,fm#W2Y2,@w1_list,@w1_flags,0,fm#MAX_FILES) 'rechtes fenster
ios.windefine(3,fm#W3X1,fm#W3Y1,fm#W3X2,fm#W3Y2) 'logfenster
pbar.define(4,fm#W4X1,fm#W4Y1,fm#W4X2,fm#W4Y2)
wbox.define(5,fm#W4X1,fm#W4Y1,fm#W4X2,fm#W4Y2)
input.define(6,fm#W4X1,fm#W4Y1,fm#W4X2,fm#W4Y2,12)
PRI f_mount
if fl_mounted
ios.sdunmount
repeat
wbox.draw(@str5,@str2,@str3) == 1
while ios.sdmount
dlbox[0].draw
dlbox[1].draw
info_print
PRI f_mkdir
ios.sdnewdir(input.draw(string("Name eingeben : ")))
w0_clrlist
w0_readdir
dlbox[0].draw
dlbox[1].draw
info_print
PRI f_selall | i
i := 0
case w_sel
0: repeat w0_number
w0_flags[i++] ^= fm#FL_SEL
1: repeat w1_number
w1_flags[i++] ^= fm#FL_SEL
dlbox[w_sel].redraw
PRI f_pos1
w_pos[w_sel] := 0
dlbox[w_sel].setpos(w_pos[w_sel])
PRI f_full
if w_sel
dlbox[1].defocus
case fl_full
0: fl_full := 1
dlbox[0].define(1,fm#W1X1,fm#W1Y1,fm#W2X2,fm#W1Y2,@w0_list,@w0_flags,0,fm#MAX_FILES) 'volles fenster
dlbox[0].focus
w_cols[0] := (fm#W2X2-fm#W1X1)/(fm#MAX_LEN+2)
1: fl_full := 0
dlbox[0].define(1,fm#W1X1,fm#W1Y1,fm#W1X2,fm#W1Y2,@w0_list,@w0_flags,0,fm#MAX_FILES) 'linkes fenster
w_cols[0] := (fm#W1X2-fm#W1X1)/(fm#MAX_LEN+2)
dlbox[0].focus
dlbox[1].draw
w_sel := 0
PRI f_open
'nur fenster 1 und verzeichnisse
if (w_sel == 0) & (w0_flags[w_view[w_sel] + w_pos[w_sel]] & fm#FL_DIR)
ios.sdchdir(get_fname(w_view[w_sel] + w_pos[w_sel]))
w0_clrlist
w0_readdir
dlbox[w_sel].draw
info_print
PRI f_back
ios.sdchdir(string(".."))
w0_clrlist
w0_readdir
dlbox[w_sel].redraw
info_print
PRI f_curup
if w_pos[w_sel] > 1
w_pos[w_sel] -= dlbox[w_sel].getcols
dlbox[w_sel].setpos(w_pos[w_sel])
info_print
dir := 0
PRI f_curdown
if w_pos[w_sel] < (fm#WROWS * w_cols[w_sel] - dlbox[w_sel].getcols)
w_pos[w_sel] += dlbox[w_sel].getcols
dlbox[w_sel].setpos(w_pos[w_sel])
info_print
dir := 1
PRI f_curleft
if w_pos[w_sel]
w_pos[w_sel]--
dlbox[w_sel].setpos(w_pos[w_sel])
info_print
dir := 0
PRI f_curright
if w_pos[w_sel] < (fm#WROWS * w_cols[w_sel] - 1)
w_pos[w_sel]++
dlbox[w_sel].setpos(w_pos[w_sel])
info_print
dir := 1
PRI f_pageup
if (w_view[w_sel] - fm#WROWS * w_cols[w_sel]) => 0
w_view[w_sel] -= fm#WROWS * w_cols[w_sel]
dlbox[w_sel].setview(w_view[w_sel])
info_print
w_pos[w_sel] := fm#WROWS * w_cols[w_sel] - 1
dlbox[w_sel].setpos(w_pos[w_sel])
PRI f_pagedown | number
case w_sel
0: number := w0_number
1: number := w1_number
if (w_view[w_sel] + fm#WROWS * w_cols[w_sel]) =< number '(fm#MAX_FILES)
w_view[w_sel] += fm#WROWS * w_cols[w_sel]
dlbox[w_sel].setview(w_view[w_sel])
info_print
w_pos[w_sel] := 0
dlbox[w_sel].setpos(w_pos[w_sel])
PRI f_select | i
i := w_view[w_sel] + w_pos[w_sel]
case w_sel
0: w0_flags[i] ^= fm#FL_SEL
1: w1_flags[i] ^= fm#FL_SEL
dlbox[w_sel].redraw
case dir
0: f_curleft
1: f_curright
PRI f_focus
ifnot fl_full
dlbox[w_sel].defocus
if w_sel == 1
w_sel := 0
else
w_sel := 1
dlbox[w_sel].focus
info_print
PRI f_quit
ios.sddmset(ios#DM_USER) 'regime soll in diesem verzeichnis landen
ios.winset(0)
ios.screeninit
ios.stop
PRI f_load | i
pbar.setmaxbar(w0_number)
i := 0
repeat w0_number
if w0_flags[i] & fm#FL_SEL
pbar.draw(string("Lade Datei : "),get_fname(i),i)
load(get_fname(i))
w0_flags[i] ^= fm#FL_SEL
info_print
i++
pbar.update(i)
w1_readdir
dlbox[0].draw
dlbox[1].draw
PRI f_save | i
pbar.setmaxbar(w1_number)
i := 0
repeat w1_number
if w1_flags[i] & fm#FL_SEL
pbar.draw(string("Speichere Datei : "),get_fname(i),i)
save(get_fname(i))
w1_flags[i] ^= fm#FL_SEL
i++
pbar.update(i)
w0_clrlist
w0_readdir
dlbox[0].draw
dlbox[1].draw
PRI f_del | i
if wbox.draw(@str1,@str2,@str3) == 1
pbar.setmaxbar(w0_number)
i := 0
repeat w0_number
if w0_flags[i] & fm#FL_SEL
pbar.draw(string("Lösche Datei : "),get_fname(i),i)
ios.sddel(get_fname(i))
w0_flags[i] ^= fm#FL_SEL
i++
pbar.update(i)
w0_clrlist
w0_readdir
dlbox[0].draw
dlbox[1].draw
info_print
PRI f_empty
if wbox.draw(@str4,@str2,@str3) == 1
ios.ram_wrlong(ios#sysmod,ios#SYSVAR,ios#RAMEND) 'Zeiger auf letzte freie Speicherzelle setzen
ios.ram_wrlong(ios#sysmod,0,ios#RAMBAS) 'Zeiger auf erste freie Speicherzelle setzen
ios.ram_wrbyte(ios#sysmod,0,ios#RAMDRV) 'Ramdrive ist abgeschaltet
ios.rd_init
w1_clrlist
w1_readdir
dlbox[0].draw
w_pos[1] := 0
w_view[1] := 0
dlbox[1].setpos(w_pos[1])
dlbox[w_sel].setview(w_view[1])
info_print
PRI f_view | n,stradr
ios.winset(3)
ios.curoff
ios.printcls
stradr := get_fname(w_view[w_sel] + w_pos[w_sel])
n := 1
ifnot ios.os_error(ios.sdopen("r",stradr)) 'datei öffnen
repeat 'text ausgeben
if ios.printchar(ios.sdgetc) == ios#CHAR_NL 'zeilenzahl zählen und stop
if ++n == (fm#W3Y2 - 2)
n := 1
if ios.keywait == "q"
ios.sdclose
ios.printcls
dlbox[0].redraw
dlbox[1].redraw
return
until ios.sdeof 'ausgabe bis eof
ios.print(string(13,"[EOF]"))
ios.keywait
ios.sdclose 'datei schließen
ios.printcls
dlbox[0].draw
dlbox[1].draw
info_print
PRI w0_clrlist | i
i := 0
repeat fm#MAX_FILES
w0_flags[i] := 0
w0_len[i] := 0
i++
i := 0
repeat fm#MAX_BUFFER
w0_list[i] := " "
i++
PRI w1_clrlist | i
i := 0
repeat fm#MAX_FILES
w1_flags[i] := 0
w1_len[i] := 0
i++
i := 0
repeat fm#MAX_BUFFER
w1_list[i] := " "
i++
PRI w0_readdir | stradr,i,j
i := 0
ios.sddir
repeat while (stradr := ios.sdnext)
if ios.sdfattrib(ios#F_DIR)
w0_flags[i] := fm#FL_DIR
j := 0
repeat fm#MAX_LEN
w0_list[i*fm#MAX_LEN+j] := byte[stradr+j]
j++
w0_len[i] := ios.sdfattrib(ios#F_SIZE)
if i++ => fm#MAX_FILES - 1
return
w0_number := i
PRI w1_readdir | stradr,i,j
i := 0
ios.rd_dir
repeat while (stradr := ios.rd_next)
j := 0
repeat fm#MAX_LEN
w1_list[i*fm#MAX_LEN+j] := byte[stradr+j]
j++
i++
w1_len[i] := ios.rd_dlen
w1_number := i
PRI get_fname(fnr):adrdat | i,stradr
i := fm#MAX_LEN * fnr
case w_sel
0: stradr := @w0_list + i
1: stradr := @w1_list + i
i := 0
repeat
fname[i] := byte[stradr+i]
i++
until byte[stradr+i] == " " OR i == fm#MAX_LEN
fname[i] := 0
return @fname
PRI load(stradr) | len,fnr,i
ifnot ios.sdopen("r",stradr) 'datei öffnen
len := ios.sdfattrib(ios#F_SIZE)
ios.rd_newfile(stradr,len) 'datei erzeugen
fnr := ios.rd_open(stradr)
ios.rd_seek(fnr,0)
i := 0
ios.sdxgetblk(fnr,len) 'daten als block direkt in ext. ram einlesen
ios.sdclose
ios.rd_close(fnr)
PRI save(stradr) | fnr,len,i
fnr := ios.rd_open(stradr)
ifnot fnr == -1
len := ios.rd_len(fnr)
ifnot ios.sdnewfile(stradr)
ifnot ios.sdopen("W",stradr)
i := 0
ios.sdxputblk(fnr,len) 'daten als block schreiben
ios.sdclose
ios.rd_close(fnr)
PRI frame_draw
ios.winset(0)
ios.curoff
ios.printcls
ios.cursetx(fm#W0X_MENU)
ios.cursety(fm#W0Y_MENU)
ios.setcolor(fm#COL_MENU)
' ios.print(string(" "))
ios.print(string(" 6: Mount | 7: MkDir | 8: ALL | 9: Full | 10: Quit "))
ios.printlogo(0,0)
ios.cursetx(fm#W0X_STAT)
ios.cursety(fm#W0Y_STAT)
ios.setcolor(fm#COL_STAT)
ios.printq(string(" 1: View | 2: Del | 3: SD>>RAM ◀▶ 4: SD<<RAM | 5: RAM Clear "))
ios.setcolor(fm#COL_DEFAULT)
PRI info_print | pos,len
pos := w_view[w_sel] + w_pos[w_sel]
case w_sel
0: len := w0_len[pos]
1: len := w1_len[pos]
ios.winset(0)
ios.curoff
ios.cursetx(fm#W0X_INFO)
ios.cursety(fm#W0Y_INFO)
ios.print(string(" "))
ios.cursetx(fm#W0X_INFO)
ios.print(get_fname(pos))
if len
ios.print(string(" : "))
ios.printdec(len)
ios.print(string(" Bytes"))
ios.cursetx(fm#W1X_INFO)
ios.print(string("RAM : "))
ios.printdec(ios.ram_getfree)
ios.print(string(" Bytes free"))
PRI testvideo 'passt div. variablen an videomodus an
vidmod := ios.belgetspec & 1
rows := ios.belgetrows 'zeilenzahl bei bella abfragen
cols := ios.belgetcols 'spaltenzahl bei bella abfragen
PRI pause(sec)
waitcnt(cnt+clkfreq*sec)
DAT
str1 byte "Dateien löschen?",0
str2 byte "Ja",0
str3 byte "Nein",0
str4 byte "RAMDrive löschen?",0
str5 byte "SD-Card mounten?",0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,88 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : Terminal
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : Terminalprogramm, ursprünglich für Experimente mit PropForth gedacht - deshalb fterm.
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios : "reg-ios"
ser : "glob-fds"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
PUB main | key
ios.start
' ios.startram 'code für test im ram, sollte bei bin-datei auskommentiert werden
ser.start(31, 30, 0, 9600)
ios.print(string("FTerm - Quit = [ESC]",ios#CHAR_NL))
term
ios.stop
PRI term | rxchar,keychar
repeat
rxchar := ser.rxcheck 'zeichen empfangen
if rxchar <> -1
case rxchar
$08: 'backspace empfangen
ios.printctrl(ios#CHAR_TER_BS)
other:
if rxchar > $05
ios.printchar(rxchar) 'textzeichen empfangen
if ios.keystat
keychar := ios.key
case keychar
ios#CHAR_BS: 'backspace senden
ser.tx($08)
ios#CHAR_ESC: 'esc - programm beenden
return
other: 'textzeichen senden
ser.tx(keychar)
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

741
system/regnatix/g0test.spin Normal file
View File

@ -0,0 +1,741 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : g0test
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
XMAX = 256
YMAX = 192
x_tiles = 16
y_tiles = 12
bit_base = $2000
disp_base = $5000
len_colblk = (x_tiles * y_tiles) * 2 + 256
'ademo1
lines = 5
thickness = 2
s_obj = 200 'scale
d_obj = 64 'durchmesser
r_obj = d_obj/2 'radius
rotvar = 14 'rotationsvarianz
VAR
'achtung, folgende reihenfolge darf nicht verändert werden!
word screen[x_tiles * y_tiles] 'tilemap
long colortab[64] 'farbregister
long heap_len
long heap_use
PUB main|i,x,y,n,len
ios.start
'g0-code laden
ios.g0_load
screenset1 'farben und tiles setzen
ios.g0_static
heap_len := ios.g0_datlen
heap_use := @grdatend - @grdat
ios.g0_datblk(@grdat,0,heap_len) 'heapdaten senden
repeat
' -------------------------------------------------------------------------- heap
ios.g0_static
ios.g0_clear
ios.g0_colorwidth(2,0)
ios.g0_textmode(2,2,6,0)
ios.g0_text(10,100,@string3 - @grdat)
ios.g0_printdec(150,100,heap_len,4,@strstart,@strstart - @grdat)
ios.g0_text(10, 70,@string4 - @grdat)
ios.g0_printdec(150, 70,heap_use,4,@strstart,@strstart - @grdat)
esc_key
waitcnt(cnt+clkfreq*5)
' -------------------------------------------------------------------------- plot
ios.g0_clear
repeat 2000
ios.g0_width(?n&%11111)
ios.g0_color(?n&%0011)
ios.g0_plot(?n&$ff,?n&$ff)
esc_key
' -------------------------------------------------------------------------- line
ios.g0_clear
ios.g0_width(0)
repeat 2000
ios.g0_color(?n&%0011)
ios.g0_line(?n&$ff,?n&$ff)
esc_key
' -------------------------------------------------------------------------- arc
ios.g0_clear
ios.g0_width(0)
repeat 2000
ios.g0_color(?n&%0011)
'ios.g0_arc(x,y,xr,yr,angle,anglestep,steps,arcmode)
ios.g0_arc(?n&$ff,?n&$ff,?n&$1f,?n&$1f,?n&$1fff,?n&$1fff,?n&$1f,?n&%0011)
esc_key
' -------------------------------------------------------------------------- tri
ios.g0_clear
ios.g0_width(0)
repeat 2000
ios.g0_colorwidth(?n&%0011,?n&%11111)
ios.g0_tri(?n&$ff,?n&$ff,?n&$ff,?n&$ff,?n&$ff,?n&$ff)
esc_key
' -------------------------------------------------------------------------- box
ios.g0_clear
ios.g0_width(0)
repeat 2000
ios.g0_colorwidth(?n&%0011,?n&%11111)
ios.g0_box(?n&$ff,?n&$ff,?n&$ff,?n&$ff)
esc_key
' -------------------------------------------------------------------------- vec
ios.g0_clear
ios.g0_width(0)
repeat 2000 'stern
ios.g0_color(?n&%0011)
'ios.g0_vec(x, y, vecscale, vecangle, vecdef_ptr)
ios.g0_vec(?n&$ff,?n&$ff,?n&$ff,cnt>>14,@star - @grdat)
'ios.g0_vec(100,100,200,0,0)
esc_key
ios.g0_clear
repeat 2000 'rombus
ios.g0_color(?n&%0011)
ios.g0_vec(?n&$ff,?n&$ff,?n&$ff,cnt>>14,@rombus - @grdat)
esc_key
' -------------------------------------------------------------------------- vecarc
ios.g0_clear
ios.g0_width(0)
repeat 2000
ios.g0_color(?n&%0011)
'vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr)
ios.g0_vecarc(XMAX/2,YMAX/2,70,70,cnt>>4,100,cnt>>14,@rombus - @grdat )
esc_key
' -------------------------------------------------------------------------- pix
ios.g0_clear
ios.g0_colorwidth(2,1)
ios.g0_pix(XMAX/2,YMAX/2,0,@oldbit1 - @grdat)
waitcnt(cnt+clkfreq*2)
ios.g0_colorwidth(2,0)
repeat x from 0 to 7
repeat y from 0 to 5
'ios.g0_pix(x, y, pixrot, pixdef_ptr)
ios.g0_pix(x*30+10,y*30+10,0,@oldbit1 - @grdat)
esc_key
waitcnt(cnt+clkfreq*2)
ios.g0_dynamic
n := 0
repeat 400
ios.g0_clear
ios.g0_colorwidth(2,1)
ios.g0_pixarc(XMAX/2,YMAX/2,50,50,cnt>>14,0,@oldbit1 - @grdat)
'ios.g0_pix(XMAX/2,YMAX/2,0,@oldbit1 - @grdat)
ios.g0_colorwidth(2,0)
repeat x from 0 to 7
repeat y from 0 to 5
'ios.g0_pix(x, y, pixrot, pixdef_ptr)
ios.g0_pix(x*30+10+n*y,y*30+10,0,@oldbit1 - @grdat)
ios.g0_copy
n++
esc_key
ios.g0_dynamic
ios.g0_colorwidth(2,1)
repeat 10
ios.g0_clear
repeat x from 0 to 7
repeat y from 0 to 5
'ios.g0_pix(x, y, pixrot, pixdef_ptr)
ios.g0_pix(x*30+10,y*30+10,0,@monkey1 - @grdat)
ios.g0_copy
esc_key
waitcnt(cnt+clkfreq/3)
ios.g0_clear
repeat x from 0 to 7
repeat y from 0 to 5
'ios.g0_pix(x, y, pixrot, pixdef_ptr)
ios.g0_pix(x*30+10,y*30+10,0,@monkey2 - @grdat)
ios.g0_copy
esc_key
waitcnt(cnt+clkfreq/3)
repeat i from 0 to 31
ios.g0_clear
ios.g0_colorwidth(1,i)
'ios.g0_pix(x, y, pixrot, pixdef_ptr)
ios.g0_pix(60,70,0,@monkey1 - @grdat)
ios.g0_copy
esc_key
waitcnt(cnt+clkfreq/7)
ios.g0_static
' -------------------------------------------------------------------------- pixarc
ios.g0_dynamic
ios.g0_colorwidth(2,1)
repeat 1000
ios.g0_clear
'ios.g0_pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr)
ios.g0_pixarc(XMAX/2,YMAX/2,50,50,cnt>>14,0,@monkey1 - @grdat)
ios.g0_copy
ios.g0_clear
'ios.g0_pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr)
ios.g0_pixarc(XMAX/2,YMAX/2,50,50,cnt>>14,0,@monkey2 - @grdat)
ios.g0_copy
esc_key
ios.g0_static
' -------------------------------------------------------------------------- text
ios.g0_dynamic
'ios.g0_textmode(x_scale, y_scale, spacing, justification)
repeat 150
ios.g0_clear
ios.g0_colorwidth(2,1)
repeat x from 0 to 7
repeat y from 0 to 3
'ios.g0_pix(x, y, pixrot, pixdef_ptr)
ios.g0_pix(x*30+10,y*30+70,0,@monkey1 - @grdat)
ios.g0_colorwidth(2,8)
ios.g0_textmode(5,5,6,0)
ios.g0_text(700 - (cnt>>20 & $fff),60,@string1 - @grdat)
ios.g0_colorwidth(1,6)
ios.g0_textmode(5,4,6,0)
ios.g0_text(700 - (cnt>>24 & $fff),0,@string2 - @grdat)
ios.g0_copy
esc_key
ios.g0_static
' -------------------------------------------------------------------------- textarc
ios.g0_dynamic
ios.g0_colorwidth(2,1)
repeat 150
ios.g0_clear
ios.g0_colorwidth(2,1)
repeat x from 0 to 7
repeat y from 0 to 5
'ios.g0_pix(x, y, pixrot, pixdef_ptr)
ios.g0_pix(x*30+10,y*30+10,0,@monkey1 - @grdat)
ios.g0_colorwidth(0,8)
ios.g0_textmode(5,5,6,0)
'ios.g0_textarc(x, y, xr, yr, angle, string_ptr)
ios.g0_textarc(XMAX/4,YMAX/4,50,50,cnt>>14,@string1 - @grdat)
ios.g0_copy
esc_key
ios.g0_static
' -------------------------------------------------------------------------- animation
ademo1
ademo2
' -------------------------------------------------------------------------- colorset
ios.g0_clear
screenset2
'draw color samples
ios.g0_width(29)'(29)
'draw saturated samples
ios.g0_color(3)
repeat x from 0 to 15
ios.g0_plot(x << 4 + 7, 183)
'draw gradient samples
repeat y from 2 to 6
ios.g0_color(y & 1 | 2)
repeat x from 0 to 15
ios.g0_plot(x << 4 + 7, 183 - y << 4)
'draw monochrome samples
ios.g0_color(3)
repeat x from 5 to 10
ios.g0_plot(x << 4 + 7, 55)
esc_key
waitcnt(cnt + clkfreq * 2)
screenset1
PUB esc_key
if ios.g0_keystat
ios.g0_reboot
ios.stop
repeat
PUB screenset1|i,tx,ty
'tilescreen setzen
repeat tx from 0 to x_tiles - 1
repeat ty from 0 to y_tiles - 1
screen[ty * x_tiles + tx] := disp_base >> 6 + ty + tx * y_tiles + ((ty & $3F) << 10)
'farbtabelle füllen
repeat i from 0 to 63
colortab[i] := $00001010 * (i<<1+4) & $F + $0D060D02
ios.g0_colortab(@colortab)
ios.g0_screen(@screen)
PUB screenset2|x, y, i, c
'init colors
repeat i from $00 to $0F
case i
5..10 : c := $01000000 * (i - 5) + $02020507
other : c := $07020504
colortab[i] := c
repeat i from $10 to $1F
colortab[i] := $10100000 * (i & $F) + $0B0A0507
repeat i from $20 to $2F
colortab[i] := $10100000 * (i & $F) + $0D0C0507
repeat i from $30 to $3F
colortab[i] := $10100000 * (i & $F) + $080E0507
'init tile screen
repeat x from 0 to x_tiles - 1
repeat y from 0 to y_tiles - 1
case y
0, 2 : i := $30 + x
3..4 : i := $20 + x
5..6 : i := $10 + x
8 : i := x
other: i := 0
screen[x + y * x_tiles] := i << 10 + disp_base >> 6 + x * y_tiles + y
ios.g0_colortab(@colortab)
ios.g0_screen(@screen)
PUB ademo1 | x,y,i,j,k,kk,dx,dy,pp,pq,rr,numx,numchr
x := XMAX/2
y := YMAX/2
dx := 1
dy := 1
k := 0
ios.g0_dynamic
repeat 500
'clear bitmap
ios.g0_clear
'draw spinning triangles
ios.g0_colorwidth(1,0)
repeat i from 1 to 16
ios.g0_vec(XMAX/2 + k & $FF, YMAX/2, s_obj-i*60, k << 6 + i << 8, @triangle - @grdat)
'draw expanding pixel halo
ios.g0_colorwidth(1,k)
ios.g0_arc(XMAX/2, YMAX/2,80,30,-k<<5,$2000/9,10,0)
'draw boing-star
ios.g0_colorwidth(1, 1)
repeat j from 0 to 5
ios.g0_vec(x+j*2, y+j*5, s_obj-j*40, cnt>>rotvar,@star - @grdat)
'kollisionsabfrage
if (x + dx - r_obj) < 0
dx := dx * -1
else
if (x + dx + r_obj + 5) > XMAX
dx := dx * -1
if (y + dy - r_obj) < 0
dy := dy * -1
else
if (y + dy + r_obj + 5) > YMAX
dy := dy * -1
x += dx
y += dy
'draw spinning stars and revolving crosshairs and dogs
ios.g0_colorwidth(2,0)
repeat i from 0 to 7
ios.g0_vecarc(40,50,30,30,-(i<<10+k<<6),$40,-(k<<7),@star - @grdat)
ios.g0_pixarc(190,140,30,30,i<<10+k<<6,0,@monkey1 - @grdat)
ios.g0_pixarc(190,140,20,20,-(i<<10+k<<6),0,@monkey1 - @grdat)
'draw text
ios.g0_textmode(5,5,6,0)
ios.g0_colorwidth(1,8)
ios.g0_text(5,120,@string1 - @grdat)
'draw text
'ios.g0_colorwidth(2,0)
'ios.g0_textmode(5,5,6,0)
'ios.g0_text(150,5,@string1 - @grdat)
'draw counter
ios.g0_colorwidth(2,16-k&$f)
ios.g0_textmode(3,3,6,0)
ios.g0_printdec(160,10,k,4,@strstart,@strstart - @grdat)
'copy bitmap to display
ios.g0_copy
'increment counter that makes everything change
k++
esc_key
ios.g0_static
PUB ademo2 | i,k,x,y,dx,dy,rad
x := XMAX/2
y := YMAX/2
dx := 6
dy := 6
rad := 8
k := 0
ios.g0_dynamic
repeat 500
'clear bitmap
ios.g0_clear
'draw spinning triangles
ios.g0_colorwidth(1,0)
repeat i from 1 to 8
ios.g0_vec(k & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 64 & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 128 & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 192 & $FF, 32+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
repeat i from 1 to 8
ios.g0_vec(k + 32 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 96 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 160 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 224 & $FF, 96+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
repeat i from 1 to 8
ios.g0_vec(k & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 64 & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 128 & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_vec(k + 192 & $FF,160+k, s_obj-i*60, k << 6 + i << 8, @star - @grdat)
ios.g0_colorwidth(2,15)
ios.g0_plot(x,y)
'kollisionsabfrage
if (x + dx - rad) < 0
dx := dx * -1
ios.sfx_fire($f1,0)
else
if (x + dx + rad + 5) > XMAX
dx := dx * -1
ios.sfx_fire($f1,0)
if (y + dy - rad) < 0
dy := dy * -1
ios.sfx_fire($f1,0)
else
if (y + dy + rad + 5) > YMAX
dy := dy * -1
ios.sfx_fire($f1,0)
x += dx
y += dy
'copy bitmap to display
ios.g0_copy
'increment counter that makes everything change
k++
esc_key
ios.g0_static
DAT 'heap-daten
grdat
strstart 'stringpuffer für zahlenausgabe
byte "00000000",0 '8 digits
byte 0 'wichtig: auf wortgrenze auffüllen!
strend
star
byte word $4000+$2000/12*0 'star
byte word 50
byte word $8000+$2000/12*1
byte word 20
byte word $8000+$2000/12*2
byte word 50
byte word $8000+$2000/12*3
byte word 20
byte word $8000+$2000/12*4
byte word 50
byte word $8000+$2000/12*5
byte word 20
byte word $8000+$2000/12*6
byte word 50
byte word $8000+$2000/12*7
byte word 20
byte word $8000+$2000/12*8
byte word 50
byte word $8000+$2000/12*9
byte word 20
byte word $8000+$2000/12*10
byte word 50
byte word $8000+$2000/12*11
byte word 20
byte word $8000+$2000/12*0
byte word 50
byte word 0
triangle
byte word $4000+$2000/3*0 'triangle
byte word 50
byte word $8000+$2000/3*1+1
byte word 50
byte word $8000+$2000/3*2-1
byte word 50
byte word $8000+$2000/3*0
byte word 50
byte word 0
rombus
byte word $4000+$2000/4*0 'rombus
byte word 50
byte word $8000+$2000/4*1
byte word 30
byte word $8000+$2000/4*2
byte word 50
byte word $8000+$2000/4*3
byte word 30
byte word $8000+$2000/4*0
byte word 50
byte word 0
oldbit1
byte 3,24,12,12
byte word %%00000000
byte word %%00000000
byte word %%00000000
byte word %%00000000
byte word %%00000000
byte word %%00000000
byte word %%12121212
byte word %%12121212
byte word %%12222212
byte word %%12121212
byte word %%12121212
byte word %%12222212
byte word %%12121212
byte word %%12121212
byte word %%12222212
byte word %%00000000
byte word %%00000000
byte word %%00000000
byte word %%00110000
byte word %%00000111
byte word %%11110000
byte word %%00110000
byte word %%00111001
byte word %%12330000
byte word %%00110001
byte word %%11113300
byte word %%11120000
byte word %%00100011
byte word %%11111230
byte word %%11110000
byte word %%00100011
byte word %%11111120
byte word %%00010000
byte word %%00100011
byte word %%11111110
byte word %%13000000
byte word %%00100011
byte word %%11001110
byte word %%11013233
byte word %%00100011
byte word %%00110110
byte word %%11011111
byte word %%00100011
byte word %%00230110
byte word %%11000000
byte word %%00100011
byte word %%00110110
byte word %%00010000
byte word %%00100011
byte word %%10000110
byte word %%11110000
byte word %%00110001
byte word %%11111100
byte word %%11110000
byte word %%00110000
byte word %%00111001
byte word %%11110000
byte word %%00110000
byte word %%00000011
byte word %%11110000
byte word %%00000000
byte word %%00000000
byte word %%00000000
byte word %%12121212
byte word %%12121212
byte word %%22121212
byte word %%12121212
byte word %%12121212
byte word %%22121212
byte word %%12121212
byte word %%12121212
byte word %%22121212
monkey1
'byte 2,11,3,3
'word %%00011111,%%00000000
'word %%00321112,%%23000000
'word %%00322112,%%21110000
'word %%02222211,%%11111000
'word %%03222111,%%11111100
'word %%00000111,%%11111110
'word %%00000111,%%11111110
'word %%00000111,%%11111110
'word %%00000111,%%11111110
'word %%00002120,%%01111200
'word %%00001220,%%22222100
byte 2,11,3,3
byte word %%00011111
byte word %%00000000
byte word %%00321112
byte word %%23000000
byte word %%00322112
byte word %%21110000
byte word %%02222211
byte word %%11111000
byte word %%03222111
byte word %%11111100
byte word %%00000111
byte word %%11111110
byte word %%00000111
byte word %%11111110
byte word %%00000111
byte word %%11111110
byte word %%00000111
byte word %%11111110
byte word %%00002120
byte word %%01111200
byte word %%00001220
byte word %%22222100
monkey2
'byte 2,11,3,3
'word %%00011111,%%00000000
'word %%00321112,%%23000000
'word %%00322112,%%21110000
'word %%02222211,%%11111000
'word %%03222111,%%11111100
'word %%00000111,%%11111110
'word %%00000111,%%11111110
'word %%00000111,%%11111110
'word %%00001110,%%11111110
'word %%00021200,%%01111200
'word %%00122000,%%00222220
byte 2,11,3,3
byte word %%00011111
byte word %%00000000
byte word %%00321112
byte word %%23000000
byte word %%00322112
byte word %%21110000
byte word %%02222211
byte word %%11111000
byte word %%03222111
byte word %%11111100
byte word %%00000111
byte word %%11111110
byte word %%00000111
byte word %%11111110
byte word %%00000111
byte word %%11111110
byte word %%00001110
byte word %%11111110
byte word %%00021200
byte word %%01111200
byte word %%00122000
byte word %%00222220
string1
byte "HIVE",0
string2
byte "abcdefghijklmnopqrstuvwxyz 0123456789",0
string3
byte "heap-len : ",0
string4
byte "heap-use : ",0
grdatend
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

418
system/regnatix/hplay.spin Normal file
View File

@ -0,0 +1,418 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : HSS-Player
Chip : Regnatix
Typ : Programm
Version : 00
Subversion : 02
Funktion : HSS-Player für die Kommandozeile
Logbuch :
08-04-2010-dr235 - fork aus regime
- anpassung an trios
16-04-2010-dr235 - umwandlung in reine kommandozeilenanwendung
Kommandoliste :
/? : hilfetext
/p name.wav : hss-datei abspielen
/d : verzeichnis abspielen
/s : wiedergabe stoppen
/t : anzeige trackerliste
/r : anzeige engine-register
/i : anzeige interface-register
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
OS_TIBLEN = 64 'größe des inputbuffers
ERAM = 1024 * 512 * 2 'größe eram
HRAM = 1024 * 32 'größe hram
RMON_ZEILEN = 16 'speichermonitor - angezeigte zeilen
RMON_BYTES = 8 'speichermonitor - zeichen pro byte
VAR
long datcnt 'zeiger für dateiliste
byte fn[12] 'puffer für dateinamen
byte parastr[64] 'parameterstring
byte fl_bye
byte fl_next
DAT 'PARAMETER
PUB main
ios.start 'ios initialisieren
ios.parastart 'parameterübergabe starten
repeat while ios.paranext(@parastr) 'parameter einlesen
if byte[@parastr][0] == "/" 'option?
case byte[@parastr][1]
"?": ios.print(string("help: man hplay")) '/? - hilfetext
"p": play_hss '/p - hss-datei wiedergeben
"d": play_dir '/d - verzeichnis wiedergeben
"t": disp_tracker '/t - anzeige tracker
"r": disp_reg '/r - anzeige register
"i": disp_ireg '/i - anzeige interfaceregister
"s": ios.hss_stop '/s - wiedergabe stoppen
ios.stop
DAT 'PLAY_FILE
PUB play_hss 'hss: player starten
if ios.paranext(@parastr) 'parameter?
ios.hss_playfile(@parastr)
else 'kein parameter: fehlermeldung
printErr(@err1)
DAT 'PLAY_DIR
PUB play_dir | stradr,len,fcnt,i 'hss: alle songs auf der sd-card abspielen
ios.sddir 'kommando: verzeichnis öffnen
hss_startlist 'zum listenanfang
fcnt := 0 'zähler für dateianzahl
fl_bye := fl_next := 0
repeat while (stradr := ios.sdnext) 'dateiliste einlesen
' ios.print(stradr)
if str_find(stradr,@ext1)
' ios.printchar("◀")
fcnt++
hss_wrfn(stradr)
' ios.printnl
ios.print(string("Anzahl Dateien : "))
ios.printdec(fcnt)
ios.printnl
hss_startlist 'zum listenanfang
if fcnt
repeat i from 0 to fcnt-1 'dateiliste abspielen
ios.printdec(i+1)
ios.printchar("/")
ios.printdec(fcnt)
ios.printchar(" ")
hss_rdfn(@fn)
hss_playsong(@fn)
if fl_bye
quit
if fl_next
fl_next := 0
else
hss_fadeout
ios.hss_stop
PUB hss_playsong(stradr) | n,q,key 'hss: spielt die musikdatei bis zum ende
ios.curoff
ios.print(string("PlaySong <q/n> : "))
ios.print(stradr)
ios.printnl
ios.hss_stop
ios.hss_playfile(stradr)
repeat
n := ios.hss_intreg(ios#iRepeat) 'anzahl der schleifendurchläufe abfragen
q := ios.hss_intreg(ios#iEndFlag)
ios.curpos1
ios.print(string("iRepeat : "))
ios.printdec(n)
ios.print(string(" iEndFlag : "))
ios.printdec(q)
if key := ios.key
case key
"n": fl_next := 1
quit
"q": fl_bye := 1
quit
until n == 3 or q == 1
ios.printnl
ios.curon
PUB hss_fadeout | i 'hss: song langsam ausblenden
repeat i from 0 to 15
ios.hss_vol(15 - i)
waitcnt(cnt + 60_000_000)
waitcnt(cnt + 30_000_000)
PUB hss_wrfn(stradr) | len,i 'hss: kopiert dateinamen in eram
len := strsize(stradr)
repeat i from 0 to len-1
ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++)
ios.ram_wrbyte(ios#usrmod,0,datcnt++)
PUB hss_rdfn(stradr) | i,n 'hss: liest dateinamen aus eram
i := 0
repeat
n := ios.ram_rdbyte(ios#usrmod,datcnt++)
byte[stradr][i++] := n
while n <> 0
PUB hss_startlist 'hss: zeiger auf listenanfang (dateinamen)
datcnt := 0
DAT 'DISPLAY
PUB disp_tracker | i,n 'disp: trackerliste ausgeben
repeat
repeat
until ios.hss_intreg(ios#iRowFlag) == 0
repeat
until ios.hss_intreg(ios#iRowFlag) == 1 'synchronisation bis zeile fertig bearbeitet
ios.printhex(ios.hss_intreg(ios#iBeatC),4)
ios.printchar("-")
ios.printhex(ios.hss_intreg(ios#iEngineC),4)
ios.printchar(":")
ios.printchar(" ")
repeat i from 1 to 4
hss_printnote(ios.hss_intreg(i*5+ios#iNote)) 'note
n := ios.hss_intreg(i*5+ios#iOktave)
if n
ios.printhex(n,1) 'oktave
else
ios.printchar("-")
ios.printchar(" ")
n := ios.hss_intreg(i*5+ios#iVolume)
if n
ios.printhex(n,1) 'volume
else
ios.printchar("-")
ios.printchar(" ")
n := ios.hss_intreg(i*5+ios#iEffekt)
if n
ios.printhex(n,1) 'effekt
else
ios.printchar("-")
ios.printchar(" ")
n := ios.hss_intreg(i*5+ios#iInstrument)
if n
ios.printhex(n,1) 'instrument
else
ios.printchar("-")
ios.printchar(" ")
ios.printnl
until ios.keystat > 0 'taste gedrückt?
ios.key
ios.curon
ios.printnl
PUB hss_printnote(n) 'disp: notenwert ausgeben
'C1,C#1,D1,D#1,E1,F1,F#1,G1,G#1,A1,A#1,H1
case n
0: ios.print(string(" "))
1: ios.print(string("C "))
2: ios.print(string("C#"))
3: ios.print(string("D "))
4: ios.print(string("D#"))
5: ios.print(string("E "))
6: ios.print(string("F "))
7: ios.print(string("F#"))
8: ios.print(string("G "))
9: ios.print(string("G#"))
10: ios.print(string("A "))
11: ios.print(string("A#"))
12: ios.print(string("H "))
PUB disp_ireg | i,j,n,wert 'disp: anzeige interfaceregister
ios.printcls
repeat
ios.curhome
ios.curoff
ios.printnl
repeat i from 0 to 4
ios.printhex(i*8,2)
ios.printchar(":")
repeat j from 0 to 4
n := (i*5)+j
wert := ios.hss_intreg(n)
ios.printhex(wert,4)
ios.printchar(" ")
ios.printnl
until ios.keystat > 0 'taste gedrückt?
ios.key
ios.curon
ios.printnl
PUB disp_reg | wert,i,j,n 'disp: kontinuierliche anzeige der regsiterwerte
{{
8 x 6 register long
0 kanal a
3>>16 f
4 v
8 kanal b
16 kanal c
24 kanal d
}}
ios.printcls
repeat
ios.curhome
ios.curoff
repeat j from 0 to 3
ios.printnl
ios.printnl
ios.printhex(j*8,2)
ios.printchar(":")
repeat i from 0 to 3
n := (j*8)+i
wert := ios.hss_peek(n)
ios.printhex(wert,8)
ios.printchar(" ")
ios.printnl
ios.printhex(j*8+4,2)
ios.printchar(":")
repeat i from 4 to 7
n := (j*8)+i
wert := ios.hss_peek(n)
ios.printhex(wert,8)
ios.printchar(" ")
ios.printnl
ios.printnl
ios.print(string("Channel A F: "))
wert := ios.hss_peek(0+3)
ios.printhex(wert>>16,4)
ios.print(string(" V: "))
wert := ios.hss_peek(0+4)
ios.printhex(wert,2)
ios.printnl
ios.print(string("Channel B F: "))
wert := ios.hss_peek(8+3)
ios.printhex(wert>>16,4)
ios.print(string(" V: "))
wert := ios.hss_peek(8+4)
ios.printhex(wert,2)
ios.printnl
ios.print(string("Channel C F: "))
wert := ios.hss_peek(16+3)
ios.printhex(wert>>16,4)
ios.print(string(" V: "))
wert := ios.hss_peek(16+4)
ios.printhex(wert,2)
ios.printnl
ios.print(string("Channel D F: "))
wert := ios.hss_peek(24+3)
ios.printhex(wert>>16,4)
ios.print(string(" V: "))
wert := ios.hss_peek(24+4)
ios.printhex(wert,2)
until ios.keystat > 0 'taste gedrückt?
ios.key
ios.curon
ios.printnl
DAT 'TOOLS
PRI printErr(stradr)
ios.print(@err0)
ios.print(stradr)
ios.print(string("help: man hplay"))
PUB str_find(string1, string2) : buffer | counter 'sys: string suchen
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Searches a string of characters for the first occurence of the specified string of characters. │
'' │ │
'' │ Returns the address of that string of characters if found and zero if not found. │
'' │ │
'' │ string1 - A pointer to the string of characters to search. │
'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(string1--)
if(byte[++string1] == byte[string2])
repeat counter from 0 to (strsize(string2) - 1)
if(byte[string1][counter] <> byte[string2][counter])
buffer~~
ifnot(buffer~)
return string1
PUB str_lower(characters) '' 4 Stack Longs 'sys: in kleine zeichen wandeln
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Demotes all upper case characters in the set of ("A","Z") to their lower case equivalents. │
'' │ │
'' │ Characters - A pointer to a string of characters to convert to lowercase. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(characters--)
result := byte[++characters]
if((result => "A") and (result =< "Z"))
byte[characters] := (result + 32)
DAT 'strings
ext1 byte ".HSS",0
err0 byte 13,"Fehler : ",0
err1 byte "Zu wenig Parameter!",13,0
DAT 'lizenz
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,86 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : keycode
Chip : Regnatix
Typ : Programm
Version : 00
Subversion : 01
Funktion : Kleines Tool um Tastencodes auszugeben
Komponenten : -
COG's : -
Logbuch :
22-03-2010-dr235 - anpassung trios
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
PUB main | key,spec
ios.start
' code für test im ram, sollte bei bin-datei auskommentiert werden
' ios.startram
repeat
ios.print(string("[q] keycode : "))
key := ios.keywait
spec := ios.keyspec
ios.printhex(key,2)
ios.print(@str1)
ios.printdec(key)
ios.printtab
ios.print(@str1)
ios.printtab
ios.printqchar(key)
ios.print(@str1)
ios.printhex(spec,2)
ios.printnl
until key == "q"
ios.stop
DAT
str1 byte " : ",0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

320
system/regnatix/m.spin Normal file
View File

@ -0,0 +1,320 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : mental-Loader für TriOS
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
mgc: "m-glob-con"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
long plen 'länge datenblock loader
byte proghdr[16] 'puffer für objektkopf
byte debug
pub main | err,sys
debug := 0
err := 0
sys := 0
ios.start
ios.sddmact(ios#DM_ROOT)
ios.print(string(13,"Wir sind Borg. Widerstand ist zwecklos.",13))
ios.print(string("Assimilation wird gestartet...",13,13))
err |= need_file(string("Check ADM-Code : "),string("adm"))
err |= need_file(string("Check BEL-Code : "),string("bel"))
err |= need_file(string("Check REG-Code : "),string("reg"))
sys := need_file(string("Check USR-Tape : "),string("usr"))
sys := need_file(string("Check SYS-Tape : "),string("sys"))
pause(3)
ifnot err
if sys
ios.print(string(13,"SYS-Tape nicht vorhanden, mental wird dennoch gestartet!",13))
timer(10)
mload
else
ios.print(string(13,"Abbruch: System nicht korrekt installiert!",13))
ios.stop
pri timer(sec)
ios.curoff
ios.printnl
repeat sec
ios.curpos1
ios.print(string("Weiter in "))
ios.printdec(sec--)
ios.print(string(" Sekunden "))
waitcnt(cnt+clkfreq)
ios.curon
pri pause(sec)
if debug
waitcnt(cnt+clkfreq*sec)
pri mload | i
'---------------------------------------------------------- slavecode starten
ios.print(string(13,"System wird nun gestartet...",13))
pause(2)
ios.belload(string("bel"))
ios.print(string(" BEL-Code wurde gestartet: ok",13))
ios.sdclose
pause(2)
ios.print(string(" ADM-Code wird gestartet: "))
ios.admload(string("adm"))
ios.print(string(" ok"))
pause(2)
ios.printnl
ios.print(string(" REG-Code wird gestartet: "))
'---------------------------------------------------------- m-core starten
m_sdopen("r",string("reg")) 'datei öffnen
repeat i from 0 to 15 '16 bytes header --> bellatrix
byte[@proghdr][i] := m_sdgetc
m_sdclose
plen := 0
plen := byte[@proghdr + $0B] << 8
plen := plen + byte[@proghdr + $0A]
plen := plen - 8 'korrekte dateilänge berechnen
m_sdopen("r",string("reg")) 'datei öffnen
ios.bus_putchar1(mgc#adm_sd_getblk) 'adm:sd_getblk
ios.bus_putlong1(plen) 'blocklänge senden
dira := 0 'diese cog vom bus trennen
repeat i from 0 to 7 'alle anderen cogs stoppen
if i <> cogid
cogstop(i)
cognew(@loader, plen) 'pasm-loader übernimmt
cogstop(cogid) 'spin-loader beenden
dat org 0
loader
mov outa, _S1 'bus inaktiv
mov dira, DINP 'bus auf eingabe schalten
mov reg_cnt, PAR 'parameter = plen
mov reg_adr, #0 'adresse ab 0
' datenblock empfangen
loop
call #m_aget 'wert einlesen
wrbyte reg_a, reg_adr 'wert --> hubram
add reg_adr, #1 'adresse + 1
djnz reg_cnt, #loop
mov dira, #0
' 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
' ---------------------------------------------------------------------
' businterface
' ---------------------------------------------------------------------
' reg_a io-zeichen
' reg_b temp
' reg_c temp
m_aput ' zeichen zu administra senden
waitpeq _hs,_hs ' warte auf hs=1 (slave bereit)
and reg_a,#$ff ' wert maskieren
or reg_a,_a1 ' + bel=0 wr=0 clk=0
mov outa,reg_a ' daten + signale ausgeben
mov dira,dout ' bus auf ausgabe schalten
or outa,_a2 ' clk=0 --> clk=1
waitpeq _zero,_hs ' warte auf hs=0
mov dira,dinp ' bus auf eingabe schalten
mov outa,_s1 ' bussignale inaktiv
m_aput_ret ret
m_bput ' zeichen zu bellatrix senden
waitpeq _hs,_hs ' warte auf hs=1 (slave bereit)
and reg_a,#$ff ' wert maskieren
or reg_a,_b1 ' + bel=0 wr=0 clk=0
mov outa,reg_a ' daten + signale ausgeben
mov dira,dout ' bus auf ausgabe schalten
or outa,_b2 ' clk=0 --> clk=1
waitpeq _zero,_hs ' warte auf hs=0
mov dira,dinp ' bus auf eingabe schalten
mov outa,_s1 ' bussignale inaktiv
m_bput_ret ret
m_aget ' zeichen von administra empfangen
waitpeq _hs,_hs ' warte auf hs=1 (slave bereit)
mov outa,_a3 ' bel=0 wr=1 clk=1
waitpeq _zero,_hs ' warte auf hs=0
mov reg_a,ina ' daten einlesen
and reg_a,#$ff ' wert maskieren
mov outa,_s1 ' bussignale inaktiv
m_aget_ret ret
m_bget ' zeichen von belatrix empfangen
waitpeq _hs,_hs ' warte auf hs=1 (slave bereit)
mov outa,_b3 ' bel=0 wr=1 clk=1
waitpeq _zero,_hs ' warte auf hs=0
mov reg_a,ina ' daten einlesen
and reg_a,#$ff ' wert maskieren
mov outa,_s1 ' bussignale inaktiv
m_bget_ret ret
' +------------------------------- /hs
' |+------------------------------ /wr
' ||+----------------------------- busclk
' |||+---------------------------- hbeat
' |||| +-------------------------- al
' |||| |+------------------------- /bel
' |||| ||+------------------------ /adm
' |||| |||+----------------------- /ram2
' |||| ||||+---------------------- /ram1
' |||| ||||| +---------- a0..10
' |||| ||||| |
' |||| ||||| | +- d0..7
' |||| |||||+----------+ +------+
_al long %00000000_10000000_00000000_00000000 ' /al bitmaske
_bwr long %00000100_00000000_00000000_00000000 ' /wr bitmaske
_ram1 long %00000000_00001000_00000000_00000000 ' /ram1 bitmaske
_latch long %00000000_00000000_11111111_00000000 ' latch bitmaske
_adr long %00000000_00000111_11111111_00000000 ' adrbus bistmaske
dinp long %00000111_11111111_11111111_00000000 ' bus input
dout long %00000111_11111111_11111111_11111111 ' bus output
_s1 long %00000100_01111000_00000000_00000000 ' bus inaktiv
_b1 long %00000000_00111000_00000000_00000000 ' adm=1, bel=0, wr=0, busclk=0
_b2 long %00000010_00111000_00000000_00000000 ' adm=1, bel=0, wr=0, busclk=1
_b3 long %00000110_00111000_00000000_00000000 ' adm=1, bel=0, wr=1, busclk=1
_a1 long %00000000_01011000_00000000_00000000 ' adm=0, bel=1, wr=0, busclk=0
_a2 long %00000010_01011000_00000000_00000000 ' adm=0, bel=1, wr=0, busclk=1
_a3 long %00000110_01011000_00000000_00000000 ' adm=0, bel=1, wr=1, busclk=1
_hs long %00001000_00000000_00000000_00000000 ' hs=1?
_zero long %00000000_00000000_00000000_00000000 '
SINT long ($0001 << 18) | ($3C01 << 4) ' Spin interpreter boot information.
SMARK long $FFF9FFFF ' Stack mark used for spin code.
reg_adr res 1
reg_cnt res 1
reg_a res 1
reg_b res 1
reg_c res 1
pri need_file(strptr1,strptr2): err
ios.print(strptr1)
ios.printtab
ios.printtab
err := ios.sdopen("R",strptr2)
ios.sdclose
ifnot err
ios.print(string("ok"))
else
ios.setcolor(1)
ios.print(string("fail"))
ios.setcolor(0)
ios.printnl
pri m_sdopen(modus,stradr):err | len,i 'sd-card: datei öffnen
''funktionsgruppe : sdcard
''funktion : eine bestehende datei öffnen
''busprotokoll : [004][put.modus][sub_putstr.fn][get.error]
'' : modus - "A" Append, "W" Write, "R" Read (Großbuchstaben!)
'' : fn - name der datei
'' : error - fehlernummer entspr. list
ios.bus_putchar1(mgc#adm_sd_open)
ios.bus_putchar1(modus)
len := strsize(stradr)
ios.bus_putchar1(len)
repeat i from 0 to len - 1
ios.bus_putchar1(byte[stradr++])
err := ios.bus_getchar1
pri m_sdclose:err 'sd-card: datei schließen
''funktionsgruppe : sdcard
''funktion : die aktuell geöffnete datei schließen
''busprotokoll : [005][get.error]
'' : error - fehlernummer entspr. list
ios.bus_putchar1(mgc#adm_sd_close)
err := ios.bus_getchar1
pri m_sdgetc: char 'sd-card: zeichen aus datei lesen
''funktionsgruppe : sdcard
''funktion : zeichen aus datei lesen
''busprotokoll : [006][get.char]
'' : char - gelesenes zeichen
ios.bus_putchar1(mgc#adm_sd_getc)
char := ios.bus_getchar1
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

138
system/regnatix/man.spin Normal file
View File

@ -0,0 +1,138 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : Hallo Hive!
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
str: "glob-string"
VAR
byte parastr[64]
byte rows 'aktuelle anzahl der nutzbaren zeilen
byte cols 'aktuelle Anzahl der nutzbaren spalten
byte vidmod 'videomodus: 0 - vga, 1 - tv
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
PUB main | i,n,len
n := 1
ios.start
ios.parastart
ios.paranext(@parastr)
vidmod := ios.belgetspec & 1
rows := ios.belgetrows 'zeilenzahl bei bella abfragen
cols := ios.belgetcols 'spaltenzahl bei bella abfragen
len := strsize(@parastr)
ios.sddmset(ios#DM_USER) 'u-marker setzen
ios.sddmact(ios#DM_SYSTEM) 's-marker aktivieren
repeat i from 0 to 3 'extender anhängen
byte[@parastr][len + i] := byte[@ext1][i]
byte[@parastr][len + i] := 0
ifnot ios.sdopen("r",@parastr)
repeat 'text ausgeben
if ios.printchar(ios.sdgetc) == ios#CHAR_NL 'zeilenzahl zählen und stop
if ++n == (rows - 2)
n := 1
if ios.keywait == "q"
ios.sdclose
ios.sddmact(ios#DM_USER) 'u-marker aktivieren
ios.stop
until ios.sdeof 'ausgabe bis eof
else
'ios.print(string("Hilfetexte : ",$0d))
cmd_dir_w(1)
ios.sdclose 'datei schließen
ios.sddmact(ios#DM_USER) 'u-marker aktivieren
ios.stop
PRI cmd_dir_w(hflag):fcnt|stradr,lcnt,wcnt,len,i,j
fcnt := 0
wcnt := (cols / 9) - 1 '3
lcnt := (rows - 2) * (cols / 15)
ios.printnl
repeat while (stradr := ios.sdnext)
len := strsize(stradr)
i := j := 0
repeat until byte[stradr + i] == "." 'extender finden
i++
repeat until byte[stradr + i + j] == " " 'endesuchen/terminieren
j++
byte[stradr + i + j] := 0
{
ios.print(stradr)
ios.print(stradr+i)
ios.print(@ext1)
ios.printdec(i)
ios.printdec(strcomp(@ext1,(stradr+i)))
ios.printnl
}
if strcomp(@ext1,(stradr+i))
ios.print(string(" "))
str.charactersToLowerCase(stradr)
byte[stradr + i] := 0 'extender abtrennen
ios.print(stradr)
ifnot wcnt--
wcnt := (cols / 15) - 1 '3
ios.printnl
else
'ios.printtab
fcnt++
ifnot --lcnt
lcnt := (rows - 2) * (cols / 15)
if ios.keywait == "q"
return
DAT
ext1 byte ".MAN",0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,362 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : ramtest
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : Testroutinen für die externen RAM-Bänke
Komponenten :
COG's :
Logbuch :
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
word cnt_err 'gesamtzähler
word cnt_test1
word cnt_test2
word cnt_test3
word cnt_testx
word cnt_loop
PUB main | tast
ios.start
'ios.startram 'nur für test im ram
ios.print(string("RAMTest - 10-06-2010-dr235"))
ios.printnl
ios.print(string("ACHTUNG: Endlostest - Alle Daten im eRam werden komplett überschrieben!"))
ios.printnl
ios.print(string("Eingabe */<a>bbruch : "))
tast := ios.keywait
repeat
if tast <> "a"
statistik
ramtest1 '1:1 random
statistik
ramtestx(0) '1:1, 0
statistik
ramtestx($FF) '1:1, 255
statistik
ramtestx($55) '1:1, $55
statistik
ramtestx($AA) '1:1, $AA
statistik
ramtest2 'test adresskontinuität
statistik
ramtest3 '1:1 negierte bänke
statistik
' ios.printnl
' ios.print(string("Fertig. "))
' ios.stop
PUB statistik 'ausgabe der fehlerstatistik
cnt_err := cnt_err + cnt_test1 + cnt_test2 + cnt_test3 + cnt_testx
ios.setcolor(4)
ios.printcls
ios.printnl
ios.print(string("Statistik eRAM-Test:", $0d, $0d))
ios.print(string("Testdurchläufe : "))
ios.printdec(cnt_loop)
ios.printnl
ios.print(string("Fehler Gesamt : "))
ios.printdec(cnt_err)
ios.printnl
ios.print(string("Fehler Test 1:1, Random : "))
ios.printdec(cnt_test1)
ios.printnl
ios.print(string("Fehler Test Adresskontinuität : "))
ios.printdec(cnt_test2)
ios.printnl
ios.print(string("Fehler Test 1:1, Negierte Bänke : "))
ios.printdec(cnt_test3)
ios.printnl
ios.print(string("Fehler Test Div. Testmuster : "))
ios.printdec(cnt_testx)
ios.printnl
ios.printnl
ios.print(string("Aktueller Test:", $0d))
ios.printnl
ios.printnl
cnt_test1 := 0
cnt_test2 := 0
cnt_test3 := 0
cnt_testx := 0
cnt_loop++
ios.setcolor(0)
PUB ramtest1 | adr,wert1,a
{{ramtest2 - zufallswerte werden gleichzeitig in beide rambänke geschrieben und im zweiten
schritt miteinander verglichen}}
ios.print(string("RAMTest - 1:1 Random",$0D))
ios.print(string("Speicher beschreiben...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat ios#ERAM/2-1
wert1?
ram_write1(wert1,adr)
ram_write2(wert1,adr)
if a++ == (ios#ERAM/2-1)/16
a := 0
ios.printhex(adr,6)
ios.printchar("-")
adr++
ios.print(string("ok",$0d,"Speicher vergleichen...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat ios#ERAM/2-1
if ram_read1(adr) <> ram_read2(adr)
ios.setcolor(3)
ios.printchar($0d)
ios.print(string("Ramfehler : "))
ios.printhex(adr,6)
ios.printchar(":")
ios.printhex(ram_read1(adr),2)
ios.printchar(":")
ios.printhex(ram_read2(adr),2)
ios.printchar(" ")
ios.sfx_fire($f3,0)
cnt_test1++
ios.setcolor(0)
if a++ == (ios#ERAM/2-1)/16
a := 0
ios.printhex(adr,6)
ios.printchar("-")
adr++
ios.print(string("ok",$0d))
PUB ramtest2 | adr,wert1,a
{{ramtest2 - adresswert wird long in den speicher geschrieben und verglichen}}
ios.print(string("RAMTest - Test Adresskontinuität",$0D))
ios.print(string("Speicher beschreiben...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat (ios#ERAM)/4
ios.ram_wrlong(ios#sysmod,adr,adr)
if a == ios#ERAM/64
a := 1
ios.printhex(adr,6)
ios.printchar("-")
else
a++
adr := adr + 4
ios.print(string("ok",$0d,"Speicher vergleichen...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat (ios#ERAM)/4
if ios.ram_rdlong(ios#sysmod,adr) <> adr
ios.setcolor(3)
ios.printchar($0d)
ios.print(string("Ramfehler : "))
ios.printhex(adr,8)
ios.printchar(":")
ios.printhex(ios.ram_rdlong(ios#sysmod,adr),8)
ios.printchar(" ")
ios.sfx_fire($f3,0)
cnt_test2++
ios.setcolor(0)
if a == ios#ERAM/64
a := 1
ios.printhex(adr,6)
ios.printchar("-")
else
a++
adr := adr + 4
ios.print(string("ok",$0d))
PUB ramtest3 | adr,wert1,wert2,a
{{ramtest3 - }}
ios.print(string("RAMTest - Random/Negierte Bänke",$0D))
ios.print(string("Speicher beschreiben...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat ios#ERAM/2-1
wert1?
wert2 := !wert1
ram_write1(wert1,adr)
ram_write2(wert2,adr)
if a++ == (ios#ERAM/2-1)/16
a := 0
ios.printhex(adr,6)
ios.printchar("-")
adr++
ios.print(string("ok",$0d,"Speicher vergleichen...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat ios#ERAM/2-1
wert1 := ram_read1(adr)
wert2 := !ram_read2(adr) & $0ff
if wert1 <> wert2
ios.setcolor(3)
ios.printchar($0d)
ios.print(string("Ramfehler : "))
ios.printhex(adr,6)
ios.printchar(":")
ios.printhex(wert1,2)
ios.printchar(":")
ios.printhex(wert2,2)
ios.printchar(" ")
ios.sfx_fire($f3,0)
cnt_test3++
ios.setcolor(0)
if a++ == (ios#ERAM/2-1)/16
a := 0
ios.printhex(adr,6)
ios.printchar("-")
adr++
ios.print(string("ok",$0d))
PUB ramtestx(wert) | adr,a
{{ramtest2 - zufallswerte werden gleichzeitig in beide ramb?nke geschrieben und im zweiten
schritt miteinander verglichen}}
ios.print(string("RAMTest - 1:1 Testwert: $"))
ios.printhex(wert,2)
ios.printnl
ios.print(string("Speicher beschreiben...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat ios#ERAM/2-1
ram_write1(wert,adr)
ram_write2(wert,adr)
if a++ == (ios#ERAM/2-1)/16
a := 0
ios.printhex(adr,6)
ios.printchar("-")
adr++
ios.print(string("ok",$0d,"Speicher vergleichen...",$0D))
adr := 0
a := 0
ios.printhex(adr,6)
ios.printchar("-")
repeat ios#ERAM/2-1
if ram_read1(adr) <> ram_read2(adr)
ios.setcolor(3)
ios.printchar($0d)
ios.print(string("Ramfehler : "))
ios.printhex(adr,6)
ios.printchar(":")
ios.printhex(ram_read1(adr),2)
ios.printchar(":")
ios.printhex(ram_read2(adr),2)
ios.printchar(" ")
ios.sfx_fire($f3,0)
cnt_testx++
ios.setcolor(0)
if a++ == (ios#ERAM/2-1)/16
a := 0
ios.printhex(adr,6)
ios.printchar("-")
adr++
ios.print(string("ok",$0d))
PUB ram_read1(adresse):wert
{{ein byte aus rambank1 lesen}}
outa[15..8] := adresse >> 11 'höherwertige adresse setzen
set_latch
outa[18..8] := adresse 'niederwertige adresse setzen
outa[ios#reg_ram1] := 0 'ram1 selektieren (wert wird geschrieben)
wert := ina[7..0] 'speicherzelle einlesen
outa[ios#reg_ram1] := 1 'ram1 deselektieren
PUB ram_read2(adresse):wert
{{ein byte aus rambank2 lesen}}
outa[15..8] := adresse >> 11 'höherwertige adresse setzen
set_latch
outa[18..8] := adresse 'niederwertige adresse setzen
outa[ios#reg_ram2] := 0 'ram2 selektieren (wert wird geschrieben)
wert := ina[7..0] 'speicherzelle einlesen
outa[ios#reg_ram2] := 1 'ram2 deselektieren
PUB ram_write1(wert,adresse)
{{ein byte in rambank1 schreiben}}
outa[ios#bus_wr] := 0 'schreiben aktivieren
dira := ios#db_out 'datenbus --> ausgang
outa[7..0] := wert 'wert --> datenbus
outa[15..8] := adresse >> 11 'höherwertige adresse setzen
set_latch
outa[18..8] := adresse 'niederwertige adresse setzen
outa[ios#reg_ram1] := 0 'ram1 selektieren (wert wird geschrieben)
outa[ios#reg_ram1] := 1 'ram1 deselektieren
dira := ios#db_in 'datenbus --> eingang
outa[ios#bus_wr] := 1 'schreiben deaktivieren
PUB ram_write2(wert,adresse)
{{ein byte in rambank2 schreiben}}
outa[ios#bus_wr] := 0 'schreiben aktivieren
dira := ios#db_out 'datenbus --> ausgang
outa[7..0] := wert 'wert --> datenbus
outa[15..8] := adresse >> 11 'höherwertige adresse setzen
set_latch
outa[18..8] := adresse 'niederwertige adresse setzen
outa[ios#reg_ram2] := 0 'ram2 selektieren (wert wird geschrieben)
outa[ios#reg_ram2] := 1 'ram2 deselektieren
dira := ios#db_in 'datenbus --> eingang
outa[ios#bus_wr] := 1 'schreiben deaktivieren
PRI set_latch
{{set_latch - übernimmt a0..a7 in adresslatch (obere adresse a11..18)}}
outa[23] := 1
outa[23] := 0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

1146
system/regnatix/regime.spin Normal file

File diff suppressed because it is too large Load Diff

72
system/regnatix/rom.spin Normal file
View File

@ -0,0 +1,72 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : rom
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : Kommandozeilentool um ein Image aus dem HI-EEPROM zu starten
Komponenten : -
COG's : -
Logbuch :
09-04-2011-dr235 - erste version
Kommandoliste :
Notizen :
}}
OBJ
ios : "reg-ios"
sdspi : "glob-sdspi" ' SPIN program loader and support routines
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
long ioControl[2]
PUB main
ios.start 'ios initialisieren
ios.parastart 'parameterübergabe starten
sdspi.start(@iocontrol)
sdspi.bootEEPROM(sdspi#bootAddr + $8000)
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,499 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : sfxtool
Chip : Regnatix
Typ : Programm
Version : 00
Subversion : 01
Funktion : Einfaches Tool um interaktiv HSS-Soundeffekte zu erstellen und als Spin-Quelltext
zu exportieren.
Logbuch :
19-04-2010-dr235 - erste version
Kommandoliste :
sfx-struktur:
wav len freq vol grundschwingung
lfo lfw fma ama modulation
att dec sus rel hüllkurve
seq (optional)
wav wellenform
0 sinus (0..500hz)
1 schneller sinus (0..1khz)
2 dreieck (0..500hz)
3 rechteck (0..1khz)
4 schnelles rechteck (0..4khz)
5 impulse (0..1,333hz)
6 rauschen
len tonlänge $0..$fe, $ff endlos
freq frequenz $00..$ff
vol lautstärke $00..$0f
lfo low frequency oscillator $ff..$01
lfw low frequency waveform
$00 sinus (0..8hz)
$01 fast sine (0..16hz)
$02 ramp up (0..8hz)
$03 ramp down (0..8hz)
$04 square (0..32hz)
$05 random
$ff sequencer data
fma frequency modulation amount
$00 no modulation
$01..$ff
ama amplitude modulation amount
$00 no modulation
$01..$ff
att attack $00..$ff
dec decay $00..$ff
sus sustain $00..$ff
rel release $00..$ff
}}
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
OBJ
ios: "reg-ios"
num: "glob-numbers"
str: "glob-string"
CON
TIBLEN = 32
FNLEN = 12
VAR
byte tib[TIBLEN] 'tastatur-input-buffer
byte rows 'aktuelle anzahl der nutzbaren zeilen
byte cols 'aktuelle Anzahl der nutzbaren spalten
byte vidmod
PUB main | a,b,c,key,n
ios.start
rows := 23 'zeilenzahl temp. setzen
cols := 64
screeninit(@prompt1,4)
repeat
ios.sfx_setslot(@fx_puffer,15)
ios.sfx_fire(15,1)
printfx(@fx_puffer)
key := ios.keywait
case key
"1":
ios.printchar($0d)
ios.print(string("Basisschwingung Waveform (0..6): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer] := n
"2":
ios.printchar($0d)
ios.print(string("Basisschwingung Länge (0..FE, FF endlos):"))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+1] := n
"3":
ios.printchar($0d)
ios.print(string("Basisschwingung Frequenz (0..FF): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+2] := n
"4":
ios.printchar($0d)
ios.print(string("Basisschwingung Volume (0..F): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+3] := n
"5":
ios.printchar($0d)
ios.print(string("Modulation LFO (Speed 01..FF): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+4] := n
"6":
ios.printchar($0d)
ios.print(string("Modulation LFW (Waveform 0..5): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+5] := n
"7":
ios.printchar($0d)
ios.print(string("Modulation FMa (Stärke der FM 0 - off, 01..FF, 01 - MAX): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+6] := n
"8":
ios.printchar($0d)
ios.print(string("Modulation AMa (Stärke der AM 0 - off, 01..FF, 01 - MAX): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+7] := n
"9":
ios.printchar($0d)
ios.print(string("Hüllkurve Attack - Anstieg (0 - off, 1..FF, 1 - lansamster Anstieg): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+8] := n
"a":
ios.printchar($0d)
ios.print(string("Hüllkurve Decay - Abfall (0 - off, 1..FF, 1 - lansamster Abfall): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+9] := n
"b":
ios.printchar($0d)
ios.print(string("Hüllkurve Sustain - Halten Volume (0 - Mute, 1..FF, 1 - Leise): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+10] := n
"c":
ios.printchar($0d)
ios.print(string("Hüllkurve Release - Freigabe (0 - off, 1..FF, 1 - Langsamste Freigabe): "))
ios.input(@tib,TIBLEN)
n := num.FromStr(@tib,num#HEX)
byte[@fx_puffer+11] := n
"m":
menu2
screeninit(@prompt1,4)
pri screeninit(stradr,n)
os_testvideo
ios.windefine(1,0,0,cols,n)
ios.winset(1)
ios.printcls
ios.print(stradr)
ios.windefine(2,0,n+1,cols,rows)
ios.winset(2)
ios.printcls
pri os_testvideo 'sys: passt div. variablen an videomodus an
vidmod := ios.belgetspec & 1
rows := ios.belgetrows 'zeilenzahl bei bella abfragen
cols := ios.belgetcols 'spaltenzahl bei bella abfragen
pub menu2 | key,a
screeninit(@prompt2,4)
key := ios.keywait
case key
"s": save
"l": load
"e": export
"r": menu3
"q": ios.winset(0)
ios.screeninit
ios.stop
pub save|i
ios.printnl
ios.print(string("Effekt speichern - Dateiname : "))
ios.input(@tib,FNLEN)
printerr(ios.sdnewfile(@tib))
ifnot printerr(ios.sdopen("W",@tib))
i := 0
repeat 32
ios.sdputc(byte[@fx_puffer + i++])
ios.sdclose
pub load|i
cmd_dir
ios.printnl
ios.print(string("Effekt laden - Dateiname : "))
ios.input(@tib,FNLEN)
ifnot printerr(ios.sdopen("R",@tib))
i := 0
repeat 32
byte[@fx_puffer + i++] := ios.sdgetc
ios.sdclose
pub export | i
ios.printnl
ios.print(string("Effekt exportieren - Dateiname : "))
ios.input(@tib,FNLEN)
printerr(ios.sdnewfile(@tib))
ifnot printerr(ios.sdopen("W",@tib))
ios.print(string(" Name : "))
ios.input(@tib,FNLEN)
sd_print(@tib)
sd_printchar($0d)
i := 0
sd_print(string("' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel"))
sd_printchar($0d)
sd_print(string("byte "))
sd_printchar("$")
sd_printhex(byte[@fx_puffer + i++],2)
repeat 11
sd_printchar(",")
sd_printchar("$")
sd_printhex(byte[@fx_puffer + i++],2)
sd_printchar($0d)
sd_print(string("byte "))
sd_printchar("$")
sd_printhex(byte[@fx_puffer + i++],2)
repeat 20
sd_printchar(",")
sd_printchar("$")
sd_printhex(byte[@fx_puffer + i++],2)
ios.sdclose
pub menu3 | key,a,n,c,w
screeninit(@prompt3,4)
w := 0
c := 32
repeat
key := ios.keywait
case key
"r":
repeat c
a?
a := a & $FF
byte[@fx_puffer+2] := a
ios.sfx_setslot(@fx_puffer,15)
ios.sfx_fire(15,1)
printfx(@fx_puffer)
if w > 0
waitcnt(clkfreq / w + cnt)
"c":
ios.printchar($0d)
ios.print(string("Anzahl = "))
ios.printdec(c)
ios.print(string(" : "))
ios.input(@tib,TIBLEN)
c := num.FromStr(@tib,num#DEC)
ios.print(string(" ok",$0d))
"w":
ios.printchar($0d)
ios.print(string("Wait = "))
ios.printdec(w)
ios.print(string(" : "))
ios.input(@tib,TIBLEN)
w := num.FromStr(@tib,num#DEC)
ios.print(string(" ok",$0d))
"b": quit
pub printfx(adr)| i,a
ios.printchar(ios#char_nl)
repeat i from 0 to 11
a := byte[adr+i]
ios.print(string("$"))
ios.printhex(a,2)
ios.print(string(" "))
PUB printerr(err):error 'sys: fehlerausgabe
if err
ios.printnl
ios.print(@err_s1)
ios.printdec(err)
ios.print(string(" : $"))
ios.printhex(err,2)
ios.printnl
ios.print(@err_s2)
case err
0: ios.print(@err0)
1: ios.print(@err1)
2: ios.print(@err2)
3: ios.print(@err3)
4: ios.print(@err4)
5: ios.print(@err5)
6: ios.print(@err6)
7: ios.print(@err7)
8: ios.print(@err8)
9: ios.print(@err9)
10: ios.print(@err10)
11: ios.print(@err11)
12: ios.print(@err12)
13: ios.print(@err13)
14: ios.print(@err14)
15: ios.print(@err15)
16: ios.print(@err16)
17: ios.print(@err17)
18: ios.print(@err18)
19: ios.print(@err19)
20: ios.print(@err20)
OTHER: ios.print(@errx)
ios.printnl
ios.print(string("<Taste>"))
ios.keywait
error := err
PUB cmd_dir|fcnt,stradr,hflag 'cmd: verzeichnis anzeigen
{{sddir - anzeige verzeichnis}}
ifnot printerr(ios.sddir) 'verzeichnis öffnen
fcnt := cmd_dir_w(hflag)
PRI cmd_dir_w(hflag):fcnt|stradr,lcnt,wcnt
fcnt := 0
wcnt := (cols / 14) - 1 '3
lcnt := (rows - 2) * (cols / 15)
ios.printnl
repeat while (stradr := ios.sdnext)
ifnot ios.sdfattrib(ios#F_HIDDEN) & hflag 'versteckte dateien anzeigen?
if ios.sdfattrib(ios#F_DIR) 'verzeichnisname
ios.setcolor(1)
ios.printqchar("▶")
ios.printchar(" ")
ios.print(stradr)
ios.setcolor(0)
elseif ios.sdfattrib(ios#F_HIDDEN)
ios.setcolor(3)
ios.print(string(" "))
str.charactersToLowerCase(stradr)
ios.print(stradr)
ios.setcolor(0)
else 'dateiname
ios.print(string(" "))
str.charactersToLowerCase(stradr)
ios.print(stradr)
ifnot wcnt--
wcnt := (cols / 15) - 1 '3
ios.printnl
else
'ios.printtab
fcnt++
ifnot --lcnt
lcnt := (rows - 2) * (cols / 15)
if ios.keywait == "q"
return
PRI str_lowercase(characters)
repeat strsize(characters--)
result := byte[++characters]
if((result => "A") and (result =< "Z"))
byte[characters] := (result + 32)
PUB sd_print(stringptr) 'screen: bildschirmausgabe einer zeichenkette (0-terminiert)
{{print(stringptr) - screen: bildschirmausgabe einer zeichenkette (0-terminiert)}}
repeat strsize(stringptr)
ios.sdputc(byte[stringptr++])
PUB sd_printdec(value) | i 'screen: dezimalen zahlenwert auf bildschirm ausgeben
{{printdec(value) - screen: dezimale bildschirmausgabe zahlenwertes}}
if value < 0 'negativer zahlenwert
-value
ios.sdputc("-")
i := 1_000_000_000
repeat 10 'zahl zerlegen
if value => i
ios.sdputc(value / i + "0")
value //= i
result~~
elseif result or i == 1
ios.sdputc("0")
i /= 10 'nächste stelle
PUB sd_printhex(value, digits) 'screen: hexadezimalen zahlenwert auf bildschirm ausgeben
{{hex(value,digits) - screen: hexadezimale bildschirmausgabe eines zahlenwertes}}
value <<= (8 - digits) << 2
repeat digits
ios.sdputc(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB sd_printchar(c):c2 'screen: einzelnes zeichen auf bildschirm ausgeben
{{printchar(c) - screen: bildschirmausgabe eines zeichens}}
ios.sdputc(c)
c2 := c
DAT
prompt1 byte "▶Hive: SFX-Tool"
byte $0d,"Basisschwingung Modulation Hüllkurve "
byte $0d,"Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel"
byte $0d,"[01] [02] [03] [04] [05] [06] [07] [08] [09] [0A] [0B] [0C] [M] ",$0
prompt2 byte "▶SFX-Tool - Menü"
byte $0d," "
byte $0d," "
byte $0d,"[S]ave [L]oad [E]xport [R]and [Q]uit",$0
prompt3 byte "▶SFX-Tool - Random Freq"
byte $0d," "
byte $0d," "
byte $0d,"[R]un [C]ount [W]ait [B]ack",$0
mod1 byte "bd1.hss ",0
mod2 byte "bd2.hss ",0
err_s1 byte "Fehlernummer : ",0
err_s2 byte "Fehler : ",0
err0 byte "no error",0
err1 byte "fsys unmounted",0
err2 byte "fsys corrupted",0
err3 byte "fsys unsupported",0
err4 byte "not found",0
err5 byte "file not found",0
err6 byte "dir not found",0
err7 byte "file read only",0
err8 byte "end of file",0
err9 byte "end of directory",0
err10 byte "end of root",0
err11 byte "dir is full",0
err12 byte "dir is not empty",0
err13 byte "checksum error",0
err14 byte "reboot error",0
err15 byte "bpb corrupt",0
err16 byte "fsi corrupt",0
err17 byte "dir already exist",0
err18 byte "file already exist",0
err19 byte "out of disk free space",0
err20 byte "disk io error",0
err21 byte "command not found",0
errx byte "undefined",0
'basisschwingung modulation hüllkurve
'Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel
fx_puffer byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80
byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
DAT 'lizenz
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

240
system/regnatix/splay.spin Normal file
View File

@ -0,0 +1,240 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : splay
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : sid-player für kommandozeile
Komponenten : -
COG's : -
Logbuch :
19-04-2010-dr235 - sid-time: start des projektes :)
Kommandoliste :
/? : Hilfetext
/m name.dmp : DMP-Datei mono auf SID2 abspielen
/s name.dmp : DMP-Datei stereo auf SID2 abspielen
/d : Alle DMP-Dateien im Verzeichnis wiedergeben
q - quit
n - next
p - pause
Notizen :
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
SIDMASK = %00000000_00000000_00000000_00010000
VAR
byte fl_bye 'flag player beenden
byte parastr[64] 'parameterstring
byte fn[12] 'puffer für dateinamen
long datcnt 'zeiger für dateiliste
DAT 'PARAMETER
PUB main
ios.start 'ios initialisieren
ios.parastart 'parameterübergabe starten
if (ios.admgetspec & SIDMASK)
repeat while ios.paranext(@parastr) 'parameter einlesen
if byte[@parastr][0] == "/" 'option?
case byte[@parastr][1]
"?": ios.print(string("help: man splay")) '/?
"m": playm_dmp '/p
"s": plays_dmp '/s
"d": play_dir '/d
else
printErr(@err2)
ios.stop
DAT 'PLAY_DIR
PUB play_dir|stradr,len,fcnt,i 'hss: alle songs auf der sd-card abspielen
ios.sddir 'kommando: verzeichnis öffnen
datcnt := 0 'zum listenanfang
fcnt := 0 'zähler für dateianzahl
fl_bye := 0
repeat while (stradr := ios.sdnext) 'dateiliste einlesen
if str_find(stradr,@ext1)
fcnt++
play_dir_wrlst(stradr)
ios.print(string("Anzahl Dateien : "))
ios.printdec(fcnt)
ios.printnl
datcnt := 0 'zum listenanfang
repeat i from 0 to fcnt-1 'dateiliste abspielen
ios.printdec(i+1)
ios.printchar("/")
ios.printdec(fcnt)
ios.printtab
play_dir_rdlst(@fn)
play_dir_file(@fn)
if fl_bye 'player beenden
quit
ios.printnl
PRI play_dir_file(stradr)|err
ios.print(stradr)
ios.printchar(" ")
if err := ios.sid_sdmpplay(stradr) 'fehler bei start des players?
ios.print(@err0) 'fehlernummer ausgeben
ios.printdec(err)
else
play_status 'warten, solange wav gespielt wird (sd belegt)
ios.printnl
PUB play_dir_wrlst(stradr)|len,i 'kopiert dateinamen in liste
len := strsize(stradr)
repeat i from 0 to len-1
ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++)
ios.ram_wrbyte(ios#usrmod,0,datcnt++)
PUB play_dir_rdlst(stradr)|i,n 'liest dateinamen aus list
i := 0
repeat
n := ios.ram_rdbyte(ios#usrmod,datcnt++)
byte[stradr][i++] := n
while n <> 0
DAT 'PLAY_DMP
PRI playm_dmp|err 'dmp-datei mono auf einem sid abspielen
if ios.paranext(@parastr) 'parameter?
if err := ios.sid_mdmpplay(@parastr) 'fehler bei start des players?
ios.print(@err0) 'fehlernummer ausgeben
ios.printdec(err)
else
play_status 'warten, solange wav gespielt wird (sd belegt)
else 'kein parameter: fehlermeldung
printErr(@err1)
PRI plays_dmp|err 'dmp-datei quasi-stereo auf zwei sidcogs abspielen
if ios.paranext(@parastr) 'parameter?
if err := ios.sid_sdmpplay(@parastr) 'fehler bei start des players?
ios.print(@err0) 'fehlernummer ausgeben
ios.printdec(err)
else
play_status 'warten, solange wav gespielt wird (sd belegt)
else 'kein parameter: fehlermeldung
printErr(@err1)
PUB play_status|status,curpos,key,l,p 'warten bis player fertig, oder abbruch
ios.print(string(" <q/n/p> : "))
ios.curoff
curpos := ios.curgetx
repeat
status := ios.sid_dmpstatus
ios.cursetx(curpos)
ios.printdec(ios.sid_dmplen)
ios.printchar("/")
ios.printdec(ios.sid_dmppos)
if key := ios.key 'bei taste stopsignal an player senden
case key
"n": ios.sid_dmpstop 'next wav
"p": ios.sid_dmppause 'pause
"q": fl_bye := 1
ios.sid_dmpstop
while status 'schleife solange player aktiv
ios.sid_mute(3)
ios.curon
DAT 'TOOLS
PRI printErr(stradr)
ios.print(@err0)
ios.print(stradr)
ios.print(string("help: man splay"))
PUB str_find(string1, string2) : buffer | counter 'sys: string suchen
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Searches a string of characters for the first occurence of the specified string of characters. │
'' │ │
'' │ Returns the address of that string of characters if found and zero if not found. │
'' │ │
'' │ string1 - A pointer to the string of characters to search. │
'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(string1--)
if(byte[++string1] == byte[string2])
repeat counter from 0 to (strsize(string2) - 1)
if(byte[string1][counter] <> byte[string2][counter])
buffer~~
ifnot(buffer~)
return string1
PUB str2dec(stradr)|buffer,counter
buffer := byte[stradr]
counter := (strsize(stradr) <# 11)
repeat while(counter--)
result *= 10
result += lookdownz(byte[stradr++]: "0".."9")
if(buffer == "-")
-result
DAT
ext1 byte ".DMP",0
err0 byte 13,"Fehler : ",0
err1 byte "Zu wenig Parameter!",13,0
err2 byte "Administra-Code unterstützt keine SID-Emulation!",13,0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,388 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : sysconf
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : Kommandozeilentool für TriOS-Systemeinstellungen
Komponenten : -
COG's : -
Logbuch :
16-04-2010-dr235 - erste version
24-10-2010-dr235 - port input/output
Kommandoliste :
/? : Hilfe
/l : list konf
/ap : Konfiguration anzeigen
/ah 0|1 : hss ab-/anschalten
/aw 0|1 : wav ab-/anschalten
/as 0|1 : systemklänge ab-/anschalten
/al 0..100: wav-lautstärke links
/ar 0..100: wav-lautstärke rechts
/ah 0..15 : hss-lautstärke
/ci : farbtabelle anzeigen
/cs datei : farbtabelle speichern
/cl datei : farbtabelle laden
/po p a : port ausgabe portnummer anzahl impulse
/pi : port eingabe portnummer
Notizen :
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
byte parastr[64]
byte vidmod 'videomodus: 0 - vga, 1 - tv
long cols,rows
PUB main
ios.start 'ios initialisieren
vidmod := ios.belgetspec & 1
rows := ios.belgetrows 'zeilenzahl bei bella abfragen
cols := ios.belgetcols 'spaltenzahl bei bella abfragen
ios.parastart 'parameterübergabe starten
repeat while ios.paranext(@parastr) 'parameter einlesen
if byte[@parastr][0] == "/" 'option?
case byte[@parastr][1]
"?": ios.print(string("help: man sysconf")) '/?
"l": printConf
"a": case byte[@parastr][2] 'administra
"h": setHSS '/ah - hss
"w": setWAV '/aw - wav
"s": setSYS '/as - systemklänge
"l": set_lvol '/al - wav-lautstärke links
"r": set_rvol '/ar - wav-lautstärke rechts
"v": set_hvol '/av - hss-lautstärke
"f": ios.admreset '/ab - administra reset, flash wird neu gebootet
"t": busTransfer '/at - transfergeschwindigkeit messen
"c": case byte[@parastr][2] 'color
"i": col_info '/ci - farbregister anzeigen
"l": col_load '/cl - farbregister laden
"s": col_save '/cs - farbregister speichern
"p": case byte[@parastr][2] 'portfunktionen
"o": port_out '/po - impulse am port ausgeben
"i": port_in '/pi - portstatus einlesen
ios.stop
DAT 'PORT
PRI port_out|pnr,anz,time,fak,i
if ios.paranext(@parastr)
pnr := str2dec(@parastr)
if ios.paranext(@parastr)
anz := str2dec(@parastr)
if ios.paranext(@parastr)
fak := str2dec(@parastr)
else
printErr(@err1)
return
else
printErr(@err1)
return
else
printErr(@err1)
return
ios.print(string("Port Nr(0..31): "))
ios.printdec(pnr)
ios.printnl
ios.print(string("Impulse : "))
ios.printdec(anz)
ios.printnl
ios.print(string("Faktor : "))
ios.printdec(fak)
ios.printnl
' ------------------------
dira[pnr]~~
time := cnt
i := 0
repeat anz
outa[pnr] := 1
waitcnt(time += clkfreq/fak)
outa[pnr] := 0
waitcnt(time += clkfreq/fak)
ios.bus_init
' ------------------------
PRI port_in|pnr,wert
ios.printnl
' ------------------------
dira := 0
wert := ina[0..31]
ios.bus_init
' ------------------------
ios.print(string("Status : "))
ios.printbin(wert,32)
DAT 'COLOR
PRI col_info|i,n
if vidmod == ios#TV
n := 7
else
n := 15
repeat i from 0 to n
ios.printhex(ios.belgetcolor(i*2),8)
ios.printchar(" ")
ios.printhex(ios.belgetcolor(i*2+1),8)
ios.setcolor(i)
ios.print(string(" Farbe : "))
ios.setcolor(0)
ios.printdec(i)
ios.printnl
PRI col_save|i,color
if ios.paranext(@parastr)
ios.printnl
ios.print(string("Farbtabelle speichern : "))
ios.print(@parastr)
ios.sdnewfile(@parastr)
ifnot ios.sdopen("W",@parastr)
repeat i from 0 to 15
color := ios.belgetcolor(i)
ios.sdputc(color >> 24)
ios.sdputc(color >> 16)
ios.sdputc(color >> 8)
ios.sdputc(color )
ios.sdclose
else
printErr(@err1)
PRI col_load|i,color
if ios.paranext(@parastr)
ios.printnl
ios.print(string("Farbtabelle laden : "))
ios.print(@parastr)
ifnot ios.sdopen("R",@parastr)
repeat i from 0 to 15
color := ios.sdgetc << 24
color += ios.sdgetc << 16
color += ios.sdgetc << 8
color += ios.sdgetc
ios.belsetcolor(i,color)
ios.sdclose
else
printErr(@err1)
DAT 'VOLUME
PRI set_lvol
if ios.paranext(@parastr) 'parameter?
ios.wav_lvol(str2dec(@parastr))
else 'kein parameter: fehlermeldung
printErr(@err1)
PRI set_rvol
if ios.paranext(@parastr) 'parameter?
ios.wav_rvol(str2dec(@parastr))
else 'kein parameter: fehlermeldung
printErr(@err1)
PRI set_hvol
if ios.paranext(@parastr) 'parameter?
ios.hss_vol(str2dec(@parastr))
else 'kein parameter: fehlermeldung
printErr(@err1)
DAT 'SOUNDSYSTEM
PRI setHSS
if ios.paranext(@parastr) 'parameter?
case byte[@parastr][0]
"0": ios.admsetsound(0)
ios.print(@msg4)
ios.print(@msg2)
"1": ios.admsetsound(1)
ios.print(@msg4)
ios.print(@msg1)
else
printErr(@err1)
PRI setWAV
if ios.paranext(@parastr) 'parameter?
case byte[@parastr][0]
"0": ios.admsetsound(2)
ios.print(@msg5)
ios.print(@msg2)
"1": ios.admsetsound(3)
ios.print(@msg5)
ios.print(@msg1)
else
printErr(@err1)
PRI setSYS
if ios.paranext(@parastr) 'parameter?
case byte[@parastr][0]
"0": ios.admsetsyssnd(0)
ios.print(@msg7)
ios.print(@msg2)
"1": ios.admsetsyssnd(1)
ios.print(@msg7)
ios.print(@msg1)
else
printErr(@err1)
VAR
long tcnt1,tcnt2 'transferzähler
byte tflag 'transferflag
CON
tbytes = 32768
PRI busTransfer|sec
ios.print(@msg8)
'zeit für reinen schleifendurchlauf berechnen
tcnt1 := cnt
repeat tbytes
busTransferDummy1
tcnt1 := cnt - tcnt1
'messvorgang
tcnt2 := cnt
repeat tbytes
ios.admgetsndsys
tcnt2 := cnt - tcnt2
ios.print(@msg10)
ios.print(@msg9)
sec := (tcnt2 - tcnt1) / clkfreq 'zeit der übertragung in sekunden
ios.printdec((tbytes*2)/sec)
ios.print(@msg11)
PRI busTransferDummy1
busTransferDummy2
return busTransferDummy2
PRI busTransferDummy2
return 1
PRI printConf
ios.printnl
ios.print(@msg3) 'soundsystem
case ios.admgetsndsys
0: ios.print(@msg6)
1: ios.print(@msg4)
2: ios.print(@msg5)
ios.printnl
ios.print(@msg12) 'ramdisk
if ios.rd_getinit
ios.print(@msg14)
else
ios.print(@msg15)
ios.printnl
ios.print(@msg13) 'usermem
ios.printdec(ios.ram_getend - ios.ram_getbas)
ios.printnl
ios.print(@msg16)
ios.printbin(ios.belgetspec,16)
ios.printnl
ios.print(@msg17)
ios.printbin(ios.admgetspec,16)
ios.printnl
PRI printErr(stradr)
ios.print(@err0)
ios.print(stradr)
ios.print(string("help: man sysconf"))
PRI str2dec(stradr)|buffer,counter
buffer := byte[stradr]
counter := (strsize(stradr) <# 11)
repeat while(counter--)
result *= 10
result += lookdownz(byte[stradr++]: "0".."9")
if(buffer == "-")
-result
DAT
msg1 byte "EIN ", 0
msg2 byte "AUS ", 0
msg3 byte "Soundsystem : ",0
msg12 byte "Ramdisk : ",0
msg13 byte "Usermem : ",0
msg16 byte "Bellatrix : ",0
msg17 byte "Administra : ",0
msg14 byte "aktiviert",0
msg15 byte "deaktiviert",0
msg4 byte "HSS-Engine ",0
msg5 byte "WAV-Engine ",0
msg6 byte "Soundsystem deaktiviert ",0
msg7 byte "Systemklänge ",0
msg8 byte "Transfergeschwindigkeit Regnatix <--> Administra messen... ",0
msg9 byte "Geschwindigkeit : ",0
msg10 byte "ok",13,0
msg11 byte " Bytes/Sekunde",13,0
err0 byte 13,"Fehler : "
err1 byte "Zu wenig Parameter!",13,0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1,166 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : tapecut - erzeugt leere tapedateien
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion :
Komponenten : -
COG's : -
Logbuch :
Kommandoliste :
Notizen :
Notizen:
- parameter c - create, erzeugt neue tape-datei
a - append, hängt screens an
n - screens nummerieren
--------------------------------------------------------------------------------------------------------- }}
OBJ
ios: "reg-ios"
num: "glob-numbers"
gc : "m-glob-con"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
SCREENSIZE = 1024
VAR
byte parastr1[32] 'dateiname
byte parastr2[32] 'größe
long screens 'anzahl der screens
PUB main2 | i,n
ios.start
ios.parastart
parastr1[0] := 0
parastr2[0] := 0
ios.printnl
ifnot rd_parameter 'parameter einlesen
ios.print(@msg1)
if ios.keywait <> "j" 'abbruch?
ios.print(string("nein"))
ios.printnl
else 'container erzeugen
ios.print(string("ja"))
ios.printnl
create
ios.stop
PRI rd_parameter
if ios.paranext(@parastr1) 'parameter dateiname einlesen
ios.print(@msg5)
ios.print(@parastr1)
ios.printnl
if ios.paranext(@parastr2) 'parameter screenzahl einlesen
screens := num.FromStr(@parastr2,num#DEC)
ios.print(@msg8)
ios.printdec(screens)
ios.printnl
ios.print(@msg4)
ios.printnl
ios.print(@msg6)
ios.printdec(screens * SCREENSIZE)
ios.print(@msg7)
else
ios.print(@err2)
ios.print(@msg3)
return -1
else
ios.print(@err1)
ios.print(@msg3)
return -1
return
PRI create | i,status,curpos,numstr,len 'erzeugt containerdatei
status := ios.sdopen("R",@parastr1) 'test ob datei vorhanden
ios.sdclose 'datei gleich wieder schlie?en
if status == 0 'datei ist schon vorhanden
ios.print(@msg12)
if ios.keywait <> "j"
ios.print(string("nein")) 'nicht ?berschreiben
ios.printnl
return
ios.printnl
ios.print(@msg10)
ios.sdnewfile(@parastr1)
ios.sdopen("W",@parastr1) 'datei erzeugen
ios.print(@msg11)
ios.print(@msg13)
curpos := ios.curgetx 'cursorposition x merken
repeat i from 1 to screens 'screens schreiben
numstr := num.ToStr(i-1,num#dec)
len := strsize(numstr)
fprint(string(gc#m_c_remark,"screen nr : "))
fprint(numstr) 'screennummer in erste zeile
repeat SCREENSIZE - len - 13 'screen auffüllen
ios.sdputc(gc#m_c_remark)
ios.cursetx(curpos) 'position setzen
ios.printdec(i)
ios.sdclose
ios.print(@msg11)
PUB fprint(stringptr) 'dateiausgabe einer zeichenkette (0-terminiert)
repeat strsize(stringptr)
ios.sdputc(byte[stringptr++])
DAT
msg1 byte 13,"Parameter korrekt? <j/n> : ", 0
msg2 byte " : ", 0
msg3 byte "Format : tapecut <datei> <screens>",13,0
msg4 byte "Screengröße : 1024 Byte",0
msg5 byte "Containerdatei : ",0
msg6 byte "Größe : ",0
msg7 byte " Bytes ",13,0
msg8 byte "Screens : ",0
msg10 byte "Datei wird geöffnet... ",0
msg11 byte " ok ",13,0
msg12 byte 13,"Vorhandene Datei überschreiben? <j/n> : ", 0
msg13 byte "Schreibe Screen : ",0
err1 byte "Fehler : Keine Parameter.",13,0
err2 byte "Fehler : Keine Größe definiert.",13,0
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

282
system/regnatix/time.spin Normal file
View File

@ -0,0 +1,282 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : flash
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : RTC-Funktionen Date/Time
Komponenten : -
COG's : -
Logbuch :
05.12.2010-stephan - DateTime Funktionen
09-04-2011-dr235 - auskopplung aus regime
Kommandoliste :
Notizen :
}}
OBJ
ios: "reg-ios"
str: "glob-string"
num: "glob-numbers" 'Number Engine
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
byte parastr[64]
PUB main
ios.start 'ios initialisieren
ios.parastart 'parameterübergabe starten
repeat while ios.paranext(@parastr) 'parameter einlesen
if byte[@parastr][0] == "/" 'option?
case byte[@parastr][1]
"?": ios.print(@help)
"d": cmd_date
"l": cmd_date_long
"t": cmd_time
"s": cmd_setDateTime
other: ios.print(@help)
ios.stop
CON ''------------------------------------------------- DATE TIME FUNKTIONEN
PUB cmd_date | stringpointer, format 'rtc: aktuelles Datum zurückgeben
format := ios.getNVSRAM(ios#NVRAM_DATEFORMAT)
case format
ios#DATEFORMAT_DE: 'YYYY-MM-DD
ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2)))
ios.print(string("."))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2)))
ios.print(string("."))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4)))
ios.printnl
ios#DATEFORMAT_UK: 'DD/MM/YYYY
ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2)))
ios.print(string("/"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2)))
ios.print(string("/"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4)))
ios.printnl
ios#DATEFORMAT_US: 'MM/DD/YYYY
ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2)))
ios.print(string("/"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2)))
ios.print(string("/"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4)))
ios.printnl
other: 'DATEFORMAT_CANONICAL 'YYYY-MM-DD
ios.print(str.trimCharacters(str.numberToDecimal(ios.getYear, 4)))
ios.print(string("-"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getMonth, 2)))
ios.print(string("-"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getDate, 2)))
ios.printnl
PRI cmd_date_long | stringpointer, month, weekday 'rtc: aktuelles Datum zurückgeben
case ios.getNVSRAM(ios#NVRAM_LANG)
ios#LANG_EN:
weekday := lookup(ios.getDay: string("Sunday"), string("Monday"), string("Tuesday"), string("Wednesday"), string("Thursday"), string("Friday"), string("Saturday"))
month := lookup(ios.getMonth: string("January"), string("February"), string("March"), string("April"), string("May"), string("June"), string("July"), string("August"), string("September"), string("October"), string("November"), string("December"))
other:
weekday := lookup(ios.getDay: string("Montag"), string("Dienstag"), string("Mittwoch"), string("Donnerstag"), string("Freitag"), string("Samstag"), string("Sonntag"))
month := lookup(ios.getMonth: string("Januar"), string("Februar"), string("März"), string("April"), string("Mai"), string("Juni"), string("Juli"), string("August"), string("September"), string("Oktober"), string("November"), string("Dezember"))
case ios.getNVSRAM(ios#NVRAM_DATEFORMAT)
ios#DATEFORMAT_DE: 'YYYY-MM-DD
ios.print(weekday)
ios.print(string(", "))
ios.print(str.trimCharacters(num.ToStr(ios.getDate, num#DEC)))
ios.print(string(". "))
ios.print(month)
ios.print(string(" "))
ios.print(str.trimCharacters(num.ToStr(ios.getYear, num#DEC)))
ios.print(string(" "))
cmd_time
ios#DATEFORMAT_UK: 'DD/MM/YYYY
ios.print(weekday)
ios.print(string(", "))
ios.print(str.trimCharacters(num.ToStr(ios.getDate, num#DEC)))
ios.print(string(" "))
ios.print(month)
ios.print(string(" "))
ios.print(str.trimCharacters(num.ToStr(ios.getYear, num#DEC)))
ios.print(string(" "))
cmd_time
ios#DATEFORMAT_US: 'MM/DD/YYYY
ios.print(weekday)
ios.print(string(", "))
ios.print(month)
ios.print(string(" "))
ios.print(str.trimCharacters(num.ToStr(ios.getDate, num#DEC)))
ios.print(string(", "))
ios.print(str.trimCharacters(num.ToStr(ios.getYear, num#DEC)))
ios.print(string(" "))
cmd_time
PUB cmd_time | stringpointer, value, suffix 'rtc: aktuelle Zeit zurückgeben
'time - aktuelle Zeit
case ios.getNVSRAM(ios#NVRAM_TIMEFORMAT)
ios#TIMEFORMAT_12: 'HH:MM:SS[PM|AM]
value := ios.getHours
if(value > 12)
suffix := string("PM")
value -= 12
else
suffix := string("AM")
ios.print(str.trimCharacters(str.numberToDecimal(value, 2)))
ios.print(string(":"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getMinutes, 2)))
ios.print(string(":"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getSeconds, 2)))
ios.print(suffix)
ios#TIMEFORMAT_12UK: 'HH.MM.SS[PM|AM]
value := ios.getHours
if(value > 12)
suffix := string("PM")
value -= 12
else
suffix := string("AM")
ios.print(str.trimCharacters(str.numberToDecimal(value, 2)))
ios.print(string("."))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getMinutes, 2)))
ios.print(string("."))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getSeconds, 2)))
ios.print(suffix)
other: 'ios#TIMEFORMAT_24: 'HH:MM:SS
ios.print(str.trimCharacters(str.numberToDecimal(ios.getHours, 2)))
ios.print(string(":"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getMinutes, 2)))
ios.print(string(":"))
ios.print(str.trimCharacters(str.numberToDecimal(ios.getSeconds, 2)))
ios.printnl
PRI cmd_setDateTime | buffer, changed 'rtc: Datum/Zeit setzen
buffer := string(" ")
'bytefill(buffer, 0, 5)
ios.print(string("aktuelles Datum: "))
cmd_Date_long
ios.print(string("neues Datum eingeben? (j/n): "))
if ios.keywait == "j"
ios.printnl
ios.print(string("Jahr (2000 - 2127): "))
ios.input(buffer, 4)
ios.setYear(num.FromStr(buffer, num#DEC))
ios.printnl
ios.print(string("Monat (1 - 12): "))
ios.input(buffer, 2)
ios.setMonth(num.FromStr(buffer, num#DEC))
ios.printnl
ios.print(string("Wochentag (1(Mo) - 7(So)): "))
ios.input(buffer, 1)
ios.setDay(num.FromStr(buffer, num#DEC))
ios.printnl
ios.print(string("Tag (1 - 31): "))
ios.input(buffer, 2)
ios.setDate(num.FromStr(buffer, num#DEC))
changed := 1
ios.printnl
ios.print(string("neue Uhrzeit eingeben? (j/n): "))
if ios.keywait == "j"
ios.printnl
ios.print(string("Stunden (0 - 23): "))
ios.input(buffer, 2)
ios.setHours(num.FromStr(buffer, num#DEC))
ios.printnl
ios.print(string("Minuten (0 - 59): "))
ios.input(buffer, 2)
ios.setMinutes(num.FromStr(buffer, num#DEC))
ios.printnl
ios.print(string("Sekunden (0 - 59): "))
ios.input(buffer, 2)
ios.setSeconds(num.FromStr(buffer, num#DEC))
changed := 1
ios.printnl
ios.print(string("Datumsformat ändern? (j/n): "))
if ios.keywait == "j"
ios.printnl
ios.print(string("Datumsformat (0-DE, 1-Canonical, 2-UK, 3-US): "))
ios.input(buffer, 1)
ios.setNVSRAM(ios#NVRAM_DATEFORMAT, num.FromStr(buffer, num#DEC))
ios.printnl
ios.print(string("Zeitformat (0-24, 1-12, 2-12UK): "))
ios.input(buffer, 2)
ios.setNVSRAM(ios#NVRAM_TIMEFORMAT, num.FromStr(buffer, num#DEC))
changed := 1
if changed == 1
ios.printnl
ios.print(string("neues Datum: "))
cmd_Date_long
ios.printnl
DAT 'sys: helptext
help byte "/? : Hilfe",13
byte "/d : Datum anzeigen",13
byte "/l : Datum Langformat anzeigen",13
byte "/t : Zeit anzeigen",13
byte "/s : Datum/Zeit stellen",13
byte 0
DAT 'lizenz
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

271
system/regnatix/wplay.spin Normal file
View File

@ -0,0 +1,271 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 : TriOS
Name : wplay
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : wav-player für kommandozeile
Komponenten : -
COG's : -
Logbuch :
16-04-2010-dr235 - erste trios-version
21-04-2010-dr235 - pausenmodus & anzeige wav-position
29-04-2010-dr235 - /i eingefügt, da offensichtlich einige konwerter den len-parameter im header falsch setzen!
Kommandoliste :
/? : Hilfetext
/p name.wav : WAV-Datei abspielen
/d : Verzeichnis wiedergeben
: q - quit
: n - next
: p - pause
/l 0..100 : Lautstärke links
/r 0..100 : Lautstärke rechts
/i name.wav : Info zur Datei anzeigen
Notizen :
}}
OBJ
ios: "reg-ios"
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
byte fl_bye 'flag player beenden
byte parastr[64] 'parameterstring
byte fn[12] 'puffer für dateinamen
long datcnt 'zeiger für dateiliste
DAT 'PARAMETER
PUB main
ios.start 'ios initialisieren
ios.parastart 'parameterübergabe starten
ios.admsetsound(ios#SND_HSSOFF) 'hss ausschalten
ios.admsetsound(ios#SND_WAVON) 'wav einschalten
repeat while ios.paranext(@parastr) 'parameter einlesen
if byte[@parastr][0] == "/" 'option?
case byte[@parastr][1]
"?": ios.print(string("help: man wplay")) '/?
"p": play_wav '/p
"d": play_dir '/r
"l": set_lvol '/l
"r": set_rvol '/r
"i": print_info
ios.admsetsound(ios#SND_WAVOFF) 'wav ausschalten
ios.admsetsound(ios#SND_HSSON) 'hss anschalten
ios.stop
DAT 'VOLUME
PUB set_lvol
if ios.paranext(@parastr) 'parameter?
ios.wav_lvol(str2dec(@parastr))
else 'kein parameter: fehlermeldung
printErr(@err1)
PUB set_rvol
if ios.paranext(@parastr) 'parameter?
ios.wav_rvol(str2dec(@parastr))
else 'kein parameter: fehlermeldung
printErr(@err1)
PUB print_info|err
if ios.paranext(@parastr) 'parameter?
if err := ios.sdopen("R",@parastr) 'fehler bei start des players?
ios.print(@err0) 'fehlernummer ausgeben
ios.printdec(err)
else
ios.sdseek(22)
ios.print(string(13,"Anzahl der Kanäle : "))
ios.printdec(ios.sdgetc | (ios.sdgetc << 8))
ios.sdseek(34)
ios.print(string(13,"Bits per Sample : "))
ios.printdec(ios.sdgetc | (ios.sdgetc << 8))
ios.sdseek(40)
ios.print(string(13,"Länge : "))
ios.printdec(ios.sdgetc | (ios.sdgetc << 8) | (ios.sdgetc << 16) | (ios.sdgetc << 24))
ios.printnl
ios.sdclose
else 'kein parameter: fehlermeldung
printErr(@err1)
DAT 'PLAY_DIR
PUB play_dir|stradr,len,fcnt,i 'hss: alle songs auf der sd-card abspielen
ios.sddir 'kommando: verzeichnis öffnen
datcnt := 0 'zum listenanfang
fcnt := 0 'zähler für dateianzahl
fl_bye := 0
repeat while (stradr := ios.sdnext) 'dateiliste einlesen
if str_find(stradr,@ext1)
fcnt++
play_dir_wrlst(stradr)
ios.print(string("Anzahl Dateien : "))
ios.printdec(fcnt)
ios.printnl
datcnt := 0 'zum listenanfang
repeat i from 0 to fcnt-1 'dateiliste abspielen
ios.printdec(i+1)
ios.printchar("/")
ios.printdec(fcnt)
ios.printtab
play_dir_rdlst(@fn)
play_dir_file(@fn)
if fl_bye 'player beenden
quit
ios.printnl
PRI play_dir_file(stradr)|err
ios.print(stradr)
ios.printchar(" ")
if err := ios.wav_play(stradr) 'fehler bei start des players?
ios.print(@err0) 'fehlernummer ausgeben
ios.printdec(err)
else
play_wav_status 'warten, solange wav gespielt wird (sd belegt)
ios.printnl
PUB play_dir_wrlst(stradr)|len,i 'kopiert dateinamen in liste
len := strsize(stradr)
repeat i from 0 to len-1
ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++)
ios.ram_wrbyte(ios#usrmod,0,datcnt++)
PUB play_dir_rdlst(stradr)|i,n 'liest dateinamen aus list
i := 0
repeat
n := ios.ram_rdbyte(ios#usrmod,datcnt++)
byte[stradr][i++] := n
while n <> 0
DAT 'PLAY_WAV
PRI play_wav|err 'wav abspielen
if ios.paranext(@parastr) 'parameter?
if err := ios.wav_play(@parastr) 'fehler bei start des players?
ios.print(@err0) 'fehlernummer ausgeben
ios.printdec(err)
else
play_wav_status 'warten, solange wav gespielt wird (sd belegt)
else 'kein parameter: fehlermeldung
printErr(@err1)
PUB play_wav_status|status,curpos,key,l,p 'warten bis player fertig, oder abbruch
ios.print(string(" <q/n/p> : "))
ios.curoff
curpos := ios.curgetx
repeat
status := ios.wav_status
ios.cursetx(curpos)
ios.printdec(ios.wav_len)
ios.printchar("/")
ios.printdec(ios.wav_pos)
ios.print(string(" "))
if key := ios.key 'bei taste stopsignal an player senden
case key
"n": ios.wav_stop 'next wav
"p": ios.wav_pause 'pause
"q": fl_bye := 1
ios.wav_stop
while status 'schleife solange player aktiv
ios.curon
DAT 'TOOLS
PRI printErr(stradr)
ios.print(@err0)
ios.print(stradr)
ios.print(string("help: man wplay"))
PUB str_find(string1, string2) : buffer | counter 'sys: string suchen
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Searches a string of characters for the first occurence of the specified string of characters. │
'' │ │
'' │ Returns the address of that string of characters if found and zero if not found. │
'' │ │
'' │ string1 - A pointer to the string of characters to search. │
'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(string1--)
if(byte[++string1] == byte[string2])
repeat counter from 0 to (strsize(string2) - 1)
if(byte[string1][counter] <> byte[string2][counter])
buffer~~
ifnot(buffer~)
return string1
PUB str2dec(stradr)|buffer,counter
buffer := byte[stradr]
counter := (strsize(stradr) <# 11)
repeat while(counter--)
result *= 10
result += lookdownz(byte[stradr++]: "0".."9")
if(buffer == "-")
-result
DAT
ext1 byte ".WAV",0
err0 byte 13,"Fehler : ",0
err1 byte "Zu wenig Parameter!",13,0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

360
system/regnatix/yplay.spin Normal file
View File

@ -0,0 +1,360 @@
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Autor: Volker Pohlers
│ See end of file for terms of use. │
│ Die Nutzungsbedingungen befinden sich am Ende der Datei │
└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
Informationen : hive-project.de
Kontakt :
System : TriOS
Name : yplay
Chip : Regnatix
Typ : Programm
Version :
Subversion :
Funktion : ay-ym-player für kommandozeile
Komponenten : -
COG's : -
Logbuch :
17-08-2010-dr040 - start des projektes :)
22.08.2010-dr040 - Timing geändert
Notizen : based on splay.bin by Ingo Kripahle
,YM6player.spin by Juergen Buchmueller
}}
OBJ
ios : "reg-ios"
gc : "glob-con" 'globale konstanten
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
VAR
byte fl_bye 'flag player beenden
byte parastr[64] 'parameterstring
byte fn[12] 'puffer für dateinamen
long datcnt 'zeiger für dateiliste
VAR
byte buffer[128]
long nvbl
long attr
long ndrums
long clock
long rate
long loop
long extra
long bytes
long fileNumber
long nextsong
long wait
DAT 'PARAMETER
PUB main
ios.start 'ios initialisieren
{ ios.startram 'ios initialisieren (f. Start aus Propeller Tool heraus)
ios.admload(@admsys)
ios.bus_putchar1(200) ' ay_start
play_dir
}
ios.parastart 'parameterübergabe starten
if (ios.admgetspec & gc#A_AYS)
ios.bus_putchar1(200) ' ay_start
repeat while ios.paranext(@parastr) 'parameter einlesen
if byte[@parastr][0] == "/" 'option?
case byte[@parastr][1]
"?": ios.print(string("help: man yplay")) '/?
"p": play_file '/p
"d": play_dir '/d
else
printErr(@err2)
ios.bus_putchar1(201) ' ay_stop
ios.stop
DAT 'PLAY_DIR
PUB play_dir|stradr,len,fcnt,i 'alle songs auf der sd-card abspielen
ios.sddir 'kommando: verzeichnis öffnen
datcnt := 0 'zum listenanfang
fcnt := 0 'zähler für dateianzahl
fl_bye := 0
repeat while (stradr := ios.sdnext) 'dateiliste einlesen
if str_find(stradr,@ext1)
fcnt++
play_dir_wrlst(stradr)
ios.print(string("Anzahl Dateien : "))
ios.printdec(fcnt)
ios.printnl
datcnt := 0 'zum listenanfang
repeat i from 0 to fcnt-1 'dateiliste abspielen
ios.printdec(i+1)
ios.printchar("/")
ios.printdec(fcnt)
ios.printtab
play_dir_rdlst(@fn)
play_dir_file(@fn)
if fl_bye 'player beenden
quit
ios.printnl
PRI play_file|err 'datei abspielen
if ios.paranext(@parastr) 'parameter?
play_dir_file(@parastr)
else 'kein parameter: fehlermeldung
printErr(@err1)
PUB play_dir_wrlst(stradr)|len,i 'kopiert dateinamen in liste
len := strsize(stradr)
repeat i from 0 to len-1
ios.ram_wrbyte(ios#usrmod,byte[stradr][i],datcnt++)
ios.ram_wrbyte(ios#usrmod,0,datcnt++)
PUB play_dir_rdlst(stradr)|i,n 'liest dateinamen aus list
i := 0
repeat
n := ios.ram_rdbyte(ios#usrmod,datcnt++)
byte[stradr][i++] := n
while n <> 0
PRI play_dir_file(stradr)|err, k,curpos,key,vblframe,timecnt
ios.print(stradr)
ios.printchar(" ")
ios.printnl
openFile(stradr)
{ if err := ios.sid_sdmpplay(stradr) 'fehler bei start des players?
ios.print(@err0) 'fehlernummer ausgeben
ios.printdec(err)
else
play_status 'warten, solange wav gespielt wird (sd belegt)
}
ios.print(string("Status <n/q> : "))
ios.curoff
curpos := ios.curgetx
timecnt := cnt
repeat
timecnt += clkFreq / rate
ios.sdeof ' eof?
ifnot ios.bus_getchar1
ios.sdgetblk(16, @buffer)
ios.bus_putchar1(202) ' ay_updateRegisters
repeat k from 0 to 13
ios.bus_putchar1(buffer[k])
waitcnt(timecnt)
else
quit
ios.cursetx(curpos)
ios.printdec(++vblframe)
ios.printchar("/")
ios.printdec(nvbl)
if key := ios.key 'bei taste stopsignal an player senden
case key
"n": quit
"q": fl_bye := 1
quit
ios.curon
ios.sdclose
ios.printnl
DAT 'PLAY_AY
PRI get_word | buff
ios.sdgetblk(2, @buff)
return byte[@buff][0] << 8 + byte[@buff][1]
PRI get_dword | buff
ios.sdgetblk(4, @buff)
return byte[@buff][0] << 24 + byte[@buff][1] << 16 + byte[@buff][2] << 8 + byte[@buff][3]
PRI get_string | n
repeat n from 0 to 127
if (buffer[n] := ios.sdgetc) =< 0
buffer[n] := 0
return
PUB openFile(filename) | i, j, m
ios.sdopen( "R", filename )
ios.sdgetblk(4, @buffer) ' 00 - read "YM6!" header
ios.sdgetblk(8, @buffer) ' 04 - read "LeOnArD!" identifier
nvbl := get_dword ' 0c - number of VBL frames
' ios.print(string("VBL frames : "))
' ios.printdec(nvbl)
' ios.printnl
attr := get_dword ' 10 - attributes
' ios.print(string("Attributes : "))
' ios.printhex(attr,8)
' ios.printnl
ndrums := get_word ' 14 - number of digi drum samples
' ios.print(string("Digi-Drums : "))
' ios.printdec(ndrums)
' ios.printnl
clock := get_dword ' 16 - YM2149 external frequency in Hz
' ios.print(string("Clock : "))
' ios.printdec(clock)
' ios.printnl
rate := get_word ' 1a - player frequency in Hz
' ios.print(string("Play rate : "))
' ios.printdec(rate)
' ios.printnl
loop := get_dword ' 1c - frame where looping starts
' ios.print(string("Loop : "))
' ios.printdec(loop)
' ios.printnl
extra := get_word ' 20 - extra bytes following (should be 0)
' ios.print(string("Extra : "))
' ios.printdec(extra)
' ios.printnl
' skip over extra data
repeat while extra > 0
m := extra <# 128
ios.sdgetblk(m, @buffer)
extra -= m
if ndrums > 0
' read digi drum samples
repeat ndrums
bytes := get_dword
repeat while bytes > 0
m := bytes <# 128
ios.sdgetblk(m, @buffer)
bytes -= m
get_string ' read song name
ios.print(string("Song name : "))
ios.print(@buffer)
ios.printnl
get_string ' read author name
ios.print(string("Author : "))
ios.print(@buffer)
ios.printnl
get_string ' read comments / software
ios.print(string("Comments : "))
ios.print(@buffer)
ios.printnl
PUB play_status|status,curpos,key,l,p 'warten bis player fertig, oder abbruch
ios.print(string("Status <q/n/p> : "))
ios.curoff
curpos := ios.curgetx
repeat
status := ios.sid_dmpstatus
ios.cursetx(curpos)
ios.printdec(ios.sid_dmplen)
ios.printchar("/")
ios.printdec(ios.sid_dmppos)
if key := ios.key 'bei taste stopsignal an player senden
case key
"n": ios.sid_dmpstop 'next wav
"p": ios.sid_dmppause 'pause
"q": fl_bye := 1
ios.sid_dmpstop
while status 'schleife solange player aktiv
ios.sid_mute(3)
ios.curon
DAT 'TOOLS
PRI printErr(stradr)
ios.print(@err0)
ios.print(stradr)
ios.print(string("help: man yplay"))
PUB str_find(string1, string2) : buf | counter 'sys: string suchen
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Searches a string of characters for the first occurence of the specified string of characters. │
'' │ │
'' │ Returns the address of that string of characters if found and zero if not found. │
'' │ │
'' │ string1 - A pointer to the string of characters to search. │
'' │ string2 - A pointer to the string of characters to find in the string of characters to search. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
repeat strsize(string1--)
if(byte[++string1] == byte[string2])
repeat counter from 0 to (strsize(string2) - 1)
if(byte[string1][counter] <> byte[string2][counter])
buf~~
ifnot(buf~)
return string1
PUB str2dec(stradr)|buf,counter
buf := byte[stradr]
counter := (strsize(stradr) <# 11)
repeat while(counter--)
result *= 10
result += lookdownz(byte[stradr++]: "0".."9")
if(buf == "-")
-result
DAT
admsys byte "admym.adm",0
ext1 byte ".YM",0
err0 byte 13,"Fehler : ",0
err1 byte "Zu wenig Parameter!",13,0
err2 byte "Administra-Code unterstützt keine AY/YM-Emulation!",13,0
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. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@ -0,0 +1 @@
<<<<ððððÀÀÀÀ0000<<<<üüüüÿ€ÿ€ÿÿ€€ˆˆˆˆ

BIN
system/sonstiges/BW.COL Normal file

Binary file not shown.

BIN
system/sonstiges/BWHALF.COL Normal file

Binary file not shown.

BIN
system/sonstiges/CHESS.COL Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More