6502

MOS Technology / Commodore / Apple II / NES etc.

Moderator: Lavr

User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Что-то я не пойму одну вещь в поведении стека микропроцессора 6502...

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

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

Но уже в который раз попадаются мне рассуждения про "overflow" и "underflow", типа:
Overflow and underflow wrote: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: Select all

/*
 *  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
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Странно как-то... этот 6502 такой древний и "разжеванный" процессор, а подробностей
про "stack overflow" и "underflow" особо-то и не найти... :(

Но мне думается, принцип работы стека 6502 я всё же понимаю правильно, исходя хотя бы
из следующих ссылок:
Описание ПЭВМ Агат wrote:В машине имеется 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.
Atari 8-bit OS User Manual wrote: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: Select all

/*
 *  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
User avatar
Shaos
Admin
Posts: 24033
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Возмжно опять дело в различиях оригинального 6502 и "исправленного" 65C02...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Shaos wrote:Возмжно опять дело в различиях оригинального 6502 и "исправленного" 65C02...
Ты хочешь сказать, что "оригинальный 6502" прекращает свою работу по "stack overflow" и "underflow" ? 8)
У него, конечно, много странностей у этого 6502, но - не поверю...
iLavr
User avatar
Shaos
Admin
Posts: 24033
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Lavr wrote:
Shaos wrote:Возмжно опять дело в различиях оригинального 6502 и "исправленного" 65C02...
Ты хочешь сказать, что "оригинальный 6502" прекращает свою работу по "stack overflow" и "underflow" ? 8)
У него, конечно, много странностей у этого 6502, но - не поверю...
не - наоборот - оригинальный беспроблем заворачивал стек, а 65C02 на эту тему "пофикшен"...

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

P.P.S. поизучал вопрос - в списке отличий 6502 и 65C02 про отличия в поведении стека ничего не указано, более того, пишут что в раннем софте для всяких апплов и т д регистр S вообще не инициализирвался никогда и проц его тоже не инициализирует - т.е. он имеет при старте случайное значение - в этом случае логичное поведение это просто крутить кольцо стека при пушах-попах т.к. переход через границу технически ничего не меняет - просто больше 256 байт нельзя затолкать не потерев самое старое...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Shaos wrote:логичное поведение это просто крутить кольцо стека при пушах-попах т.к. переход через границу
технически ничего не меняет - просто больше 256 байт нельзя затолкать не потерев самое старое...
Чисто аппаратно, естественно, ничего не меняет... а чисто программно - я почитал - это довольно
зловещий трюк иногда.

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

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

Image
Last edited by Lavr on 24 Dec 2014 09:16, edited 1 time in total.
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Я не так чтобы давно занимаюсь как 6502, так и его ассемблером,
но тут один код ввел меня в смущение: :(

Code: Select all

*=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: Select all

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
Mixa64
Doomed
Posts: 481
Joined: 25 Aug 2009 07:02
Location: Москва

Post by Mixa64 »

*= на ORG похоже, < и > похожи на взятие младшего и старшего байтов 16-бит слова.
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Mixa64 wrote:*= на ORG похоже...
А не многовато ORG-ов?

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

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

Но я нигде ничего не смог нагуглить про *=, <, > ... :-?
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

По тексту *= обрабатывается вот так:

Code: Select all

      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: Select all

 // 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
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Lavr wrote:Я не так чтобы давно занимаюсь как 6502, так и его ассемблером,
Что означает звездочка ' *= ' ?
Что означают "стрелки" ' < ' , ' > ' ?
Мне такие обозначения не встречались ранее ни разу... :o
Оказывается, это псевдооператоры Assembler - C64.
http://tnd64.unikat.sk/assemble_it4.html
iLavr
Mixa64
Doomed
Posts: 481
Joined: 25 Aug 2009 07:02
Location: Москва

Post by Mixa64 »

Lavr wrote:
Lavr wrote:Я не так чтобы давно занимаюсь как 6502, так и его ассемблером,
Что означает звездочка ' *= ' ?
Что означают "стрелки" ' < ' , ' > ' ?
Мне такие обозначения не встречались ранее ни разу... :o
Оказывается, это псевдооператоры Assembler - C64.
http://tnd64.unikat.sk/assemble_it4.html
Ну так *= аналог ORG и есть. Это как если бы в асме 8080 написать $=1234 вместо ORG 1234, но асм 8080 так не поймет.
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Mixa64 wrote:Это как если бы в асме 8080 написать $=1234 вместо ORG 1234, но асм 8080 так не поймет.
Это смотря еще какой асм 8080, а то может так случиться, что он множество псевдооператоров
ORG и не поймёт вовсе.

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


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

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

Code: Select all

    CALL KBD

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

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

Code: Select all

KBD  =  $f803
Но здесь это не срабатывает... :(
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: 6502

Post by Lavr »

Джентльмены!!! У кого старшие свежие версии 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
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: 6502

Post by Lavr »

Я сегодня много всякой всячины по 6502 понаходил, поскольку проводил поиск по вопросу довольно наивному:
"отечественное УГО микропроцессора 6502". :wink:

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

Я, конечно, и сам нарисовать могу, но хотелось посмотреть хотя бы на один реальный образец...
И как-то я не сразу пришел к мысли, что копать надо в схемотехнике компьютера "Агат" - там-то уж наверняка
отечественное УГО микропроцессора 6502 или его клона должно быть!
CM630P.gif
http://agatcomp.ru/Reading/ns/sysboard-elect-0-l.djvu

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

А вот так и сам CM630P выглядит.
CM630P.jpg
You do not have the required permissions to view the files attached to this post.
iLavr