National Semiconductor's HPC46003 (строим комп nedoPC-46)

Другие микроконтроллеры и микропроцессоры, не попавшие в предыдущие разделы

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

National Semiconductor's HPC46003 (строим комп nedoPC-46)

Post by Shaos »

Блуждая по www.jameco.com наткнулся на безромный 16-битный микроконтроллер от National Semiconductor 80х-90х под названием HPC46003V20 в корпусе PLCC68 за 15 бабосов - не глядя купил два :)

Image

К нему можно цеплять внешнюю память до 64К (как 8-битную, так и 16-битную).
Бортовое ОЗУ - 256 байт (находится в начале ОБЩЕГО адресного пространства, причём вместе с регистрами).
Внутри есть умножитель 16x16 и делитель 32x16.
Есть полнодуплексный UART и ещё четыре таймера.
Частота 20 МГц при которой обещается 200 нс для самой быстрой инструкции (4 такта на инструкцию?).

P.S. Наименование чипа формируется следующим образом: HPCx60y3Vz0 где
x=1 для Military (-55C...+125C)
x=2 для Automotive (-40C...+105C)
x=3 для Industrial (-40C...+85C)
x=4 для Commercial (0C...+70C)
y=0 означает ROMless
y=8 означает 8KB ROM
z=2 это 20МГц
z=3 это 30МГц
но я везде вижу только Commercial ROMless 20MHz HPC46003V20

P.P.S. Регистры располагаются в первых 512 ячейках памяти, вместе с бортовым ОЗУ пользователя, регистрами управления и портами:

Code: Select all

#0000...#00BF - первая часть пользовательского ОЗУ (192 байта);
#00C0 - регистр PSW (флаги);
#00C4,#00C5 - 16-битный регистр SP (байты упорядочены как little endian);
#00C6,#00C7 - 16-битный регистр PC (байты упорядочены как little endian);
#00C8,#00C9 - 16-битный регистр A (байты упорядочены как little endian);
#00CA,#00CB - 16-битный регистр K (байты упорядочены как little endian);
#00CC,#00CD - 16-битный регистр B (байты упорядочены как little endian);
#00CE,#00CF - 16-битный регистр X (байты упорядочены как little endian);
#00D0...#01BF - порты и регистры управления;
#01C0...#01FF - вторая часть пользовательского ОЗУ (64 байта);
#0200...#FFFF - внешнаяя память, причём в конце находятся вектора перехода:

#FFFE,#FFFF - адрес, куда передаётся управление по RESET (байты упорядочены как little endian);
#FFFC,#FFFD - адрес немаскируемого прерывания по фронту на входе I1;
#FFFA,#FFFB - адрес прерывания по входу I2;
#FFF8,#FFF9 - адрес прерывания по входу I3;
#FFF6,#FFF7 - адрес прерывания по входу I4;
#FFF4,#FFF5 - адрес прерывания по переполнению внутренних таймеров;
#FFF2,#FFF3 - адрес прерывания по окончанию передачи/приёма через UART или по входу EXUI;
#FFF0,#FFF1 - адрес прерывания по входу EI;
#FFD0...#FFEF - таблица для быстрого вызова 16 подпрограмм командой JSRP.
P.P.P.S. Восстановленная по листингам из Application Notes система команд:

Code: Select all

