nedoPC.org

Community of electronics hobbyists established in 2002

...
Atom Feed | View unanswered posts | View active topics It is currently 22 Oct 2018 02:08



Reply to topic  [ 79 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
6502 
Author Message
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Что-то я не пойму одну вещь в поведении стека микропроцессора 6502...

Я так полагал, что поскольку регистр указателя стека S - 8-битный и указывает в 1 страницу,
то он уменьшается, скажем, от значения $FF до значения $00, если мы заносим в стек значения.

Если при значении указателя стека S = $00 мы занесем в стек еще 1 байт, то указатель стека S
примет значение $FF.
То есть стек на увеличение или уменьшение работает как-бы "по кругу", как в PIC-ах...

Но уже в который раз попадаются мне рассуждения про "overflow" и "underflow", типа:
The terms "overflow" and "underflow" refer to situations where the program is either attempting to push more data on to the stack when S is already at $FF, or attempting to pull data off of the stack when S is already at $00. Usually this implies a PHA vs. PLA mismatch of some sort.

Most commonly, "overflow" refers to pushing more items than the stack's array can hold, and "underflow" refers to pulling from an empty stack. But occasionally, especially with descending stacks, some people reverse these two terms.


Нет, я, конечно, понимаю, что при выходе за верхнюю или нижнюю границу стека, мы "запорем" частично его содержимое.
Но сам процессор-то 6502, как не остановится при этом, так и никак аппаратно не среагирует на эти "overflow" и "underflow".

Так в чем же смысл этих рассуждений про "overflow" и "underflow", или я что-то не так понимаю?

Меня смутила реализация push и pop в JS-эмуляторе 6502:
Code:
/*
 *  stackPush() - Push byte to stack
 *
 */

function stackPush( value ) {
  if( regSP >= 0 ) {
      regSP--;
      memory[(regSP&0xff)+0x100] = value & 0xff;
    }
     else
    {
      message( "Stack full: " + regSP );
      codeRunning = false;
    }
}

/*
 *  stackPop() - Pop byte from stack
 *
 */

function stackPop() {
  if( regSP < 0x100 ) {
    value = memory[regSP+0x100];
    regSP++;
    return value;
  }
   else
  {
    message( "Stack empty" );
    codeRunning = false;
    return 0;
  }
}


Они останавливают эмуляцию в ситуациях "overflow" и "underflow". :o

_________________
iLavr


13 Dec 2014 12:54
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Странно как-то... этот 6502 такой древний и "разжеванный" процессор, а подробностей
про "stack overflow" и "underflow" особо-то и не найти... :(

Но мне думается, принцип работы стека 6502 я всё же понимаю правильно, исходя хотя бы
из следующих ссылок:
В машине имеется aппaрaтно реaлизовaнный стек, предназначенный, в первую очередь, для сохранения адресов возврата из подпрограмм и прерываний и для временного сохранения регистров процессора. Физически под нeгo отведенa облaсть пaмяти в aдpecax 100-1FF. Зaпoлнeниe cтeкa пpoиcxoдит в cтopoну умeньшeния aдpecoв цикличecки (нaчaльнoe знaчeниe oбычнo нecущecтвeннo, контроля за переполнением стека нет). Cпeцpегистp S содержит млaдший бaйт aдpeca пepвoгo cвoбoднoгo бaйтa cтeкa.

The 6502 stack pointer is initialized at power-up or system reset to point to location 01FF. The stack than pushes downward toward 0100. The stack will wrap around from 0100 to 01FF if a stack overflow condition occurs, because of the nature of the 6502's 8-bit stack pointer register.

Исправил код:
Code:
/*
 *  stackPush() - Push byte to stack
 *
 */

function stackPush( value ) {
  if( regSP >= 0 ) {
      regSP--;
      memory[(regSP&0xff)+0x100] = value & 0xff;
    }
     else
    {
      message( "CPU Stack full: SP = $" + addr2hex(regSP).toUpperCase() );
      regSP = 0xff;
      message( "Stack overflow: SP = $" + num2hex(regSP).toUpperCase() );
      memory[(regSP&0xff)+0x100] = value & 0xff;
    }
}

/*
 *  stackPop() - Pop byte from stack
 *
 */

function stackPop() {
  if( regSP < 0x100 ) {
    value = memory[regSP+0x100];
    regSP++;
    return value;
  }
   else
  {
    message( "CPU Stack empty: SP = $" + addr2hex(regSP).toUpperCase() );
    regSP = 0;
    message( "Stack underflow: SP = $" + num2hex(regSP).toUpperCase() );
    value = memory[regSP+0x100];
    return value;
  }
}

_________________
iLavr


14 Dec 2014 01:25
Profile
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 17028
Location: Colorado
Reply with quote
Post 
Возмжно опять дело в различиях оригинального 6502 и "исправленного" 65C02...

_________________
:eugeek: https://twitter.com/Shaos1973


14 Dec 2014 11:39
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Shaos wrote:
Возмжно опять дело в различиях оригинального 6502 и "исправленного" 65C02...

Ты хочешь сказать, что "оригинальный 6502" прекращает свою работу по "stack overflow" и "underflow" ? 8)
У него, конечно, много странностей у этого 6502, но - не поверю...

_________________
iLavr


14 Dec 2014 13:13
Profile
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 17028
Location: Colorado
Reply with quote
Post 
Lavr wrote:
Shaos wrote:
Возмжно опять дело в различиях оригинального 6502 и "исправленного" 65C02...

Ты хочешь сказать, что "оригинальный 6502" прекращает свою работу по "stack overflow" и "underflow" ? 8)
У него, конечно, много странностей у этого 6502, но - не поверю...


