Page 1 of 1
Sched Handler (WIP)
Posted: Sun Apr 07, 2013 10:37 pm
by SMcClouth
For a w.i.p. (work in process) schedule handler,
I've the following code:
Code: Select all
DIM SHARED task(100) AS INTEGER
CONST NR.TASKS = 64
SUB sched.init
FOR i = 1 TO NR.TASKS
task(i) = 0
NEXT
END SUB
Now the thing is, that it doesn't walk through till the 64.
When trying to debug, I REMarked
and added
which then gives diffrent values. When adjusting this to:
it gets to 32 - 0 and hangs there. Does anyone have a clue why this could be and how to fix this?
Posted: Mon Apr 08, 2013 1:31 am
by burger2227
1) post code that actually runs! Good or bad, you have to care before we do. NEX? USB?
2) all the elements of an array are zero already
3) use dot names after you know how the code works. Dot names do not make a program or the programmer any better!
Posted: Mon Apr 08, 2013 3:23 am
by SMcClouth
burger2227 wrote:1) post code that actually runs! Good or bad, you have to care before we do. NEX? USB?
My bad, sorry. Fixed it.
burger2227 wrote:2) all the elements of an array are zero already
Apparently for some reason, because it runs in modules, it isn't. But you're right though, they should be zero.[/quote]
burger2227 wrote:3) use dot names after you know how the code works. Dot names do not make a program or the programmer any better!
Thanks for the tip.
Alright, I'll put up the source in which in runs, and perhaps that will explain some more.
I use PDS 7.1
Posted: Mon Apr 08, 2013 4:46 am
by SMcClouth
PART 1
kernel/include/qbinux.bi:
Code: Select all
DEFINT A-Z
'$DYNAMIC
TYPE RegTypeX
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
flags AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
TYPE tm
sec AS INTEGER
min AS INTEGER
hour AS INTEGER
mday AS INTEGER
mon AS INTEGER
year AS INTEGER
wday AS INTEGER
yday AS INTEGER
isdst AS INTEGER
END TYPE
DECLARE FUNCTION BCD2BIN (Value AS INTEGER)
DECLARE FUNCTION BITS2NUM& (bits AS STRING)
DECLARE FUNCTION BitShift (Value%, way$, count%)
DECLARE SUB bufferinit ()
DECLARE FUNCTION CMOS.Read (Addr)
DECLARE FUNCTION CreateArray$ (slots&, bytes%)
DECLARE FUNCTION Day! ()
DECLARE FUNCTION FindFATFile% (fil AS STRING)
DECLARE SUB hdinit ()
DECLARE SUB head ()
DECLARE SUB InterruptX (intnm AS INTEGER, inreg AS RegTypeX, outreg AS RegTypeX)
DECLARE FUNCTION Kernel.MkTime (tmx AS tm)
DECLARE SUB main ()
DECLARE SUB MakDir (dir AS STRING)
DECLARE FUNCTION Month! (mont%)
DECLARE SUB movetousermode ()
DECLARE FUNCTION NUM2BITS$ (num AS INTEGER, bits AS INTEGER)
DECLARE FUNCTION RHEX$ (lenght AS INTEGER)
DECLARE SUB sched.init ()
DECLARE SUB SetDir (DirID AS LONG)
DECLARE SUB SetDrv (DrvID AS LONG)
DECLARE SUB setup ()
DECLARE SUB TimeInit ()
DECLARE FUNCTION WorkPath$ (file AS STRING)
DECLARE FUNCTION Year! ()
'Shared variables
COMMON SHARED CurDir AS STRING * 4, CurDrive AS STRING * 4, CurUser AS STRING * 1
COMMON SHARED FileFound AS STRING * 1, PriPub AS STRING * 1, IsSystem AS STRING * 1
COMMON SHARED DirFound AS STRING * 1, PathAccess AS STRING * 1
COMMON SHARED EditArr AS STRING * 8, cTask AS STRING
COMMON SHARED PMode
'Shared dims
DIM SHARED curpos AS INTEGER
DIM SHARED msg1 AS STRING
DIM SHARED RegsX AS RegTypeX
DIM SHARED startuptime AS LONG
DIM SHARED task(100) AS INTEGER
DIM SHARED tme AS tm
CONST MINUTE = 60
CONST NR.TASKS = 64
ON ERROR RESUME NEXT
kernel/boot/boot.bas:
Code: Select all
'
' boot.bas
'
'$INCLUDE:'include/qbinux.bi'
msg1 = "Loading system ..." + CHR$(13) + CHR$(10)
start:
RegsX.AX = &H300 ' read cursor pos
RegsX.BX = &H10
InterruptX &H10, RegsX, RegsX
FOR ascii = 1 TO LEN(msg1)
RegsX. AX = &HE00 + ASC(MID$(msg1, ascii))
RegsX. BX = 0
InterruptX &H10, RegsX, RegsX ' write string, move cursor
NEXT
' ok, we've written the message, now
' we get the current cursor position and save it for
' posterity.
RegsX.AX = &H300 ' read cursor pos
RegsX.BX = &H10
InterruptX &H10, RegsX, RegsX ' save it in known place, con_init fetches
CurPos = RegsX.DX ' it from CurPos.
' that was painless, now we see if A20 is enabled
DEF SEG = 0: a% = PEEK(&H4F0): POKE &H4F0, &HE7
DEF SEG = &HFFFF: b% = PEEK(&H500) '&H4F0+&H10
DEF SEG = 0: POKE &H4F0, a%
IF b% <> &HE7 THEN
GOTO empty8042
ELSE
PRINT "A20 not enabled": SYSTEM
END IF
' This routine checks that the keyboard command queue is empty
' No timeout is used - if this hangs there is something wrong with
' the machine, and we probably couldn't proceed anyway.
empty8042:
RegsX.AX = &HB00
InterruptX &H21, RegsX, RegsX ' 8042 status port
IF (RegsX.AX AND &HFF) <> 0 THEN ' is input buffer full?
goto empty8042 ' yes - loop
END IF
head
kernel/boot/head.bas:
Code: Select all
'
' head.bas
'
'$INCLUDE:'include/qbinux.bi'
SUB head
startup32:
DEF SEG = 0: a% = PEEK(&H4F0): POKE &H4F0, &HE7 ' check that A20 really IS enabled
DEF SEG = &HFFFF: b% = PEEK(&H500)
DEF SEG = 0: POKE &H4F0, a%
InterruptX &H11, RegsX, RegsX ' check math chip
SHARED ax2 AS LONG
ax2 = CVL(MKI$(RegsX.AX) + CHR$(0) + CHR$(0))
IF ((ax2 AND 2) \ 2) = 1 THEN
ET = 1 ' ET is set - 387 is present
END IF
GOTO afterpagetables
afterpagetables:
goto setuppaging
setuppaging: 'will be added later
' IF b4ginit THEN
' PMode = 0
' ELSE
' PMode = 1
' END IF
main
END SUB
Posted: Mon Apr 08, 2013 4:47 am
by SMcClouth
Part 2
kernel/fs/fs.bas:
Code: Select all
'
' fs.bas
'
'$INCLUDE:'include/qbinux.bi'
SUB AscendDir
END SUB
SUB bufferinit
EditArr = CreateArray(131074, 80)
IF EditArr = STRING$(8, 0) THEN
PRINT "Failed..."
END IF
END SUB
FUNCTION CreateArray$ (slots&, bytes%)
IF bytes > 8192 THEN EXIT FUNCTION
DO
arrn$ = RHEX(8)
LOOP WHILE FindFATFILE("ARR\" + arrn$ + ".Arr")
ff = FREEFILE
OPEN "ARR\" + arrn$ + ".Arr" FOR OUTPUT AS #FF
t$ = MKL$(slots&) + MKI$(bytes)
PRINT #ff, t$
FOR a = 8193 TO bytes STEP - 1
i! = a / bytes
n! = slots& / ( a / bytes)
IF i! = INT(a / bytes) AND n! = INT(n!) THEN EXIT FOR
NEXT
END FUNCTION
FUNCTION FindFATFile (fil AS STRING)
spec$ = fil + CHR$(0)
RegsX.AX = &H4E00
RegsX.CX = 39
RegsX.DX = SADD(Spec$)
RegsX.DS = SSEG(Spec$)
InterruptX &H21, RegsX, RegsX
IF RegsX.flags AND 1 THEN
FindFATFile = VAL("0")
ELSE
FindFATFile = VAL("1")
END IF
END FUNCTION
FUNCTION GetID& (filedir AS STRING, typ AS INTEGER)
IF filedir = "" THEN EXIT FUNCTION
ff = FREEFILE
IF typ = 0 THEN 'file
IF FindFATFile("NVXFS/FileList.nff") = 0 THEN GetID = 0: EXIT FUNCTION
OPEN "NVXFS/FileList.nff" FOR BINARY AS #ff
mt$ = " "
GET #ff, 1, mt$
k = CVI(mt$)
FOR a = 0 TO k
offs& = a * 272& + 3
t$ = SPACE$(271)
GET #ff, offs&, t$
dnam$ = MID$(t$, 2, ASC(MID$(t$, 1, 1)))
ddrive$ = MID$(t$, 257, 4)
ddir$ = MID$(t$, 261, 4)
ID$ = MID$(t$, 265, 4)
IF dnam$ = filedir THEN
IF ddrive$ = CurDrive THEN
IF ddir$ = CurDir THEN
GetID& = CVL(ID$)
CLOSE #ff
EXIT FUNCTION
END IF
END IF
END IF
NEXT
CLOSE #FF
ELSEIF typ = 1 THEN 'directory
IF FindFATFile("NVXFS/DirList.nfd") = 0 THEN GetID = 0: EXIT FUNCTION
OPEN "NVXFS/DirList.nfd" FOR BINARY AS #FF
mt$ = " "
GET #ff, 1, mt$
k = CVI(mt$)
FOR a = 0 TO k
offs& = a * 272& + 3
t$ = SPACE$(271)
GET #ff, offs&, t$
dnam$ = MID$(t$, 2, ASC(MID$(t$, 1, 1)))
ddrive$ = MID$(t$, 257, 4)
ddir$ = MID$(t$, 261, 4)
ID$ = MID$(t$, 265, 4)
IF dnam$ = filedir THEN
IF ddrive$ = CurDrive THEN
IF ddir$ = CurDir THEN
GetID& = CVL(ID$)
CLOSE #ff
EXIT FUNCTION
END IF
END IF
END IF
NEXT
CLOSE #ff
ELSE 'drive
IF FindFATFile("NVXFS/DrvList.drv") = 0 THEN GetID = 0: EXIT FUNCTION
END IF
END FUNCTION
SUB MakDir (dir AS STRING)
odir$ = CurDir
dirn$ = WorkPath(dir)
END SUB
FUNCTION RHEX$ (lenght AS INTEGER)
FOR A = 1 to lenght
s$ = s$ + HEX$(INT(16 * RND))
NEXT
RHEX$ = s$
END FUNCTION
SUB SetDir (DirID AS LONG)
CurDir = MKL$(DirID)
END SUB
SUB SetDrv (DrvID AS LONG)
CurDrive = MKL$(DrvID)
END SUB
FUNCTION WorkPath$ (file AS STRING)
h$ = file
Ompa$ = CurDir
IF INSTR(file, "/") THEN
DO
t$ = LEFT$(h$, INSTR(h$, "/") - 1)
IF t$ = "..." THEN
SetDir 0
ELSEIF t$ = ".." THEN
AscendDir
ELSE
IF GetID(t$, 1) <> 0 THEN
SetDir GetID(t$, 1)
ELSE
WorkPath$ = "DNF"
CurDir = Ompa$
EXIT FUNCTION
END IF
END IF
h$ = RIGHT$(h$, LEN(h$) - (LEN(t$) + 1))
LOOP WHILE INSTR(h$, "/")
END IF
WorkPath$ = h$
END FUNCTION
kernel/init/main.bas:
Code: Select all
'
' main.bas
'
'$INCLUDE:'include/qbinux.bi'
'
' Yeah, yeah, it's ugly, but I cannot find how to do this correctly
' and this seems to work. If anybody has more info on the real-time
' clock I'd be interested. Most of this was trial and error, and some
' bios-listing reading. Urghh.
'
REM $STATIC
FUNCTION BCD2BIN (Value AS INTEGER)
BCD2BIN = ((Value) AND 15) + (BitShift(Value, ">>", 4) * 10)
END FUNCTION
'Needs to be moved to proper library
REM $DYNAMIC
FUNCTION BitShift (Value%, way$, count%)
IF way$ = "<<" THEN
X = Value% * (2 ^ count%)
temp& = x%
temp& = (temp% * (X ^ count%)) AND &HFFFF
BitShift = temp&
ELSEIF way$ = ">>" THEN
BitShift = INT(Value% / 2 ^ count%)
END IF
END FUNCTION
FUNCTION CMOS.Read (Addr)
OUT &H70, Addr
CMOS.Read = INP(&H71)
END FUNCTION
SUB init
setup
END SUB
SUB main
timeinit
sched.init
bufferinit
hdinit
movetousermode
rem init
END SUB
SUB movetousermode
PriPub = CHR$(BITS2NUM("11000000"))
IsSystem = CHR$(BITS2NUM("00000000"))
END SUB
SUB timeinit
DO
tme.sec = CMOS.READ(0)
tme.min = CMOS.READ(2)
tme.hour = CMOS.READ(4)
tme.mday = CMOS.READ(7)
tme.mon = CMOS.READ(8)
tme.year = CMOS.READ(9)
LOOP WHILE (tme.sec = CMOS.READ(0))
x% = BCD2BIN(tme.sec): tme.sec = x%
x% = BCD2BIN(tme.min): tme.min = x%
x% = BCD2BIN(tme.hour): tme.hour = x%
x% = BCD2BIN(tme.mday): tme.mday = x%
x% = BCD2BIN(tme.mon): tme.mon = x%
x% = BCD2BIN(tme.year): tme.year = x%
startuptime = Kernel.MkTime(tme)
END SUB
Posted: Mon Apr 08, 2013 4:48 am
by SMcClouth
PART 3
kernel/kernel/kernel.bas:
Code: Select all
'
' kernel.bas
'
'$INCLUDE:'include/qbinux.bi'
REM $STATIC
FUNCTION Day!
Day! = 24 * hour!
END FUNCTION
SUB hdinit
ff = FREEFILE
OPEN "TEMP\WPM.chk" FOR OUTPUT AS #ff: CLOSE #ff
IF FindFATFile("TEMP\WPM.CHK") = 0 THEN
'COLOR 4
PRINT " ---ERROR: Running on write protected medium."
PRINT
'COLOR 1
'PRINT
'PRINT "This means that there is really not much use starting QBinux at all."
END IF
PriPub = CHR$(BITS2NUM("11010000"))
CurUser = CHR$(BITS2NUM("00000000"))
IsSystem = CHR$(BITS2NUM("10000000"))
SetDir 0
SetDrv 0
END SUB
FUNCTION Kernel.MkTime (tmx AS tm)
DIM res AS DOUBLE
DIM year2 AS DOUBLE
year2 = tmx.year - 70 ' magic offset (y+1) needed to get leapyears right
res = year * year2 + day * ((year2 + 1) / 4)
res = res + month(tmx.mon) ' and (y+2) here. If it wasn't a leap-year, we have to adjust
IF tmx.mon > 1 AND ((year2 + 2) \ 4) THEN
res = res - day
END IF
res = res + day * (tmx.mday - 1)
res = res + hour * tmx.hour
res = res + MINUTE * tmx.min
res = res + tmx.sec
Kernel.MkTime = res
END FUNCTION
FUNCTION Month! (mont%)
IF mont% = 1 THEN month! = 0
IF mont% = 2 THEN mont! = day! * 31
IF mont% = 3 THEN mont! = day! * (31 + 29)
IF mont% = 4 THEN mont! = day! * (31 + 29 + 31)
IF mont% = 5 THEN mont! = day! * (31 + 29 + 31 + 30)
IF mont% = 6 THEN mont! = day! * (31 + 29 + 31 + 30 + 31)
IF mont% = 7 THEN mont! = day! * (31 + 29 + 31 + 30 + 31 + 30)
IF mont% = 8 THEN mont! = day! * (31 + 29 + 31 + 30 + 31 + 30 + 31)
IF mont% = 9 THEN mont! = day! * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31)
IF mont% = 10 THEN mont! = day! * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30)
IF mont% = 11 THEN mont! = day! * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31)
IF mont% = 12 THEN mont! = day! * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)
END FUNCTION
SUB sched.init
FOR i = 1 to NR.TASKS
task(i) = 0
NEXT
END SUB
SUB setup
CurUser = CHR$(BITS2NUM("00000000"))
IsSystem = CHR$(BITS2NUM("00000000"))
PathAccess = "1"
SetDir 0
SetDrv 0
END SUB
REM $STATIC
FUNCTION year!
year! = 365 * day!
END FUNCTION
kernel/lib/lib.bas:
Code: Select all
'
' lib.bas
'
'$INCLUDE:'include/b4g.bi'
FUNCTION BITS2NUM& (bits AS STRING)
IF LEN(bits) > 16 THEN bits = LEFT$(bits, 16)
FOR a = LEN(bits) TO 1 STEP - 1
IF MID$(bits, a, 1) = "1" THEN n& = n& + (2 ^ (a - 1))
NEXT
BITS2NUM& = n&
END FUNCTION
kernel/compile.bat:
Code: Select all
@ECHO OFF
del testrun.exe
REM build Image: boot/boot tools/system
REM build boot/boot
bc /o /Ot /Fs /G2 /Fpi /E /X boot\boot.bas;
REM build tools/system
bc /o /Ot /Fs /G2 /Fpi /E /X boot\head.bas;
bc /o /Ot /Fs /G2 /Fpi /E /X init\main.bas;
REM build ARCHIVES = kernel/kernel.bas mm/mm.bas fs/fs.bas
bc /o /Ot /Fs /G2 /Fpi /E /X kernel\kernel.bas;
bc /o /Ot /Fs /G2 /Fpi /E /X fs\fs.bas;
REM build lib/lib.bas
bc /o /Ot /Fs /G2 /Fpi /E /X lib\lib.bas;
ren boot.obj a.obj
ren head.obj b.obj
ren main.obj c.obj
ren kernel.obj d.obj
ren fs.obj f.obj
ren lib.obj g.obj
link a+b+c++d+f+g,,nul,lib\bcl71efr.lib+lib\qbx.lib;
ren a.exe testrun.exe
del *.obj
Posted: Mon Apr 08, 2013 9:12 am
by burger2227
This works fine in QB64:
Code: Select all
DIM SHARED task(100) AS INTEGER
CONST NR.TASKS = 64
sched.init
END
SUB sched.init
FOR i = 1 TO NR.TASKS
task(i) = 0
PRINT i; "-"; task(i);
NEXT
END SUB
I did not notice a call to the SUB in your original posted code.
Posted: Mon Apr 08, 2013 9:39 am
by SMcClouth
Thx for bearing with me!
Yes that way it does. But when running it in QBinux, it crashes when during the FOR-NEXT-loop in sched.init.
When I REMarked the task(i)= 0 and I still used the PRINT i; "-"; task(i), it displays diffrent values (not zero). When I unREMark the task(i) = 0, it crashes at either i = 20, or 25, or 32.
Grtz
Posted: Mon Apr 08, 2013 10:18 am
by burger2227
CONST values should be shared globally too.
Posted: Mon Apr 08, 2013 10:46 am
by SMcClouth
burger2227 wrote:CONST values should be shared globally too.
edit: You mean that I should use:
Code: Select all
DIM SHARED NR.TASKS AS INTEGER
NR.TASKS = 64
Follow up:
I changed it to the above, with the result that NR.TASKS = 0, on checking in the routine.
When chancing DIM SHARED to COMMON SHARED, NR.TASKS results in 64, but the after check, when the FOR-NEXT-loop is done, states that i = 65, which shouldn't be possible as i = 1 TO NR.TASKS (=64). and then crashes again.
Grtz
Posted: Mon Apr 08, 2013 3:01 pm
by burger2227
NEXT will do that at the end of a FOR loop every time. It goes to the next STEP interval value. Without STEP it always goes up one by default.
11
If you read an invalid array element(index) it will cause an error too.
Posted: Tue Apr 09, 2013 10:03 am
by SMcClouth
Thanks for clear that out burger2227.
edit: I added DEFINT A-Z to the kernel.bas file, on top.
When running the code now, it states in the debug check that NR.TASKS = 64 and ends with i= 64.
But still a crash.
edit2: after removing the debug checks (PRINT NR.TASKS, and PRINT i) it continues to print the next debug check (PRINT sched.init), but then crashes. It a very special way, (since I run this now in VirtualBox for a real DOS-experience) randomly the screens get filled with ASCII-code 219 and turns white...
grtz