#00 - CLR A (обнулить 16-битный регистр A)
#01 - COMP A (инвертировать каждый бит 16-битного регистра A)
#02 - SC (SET C - установить флаг C)
#03 - RC (RESET C - сбросить флаг C)
#04 - INC A (инкрементировать 16-битный регистр A)
#05 - DEC A (декрементировать 16-битный регистр A)
#06 - IFNC (выполнить следующую команду, если C=0)
#07 - IFC (выполнить следующую команду, если C=1)
#08 - SBIT [B].0 ?
#09 - SBIT [B].1 ?
#0A - SBIT [B].2 ?
#0B - SBIT [B].3 ?
#0C - SBIT [B].4 ?
#0D - SBIT [B].5 ?
#0E - SBIT [B].6 ?
#0F - SBIT [B].7 ?
#10 - IFBIT [B].0 ?
#11 - IFBIT [B].1 ?
#12 - IFBIT [B].2 ?
#13 - IFBIT [B].3 ?
#14 - IFBIT [B].4 ?
#15 - IFBIT [B].5 ?
#16 - IFBIT [B].6 ?
#17 - IFBIT [B].7 (если бит 7 из байта по 16-битному адресу из B установлен, то выполнить следующую инструкцию)
#18 - RBIT [B].0 ?
#19 - RBIT [B].1 ?
#1A - RBIT [B].2 ?
#1B - RBIT [B].3 ?
#1C - RBIT [B].4 ?
#1D - RBIT [B].5 ?
#1E - RBIT [B].6 ?
#1F - RBIT [B].7 ?
#20 - JSRP 0
#21 - JSRP 1
#22 - JSRP 2
#23 - JSRP 3
#24 - JSRP 4
#25 - JSRP 5
#26 - JSRP 6
#27 - JSRP 7
#28 - JSRP 8
#29 - JSRP 9
#2A - JSRP 10
#2B - JSRP 11
#2C - JSRP 12
#2D - JSRP 13
#2E - JSRP 14
#2F - JSRP 15
#30 X - JSR +X+2 (вызов подпрограммы по смещению X от следующей команды)
#31 X - JSR +X+258 (вызов подпрограммы по смещению #0100+X от следующей команды)
#32 X - JSR +X+514 (вызов подпрограммы по смещению #0200+X от следующей команды?)
#33 X - JSR +X+770 (вызов подпрограммы по смещению #0300+X от следующей команды?)
#34 X - JSR -X (вызов подпрограммы по смещению назад X от текущей команды?)
#35 X - JSR -X-256 (вызов подпрограммы по смещению назад #0100+X от текущей команды)
#36 X - JSR -X-512 (вызов подпрограммы по смещению назад #0200+X от текущей команды?)
#37 X - JSR -X-768 (вызов подпрограммы по смещению назад #0300+X от текущей команды?)
#38 ? - RBIT X ?
#39 ? - SBIT X ?
#3A ? - IFBIT X ?
#3B - SWAP A (поменять нибблы в 16-битном регистре A, причём старший байт получает две копии старшего ниббла младшего байта?)
#3C - RET (возврат из подрограммы)
#3D - RETSK (возврат и пропуск следующей команды)
#3E - RETI (возврат из прерывания)
#3F X - POP X (снять со стека слово и запомнить его в слове памяти по короткому адресу X)
#40 - JMP +1 (NOP - просто переход на следующий байт)
#41 - JMP +2 (смещение 1 вперёд от следующего байта)
#42 - JMP +3
#43 - JMP +4
#44 - JMP +5
#45 - JMP +6
#46 - JMP +7
#47 - JMP +8
#48 - JMP +9
#49 - JMP +10
#4A - JMP +11
#4B - JMP +12
#4C - JMP +13
#4D - JMP +14
#4E - JMP +15
#4F - JMP +16
#50 - JMP +17
#51 - JMP +18
#52 - JMP +19
#53 - JMP +20
#54 - JMP +21
#55 - JMP +22
#56 - JMP +23
#57 - JMP +24
#58 - JMP +25
#59 - JMP +26
#5A - JMP +27
#5B - JMP +28
#5C - JMP +29
#5D - JMP +30
#5E - JMP +31
#5F - JMP +32
#60 - JMP 0 (HLT - зацикливание на текущей команде)
#61 - JMP -1 (смещение 1 назад от текущего адреса)
#62 - JMP -2
#63 - JMP -3
#64 - JMP -4
#65 - JMP -5
#66 - JMP -6
#67 - JMP -7
#68 - JMP -8
#69 - JMP -9
#6A - JMP -10
#6B - JMP -11
#6C - JMP -12
#6D - JMP -13
#6E - JMP -14
#6F - JMP -15
#70 - JMP -16
#71 - JMP -17
#72 - JMP -18
#73 - JMP -19
#74 - JMP -20
#75 - JMP -21
#76 - JMP -22
#77 - JMP -23
#78 - JMP -24
#79 - JMP -25
#7A - JMP -26
#7B - JMP -27
#7C - JMP -28
#7D - JMP -29
#7E - JMP -30
#7F - JMP -31
#80 - PREFIX Dir-Dir
#81 - PREFIX Dir-Dir
#82 X Y #F8 - ADD Y,X (привавить байт X к слову по короткому адресу X и сохранить результат там же) PREFIX Imm-Dir
#83 X Y Z #8B/#AB - LD 256*Y+Z,X (записать байт X в байт с адресом YZ если суффикс #8B или в слово с адресом YZ если суффикс #AB) PREFIX Imm-Dir
#84 - PREFIX Dir-Dir
#85 - PREFIX Dir-Dir
#86 - PREFIX Imm-Dir
#87 W X Y Z #AB - LD 256*Y+Z,256*W+X (записать слово WX в слово памяти с адресом YZ) PREFIX Imm-Dir
#88 X - LD A,X (прочитать один байт по короткому адресу X и сохранить его в регистре A)
#89 X - INC X (инкрементировать один байт по короткому адресу X)
#8A X - DECSZ X (декрементировать один байт по короткому адресу X и пропустить следующую команду, если результат равен нулю)
#8B X - ST A,X (сохранить содержимое младшего байта регистра A в байте по короткому адресу X, превращается в LD с префиксами Dir-Dir и Imm-Dir)
#8C X Y - LD Y,X (записать содержимое байта памяти с коротким адресом X в байт памяти с коротким адресом Y)
#8D X Y - LD BK,X,Y (записать в 16-битный регистр B байт X и в 16-битный регистр K байт Y)
#8E Y - X A,Y (поменять местами содержимое регистра A и байта по короткому адресу Y)
#8F - XInderect?
#90 X - LD A,X (прочитать 16-битное слово по короткому адресу X и сохранить его в регистре A)
#91 X - LD K,X (записать один байт X в 16-битный регистр K)
#92 X - LD B,X (записать один байт X в 16-битный регистр B)
#93 Y - LD X,Y (записать один байт Y в 16-битный регистр X)
#94 X - JMP +X+2 (X это смещение вперёд от следующей команды)
#95 X - JMP -X (X это смещение назад от текущей команды)
#96 X Y - PREFIX-Direct X Y (выполнить однобайтовую команду Y где вместо [B] нужно использовать ячейку по короткому адресу X)
#97 X Y - LD Y,X (сохранить байт X в 8-битной ячейке с адресом Y)
#98 X - ADD A,X (прибавить к 16-битному регистру A байт X?)
#99 X - AND A,X (побитная операция И 16-битного регистра A и байта X)
#9A X - OR A,X (побитная операция ИЛИ 16-битного регистра A и байта X?)
#9B X - XOR A,X (побитная операция ИСКЛ.ИЛИ 16-битного регистра A и байта X?)
#9C X - IFEQ A,X (выполнить следующую инструкцию, если A равно байту X?)
#9D X - IFGT A,X (выполнить следующую инструкцию, если A больше байта X?)
#9E X - MULT A,X (беззнаково умножить A на байт X?)
#9F X - DIV A,X (беззнаково разделить A на байт X?)
#A0 X Y #F8 - ADD Y,X (сложить слово по короткому адресу Y и слово по короткому адресу X, сохранить результат по короткому адресу Y) PREFIX Dir-Dir
#A1 - PREFIX Dir-Dir?
#A2 - PREFIX Index?
#A3 - N/A
#A4 X Y Z #AB - LD Z,256*X+Y (сохранить слово взятое по адресу XY в слово с коротким адресом Z) PREFIX Dir-Dir
#A5 - PREFIX Dir-Dir?
#A6 - PREFIX Index?
#A7 W X Y Z - LD BK,256*W+X,256*Y+Z (сохранить 2 слова в 16-битных регистрах B и K) 
#A8 X - LD A,X (сохранить слово по короткому адресу X в 16-битном регистре A)
#A9 X - INC X (инкрементировать 16-битное слово по короткому адресу X)
#AA X - DECSZ X (декрементировать 16-битное слово по короткому адресу X и пропустить следующую команду, если результат равен нулю)
#AB X - ST A,X (сохранить содержимое 16-битного регистра A в слове по короткому адресу X)
#AC X Y - LD Y,X (сохранить байт X в 16-битной ячейке с адресом Y)
#AD X Y - PREFIX-Indicrect X Y (выполнить команду Y где вместо ? используется слово по короткому адресу X? Y=#F8 -> ADD A,X; Y=#A8 -> LD A,X; Y=#AB -> ST A,X) 
#AE Y - X A,Y (поменять местами содержимое 16-битного регистра A и слова по короткому адресу Y)
#AF X - PUSH X (прочитать слово по короткому адресу X и положить его на стек)
#B0 X Y - LD A,256*X+Y (записать 16-битное слово XY в регистр A)
#B1 X Y - LD K,256*X+Y (записать 16-битное слово XY в регистр K)
#B2 X Y - LD B,256*X+Y (записать 16-битное слово XY в регистр B)
#B3 Y Z - LD X,256*Y+Z (записать 16-битное слово YZ в регистр X)
#B4 X Y - JMP +256*X+Y (длинный относительный переход со смещением XY)
#B5 X Y - JSRL XY?
#B6 X Y Z - PREFIX-Direct 256*X+Y Z (выполнить однобайтовую команду Z, но вместо регистра ? надо использовать слово 256*X+Y)
#B7 X Y Z - LD Z,256*X+Y (записать по короткому адресу Z слово XY) 
#B8 X Y - ADD A,256*X+Y (увеличить содержимое 16-битного регистра A на XY)
#B9 X Y - AND A,256*X+Y (побитная операция И 16-битного регистра A и 16-битного числа XY)
#BA X Y - OR A,256*X+Y (побитная операция ИЛИ 16-битного регистра A и 16-битного числа XY) 
#BB X Y - XOR A,256*X+Y (побитная операция ИСКЛ.ИЛИ 16-битного регистра A и 16-битного числа XY) 
#BC X Y - IFEQ A,256*X+Y (выполнить следующую команду, если 16-битный регистр A равен 16-битному числу XY) 
#BD X Y - IFGT A,256*X+Y (выполнить следующую команду, если 16-битный регистр A больше 16-битного числа XY)
#BE X Y - MULT A,256*X+Y (беззнаково умножить содержимое 16-битного регистра A на XY)
#BF X Y - DIV A,256*X+Y (беззнаково разделить содержимое 16-битного регистра A на XY, остаток положить в X)
#C0 - LDS A,[B+].B (прочитать в A байт по адресу из 16-битного регистра B, инкрементировать B и пропустить следующую команду, если B>K)?
#C1 - XS A,[B+].B (поменять местами байты A и [B], инкрементировать B и пропустить следующую инстукцию если B>K)?
#C2 - LDS A,[B-].B (прочитать в A байт по адресу из 16-битного регистра B, декрементировать B и пропустить следующую команду, если B<K)?
#C3 - XS A,[B-].B (поменять местами байты A и [B], декрементировать B и пропустить следующую инстукцию если B<K)?
#C4 - LD A,[B].B (сохранить в 16-битном регистре A содержимое байта по адресу из 16-битного регистра B)?
#C5 - X A,[B].B (поменять местами байты A и [B])?
#C6 - ST A,[B].B (сохранить байт из A в [B])?
#C7 - SHR A (сдвинуть 16-битный регистр A вправо)?
#C8 - ADC A,[B].B (сложить содержимое байта с адресом из B с регистром A с учётом флага переноса C)?
#C9 - DADC A,[B].B (десятично сложить содержимое байта с адресом из B с регистром A с учётом флага переноса C)?
#CA - DSUBC A,[B].B (десятично вычесть содержимое байта с адресом B из регистра A с учётом переноса C)?
#CB - SUBC A,[B].B (вычесть содержимое байта с адресом B из регистра A с учётом переноса C)?
#CC - JID (передать управление на команду с адресом A+1)?
#CD - N/A
#CE - N/A
#CF - DIVD A,[B].B (беззнаково разделить двойное число X:A на байт из [B], остаток положить в X)? 
#D0 - LD A,[X+].B (сохранить в 16-битном регистре A содержимое байта памяти с адресом [X], увеличив затем X на 1)
#D1 - X A,[X+].B (поменять местами содержимое 16-битного регистра A и байта памяти с адресом X, увеличив затем X на 1)
#D2 - LD A,[X-].B (сохранить в 16-битном регистре A содержимое байта памяти с адресом [X], уменьшив затем X на 1)
#D3 - X A,[X-].B (поменять местами содержимое 16-битного регистра A и байта памяти с адресом X, уменьшив затем X на 1)
#D4 - LD A,[X] (сохранить в 16-битном регистре A содержимое байта памяти с адресом [X])
#D5 - X A,[X].B (поменять местами содержимое 16-битного регистра A и байта памяти с адресом X)
#D6 - ST A,[X].B (сохранить содержимое регистра A в байте пемяти с адресом X)
#D7 - RRC A (повернуть 16-битный регистр A вправо через флаг C)? 
#D8 - ADD A,[B].B (сложить A и байт по 16-битному адресу из регистра B и сохранить результат в A)?
#D9 - AND A,[B].B (побитная операция И 16-битного регистра A и байта по адресу, хранящемуся в регистре B)?
#DA - OR A,[B].B (побитная операция ИЛИ 16-битного регистра A и байта по адресу, хранящемуся в регистре B)?
#DB - XOR A,[B].B (побитная операция ИСКЛ.ИЛИ 16-битного регистра A и байта по адресу, хранящемуся в регистре B)?
#DC - IFEQ A,[B].B (выполнить следующую команду, если 16-битный регистр A равен байту из памяти по адресу из регистра B) 
#DD - IFGT A,[B].B (выполнить следующую команду, если 16-битный регистр A больше байта из памяти по адресу из регистра B)
#DE - MULT A,[B].B (беззнаково умножить A и байт по 16-адресу из регистра B и сохранить результат в регистре A и старшее слово в X)
#DF - DIV A,[B].B (беззнаково разделить A на байт по 16-адресу из регистра B и сохранить результат в регистре A и остаток в X)
#E0 - LDS A,[B+].W (записать в A слово из [B], увеличить B на 2 и пропустить следующую инструкцию, если B>K)?
#E1 - XS A,[B+].W (поменять местами A и [B], увеличить B на 2 и пропустить следующую инстукцию если B>K)
#E2 - LDS A,[B-].W (записать в A слово из [B], уменьшить B на 2 и пропустить следующую инструкцию, если B>K)?
#E3 - XS A,[B-].W (поменять местами A и [B], уменьшить B на 2 и пропустить следующую инстукцию если B>K)?
#E4 - LD A,[B].W (записать в A слово из [B])
#E5 - X A,[B].W (поменять местами A и [B])
#E6 - ST A,[B].W (сохранить A в [B])
#E7 - SHL A (сдвинуть 16-битный регистр A влево)
#E8 - ADC A,[B].W (сложить содержимое слова с адресом из B с регистром A с учётом флага переноса C)?
#E9 - DADC A,[B].W (десятично сложить содержимое слова с адресом из B с регистром A с учётом флага переноса C)?
#EA - DSUBC A,[B].W (десятично вычесть содержимое слова с адресом B из регистра A с учётом переноса C)?
#EB - SUBC A,[B].W (вычесть содержимое слово с адресом B из регистра A с учётом переноса C)?
#EC - JIDW (передать управление на команду с адресом A+1 и затем перейти по адресу из этого слова памяти)?
#ED - N/A
#EE - N/A
#EF - DIVD A,[B].W (беззнаково разделить двойное число X:A на слово из [B], остаток положить в X)? 
#F0 - LD A,[X+].W (загрузить в A слово по адресу из регистра X увеличив затем регистр X на 2)
#F1 - X A,[X+].W (поменять местами содержимое регистра A и слова по адресу X, увеличив затем регистр X на 2)
#F2 - LD A,[X-].W (загрузить в A слово по адресу из регистра X уменьшив затем регистр X на 2)
#F3 - X A,[X-].W (поменять местами содержимое регистра A и слова по адресу X, уменьшив затем регистр X на 2)
#F4 - LD A,[X].W (загрузить в A слово по адресу из регистра X)
#F5 - X A,[X].W (поменять местами содержимое регистра A и слова по адресу X)
#F6 - ST A,[X].W (сохранить содержимое регистра A в слове памяти по адресу X)
#F7 - RLC A (повернуть 16-битный регистр A влево через флаг C)
#F8 - ADD A,[B].W (сложить A и слово по 16-битному адресу из регистра B и сохранить результат в A)
#F9 - AND A,[B].W (побитная операция И 16-битного регистра A и слова по адресу, хранящемуся в регистре B)?
#FA - OR A,[B].W (побитная операция ИЛИ 16-битного регистра A и слова по адресу, хранящемуся в регистре B)?
#FB - XOR A,[B].W (побитная операция ИСКЛ.ИЛИ 16-битного регистра A и слова по адресу, хранящемуся в регистре B)?
#FC - IFEQ A,[B].W (выполнить следующую команду, если 16-битный регистр A равен слову из памяти по адресу из регистра B) 
#FD - IFGT A,[B].W (выполнить следующую команду, если 16-битный регистр A больше слова из памяти по адресу из регистра B)
#FE - MULT A,[B].W (беззнаково умножить A и слово по 16-адресу из регистра B и сохранить результат в регистре A и старшее слово в X) 
#FF - DIV A,[B].W (беззнаково разделить A на слово по 16-адресу из регистра B и сохранить результат в регистре A и остаток в X)
P.P.P.P.S. Ещё судя по листингам у них было 2 разных ассемблера со слегка отличающимся синтаксисом - HPCASM и "HPC CROSS ASSEMBLER".
Last edited by Shaos on 26 Apr 2013 06:55, edited 42 times in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Как он выглядит-то хоть?
iLavr
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Lavr wrote:Как он выглядит-то хоть?
Чёрный квадрат PLCC-68 :)

