diff --git a/README.md b/README.md index db3f98f..a58bce0 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ Completed: In progress: -* context switching for simple multitasking * a unit test suite to ensure each instruction is correct * a proof-of-concept application +* “simple” multitasking? The meat of the project: diff --git a/common/Makefile b/common/Makefile index 3993c6f..ce92777 100644 --- a/common/Makefile +++ b/common/Makefile @@ -11,7 +11,7 @@ page6.obj: rom.h macros.h globals.h page6.src xa -C -M page6.asm -l page6.lbl -o page6.obj globals.h: common.obj - grep -E -v '^(_|CMN_CD|CMN_DT|FN_FX)' common.lbl | sed -e 's/, 0, 0x0000//' -e 's/, / = /' -e 's/ 0x/ \x24/' > globals.h + grep -E -v '^(_|CMN_CD|CMN_DT|FN_FX|CODE|DATA)' common.lbl | sed -e 's/, 0, 0x0000//' -e 's/, / = /' -e 's/ 0x/ \x24/' > globals.h clean: rm -f globals.h page6.asm common.obj page6.obj common.lbl page6.lbl system.obj diff --git a/common/common.asm b/common/common.asm index 7dc531d..4c1de7f 100644 --- a/common/common.asm +++ b/common/common.asm @@ -2,6 +2,7 @@ #include "common.h" ; ROM code header + .BYTE CODE .WORD CMN_CD, _END_CMN_CD - CMN_CD ; beginning of ROM code @@ -976,14 +977,13 @@ _CPR .( ; CPR pq 0c pq Rp <- Rq - copy register _INILS .( ; common initialization for LDI and SVI JSR _CPYI1 ; copy q to I1 - CLC ; shift to get an address - ROR _I1+3 - ROR _I1+2 - ROR _I1+1 - CLC - ROR _I1+3 - ROR _I1+2 - ROR _I1+1 + CLC ; add the allocated memory offset + LDA _ARL + ADC _I1+1 + STA _I1+1 + LDA _ARH + ADC _I1+2 + STA _I1+2 RTS .) @@ -1054,6 +1054,7 @@ _3 ORA _F _END_CMN_CD ; ROM data header + .BYTE DATA .WORD CMN_DT, _END_CMN_DT - CMN_DT ; beginning of ROM data @@ -1071,6 +1072,7 @@ MNS_1 .BYTE $00, $fc, $ff, $ff _END_CMN_DT ; 6502 addresses + .BYTE DATA .WORD ADDR, 6 ; 6502 NMI, Reset and IRQ diff --git a/common/common.h b/common/common.h index ca1deae..558b26d 100644 --- a/common/common.h +++ b/common/common.h @@ -46,9 +46,6 @@ ; SVI pq 0e pq (int(Rp)) <- Rq - save indirect via allocated memory offset ; CMR pq 0f pq F <- Rp <=> Rq - compare registers -; 32 bytes in page zero for memory map allocation -_MAP = _R0 - 256 / 8 - ; 40 bytes in page zero for common registers _R0 = $100 - 4 * (10 + 10) _R1 = _R0 + 4 @@ -69,8 +66,8 @@ _I3 = _I2 + 4 _I4 = _I3 + 4 _I5 = _I4 + 4 _I6 = _I5 + 4 ; register I6 maintains common status -_I7 = _I6 + 4 ; register I7 maintains locations of process and allocated memory -_I8 = _I7 + 4 ; register I8 maintains process information for context switching +_I7 = _I6 + 4 ; register I7 maintains locations of code and allocated memory +_I8 = _I7 + 4 ; register I8 is reserved for future use, e.g. context switching _I9 = _I8 + 4 ; register I9 saves/restores processor status ; register I6 maintains common status @@ -91,19 +88,15 @@ _F_N = 32 ; if Rr < 0.0 (after TST) _F_O = 64 ; if overflow (after arithmetic operations) _F_U = 128 ; if underflow (after arithmetic operations) -; register I7 maintains locations of code and allocated real memory addresses +; register I7 maintains locations of code and allocated memory _CRL = _I7 ; code low and high bytes _CRH = _CRL + 1 _ARL = _CRH + 1 ; allocated low and high bytes _ARH = _ARL + 1 -_CR = _CRL ; code real memory address -_AR = _ARL ; allocated real memory address +_CR = _CRL ; code memory address +_AR = _ARL ; allocated memory address -; register I8 maintains process information for context switching -_PSO = _I8 ; offset to running processes table -_PSF = _PSO + 1 ; initial running process status PPPCCCLF -_PST = _PSF + 1 ; current process status -_PSI = _PST + 1 ; process stack index to save/restore +; register I8 is reserved for future use, e.g. context switching ; register I9 saves/restores processor status ; (dd cc bb aa) aa: accumulator, bb: index X, cc: index Y, dd: processor status @@ -116,31 +109,11 @@ _PS = _IDY + 1 ; saved processor status to restore ; using some of page two for register stack _RS = $200 ; register stack -_RSS = _R0 ; register stack size +_RSS = FN_FX - _RS ; register stack size -; for context switching, _R0 to _RS + _RSS - 1 needs to be saved and restored -; this should comprise two pages or 512 bytes +; system & user functions -; the following are common process table and system & user functions - -; process information in the middle of page two -_RP = _RS + _RSS ; running processes table -_RPS = FN_FX - _RP ; running process table size - -; process information indices -_RPV_I = 0 ; 4 bytes virtual memory address -_RPR_I = _RPV_I + 4 ; 2 bytes real memory address -_RPS_I = _RPR_I + 2 ; 1 byte size in pages: code + allocated memory + context switching -_RPF_I = _RPS_I + 1 ; 1 byte status PPPCCCLF: P priority / C counter / L loaded / F finished - -; bits for status -_S_L = 1 ; if program is loaded in memory -_S_F = 2 ; if program is finished - -_RPE = _RPF_I + 1 ; size of running process entry -_RPL = _RPS / _RPE ; number of running processes limit - -; last 32 bytes of page two +; 32 bytes at the end of page two FN_FX = $300 - 2 * 16 ; list of system and user functions ; function constants @@ -183,4 +156,8 @@ _MSK_R = %00111100 ; mask for registers _MSK_T = (_F_Z + _F_P + _F_N) ^ $ff ; mask for TST _MSK_C = (_F_E + _F_G + _F_L) ^ $ff ; mask for CMP +; section identifiers +CODE = %10101010 ; to indicate CODE section +DATA = %01010101 ; to indicate DATA section + #endif /* __COMMON_H */ diff --git a/common/macros.h b/common/macros.h index 5dad70a..a614151 100644 --- a/common/macros.h +++ b/common/macros.h @@ -78,7 +78,7 @@ #define EXT(f) .BYTE _EXT_C + (f) ; header, begin and end of blocks -#define HDR(a) .WORD a, _END_##a - a:* = * - 4:a .( +#define HDR(t, a) .BYTE t:.WORD a, _END_##a - a:* = * - 5:a .( #define BGN(a) a .( #define END(a) .):_END_##a diff --git a/common/page6.src b/common/page6.src index fd4e734..2b404fc 100644 --- a/common/page6.src +++ b/common/page6.src @@ -4,12 +4,16 @@ * = $600 -HDR(DEMO) +HDR(CODE, DEMO) CMN SET(R0, 9.4662) + SET(R1, 0) + SVI(R1, R0) PSH(R0) BRS(FACTORIAL) POP(R4) + SET(R5, 0) + LDI(R6, R5) ESC BRK @@ -29,4 +33,9 @@ END(FACTORIAL) END(DEMO) -SVD_T .BYTE 0, 0, 0, 0 +HDR(DATA, WORKING) + +ONE .BYTE 0, 0, 0, 0 +TWO .BYTE 0, 0, 0, 0 + +END(WORKING) diff --git a/emulator/main.c b/emulator/main.c index 9ae2281..564935a 100644 --- a/emulator/main.c +++ b/emulator/main.c @@ -7,6 +7,7 @@ #define _R8 0xd0 #define _I0 0xd8 #define _I6 0xf0 +#define _I7 0xf4 #define _I8 0xf8 /* (dd cc bb aa) aa: index for register stack RS / ccbb: program counter PC / dd: flags F UONPZLGE */ @@ -16,6 +17,17 @@ #define _F _PCH + 1 /* flags */ #define _PC _PCL /* program counter */ +/* register I7 maintains locations of code and allocated memory */ +#define _CRL _I7 /* code low and high bytes */ +#define _CRH _CRL + 1 +#define _ARL _CRH + 1 /* allocated low and high bytes */ +#define _ARH _ARL + 1 +#define _CR _CRL /* code memory address */ +#define _AR _ARL /* allocated memory address */ + +#define CODE 0xaa /* to indicate CODE section */ +#define DATA 0x55 /* to indicate DATA section */ + uint8_t memory[65536]; uint8_t read6502(uint16_t address) { @@ -48,22 +60,34 @@ void hook() { int main() { - uint8_t header[4]; + uint8_t header[5]; while (fread(header, sizeof(header), 1, stdin)) { - uint16_t index = header[0] + (header[1] << 8); - uint16_t length = header[2] + (header[3] << 8); + uint8_t type = header[0]; + uint16_t index = header[1] + (header[2] << 8); + uint16_t length = header[3] + (header[4] << 8); - printf("\n%04x %u\n", index, length); + printf("\n%x %04x %u\n", type, index, length); if (fread(memory + index, length, 1, stdin)) { - memory[_PCL] = header[0]; - memory[_PCH] = header[1]; + switch (type) { + case CODE: + memory[_CRL] = header[1]; + memory[_CRH] = header[2]; + break; + case DATA: + memory[_ARL] = header[1]; + memory[_ARH] = header[2]; + break; + } } } + memory[_PCL] = memory[_CRL]; + memory[_PCH] = memory[_CRH]; + hookexternal(hook); reset6502();