# HG changeset patch # User John Tsiombikas # Date 1519385377 -7200 # Node ID 995d42b339747b6a49018f9c595524ba9fecc95c # Parent 555b986cc4208b1e47eeeef4de5cf13a77ba52bb serial output diff -r 555b986cc420 -r 995d42b33974 README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Fri Feb 23 13:29:37 2018 +0200 @@ -0,0 +1,27 @@ +Amiga floppy boot test +---------------------- +Bootblock code in src/boot/boot.s uses the Amiga exec in ROM to load the +flat binary image from from the first N sectors to address 0x10000, and jumps +there. The size of the binary is patched immediately before the first +instruction of the boot code by tools/mk_adf.py. + +Linkscript puts code from the .startup segment (src/startup.s) at the load +address, and it starts by setting the trap0 exception vector to point to the +next instruction and executes a trap 0, to enter supervisor mode and take +complete control of the system. Then it clears .bss, sets the stack and calls +the C main function. + +A few words about the graphics hack +----------------------------------- +The IFS fractal is calculated in 16.16 fixed point, using a mersenne twister +random number generator (src/rng.c) for picking an IFS transformation to do each +time. Two bitplanes are enabled both pointing to the same IFS pixel buffer, with +a few scanlines offset and a different per-pixel scroll (data fetch delay) in +BPLCON1. The palette is set up in a way to give priority to bitplane 0, i.e. use +green for pixels with bit 0 set, and use a shadow color for pixels which have +only bit 1 set. This gives the illusion of a shadow layer. + +Serial debug output +------------------- +Serial comm needs RTS/CTS (hardware) flow control. + stty 38400 crtscts cs8 -parenb -ixon -ixoff raw -iutf8 -F /dev/ttyUSB0 diff -r 555b986cc420 -r 995d42b33974 src/hwregs.h --- a/src/hwregs.h Thu Feb 22 14:46:32 2018 +0200 +++ b/src/hwregs.h Fri Feb 23 13:29:37 2018 +0200 @@ -345,6 +345,10 @@ #define REG_COPJMP1 REG(REGN_COPJMP1) #define REG_COPJMP2 REG(REGN_COPJMP2) +#define REG_SERPER REG(REGN_SERPER) +#define REG_SERDATR REG(REGN_SERDATR) +#define REG_SERDAT REG(REGN_SERDAT) + /* ------ bits ------- */ #define SETBITS(x) ((x) | 0x8000) #define CLRBITS(x) (x) @@ -425,4 +429,16 @@ #define CIAA_PA_FIR0 0x40 #define CIAA_PA_FIR1 0x80 +enum { + SERDATR_STOP8 = 0x0100, + SERDATR_STOP9 = 0x0200, + SERDATR_RXD = 0x0800, + SERDATR_TSRE = 0x1000, + SERDATR_TBE = 0x2000, + SERDATR_RBF = 0x4000, + SERDATR_OVRUN = 0x8000 +}; + +#define ADKCON_UARTBRK 0x0800 + #endif /* HWREGS_H_ */ diff -r 555b986cc420 -r 995d42b33974 src/main.c --- a/src/main.c Thu Feb 22 14:46:32 2018 +0200 +++ b/src/main.c Fri Feb 23 13:29:37 2018 +0200 @@ -2,9 +2,14 @@ #include "intr.h" #include "copper.h" #include "rng.h" +#include "serial.h" -#define BPLSZ (320 / 8 * 256) -static unsigned char fb0[BPLSZ]; +#define SCR_W 336 +#define SCR_H 256 +#define HMOD ((SCR_W - 320) / 8) + +#define BPLSZ (SCR_W / 8 * SCR_H) +static unsigned char fb0[BPLSZ + 3 * SCR_W]; extern uint16_t dbgval; @@ -29,8 +34,7 @@ : "a0", "d0") static uint32_t coplist[] = { - COPPER_MOVE(REGN_BPL1PTH, 0), - COPPER_MOVE(REGN_BPL1PTL, 0), + 0, 0, 0, 0, /* placeholder of bitplane pointer setting */ COPPER_MOVE(REGN_COLOR0, 0x234), COPPER_VWAIT(15), @@ -52,22 +56,31 @@ { int32_t x = 0, y = 0; + ser_init(38400); + ser_print("Amiga debug console initialized\n"); + REG_INTENA = SETBITS(INTEN_VERTB | INTEN_MASTER); REG_DMACON = CLRBITS(DMA_ALL); - REG_BPLCON0 = BPLCON0_COUNT(1) | BPLCON0_COLOR; - REG_BPLCON1 = 0; + REG_BPLCON0 = BPLCON0_COUNT(2) | BPLCON0_COLOR; + REG_BPLCON1 = 0xfa; + REG_BPL1MOD = HMOD - 2; + REG_BPL2MOD = HMOD - 2; REG_DIWSTART = 0x2981; REG_DIWSTOP = 0x29c1; - REG_DDFSTART = 0x38; + REG_DDFSTART = 0x30; REG_DDFSTOP = 0xd0; REG_COLOR0 = 0x235; - REG_COLOR1 = 0x2f5; + REG_COLOR1 = 0x2e5; + REG_COLOR2 = 0x113; + REG_COLOR3 = 0x2e5; wait_vblank(); - coplist[0] = COPPER_MOVE(REGN_BPL1PTH, (uint32_t)fb0 >> 16); - coplist[1] = COPPER_MOVE(REGN_BPL1PTL, (uint32_t)fb0); + coplist[0] = COPPER_MOVE(REGN_BPL1PTH, ((uint32_t)fb0 + 3 * SCR_W / 8) >> 16); + coplist[1] = COPPER_MOVE(REGN_BPL1PTL, (uint32_t)fb0 + 3 * SCR_W / 8); + coplist[2] = COPPER_MOVE(REGN_BPL2PTH, (uint32_t)fb0 >> 16); + coplist[3] = COPPER_MOVE(REGN_BPL2PTL, (uint32_t)fb0); REG32_COP1LC = (uint32_t)coplist; REG_COPJMP1 = 0; @@ -105,11 +118,15 @@ py = 128 - (x >> 11); if(py >= 0) { - pptr = fb0 + (py * 320 + px) / 8; + pptr = fb0 + (py * SCR_W + px) / 8; *pptr = *pptr | (0x80 >> (px & 7)); } - wait_vblank(); + if((REG_CIAA_PORTA & CIAA_PA_FIR0) == 0) { + ser_print("restarting fractal\n"); + wait_vblank(); + clear_bpl(fb0); + } } return 0; diff -r 555b986cc420 -r 995d42b33974 src/serial.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/serial.c Fri Feb 23 13:29:37 2018 +0200 @@ -0,0 +1,48 @@ +#include "hwregs.h" +#include "serial.h" + +#define CLK 3546895 +#define BVAL(b) (CLK / (b) - 1) + +static inline uint16_t baudval(int baud) +{ + switch(baud) { + case 110: return BVAL(110); + case 300: return BVAL(300); + case 600: return BVAL(600); + case 1200: return BVAL(1200); + case 2400: return BVAL(2400); + case 4800: return BVAL(4800); + case 9600: return BVAL(9600); + case 14400: return BVAL(14400); + case 19200: return BVAL(19200); + case 38400: return BVAL(38400); + case 57600: return BVAL(57600); + case 115200: return BVAL(115200); + default: + break; + } + return BVAL(baud); +} + +void ser_init(int baud) +{ + REG_SERPER = baudval(baud) & 0x7fff; +} + +/* +void ser_putchar(int c) +{ + REG_SERDAT = ((uint16_t)c & 0xff) | 0x100; +} +*/ + +void ser_print(const char *s) +{ + while(*s) { + if(*s == '\n') { + ser_putchar('\r'); + } + ser_putchar(*s++); + } +} diff -r 555b986cc420 -r 995d42b33974 src/serial.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/serial.h Fri Feb 23 13:29:37 2018 +0200 @@ -0,0 +1,21 @@ +#ifndef SERIAL_H_ +#define SERIAL_H_ + +#include "hwregs.h" + +/* dff030 is REG_SERDAT + * dff018 is REG_SERDATR + * bit 13 of SERDATR is TBE (transmit buffer empty) + */ +#define ser_putchar(c) \ + asm volatile( \ + "or.w #0x100, %0\n\t" \ + "0: btst #13, 0xdff018\n\t" \ + "beq 0b\n\t" \ + "move.w %0, 0xdff030\n\t" \ + :: "d"((int16_t)c)) + +void ser_init(int baud); +void ser_print(const char *s); + +#endif /* SERIAL_H_ */