P.S. осталось документацию по опкодам найти... :roll:
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Интересно, что и mouser.com, и digkey.com их всё ещё продают - в том же самом безромном варианте, только там они числятся за Texas Instruments (который по видимому купил National Semiconductor какое-то время назад). Попробовал поискать на ti.com - в строке поиска даёт подсказки по названиям HPC46003, но результатов не находит :(

Почему они как микрочип например не писали систему команд прямо в даташите?...

P.S. Нашёл в интернете несколько Application Notes-ов от National Semiconductors 80-х годов, в которых есть листинги ассемблерных HPC-программ, в которых видно соответствие шестнадцатиричных кодов и ассемблерных команд - думаю можно поробовать составить таблицу :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote:P.S. Нашёл в интернете несколько Application Notes-ов от National Semiconductors 80-х годов, в которых есть листинги ассемблерных HPC-программ, в которых видно соответствие шестнадцатиричных кодов и ассемблерных команд - думаю можно поробовать составить таблицу :)
Пока из понятого по листингам: #4X это команда jmpl (и кстати jp тоже), которая перескакивает вперёд на X байт - причём #40 означает NOP (перескок на следующий байт), однако при более дальнем переходе уже используется команда #94 (которая на ассемблере тоже обозначена как jmpl), после которой идёт 1 байт где хранится беззнаковое смещение от следующего за этой командой байта (по видимому от 0 до 255), а при ещё более дальнем относительном переходе используется #B4 (как ни странно тоже jmpl), после которой идут 2 байта со смещением (судя по всему big endian). Это всё про смещение вперед - что же касается смещения назад, то для однобайтовой команды это #6X (обозначена почему то jp), для 1 байтового смешения используется код #95 с одним байтом после него. Движение назад считается не со следующего байта после команды, а от адреса самой команды, поэтому #60 используется как останов - зацикливание команды на саму себя, обозначаемое как jp .