не - наоборот - оригинальный беспроблем заворачивал стек, а 65C02 на эту тему "пофикшен"...

P.S. это только моя гипотеза, если что...

P.P.S. поизучал вопрос - в списке отличий 6502 и 65C02 про отличия в поведении стека ничего не указано, более того, пишут что в раннем софте для всяких апплов и т д регистр S вообще не инициализирвался никогда и проц его тоже не инициализирует - т.е. он имеет при старте случайное значение - в этом случае логичное поведение это просто крутить кольцо стека при пушах-попах т.к. переход через границу технически ничего не меняет - просто больше 256 байт нельзя затолкать не потерев самое старое...

_________________
:eugeek: https://twitter.com/Shaos1973


14 Dec 2014 14:09
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Shaos wrote:
логичное поведение это просто крутить кольцо стека при пушах-попах т.к. переход через границу
технически ничего не меняет - просто больше 256 байт нельзя затолкать не потерев самое старое...

Чисто аппаратно, естественно, ничего не меняет... а чисто программно - я почитал - это довольно
зловещий трюк иногда.

Но меня это здесь, естественно, чисто аппаратно интересовало - из-за кода выше...

Это я, кстати, вот этот код правлю: http://www.6502asm.com/
ошибок там имеется, ну и я кое-какие свои приблуды добавил.

Image

_________________
iLavr


Last edited by Lavr on 24 Dec 2014 10:16, edited 1 time in total.



