diff --git a/TODO b/TODO index a8403a7..6083b62 100644 --- a/TODO +++ b/TODO @@ -16,6 +16,7 @@ Things to do before 1.0: Things to do later: - bopti: Implement blending modes for monochrome bitmaps - clock: Handle overclock (relaunch clocks when overclocking) +- core: Change interrupt priority using the gint API - core: Register more interrupts (and understand their parameters) - core: Remove redundant code linked to environment saves - core: Review interrupt system (again) - this one is too slow diff --git a/include/internals/bopti.h b/include/internals/bopti.h index 2c93153..e1b11dd 100644 --- a/include/internals/bopti.h +++ b/include/internals/bopti.h @@ -75,7 +75,7 @@ typedef struct command_t uint32_t masks[4]; // Video rams being used. union { - // Different names, same fate. (Kingdom Hearts II) + // "Different names, same fate." (Kingdom Hearts II) uint32_t *vram; uint32_t *v1; }; diff --git a/include/modules/interrupts.h b/include/modules/interrupts.h new file mode 100644 index 0000000..47a0129 --- /dev/null +++ b/include/modules/interrupts.h @@ -0,0 +1,489 @@ +#ifndef _MODULES_INTERRUPTS +#define _MODULES_INTERRUPTS + +#include +#include + +//--- +// Interrupt controller. +// This part is difficult to handle, because the interrupt controllers of +// SH7705 and SH7305 MPUs have virtually nothing in common. I eventually +// decided to completely split it up into two kinds of structures and +// types. +// Use the gint API, not this module, for platform-independent interrupt +// management. +//--- + +//--- +// SH7705-related definitions. +//--- + +/* + mod_intc_ipc_7705_t + Interrupt priority controller. Just a bunch of 16-bit-registers that + handle the interrupt priority of all interrupt sources. + + Please note that because the interrupt priority controller of the + SH7705 MPU has registers scattered everywhere in the memory, its + structure below has a different pointer for each register. On the + opposite, the SH7305 registers are all in a contiguous area thus there + is only one pointer for the whole group. +*/ +typedef struct +{ + volatile word_union(*IPRA, + uint TMU0 :4; /* Timer 0 */ + uint TMU1 :4; /* Timer 1 */ + uint TMU2 :4; /* Timer 2 */ + uint RTC :4; /* Real-Time Clock */ + ); + + volatile word_union(*IPRB, + uint WDT :4; /* Watchdog Timer */ + uint REF :4; /* BSC Refresh Request, SDRAM (?) */ + uint :4; + uint :4; + ); + + volatile word_union(*IPRC, + uint IRQ3 :4; /* Interrupt request 3 */ + uint IRQ2 :4; /* Interrupt request 2 */ + uint IRQ1 :4; /* Interrupt request 1 */ + uint IRQ0 :4; /* Interrupt request 0 */ + ); + + volatile word_union(*IPRD, + uint PINT0_7 :4; /* External interrupt pins 0 to 7 */ + uint PINT8_15 :4; /* External interrupt pins 8 to 15 */ + uint IRQ5 :4; /* Interrupt request 5 */ + uint IRQ4 :4; /* Interrupt request 4 */ + ); + + volatile word_union(*IPRE, + uint DMAC :4; /* Direct Memory Access Controller */ + uint SCIF0 :4; /* Serial Communication Interface 0 */ + uint SCIF2 :4; /* Serial Communication Interface 2 */ + uint ADC :4; /* Analog/Decimal Converter */ + ); + + volatile word_union(*IPRF, + uint :4; + uint :4; + uint USB :4; /* USB Controller */ + uint :4; + ); + + volatile word_union(*IPRG, + uint TPU0 :4; /* Timer Pulse Unit 0 */ + uint TPU1 :4; /* Timer Pulse Unit 1 */ + uint :4; + uint :4; + ); + + volatile word_union(*IPRH, + uint TPU2 :4; /* Timer Pulse Unit 2 */ + uint TPU3 :4; /* Timer Pulse Unit 3 */ + uint :4; + uint :4; + ); + +} __attribute__((packed)) mod_intc_ipc_7705_t; + +/* + mod_intc_icr0_7705_t + Interrupt control register 0: configuration of the NMI interrupt. +*/ +typedef struct +{ + word_union(, + uint const NMIL :1; /* NMI Input Level */ + uint :6; + uint NMIE :1; /* NMI Edge Select */ + uint :8; + ); + +} __attribute__((packed, aligned(2))) mod_intc_icr0_7705_t; + +/* + mod_intc_icr1_7705_t + Interrupt control register 1: general interrupt configuration. +*/ +typedef struct +{ + word_union(, + uint MAI :1; /* Mask All Interrupts */ + uint IRQLVL :1; /* Interrupt Request Level Detect */ + uint BLMSK :1; /* Enable NMI when BL is set */ + uint :1; + uint IRQ5E :2; /* IRQ 5 Edge Detection */ + uint IRQ4E :2; + uint IRQ3E :2; + uint IRQ2E :2; + uint IRQ1E :2; + uint IRQ0E :2; + ); + +} __attribute__((packed, aligned(2))) mod_intc_icr1_7705_t; + +/* + mod_intc_icr2_7705_t + Interrupt control register 2: individual PINT interrupt management. +*/ +typedef struct +{ + word_union(, + uint PINT15 :1; /* PINT15 interrupt detection level */ + uint PINT14 :1; + uint PINT13 :1; + uint PINT12 :1; + uint PINT11 :1; + uint PINT10 :1; + uint PINT9 :1; + uint PINT8 :1; + uint PINT7 :1; + uint PINT6 :1; + uint PINT5 :1; + uint PINT4 :1; + uint PINT3 :1; + uint PINT2 :1; + uint PINT1 :1; + uint PINT0 :1; + ); + +} __attribute__((packed, aligned(2))) mod_intc_icr2_7705_t; + +/* + mod_intc_pinter_7705_t + PINTER register: individual masks for all PINT interrupts. +*/ +typedef struct +{ + word_union(, + uint PINT15 :1; /* PINT15 interrupt enable */ + uint PINT14 :1; + uint PINT13 :1; + uint PINT12 :1; + uint PINT11 :1; + uint PINT10 :1; + uint PINT9 :1; + uint PINT8 :1; + uint PINT7 :1; + uint PINT6 :1; + uint PINT5 :1; + uint PINT4 :1; + uint PINT3 :1; + uint PINT2 :1; + uint PINT1 :1; + uint PINT0 :1; + ); + +} __attribute__((packed, aligned(2))) mod_intc_pinter_7705_t; + +/* + mod_intc_irr0_7705_t + Interrupt Request Register 0: Indicates whether interrupt requests are + being input to the various interrupt lines. Also allows to clear the + IRQ request bits in edge-detection mode. +*/ +typedef struct +{ + byte_union(, + uint const PINT0_7R :1; /* PINT0-7 state */ + uint const PINT8_15R :1; /* PINT8-15 state */ + uint IRQ5 :1; /* IRQ5 request pin state */ + uint IRQ4 :1; + uint IRQ3 :1; + uint IRQ2 :1; + uint IRQ1 :1; + uint IRQ0 :1; + ); + +} __attribute__((packed)) mod_intc_irr0_7705_t; + +/* + mod_intc_irr1_7705_t + Interrupt Request Register 1: State of SCIF0 and DMAC requests. +*/ +typedef struct +{ + const byte_union(, + uint TXIOR :1; /* SCIF0 TXI interrupt */ + uint :1; + uint RXI0R :1; /* SCIF0 RXI interrupt */ + uint ERI0R :1; /* SCIF0 ERI interrupt */ + uint DEI3R :1; /* DMAC DEI3 interrupt */ + uint DEI2R :1; /* DMAC DEI2 interrupt */ + uint DEI1R :1; /* DMAC DEI1 interrupt */ + uint DEI0R :1; /* DMAC DEI0 interrupt */ + ); + +} __attribute__((packed)) mod_intc_irr1_7705_t; + +/* + mod_intc_irr2_7705_t + Interrupt Request Register 2: State of SCIF2 and ADC requests. +*/ +typedef struct +{ + const byte_union(, + uint :3; + uint ADIR :1; /* AD/C ADI interrupt */ + uint TXI2R :1; /* SCIF2 TXI interrupt */ + uint :1; + uint RXI2R :1; /* SCIF2 RXI interrupt */ + uint ERI2R :1; /* SCIF2 ERI interrupt */ + ); + +} __attribute__((packed, aligned(2))) mod_intc_irr2_7705_t; + +/* + mod_intc_7705_t + Finally the SH7705 interrupt controller. +*/ +typedef struct +{ + /* All interrupt priority registers */ + mod_intc_ipc_7705_t iprs; + + /* Control registers */ + volatile mod_intc_icr0_7705_t *ICR0; + volatile mod_intc_icr1_7705_t *ICR1; + volatile mod_intc_icr2_7705_t *ICR2; + + /* PINTER register */ + volatile mod_intc_pinter_7705_t *PINTER; + + /* Interrupt request registers */ + volatile mod_intc_irr0_7705_t *IRR0; + volatile mod_intc_irr1_7705_t *IRR1; + volatile mod_intc_irr2_7705_t *IRR2; + +} __attribute__((packed)) mod_intc_7705_t; + + + +//--- +// SH7305-related definitions. +//--- + +/* + mod_intc_ipc_7305_t + Interrupt priority controller, same idea as the previous one. + + Some of the interrupt fields of the SH7305 registers, the contents of + which have been directly taken from the SH7724 documentation, have been + left unnamed because the related peripheral modules are *very* unlikely + to even exist in the SH7305, let alone be of any use to us. +*/ +typedef struct +{ + word_union(IPRA, + uint TMU0_0 :4; /* TMU0 Channel 0 */ + uint TMU0_1 :4; /* TMU0 Channel 1 */ + uint TMU0_2 :4; /* TMU0 Channel 2 */ + uint IrDA :4; /* Infrared Communication */ + ); + pad(2); + + word_union(IPRB, + uint :4; /* JPEG Processing Unit */ + uint LCDC :4; /* LCD Controller */ + uint DMAC1A :4; /* Direct Memory Access Controller 1 */ + uint :4; /* Blending Engine Unit */ + ); + pad(2); + + word_union(IPRC, + uint TMU1_0 :4; /* TMU1 Channel 0 */ + uint TMU1_1 :4; /* TMU1 Channel 1 */ + uint TMU1_2 :4; /* TMU1 Channel 2 */ + uint :4; /* Sound Processing Unit */ + ); + pad(2); + + word_union(IPRD, + uint :4; + uint MMCIF :4; /* MultiMedia Card Interface */ + uint :4; + uint :4; /* ATAPI Interface */ + ); + pad(2); + + word_union(IPRE, + uint DMAC0A :4; /* Direct Memory Access Controller 0 */ + uint :4; /* Various graphical engines */ + uint SCIFA3 :4; /* SCIFA channel 3 interrupt */ + uint :4; /* Video Processing Unit */ + ); + pad(2); + + word_union(IPRF, + uint KEYSC :4; /* Key Scan Interface */ + uint DMACOB :4; /* DMAC0 transfer/error info */ + uint USB0_1 :4; /* USB controller */ + uint CMT :4; /* Compare Match Timer */ + ); + pad(2); + + word_union(IPRG, + uint SCIF0 :4; /* SCIF0 transfer/error info */ + uint SCIF1 :4; /* SCIF1 transfer/error info */ + uint SCIF2 :4; /* SCIF2 transfer/error info */ + uint :4; /* Video Engine Unit */ + ); + pad(2); + + word_union(IPRH, + uint MSIOF0 :4; /* Clock-synchronized SCIF channel 0 */ + uint MSIOF1 :4; /* Clock-synchronized SCIF channel 1 */ + uint :4; /* I2C Interface channel 0 */ + uint :4; /* I2C Interface channel 1 */ + ); + pad(2); + + word_union(IPRI, + uint SCIFA4 :4; /* SCIFA channel 4 interrupt */ + uint :4; /* MediaRAM InterConnected Buffers */ + uint :4; /* Transport Stream Interface */ + uint :4; /* 2D Graphics Accelerator & ICB */ + ); + pad(2); + + word_union(IPRJ, + uint :4; /* Capture Engine Unit */ + uint :4; /* Ethernet Memory Access Controller */ + uint FSI :4; /* FIFO-Buffered Serial Interface */ + uint SDHI1 :4; /* SD Card Host Interface channel 1 */ + ); + pad(2); + + word_union(IPRK, + uint RTC :4; /* Real-Time Clock */ + uint DMAC1B :4; /* DMAC1 transfer/error info */ + uint :4; /* MediaRAM InterConnected Buffers */ + uint SDHI0 :4; /* SD Card Host Interface channel 0 */ + ); + pad(2); + + word_union(IPRL, + uint SCIFA5 :4; /* SCIFA channel 5 interrupt */ + uint :4; + uint TPU :4; /* Timer-Pulse Unit */ + uint :4; /* Image Extraction DMAC */ + ); + pad(2); + +} __attribute((packed, aligned(4))) mod_intc_ipc_7305_t; + +/* + mod_intc_icr0_7305_t + Interrupt Control Register 0: Detection mode of external pins. +*/ +typedef struct +{ + word_union(, + uint const NMIL :1; /* NMI Input Level */ + uint MAI :1; /* Mask All Interrupts */ + uint :4; + uint NMIB :1; /* Enable NMI when BL is set */ + uint NMIE :1; /* NMI Edge Selection */ + uint :2; + uint LVLMODE :1; /* Level-Sensed IRQ Retention Mode */ + uint :5; + ); + +} __attribute__((packed, aligned(2))) mod_intc_icr0_7305_t; + +/* + mod_intc_icr1_7305_t + Interrupt Control Register 1: Manages detection of IRQ interrupts +*/ +typedef struct +{ + word_union(, + uint IRQ0 :2; /* IRQ0 Sense (Edge) Select */ + uint IRQ1 :2; + uint IRQ2 :2; + uint IRQ3 :2; + uint IRQ4 :2; + uint IRQ5 :2; + uint IRQ6 :2; + uint IRQ7 :2; + ); + +} __attribute__((packed, aligned(2))) mod_intc_icr1_7305_t; + +/* + mod_intc_intpri00_7305_t + Interrupt Priority 00: Priority settings for IRQ interrupts. +*/ +typedef struct +{ + lword_union(, + uint IRQ0 :4; /* IRQ0 Interrupt Priority */ + uint IRQ1 :4; + uint IRQ2 :4; + uint IRQ3 :4; + uint IRQ4 :4; + uint IRQ5 :4; + uint IRQ6 :4; + uint IRQ7 :4; + ); + +} __attribute((packed, aligned(4))) mod_intc_intpri00_7305_t; + +/* + mod_intc_intreq00_7305_t + Interrupt Request 00: Request information of IRQ interrupts. Each of + these bits indicates whether an interrupt is being input. + + mod_intc_intmsk00_7305_t + Interrupt Mask 00: Set interrupt mask for IRQ interrupts. Writing 0 to + these bits is ignored, writing 1 masks the interrupt. + + mod_intc_intmskclr00_7305_t + Interrupt Mask Clear 00: Clear interrupt mask for IRQ interrupts. + Writing 0 to these bits is ignored, writing 1 clears the mask. +*/ +typedef struct +{ + byte_union(, + uint IRQ0 :1; + uint IRQ1 :1; + uint IRQ2 :1; + uint IRQ3 :1; + uint IRQ4 :1; + uint IRQ5 :1; + uint IRQ6 :1; + uint IRQ7 :1; + ); + +} __attribute__((packed)) mod_intc_irq_7305_t; + +typedef mod_intc_irq_7305_t mod_intc_intreq00_7305_t; +typedef mod_intc_irq_7305_t mod_intc_intmsk00_7305_t; +typedef mod_intc_irq_7305_t mod_intc_intmskclr00_7305_t; + +/* + mod_intc_7305_t + Finally the whole interrupt controller. +*/ +typedef struct +{ + /* Control registers */ + volatile mod_intc_icr0_7305_t *ICR0; + volatile mod_intc_icr1_7305_t *ICR1; + + /* Interrupt priority registers */ + volatile mod_intc_intpri00_7305_t *INTPRI00; + volatile mod_intc_ipc_7305_t *iprs; + + /* Interrupt mask & mask clear registers */ + volatile mod_intc_intmsk00_7305_t *INTMSK00; +// volatile mod_intc_masks_7305_t *masks; + volatile mod_intc_intmskclr00_7305_t *INTMSKCLR00; +// volatile mod_intc_masks_clear_7305_t *masks_clear; + +} mod_intc_7305_t; + +#endif // _MODULE_INTERRUPTS diff --git a/src/bopti/bopti_internals.c b/src/bopti/bopti_internals.c index 0469e81..cfe5013 100644 --- a/src/bopti/bopti_internals.c +++ b/src/bopti/bopti_internals.c @@ -298,6 +298,12 @@ void getStructure(image_t *img, structure_t *s) s->height = img->height; s->data = (uint8_t *)img->data; + /* TODO This is the same as + column_count = (img->width + 15) >> 5; + end = (img->width & 0x0f); + end_bytes = (end + 7) >> 3; + */ + column_count = img->width >> 5; end = img->width & 31; end_bytes = diff --git a/src/bopti/dimage.c b/src/bopti/dimage.c index fe34859..d32c09f 100644 --- a/src/bopti/dimage.c +++ b/src/bopti/dimage.c @@ -14,8 +14,8 @@ void dimage_part(int x, int y, image_t *img, int left, int top, int width, structure_t s; command_t command; - int actual_width; - int format = img->format, i = 0; + int actual_width, actual_height; + int format = img->format; if(format != format_mono && format != format_mono_alpha) return; getStructure(img, &s); @@ -33,14 +33,17 @@ void dimage_part(int x, int y, image_t *img, int left, int top, int width, if(left + width > s.width) width = s.width - left; if(top + height > s.height) height = s.height - top; - if(x + left + width <= 0 || x > 127 || y + top + height <= 0 || y > 63) + if(x + width <= 0 || x > 127 || y + height <= 0 || y > 63 + || width <= 0 || height <= 0) return; command.top = (y < 0) ? (top - y) : top; - command.bottom = top + ((y + height > 64) ? (64 - y) : height); + actual_height = (y + height > 64) ? (64 - y) : height; + command.bottom = top + actual_height; + command.left = ((x < 0) ? (left - x) : left) >> 5; actual_width = (x + width > 128) ? (128 - x) : width; - command.right = ((left + actual_width + 31) >> 5) - 1; + command.right = (left + actual_width - 1) >> 5; command.op = bopti_op_mono; @@ -49,20 +52,14 @@ void dimage_part(int x, int y, image_t *img, int left, int top, int width, bopti_vram = display_getCurrentVRAM(); - while(format) + for(int i = 0; format; format >>= 1, i++) if(format & 1) { - if(format & 1) - { - command.x = x - left; - command.y = y - top; - command.channel = (1 << i); + command.x = x - left; + command.y = y - top; + command.channel = (1 << i); - bopti(s.data, &s, &command); - s.data += s.layer_size; - } - - format >>= 1; - i++; + bopti(s.data, &s, &command); + s.data += s.layer_size; } } diff --git a/src/bopti/gimage.c b/src/bopti/gimage.c index e570634..84dc241 100644 --- a/src/bopti/gimage.c +++ b/src/bopti/gimage.c @@ -15,8 +15,8 @@ void gimage_part(int x, int y, image_t *img, int left, int top, int width, structure_t s; command_t command; - int actual_width; - int format = img->format, i = 0; + int actual_width, actual_height; + int format = img->format; getStructure(img, &s); if(width < 0) width = s.width; @@ -33,14 +33,19 @@ void gimage_part(int x, int y, image_t *img, int left, int top, int width, if(left + width > s.width) width = s.width - left; if(top + height > s.height) height = s.height - top; - if(x + left + width <= 0 || x > 127 || y + top + height <= 0 || y > 63) + if(x + width <= 0 || x > 127 || y + height <= 0 || y > 63 + || width <= 0 || height <= 0) return; + // command.bottom is excluded... command.top = (y < 0) ? (top - y) : top; - command.bottom = top + ((y + height > 64) ? (64 - y) : height); + actual_height = (y + height > 64) ? (64 - y) : height; + command.bottom = top + actual_height; + + // ... but command.right is included. Great. command.left = ((x < 0) ? (left - x) : left) >> 5; actual_width = (x + width > 128) ? (128 - x) : width; - command.right = ((left + actual_width + 31) >> 5) - 1; + command.right = (left + actual_width - 1) >> 5; command.op = bopti_op_gray; @@ -50,20 +55,14 @@ void gimage_part(int x, int y, image_t *img, int left, int top, int width, bopti_v1 = gray_lightVRAM(); bopti_v2 = gray_darkVRAM(); - while(format) + for(int i = 0; format; format >>= 1, i++) if(format & 1) { - if(format & 1) - { - command.x = x - left; - command.y = y - top; - command.channel = (1 << i); + command.x = x - left; + command.y = y - top; + command.channel = (1 << i); - bopti(s.data, &s, &command); - s.data += s.layer_size; - } - - format >>= 1; - i++; + bopti(s.data, &s, &command); + s.data += s.layer_size; } } diff --git a/src/core/gint_sh7705.c b/src/core/gint_sh7705.c index d19924d..a79802c 100644 --- a/src/core/gint_sh7705.c +++ b/src/core/gint_sh7705.c @@ -1,9 +1,10 @@ #include #include +#include #include #include -#include <7705.h> #include +#include <7705.h> /* gint_reg() diff --git a/src/core/modules.c b/src/core/modules.c index 60cc146..827110c 100644 --- a/src/core/modules.c +++ b/src/core/modules.c @@ -24,28 +24,49 @@ mod_rtc_t RTC; static void mod_init_7705(void) { - TMU.timers[0] = (void *)0xfffffe94; - TMU.timers[1] = (void *)0xfffffea0; - TMU.timers[2] = (void *)0xfffffeac; - TMU.TSTR = (void *)0xfffffe92; - TMU.TCPR2 = (void *)0xfffffeb8; +/* + INTC._7705.iprs.IPRA = (void *)0xfffffee2; + INTC._7705.iprs.IPRB = (void *)0xfffffee4; + INTC._7705.iprs.IPRC = (void *)0xa4000016; + INTC._7705.iprs.IPRD = (void *)0xa4000018; + INTC._7705.iprs.IPRE = (void *)0xa400001a; + INTC._7705.iprs.IPRF = (void *)0xa4080000; + INTC._7705.iprs.IPRG = (void *)0xa4080002; + INTC._7705.iprs.IPRH = (void *)0xa4080004; - RTC.RCR1 = (void *)0xfffffedc; - RTC.RCR2 = (void *)0xfffffede; - RTC.time = (void *)0xfffffec0; + INTC._7705.ICR0 = (void *)0xfffffee0; + INTC._7705.ICR1 = (void *)0xa4000010; + INTC._7705.ICR2 = (void *)0xa4000012; + INTC._7705.PINTER = (void *)0xa4000014; + INTC._7705.IRR0 = (void *)0xa4000004; + INTC._7705.IRR1 = (void *)0xa4000006; + INTC._7705.IRR2 = (void *)0xa4000008; +*/ + + TMU.timers[0] = (void *)0xfffffe94; + TMU.timers[1] = (void *)0xfffffea0; + TMU.timers[2] = (void *)0xfffffeac; + TMU.TSTR = (void *)0xfffffe92; + TMU.TCPR2 = (void *)0xfffffeb8; + + RTC.RCR1 = (void *)0xfffffedc; + RTC.RCR2 = (void *)0xfffffede; + RTC.time = (void *)0xfffffec0; } static void mod_init_7305(void) { - TMU.timers[0] = (void *)0xa4490008; - TMU.timers[1] = (void *)0xa4490014; - TMU.timers[2] = (void *)0xa4490020; - TMU.TSTR = (void *)0xa4490004; - TMU.TCPR2 = NULL; +// INTC._7305.iprs = (void *)0xa4080000; - RTC.RCR1 = (void *)0xa413fedc; - RTC.RCR2 = (void *)0xa413fede; - RTC.time = (void *)0xa413fec0; + TMU.timers[0] = (void *)0xa4490008; + TMU.timers[1] = (void *)0xa4490014; + TMU.timers[2] = (void *)0xa4490020; + TMU.TSTR = (void *)0xa4490004; + TMU.TCPR2 = NULL; + + RTC.RCR1 = (void *)0xa413fedc; + RTC.RCR2 = (void *)0xa413fede; + RTC.time = (void *)0xa413fec0; } /* diff --git a/src/stdlib/stdlib_rand.c b/src/stdlib/stdlib_rand.c index 9cd7765..6afcc10 100644 --- a/src/stdlib/stdlib_rand.c +++ b/src/stdlib/stdlib_rand.c @@ -1,6 +1,7 @@ #include +#include -static unsigned int seed = 1; +static uint32_t seed = 1; void srand(unsigned int new_seed) { @@ -9,7 +10,10 @@ void srand(unsigned int new_seed) int rand(void) { + seed = 16807 * seed; + uint32_t top = ((uint32_t)1 << 31) - 1; + while(seed >= top) seed -= top; /* TODO Or maybe seed = (16807 * seed) % ((1 << 31) - 1); */ - seed = seed * 1103515245 + 12345; +// seed = seed * 1103515245 + 12345; return seed & 0x7fffffff; } diff --git a/version b/version index fa6bbd4..7409007 100644 --- a/version +++ b/version @@ -1 +1 @@ -beta-0.9-349 +beta-0.9-352