P.S. Судя по инфе из даташита (в котором описаны ассемблерные команды, но нету опкодов), JP - это "jump relative short" (со значением смещения от +32 до -31), JMP - это "jump relative" (со значением смещения от +257 до -255), а JMPL - это "jump relative long" (с 2-байтовым значением), однако судя по листингу - ассемблер сам подставляет правильную команду, что бы там ни стояло. И кстати абсолютных переходов там нет совсем - только относительные...

P.P.S. Что-то сдаётся мне, что они в описании смещения "учли" размер самой команды при смещении вперёд - 1 байт для JP и 2 байта для JMP, т.е. на самом деле смещение от +31 до -31 и от +255 до -255 соответственно...

P.P.P.S. Короче, #40 это 0100 0000, а #60 это 0110 0000, т.е. похоже, что третий слева бит - это просто "знак" смещения:
010x xxxx - движение вперёд, причём следующая ячейка имеет нулевое смещение;
011x xxxx - движение назад, причём текущая ячейка имеет нулевое смещение.
Аналогично #94 это 1001 0100 (смещение вперёд) и #95 это 1001 0101 (смещение назад) где младший байт команды задаёт "знак" смещения.

P.P.P.P.S. Чую я, что для этой штуки придётся писать ассемблер с нуля, т.к. оригинального ассемблера уже не найти, а мой универсальный настраиваемый ассемблер RASM не понимает относительные переходы...