14 Dec 2014 18:04
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Я не так чтобы давно занимаюсь как 6502, так и его ассемблером,
но тут один код ввел меня в смущение: :(
Code:
*=128
player_map_x:
*=129
player_map_y:
*=130
player_screen_x:
*=131
player_screen_y:
*=132
player_sprite:
*=133
screen_item_x:
*=134
screen_item_y:
*=135
screen_item_idx:
*=136
item_flags:
*=138

*=254
random:
*=255
keypress:

*=512
frame_buffer:

*=1536
jmp    start

Что означает звездочка ' * ' ?

Code:
start:
  ; Init item patch table pointers
  ldx    #0
  lda    #<screen_data
  sta    item_patch_table_lo,x
  lda    #>screen_data
  sta    item_patch_table_hi,x
  inx
  lda    #<sprite_data
  sta    item_patch_table_lo,x
  lda    #>sprite_data
  sta    item_patch_table_hi,x
  inx
  lda    #<tile_flags
  sta    item_patch_table_lo,x
  lda    #>tile_flags
  sta    item_patch_table_hi,x
  inx
  lda    #<item_flags
  sta    item_patch_table_lo,x
  lda    #>item_flags
  sta    item_patch_table_hi,x

  ; Init player position, etc
  lda    #$00
  sta    player_map_x
  lda    #$00
  sta    player_map_y
...

Что означают "стрелки" ' < ' , ' > ' ?

Мне такие обозначения не встречались ранее ни разу... :o
Возможно, это какая-то локальная нотация?

Код взят отюда: adventure.asm

_________________
iLavr


16 Dec 2014 14:00
Profile
Doomed

Joined: 25 Aug 2009 08:02
Posts: 360
Location: Москва
Reply with quote
Post 
*= на ORG похоже, < и > похожи на взятие младшего и старшего байтов 16-бит слова.


16 Dec 2014 14:54
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Mixa64 wrote:
*= на ORG похоже...

А не многовато ORG-ов?

У меня такое предположение, что *= похоже на $ в обычном ассемблере -
"этот адрес" ($+1 и т.д.).

У 6502 $ в ассемблере задействован под hex.

Но я нигде ничего не смог нагуглить про *=, <, > ... :-?

_________________
iLavr


16 Dec 2014 16:03
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
По тексту *= обрабатывается вот так:
Code:
      command = command.toUpperCase(); //--- Upper Case
  if( input.match( /^\*[\s]*=[\s]*[\$]?[0-9a-f]*$/ ) ) {
    // equ spotted --
    param = input.replace( new RegExp( /^[\s]*\*[\s]*=[\s]*/ ), "" );
    if( param[0] == "$" ) {
      param = param.replace( new RegExp( /^\$/ ), "" );
      addr = parseInt( param, 16 );
    } else {
      addr = parseInt( param, 10 );
    }


Mixa64 wrote:
< и > похожи на взятие младшего и старшего байтов 16-бит слова.

А вот это, видимо, реально так:
Code:
 // Label lo/hi
  if( param.match( new RegExp( /^#[<>]\w+$/ ) ) ) {
    label = param.replace( new RegExp( /^#[<>](\w+)$/ ), "$1" );
    hilo = param.replace( new RegExp( /^#([<>]).*$/ ), "$1" );
    pushByte( opcode );
    if( findLabel( label ) ) {
      addr = getLabelPC( label );
      switch( hilo ) {
        case ">":
          pushByte( (addr >> 8) & 0xff );
          return true;
          break;
        case "<":
          pushByte( addr & 0xff );
          return true;
          break;
        default:
          return false;
          break;
     }

_________________
iLavr


16 Dec 2014 16:33
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Lavr wrote:
Я не так чтобы давно занимаюсь как 6502, так и его ассемблером,
Что означает звездочка ' *= ' ?
Что означают "стрелки" ' < ' , ' > ' ?
Мне такие обозначения не встречались ранее ни разу... :o

Оказывается, это псевдооператоры Assembler - C64.
http://tnd64.unikat.sk/assemble_it4.html

_________________
iLavr


20 Dec 2014 19:45
Profile
Doomed

Joined: 25 Aug 2009 08:02
Posts: 360
Location: Москва
Reply with quote
Post 
Lavr wrote:
Lavr wrote:
Я не так чтобы давно занимаюсь как 6502, так и его ассемблером,
Что означает звездочка ' *= ' ?
Что означают "стрелки" ' < ' , ' > ' ?
Мне такие обозначения не встречались ранее ни разу... :o

Оказывается, это псевдооператоры Assembler - C64.
http://tnd64.unikat.sk/assemble_it4.html

Ну так *= аналог ORG и есть. Это как если бы в асме 8080 написать $=1234 вместо ORG 1234, но асм 8080 так не поймет.


23 Dec 2014 04:42
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Mixa64 wrote:
Это как если бы в асме 8080 написать $=1234 вместо ORG 1234, но асм 8080 так не поймет.

Это смотря еще какой асм 8080, а то может так случиться, что он множество псевдооператоров
ORG и не поймёт вовсе.

По крайней мере "Микрон", который здесь на форуме мне насоветовали в качестве 'стандарта',
несколько ORG не поймёт однозначно.


Я что-то одного не пойму пока в этом Assembler - C64 - что у них является эквивалентом 'EQU'.

Если для 8080 я могу написать:

Code:
    CALL KBD

KBD:EQU 0F803H


То как это сделать в Assembler - C64 - пока не представляю и не попалось нигде...

На страницах о C64 'EQU' в его ассемблере изображают вот так:
Code:
KBD  =  $f803

Но здесь это не срабатывает... :(

_________________
iLavr


23 Dec 2014 11:23
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Джентльмены!!! У кого старшие свежие версии Proteus ISIS? Похоже, что в них появилась модель 65С02 ! :o

По меньшей мере схему я увидел вот здесь: Problem with glue logic/memory decoding on a 6502 project... :roll:

 Memory decoding on a 6502 project schematics
Image

_________________
iLavr


07 May 2016 06:06
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 09:08
Posts: 7777
Location: Россия
Reply with quote
Я сегодня много всякой всячины по 6502 понаходил, поскольку проводил поиск по вопросу довольно наивному:
"отечественное УГО микропроцессора 6502". :wink:

Ведь был же у нас хотя бы клон 4.К602ВМ1 (https://ru.wikipedia.org/wiki/4К602ВМ1), значит и отечественное
УГО должно быть! :o

Я, конечно, и сам нарисовать могу, но хотелось посмотреть хотя бы на один реальный образец...
И как-то я не сразу пришел к мысли, что копать надо в схемотехнике компьютера "Агат" - там-то уж наверняка
отечественное УГО микропроцессора 6502 или его клона должно быть!

Attachment:
CM630P.gif
CM630P.gif [ 317.36 KiB | Viewed 3918 times ]
http://agatcomp.ru/Reading/ns/sysboard-elect-0-l.djvu

Вот так на схемах компьютера "Агат" выглядит клон 6502 - CM630P...

А вот так и сам CM630P выглядит.
Attachment:
CM630P.jpg
CM630P.jpg [ 36.23 KiB | Viewed 3918 times ]

_________________
iLavr


07 May 2016 07:15
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 79 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.