P.P.P.P.P.S. Буду писать выявленные опкоды в первый пост этого топика :roll:
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: HPC46003

Post by Shaos »

Shaos wrote:#96 X Y - SBIT/RBIT Y',X (установить или сбросить бит в байте по адресу X, а с представлением Y пока не разобрался,
т.к. SBIT 1... превращается в Y=#09, SBIT 5... в Y=#0D, SBIT 6... в Y=#0E, RBIT 6... в Y=#1E)
боюсь, что с этим опкодом придётся разбираться экспериментально, т.к. все примеры что есть - это обращение к чётным байтам и дополнительный бит номер 3 это может быть просто полное смещение в слове (плюс 8) - если были бы примеры нечётных байтов и там этой единички бы небыло, то теория бы подтвердилась
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16680
Joined: 21 Oct 2009 08:08
Location: Россия

Re: HPC46003

Post by Lavr »

Shaos wrote:Блуждая по www.jameco.com наткнулся на безромный 16-битный микроконтроллер
от National Semiconductor середины 90-х под названием HPC46003V20 в корпусе
PLCC68 за 15 бабосов ...
А чем он тебя так неожиданно заинтересовал, что ты "не глядя купил два"? 8)

Я посмотрел его Datasheet, пошарил о нём в сети, ничего, на мой взгляд,
сверхъестественного в нем... :-?
iLavr
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: HPC46003

Post by Shaos »

Lavr wrote:
Shaos wrote:Блуждая по www.jameco.com наткнулся на безромный 16-битный микроконтроллер
от National Semiconductor середины 90-х под названием HPC46003V20 в корпусе
PLCC68 за 15 бабосов ...
А чем он тебя так неожиданно заинтересовал, что ты "не глядя купил два"? 8)

Я посмотрел его Datasheet, пошарил о нём в сети, ничего, на мой взгляд,
сверхъестественного в нем... :-?
Объясняю свою мотивацию:
- этот микроконтроллер имеет возможность работать с внешней памятью, причём тот факт, что это фон-нейман, а не гарвард, делает из него полноценный микропроцессор;
- для своего времени он был самым быстрым, как пишут - и действительно, многое можно делать 1-байтными командами, самые быстрые из которых занимают только 4 такта процессора (если верить даташиту);
- проц полноценно 16-битный с 16-битным ALU, 16-битными регистрами и опциональной 16-битной памятью снаружи;
- все регистры, порты и управление замаплены в общую память с 16-битной адресацией, причём есть своя "zero page" (по аналогии с 6502), для работы с которой есть более короткие команды (адрес задаётся 8 битами вместо 16);
- безромная версия до сих пор продаётся как минимум в трёх местах (jameco.com, mouser.com, digikey.com);
- описание опкодов нет и все официальные средства разработки потеряны, а опенсорцных не создано - есть где применить свои способности реверс-инжиниринга (читай "хакерские");
- самоделок на основе этого проца в сети не найдено и я намереваюсь восполнить этот пробел.

P.S. С другой стороны наличие у этого проца милитаристского варианта может привести к тому, что мне придётся общаться с эфбиайщиками после публикации информации о системе команд этого "засекреченного" проца и опенсорцных средств разработки под него...

P.P.S. Также была мысль попробовать построить PIXPUTER на HPC46003 вместо PIC17, сохранив всю периферию и способ разбивки памяти на части...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: HPC46003

Post by Shaos »

Shaos wrote: #96 X Y - SBIT/RBIT/IFBIT Y',X (установить, сбросить или проверить бит в байте по адресу X, а с представлением Y пока не разобрался,
т.к. SBIT 1... превращается в Y=#09, SBIT 5... в Y=#0D, SBIT 6... в Y=#0E, RBIT 6... в Y=#1E, IFBIT 7... в Y=#17)
Увидев, что в листинге есть команда SUBC с тем же кодом #96 я похоже понял его назначение - это ПРЕФИКС :)
Команда вида #96 X Y означает - выполнить 1-байтовкую команду Y, но вместо надо взять ячейку с адресом X :)
Таким обрзом команда #17 означает проверить бит 7 у ячейки (ячейка с адресом из регистра B), а команда #96 #00 #17 - проверить бит 7 у 16-битного слова, расположенного по нулевому адресу!

P.S. Означает ли это положить значение X в регистр B? Временно?...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Есть некоторые непонятности с загрузкой данных в адреса памяти больше #0100, например - запись числа 7 в слово с адресом #0188:
#83 #07 #01 #88 #AB
что делает в конце этой команды #AB совершенно непонятно, а вот запись числа 0 в байт с адресом #018F:
#83 #00 #01 #8F #8B
как видим тут уже стоит необъяснимый код #8B
Вот ещё более "страшная" конструкция - запись числа #4040 в слово по адресу #0190:
#87 #40 #40 #01 #90 #AB
как видим тут опять #AB в конце, но код самой команды другой - #87 вместо #83 - если предположить что это префиксы, меняющее поведение далее идущей команды (как #96 например), то можно посмотреть на команду #AB - это команда сохранения A по короткому адресу - ST A,short_addr - которая к тому же имеет однобайтовый аргумент - т.е. не совсем логично...

P.S. Вобщем опишу как есть - предполагая что эти суффиксы обязательны и являются составной частью длинной команды...
Я тут за главного - если что шлите мыло на me собака shaos точка net
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Post by b2m »

Shaos wrote:но код самой команды другой - #87 вместо #83 - если предположить что это префиксы, меняющее поведение далее идущей команды (как #96 например), то можно посмотреть на команду #AB - это команда сохранения A по короткому адресу - ST A,short_addr - которая к тому же имеет однобайтовый аргумент - т.е. не совсем логично...
Видимо, это команды-префиксы, которые меняют для следующей команды регистр или аргумент. Можно поменять только регистр, или только аргумент, или оба сразу. Типа как префиксы IX,IY у Z80 или префиксы размера данных/адреса у x86. И похоже, что 80-87 это всё префиксы, т.е. младшие три бита определяют, что именно будет заменено.

Короче, я так думаю, команды контроллера работают с временными регистрами-адресами источника и приёмника (номер регистра или адрес в памяти), которые по-умолчанию устанавливаются в начале команды (или в конце пердыдущей) в какие-то предопределённые значения. А префиксы могут их менять. Например, по-умолчанию A и (PC)+, т.е. приёмник - 00С8, источник - (00С6) с автоинкрементом. Тут сразу вспоминаются методы адресации PDP-11 :)

Кстати, AB работает со словами, 8B с байтами, т.е. возможно в команде есть бит размера операнда. Сравни, например, D0 и F0.
Т.е. 5-тый бит определяет - байт или слово.
В связи с этим, A0-A7 тоже префиксы :)
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Post by b2m »

Вот, не мучайся - полная таблица opcode map на пятой странице.
И на всякий случай прямая ссылка на datasheet.

Хи-хи-хи, самая быстрая команда 6 тактов :)
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Post by b2m »

В документе по ссылке выше совсем не описано соответствие префиксов конкретным методам адресации. По информации из первого поста заключаем следующее:

Code: Select all

80 
81 
82 #i8 -> (a8).b
83 #i8 -> (a16).b
84 
85 
86 
87 #i16 -> (a16).w

A0 (a8).w -> (a8).w
A1 
A2 
A3 ---
A4 (a16).w -> (a8).w
A5 
A6 
A7 ---
Сразу можно "додумать" четвёртый способ Imm - Dir:

Code: Select all

80 
81 
82 #i8 -> (a8).b
83 #i8 -> (a16).b
84 
85 
86 #i16 -> (a8).w
87 #i16 -> (a16).w

A0 (a8).w -> (a8).w
A1 
A2 
A3 ---
A4 (a16).w -> (a8).w
A5 
A6 
A7 ---
А также пару способов Dir - Dir (сначала предполагаем A5, потом становится ясным A1):

Code: Select all

80 
81 
82 #i8 -> (a8).b
83 #i8 -> (a16).b
84 
85 
86 #i16 -> (a8).w
87 #i16 -> (a16).w

A0 (a8).w -> (a8).w
A1 (a8).w -> (a16).w
A2 
A3 ---
A4 (a16).w -> (a8).w
A5 (a16).w -> (a16).w
A6 
A7 ---
Можно ещё про индексный догадаться:

Code: Select all

80 
81 
82 #i8 -> (a8).b
83 #i8 -> (a16).b
84 
85 
86 #i16 -> (a8).w
87 #i16 -> (a16).w

A0 (a8).w -> (a8).w
A1 (a8).w -> (a16).w
A2 ((a8)+#i8).w -> A
A3 ---
A4 (a16).w -> (a8).w
A5 (a16).w -> (a16).w
A6 ((a8)+#i16).w -> A
A7 ---
А вот что означают ещё 4 способа Dir - Dir, пока непонятно. Полагаю, они позволяют брать байт, расширять знак (хотя может и просто с нулевым старшим байтом), и использовать как слово. В таком случае полная таблица соответствия будет:

Code: Select all

80 (a8).b -> (a8).w
81 (a8).b -> (a16).w
82 #i8 -> (a8).b
83 #i8 -> (a16).b
84 (a16).b -> (a8).w
85 (a16).b -> (a16).w
86 #i16 -> (a8).w
87 #i16 -> (a16).w

A0 (a8).w -> (a8).w
A1 (a8).w -> (a16).w
A2 ((a8)+#i8).w -> A
A3 ---
A4 (a16).w -> (a8).w
A5 (a16).w -> (a16).w
A6 ((a8)+#i16).w -> A
A7 ---
Но последнее - это только догадки.

Команды, работающие с байтами, делают всё аналогично, но пишут только младший байт.

Ещё наблюдение: бинарные команды ALU в диапазоне 80-BF полагают по-умолчанию адресацию (PC)+ -> A, а в диапазоне C0-FF адресацию (B) -> A
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

b2m wrote:Вот, не мучайся - полная таблица opcode map на пятой странице.
И на всякий случай прямая ссылка на datasheet.

Хи-хи-хи, самая быстрая команда 6 тактов :)
О - за таблицу опкодов спасибо :)
Самое интересное, что это тоже "Application Note" (AN-585), но его небыло в общей свалке AN от National на bitsavers где я взял все остальные с листингами :roll:
А датащит у меня был - там опкодов нету ;)
Last edited by Shaos on 22 Apr 2013 06:24, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Post by b2m »

Shaos wrote:А датащит у меня был - там опкодов нету ;)
Зато там есть кое-что про 16-битный режим работы памяти, но как адресуются байты в этом режиме - я так и не понял, написано, что для этого используется /HBE, видимо в комбинации с битом A0. А как конкретно происходит обмен - диаграмм нет.

А, нашёл на картинке - /CS младшего байта это A0, а /CS старшего байта это /HBE.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/